mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Add running-task exit choices to local daemon sessions (#38447)
## What changed When `Ctrl-C` is pressed with an empty composer while a task is running in a local daemon session, show a menu that lets the user: - cancel the task and stay in Codex; - exit Codex while leaving the task running; or - stop the task and exit Codex. Do not offer background execution for side-thread tasks or when follow-up messages are queued. Preserve existing `Ctrl-C` behavior for non-daemon sessions, drafts, paste bursts, MCP startup, and returning from an active side thread. ## Testing Add TUI tests for each exit action, menu dismissal, side threads, queued follow-ups, composer input, MCP startup, and non-daemon sessions. GitOrigin-RevId: 539c33d3a4ff288a015bddbe9465d2bbdbe018d0
This commit is contained in:
1 parent
6344a655a5
commit
ca83f7908c
9 files changed
+593
-11
No files matched your search
@@ -531,6 +531,61 @@ impl App {
|
||||
}
|
||||
return Ok(self.handle_exit_mode(app_server, mode).await);
|
||||
}
|
||||
AppEvent::RunningTaskExit { action, thread_id } => match action {
|
||||
RunningTaskExitAction::RunInBackground => {
|
||||
return Ok(self.handle_exit_mode(app_server, ExitMode::Immediate).await);
|
||||
}
|
||||
RunningTaskExitAction::CancelTask => {
|
||||
if self.chat_widget.thread_id() == Some(thread_id)
|
||||
&& self.chat_widget.is_agent_turn_running()
|
||||
&& self.chat_widget.submit_op(AppCommand::interrupt())
|
||||
{
|
||||
self.chat_widget.pause_active_goal_for_interrupt();
|
||||
} else if self.side_threads.contains_key(&thread_id)
|
||||
&& let Err(error) = self
|
||||
.try_submit_active_thread_op_via_app_server(
|
||||
app_server,
|
||||
thread_id,
|
||||
&AppCommand::interrupt(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
self.chat_widget
|
||||
.add_error_message(format!("Failed to interrupt task: {error}"));
|
||||
}
|
||||
}
|
||||
RunningTaskExitAction::Exit => {
|
||||
if self.chat_widget.thread_id() == Some(thread_id)
|
||||
&& self.chat_widget.is_active_goal_turn_running()
|
||||
&& let Err(error) = app_server
|
||||
.thread_goal_set(
|
||||
thread_id,
|
||||
/*objective*/ None,
|
||||
Some(codex_app_server_protocol::ThreadGoalStatus::Paused),
|
||||
/*token_budget*/ None,
|
||||
)
|
||||
.await
|
||||
{
|
||||
self.chat_widget
|
||||
.add_error_message(format!("Failed to pause task goal: {error}"));
|
||||
return Ok(AppRunControl::Continue);
|
||||
}
|
||||
let turn_id = self
|
||||
.active_turn_id_for_thread(thread_id)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
match app_server.turn_interrupt(thread_id, turn_id).await {
|
||||
Ok(()) => {
|
||||
self.app_event_tx
|
||||
.send(AppEvent::Exit(ExitMode::ShutdownFirst));
|
||||
}
|
||||
Err(error) => {
|
||||
self.chat_widget
|
||||
.add_error_message(format!("Failed to interrupt task: {error}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
AppEvent::Logout => match app_server.logout_account().await {
|
||||
Ok(()) => {
|
||||
self.show_shutdown_feedback(tui)?;
|
||||
|
||||
Reference in new issue
Block a user