diff --git a/codex-rs/core/src/agent/registry.rs b/codex-rs/core/src/agent/registry.rs index 75324f9ee6..ef64ab5ab5 100644 --- a/codex-rs/core/src/agent/registry.rs +++ b/codex-rs/core/src/agent/registry.rs @@ -225,7 +225,7 @@ impl AgentRegistry { } } - pub(crate) fn register_agent(&self, mut agent_metadata: AgentMetadata) { + fn register_agent(&self, agent_metadata: AgentMetadata) { let Some(thread_id) = agent_metadata.agent_id else { return; }; @@ -241,11 +241,6 @@ impl AgentRegistry { if let Some(agent_nickname) = agent_metadata.agent_nickname.clone() { active_agents.used_agent_nicknames.insert(agent_nickname); } - if let Some(existing) = active_agents.agent_tree.get(key.as_str()) - && agent_metadata.last_task_message.is_none() - { - agent_metadata.last_task_message = existing.last_task_message.clone(); - } active_agents.agent_tree.insert(key, agent_metadata); } diff --git a/codex-rs/core/src/goals.rs b/codex-rs/core/src/goals.rs index 6e0663655c..b731c2aa16 100644 --- a/codex-rs/core/src/goals.rs +++ b/codex-rs/core/src/goals.rs @@ -1326,7 +1326,8 @@ impl Session { .await; return; } - self.start_task(turn_context, Vec::new(), RegularTask::new()) + let _ = self + .start_task(turn_context, Vec::new(), RegularTask::new()) .await; } diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index 6a032f8166..b9787b1c34 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -22,7 +22,6 @@ use crate::realtime_conversation::prefix_realtime_v2_text; use crate::review_prompts::resolve_review_request; use crate::session::spawn_review_thread; use crate::tasks::CompactTask; -use crate::tasks::StartTaskOutcome; use crate::tasks::UserShellCommandMode; use crate::tasks::UserShellCommandTask; use crate::tasks::execute_user_shell_command; @@ -282,8 +281,8 @@ pub(super) async fn user_input_or_turn_inner( ) .await { - StartTaskOutcome::Started => Some(accepted_items), - StartTaskOutcome::Rejected(err) => { + Ok(()) => Some(accepted_items), + Err(err) => { sess.send_event_raw(Event { id: sub_id, msg: EventMsg::Error(err.to_error_event(/*message_prefix*/ None)), @@ -365,12 +364,13 @@ pub async fn run_user_shell_command(sess: &Arc, sub_id: String, command } let turn_context = sess.new_default_turn_with_sub_id(sub_id).await; - sess.spawn_task( - Arc::clone(&turn_context), - Vec::new(), - UserShellCommandTask::new(command), - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&turn_context), + Vec::new(), + UserShellCommandTask::new(command), + ) + .await; } pub async fn resolve_elicitation( @@ -499,7 +499,8 @@ pub async fn reload_user_config(sess: &Arc) { pub async fn compact(sess: &Arc, sub_id: String) { let turn_context = sess.new_default_turn_with_sub_id(sub_id).await; - sess.spawn_task(Arc::clone(&turn_context), Vec::new(), CompactTask) + let _ = sess + .spawn_task(Arc::clone(&turn_context), Vec::new(), CompactTask) .await; } diff --git a/codex-rs/core/src/session/inject.rs b/codex-rs/core/src/session/inject.rs index 3f73cd96d0..3c3d0f9aca 100644 --- a/codex-rs/core/src/session/inject.rs +++ b/codex-rs/core/src/session/inject.rs @@ -124,7 +124,8 @@ impl Session { input.into_iter().map(TurnInput::ResponseItem).collect(), ) .await; - self.start_task(turn_context, Vec::new(), RegularTask::new()) + let _ = self + .start_task(turn_context, Vec::new(), RegularTask::new()) .await; Ok(()) } diff --git a/codex-rs/core/src/session/review.rs b/codex-rs/core/src/session/review.rs index ff4c77aab9..4154c11819 100644 --- a/codex-rs/core/src/session/review.rs +++ b/codex-rs/core/src/session/review.rs @@ -174,7 +174,7 @@ pub(super) async fn spawn_review_thread( // TODO(ccunningham): Review turns currently rely on `spawn_task` for TurnComplete but do not // emit a parent TurnStarted. Consider giving review a full parent turn lifecycle // (TurnStarted + TurnComplete) for consistency with other standalone tasks. - sess.spawn_task(tc.clone(), input, ReviewTask::new()).await; + let _ = sess.spawn_task(tc.clone(), input, ReviewTask::new()).await; // Announce entering review mode so UIs can switch modes. let review_request = ReviewRequest { diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index a2023ea378..12ca618b37 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -305,12 +305,13 @@ async fn regular_turn_emits_turn_started_with_trace_id_without_waiting_for_start ), ) .await; - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - crate::tasks::RegularTask::new(), - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + crate::tasks::RegularTask::new(), + ) + .await; let first = tokio::time::timeout(std::time::Duration::from_millis(200), rx.recv()) .await @@ -386,12 +387,13 @@ async fn interrupting_regular_turn_waiting_on_startup_prewarm_emits_turn_aborted ), ) .await; - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - crate::tasks::RegularTask::new(), - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + crate::tasks::RegularTask::new(), + ) + .await; let first = tokio::time::timeout(std::time::Duration::from_millis(200), rx.recv()) .await @@ -2111,15 +2113,16 @@ async fn turn_start_lifecycle_exposes_turn_metadata_and_token_baseline() { }; let sess = Arc::new(session); - sess.spawn_task( - Arc::new(turn_context), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: true, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::new(turn_context), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: true, + }, + ) + .await; sess.abort_all_tasks(TurnAbortReason::Interrupted).await; let actual = records @@ -6309,20 +6312,21 @@ async fn spawn_task_turn_span_inherits_dispatch_trace_context() { let captured_trace = Arc::new(std::sync::Mutex::new(None)); async { - sess.spawn_task( - Arc::clone(&tc), - vec![TurnInput::UserInput { - content: vec![UserInput::Text { - text: "hello".to_string(), - text_elements: Vec::new(), + let _ = sess + .spawn_task( + Arc::clone(&tc), + vec![TurnInput::UserInput { + content: vec![UserInput::Text { + text: "hello".to_string(), + text_elements: Vec::new(), + }], + client_id: None, }], - client_id: None, - }], - TraceCaptureTask { - captured_trace: Arc::clone(&captured_trace), - }, - ) - .await; + TraceCaptureTask { + captured_trace: Arc::clone(&captured_trace), + }, + ) + .await; } .instrument(dispatch_span) .await; @@ -6498,7 +6502,7 @@ async fn submission_loop_channel_close_aborts_active_turn_before_thread_stop_lif session.services.extensions = Arc::new(builder.build()); let session = Arc::new(session); - session + let _ = session .spawn_task( Arc::new(turn_context), Vec::new(), @@ -7138,15 +7142,16 @@ async fn spawn_task_does_not_update_previous_turn_settings_for_non_run_turn_task client_id: None, }]; - sess.spawn_task( - Arc::clone(&tc), - input, - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: true, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + input, + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: true, + }, + ) + .await; sess.abort_all_tasks(TurnAbortReason::Interrupted).await; assert_eq!(sess.previous_turn_settings().await, None); @@ -8461,7 +8466,8 @@ async fn guardian_auto_review_interrupts_after_three_consecutive_denials() { }], client_id: None, }]; - sess.spawn_task(Arc::clone(&tc), input, GuardianDeniedApprovalTask) + let _ = sess + .spawn_task(Arc::clone(&tc), input, GuardianDeniedApprovalTask) .await; let mut observed = Vec::new(); @@ -8495,15 +8501,16 @@ async fn guardian_helper_review_interrupts_after_three_consecutive_denials() { }], client_id: None, }]; - sess.spawn_task( - Arc::clone(&tc), - input, - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: true, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + input, + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: true, + }, + ) + .await; let session_for_review = Arc::clone(&sess); let turn_for_review = Arc::clone(&tc); @@ -8558,15 +8565,16 @@ async fn abort_regular_task_emits_marker_before_turn_aborted() { }], client_id: None, }]; - sess.spawn_task( - Arc::clone(&tc), - input, - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: false, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + input, + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: false, + }, + ) + .await; sess.abort_all_tasks(TurnAbortReason::Interrupted).await; @@ -8599,15 +8607,16 @@ async fn abort_gracefully_emits_marker_before_turn_aborted() { }], client_id: None, }]; - sess.spawn_task( - Arc::clone(&tc), - input, - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: true, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + input, + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: true, + }, + ) + .await; sess.abort_all_tasks(TurnAbortReason::Interrupted).await; @@ -8640,15 +8649,16 @@ async fn task_finish_emits_turn_item_lifecycle_for_leftover_pending_user_input() }], client_id: None, }]; - sess.spawn_task( - Arc::clone(&tc), - input, - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: false, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + input, + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: false, + }, + ) + .await; while rx.try_recv().is_ok() {} @@ -8783,7 +8793,7 @@ async fn task_finish_emits_thread_idle_lifecycle_after_active_turn_clears() { session.services.extensions = Arc::new(builder.build()); let session = Arc::new(session); - session + let _ = session .spawn_task(Arc::new(turn_context), Vec::new(), CompletingTask) .await; @@ -8834,15 +8844,16 @@ async fn thread_idle_lifecycle_waits_for_trigger_turn_mailbox_work() { #[tokio::test] async fn try_start_turn_if_idle_rejects_active_turn_without_injecting() { let (sess, tc, _rx) = make_session_and_context_with_rx().await; - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: true, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: true, + }, + ) + .await; let item = user_message("synthetic idle input"); let err = sess @@ -8916,15 +8927,16 @@ async fn try_start_turn_if_idle_rejects_pending_trigger_turn_without_injecting() #[tokio::test] async fn try_start_turn_if_idle_rejects_active_review_turn_without_injecting() { let (sess, tc, _rx) = make_session_and_context_with_rx().await; - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Review, - listen_to_cancellation_token: true, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Review, + listen_to_cancellation_token: true, + }, + ) + .await; let item = user_message("synthetic idle input"); let err = sess @@ -8974,15 +8986,16 @@ async fn steer_input_enforces_expected_turn_id() { }], client_id: None, }]; - sess.spawn_task( - Arc::clone(&tc), - input, - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: false, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + input, + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: false, + }, + ) + .await; let steer_input = vec![UserInput::Text { text: "steer".to_string(), @@ -9025,15 +9038,16 @@ async fn steer_input_rejects_non_regular_turns() { client_id: None, }]; let turn_context = sess.new_default_turn_with_sub_id("turn".to_string()).await; - sess.spawn_task( - turn_context, - input, - NeverEndingTask { - kind: task_kind, - listen_to_cancellation_token: true, - }, - ) - .await; + let _ = sess + .spawn_task( + turn_context, + input, + NeverEndingTask { + kind: task_kind, + listen_to_cancellation_token: true, + }, + ) + .await; let steer_input = vec![UserInput::Text { text: "steer".to_string(), @@ -9066,15 +9080,16 @@ async fn steer_input_returns_active_turn_id() { }], client_id: None, }]; - sess.spawn_task( - Arc::clone(&tc), - input, - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: false, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + input, + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: false, + }, + ) + .await; let steer_input = vec![UserInput::Text { text: "steer".to_string(), @@ -9142,15 +9157,16 @@ async fn interrupt_accounts_active_goal_without_pausing() -> anyhow::Result<()> ) .await?; - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: false, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: false, + }, + ) + .await; set_total_token_usage(&sess, post_goal_token_usage()).await; sess.abort_all_tasks(TurnAbortReason::Interrupted).await; @@ -9510,15 +9526,16 @@ async fn budget_limited_accounting_steers_active_turn_without_aborting() -> anyh token_usage: TokenUsage::default(), }) .await?; - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: false, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: false, + }, + ) + .await; while rx.try_recv().is_ok() {} set_total_token_usage( @@ -9617,15 +9634,16 @@ async fn usage_limit_runtime_stops_active_goal_and_prevents_idle_continuation() token_usage: TokenUsage::default(), }) .await?; - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: false, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: false, + }, + ) + .await; set_total_token_usage(&sess, post_goal_token_usage()).await; sess.goal_runtime_apply(GoalRuntimeEvent::UsageLimitReached { @@ -9662,15 +9680,16 @@ async fn external_goal_mutation_accounts_active_turn_before_status_change() -> a }, ) .await?; - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: false, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: false, + }, + ) + .await; set_total_token_usage(&sess, post_goal_token_usage()).await; sess.goal_runtime_apply(GoalRuntimeEvent::ExternalMutationStarting) @@ -9724,15 +9743,16 @@ async fn external_goal_mutation_accounts_active_turn_before_status_change() -> a #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn external_objective_change_steers_active_turn() -> anyhow::Result<()> { let (sess, tc, _rx, _codex_home) = make_goal_session_and_context_with_rx().await; - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: false, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: false, + }, + ) + .await; let state_db = goal_test_state_db(sess.as_ref()).await?; let old_goal = state_db @@ -9790,15 +9810,16 @@ async fn external_objective_change_steers_active_turn() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn external_active_goal_set_marks_current_turn_for_accounting() -> anyhow::Result<()> { let (sess, tc, _rx, _codex_home) = make_goal_session_and_context_with_rx().await; - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: false, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: false, + }, + ) + .await; set_total_token_usage(&sess, post_goal_token_usage()).await; let state_db = goal_test_state_db(sess.as_ref()).await?; @@ -9961,15 +9982,16 @@ async fn queue_only_mailbox_mail_waits_for_next_turn_after_answer_boundary() { "late queue-only update".to_string(), /*trigger_turn*/ false, ); - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: true, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: true, + }, + ) + .await; sess.input_queue .defer_mailbox_delivery_to_next_turn(&sess.active_turn, &tc.sub_id) @@ -10000,15 +10022,16 @@ async fn queue_only_mailbox_mail_waits_for_next_turn_after_answer_boundary() { #[tokio::test] async fn trigger_turn_mailbox_mail_waits_for_next_turn_after_answer_boundary() { let (sess, tc, _rx) = make_session_and_context_with_rx().await; - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: true, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: true, + }, + ) + .await; sess.input_queue .defer_mailbox_delivery_to_next_turn(&sess.active_turn, &tc.sub_id) @@ -10043,15 +10066,16 @@ async fn steered_input_reopens_mailbox_delivery_for_current_turn() { "queued child update".to_string(), /*trigger_turn*/ false, ); - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: true, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: true, + }, + ) + .await; sess.input_queue .defer_mailbox_delivery_to_next_turn(&sess.active_turn, &tc.sub_id) @@ -10097,15 +10121,16 @@ async fn stale_defer_mailbox_delivery_does_not_override_steered_input() { "queued child update".to_string(), /*trigger_turn*/ false, ); - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: true, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: true, + }, + ) + .await; sess.input_queue .defer_mailbox_delivery_to_next_turn(&sess.active_turn, &tc.sub_id) @@ -10155,15 +10180,16 @@ async fn tool_calls_reopen_mailbox_delivery_for_current_turn() { "queued child update".to_string(), /*trigger_turn*/ false, ); - sess.spawn_task( - Arc::clone(&tc), - Vec::new(), - NeverEndingTask { - kind: TaskKind::Regular, - listen_to_cancellation_token: true, - }, - ) - .await; + let _ = sess + .spawn_task( + Arc::clone(&tc), + Vec::new(), + NeverEndingTask { + kind: TaskKind::Regular, + listen_to_cancellation_token: true, + }, + ) + .await; sess.input_queue .defer_mailbox_delivery_to_next_turn(&sess.active_turn, &tc.sub_id) @@ -10211,7 +10237,8 @@ async fn abort_review_task_emits_exited_then_aborted_and_records_history() { }], client_id: None, }]; - sess.spawn_task(Arc::clone(&tc), input, ReviewTask::new()) + let _ = sess + .spawn_task(Arc::clone(&tc), input, ReviewTask::new()) .await; sess.abort_all_tasks(TurnAbortReason::Interrupted).await; diff --git a/codex-rs/core/src/tasks/mod.rs b/codex-rs/core/src/tasks/mod.rs index ac0687cd1a..610ba63b55 100644 --- a/codex-rs/core/src/tasks/mod.rs +++ b/codex-rs/core/src/tasks/mod.rs @@ -44,6 +44,7 @@ use codex_otel::TURN_NETWORK_PROXY_METRIC; use codex_otel::TURN_TOKEN_USAGE_METRIC; use codex_otel::TURN_TOOL_CALL_METRIC; use codex_protocol::error::CodexErr; +use codex_protocol::error::Result as CodexResult; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::MultiAgentVersion; @@ -72,12 +73,6 @@ pub(crate) enum InterruptedTurnHistoryMarker { Developer, } -#[derive(Debug)] -pub(crate) enum StartTaskOutcome { - Started, - Rejected(CodexErr), -} - impl InterruptedTurnHistoryMarker { pub(crate) fn from_config_and_version( config: &Config, @@ -315,10 +310,10 @@ impl Session { turn_context: Arc, input: Vec, task: T, - ) -> StartTaskOutcome { + ) -> CodexResult<()> { self.abort_all_tasks(TurnAbortReason::Replaced).await; self.clear_connector_selection().await; - self.start_task(turn_context, input, task).await; + self.start_task(turn_context, input, task).await } pub(crate) async fn start_task( @@ -326,12 +321,12 @@ impl Session { turn_context: Arc, input: Vec, task: T, - ) -> StartTaskOutcome { + ) -> CodexResult<()> { let turn_state = { let mut active = self.active_turn.lock().await; let turn = active.get_or_insert_with(ActiveTurn::default); if turn.task.is_some() { - return StartTaskOutcome::Rejected(CodexErr::InvalidRequest( + return Err(CodexErr::InvalidRequest( "thread already has an active turn".to_string(), )); } @@ -350,12 +345,9 @@ impl Session { thread_id = %self.thread_id, "agent turn could not reserve an execution slot: {err}" ); - return StartTaskOutcome::Rejected(err); + return Err(err); } }; - if let Some(execution_reservation) = execution_reservation { - execution_reservation.commit(); - } let task: Arc = Arc::new(task); let task_kind = task.kind(); @@ -399,7 +391,7 @@ impl Session { let turn_extension_data = Arc::clone(&turn_context.extension_data); let mut active = self.active_turn.lock().await; let Some(turn) = active.as_mut() else { - return StartTaskOutcome::Rejected(CodexErr::Fatal( + return Err(CodexErr::Fatal( "active turn reservation was lost before task start".to_string(), )); }; @@ -479,7 +471,10 @@ impl Session { _timer: timer, }; turn.task = Some(running_task); - StartTaskOutcome::Started + if let Some(execution_reservation) = execution_reservation { + execution_reservation.commit(); + } + Ok(()) } /// Starts a regular turn when the session is idle and pending work is waiting. @@ -523,7 +518,8 @@ impl Session { self.clear_reserved_active_turn(&turn_state).await; return; } - self.start_task(turn_context, Vec::new(), RegularTask::new()) + let _ = self + .start_task(turn_context, Vec::new(), RegularTask::new()) .await; }) }