mirror of
https://github.com/openai/codex.git
synced 2026-05-05 05:42:33 +03:00
Allow user shell commands to run alongside active turns (#10513)
Summary - refactor user shell command execution into a shared helper and add modes for standalone vs active-turn execution - run user shell commands asynchronously when a turn is already active so they don’t replace or abort the current turn - extend the tests to cover the new behavior and add the generated Codex environment manifest Testing - Not run (not requested)
This commit is contained in:
@@ -31,6 +31,7 @@ use crate::state::ActiveTurn;
|
||||
use crate::state::RunningTask;
|
||||
use crate::state::TaskKind;
|
||||
use codex_protocol::models::ContentItem;
|
||||
use codex_protocol::models::ResponseInputItem;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::protocol::RolloutItem;
|
||||
use codex_protocol::user_input::UserInput;
|
||||
@@ -40,7 +41,9 @@ pub(crate) use ghost_snapshot::GhostSnapshotTask;
|
||||
pub(crate) use regular::RegularTask;
|
||||
pub(crate) use review::ReviewTask;
|
||||
pub(crate) use undo::UndoTask;
|
||||
pub(crate) use user_shell::UserShellCommandMode;
|
||||
pub(crate) use user_shell::UserShellCommandTask;
|
||||
pub(crate) use user_shell::execute_user_shell_command;
|
||||
|
||||
const GRACEFULL_INTERRUPTION_TIMEOUT_MS: u64 = 100;
|
||||
const TURN_ABORTED_INTERRUPTED_GUIDANCE: &str = "The user interrupted the previous turn on purpose. If any tools/commands were aborted, they may have partially executed; verify current state before retrying.";
|
||||
@@ -187,15 +190,27 @@ impl Session {
|
||||
last_agent_message: Option<String>,
|
||||
) {
|
||||
let mut active = self.active_turn.lock().await;
|
||||
let should_close_processes = if let Some(at) = active.as_mut()
|
||||
let mut pending_input = Vec::<ResponseInputItem>::new();
|
||||
let mut should_close_processes = false;
|
||||
if let Some(at) = active.as_mut()
|
||||
&& at.remove_task(&turn_context.sub_id)
|
||||
{
|
||||
let mut ts = at.turn_state.lock().await;
|
||||
pending_input = ts.take_pending_input();
|
||||
should_close_processes = true;
|
||||
}
|
||||
if should_close_processes {
|
||||
*active = None;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
}
|
||||
drop(active);
|
||||
if !pending_input.is_empty() {
|
||||
let pending_response_items = pending_input
|
||||
.into_iter()
|
||||
.map(ResponseItem::from)
|
||||
.collect::<Vec<_>>();
|
||||
self.record_conversation_items(turn_context.as_ref(), &pending_response_items)
|
||||
.await;
|
||||
}
|
||||
if should_close_processes {
|
||||
self.close_unified_exec_processes().await;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user