diff --git a/codex-rs/core/src/tools/tool_dispatch_trace_tests.rs b/codex-rs/core/src/tools/tool_dispatch_trace_tests.rs index 194c5d6bca..3dfce4bd47 100644 --- a/codex-rs/core/src/tools/tool_dispatch_trace_tests.rs +++ b/codex-rs/core/src/tools/tool_dispatch_trace_tests.rs @@ -249,7 +249,7 @@ async fn dispatch_lifecycle_trace_records_incompatible_payload_failures() -> any attach_test_trace(&mut session, &turn, temp.path())?; let registry = ToolRegistry::with_handler_for_test(Arc::new(TestHandler { - tool_name: codex_tools::ToolName::plain("test_tool"), + tool_name: codex_tools::ToolName::plain(codex_code_mode::PUBLIC_TOOL_NAME), })); let session = Arc::new(session); let turn = Arc::new(turn); @@ -260,7 +260,7 @@ async fn dispatch_lifecycle_trace_records_incompatible_payload_failures() -> any session, turn, "incompatible-call", - codex_tools::ToolName::plain("test_tool"), + codex_tools::ToolName::plain(codex_code_mode::PUBLIC_TOOL_NAME), ToolCallSource::Direct, ToolPayload::Custom { input: "{}".to_string(), @@ -275,6 +275,7 @@ async fn dispatch_lifecycle_trace_records_incompatible_payload_failures() -> any let tool_call = &replayed.tool_calls["incompatible-call"]; assert_eq!(tool_call.execution.status, ExecutionStatus::Failed); assert!(tool_call.raw_result_payload_id.is_some()); + assert!(replayed.code_cells.is_empty()); Ok(()) } diff --git a/codex-rs/rollout-trace/src/tool_dispatch.rs b/codex-rs/rollout-trace/src/tool_dispatch.rs index 94dcb37507..5dee5bf150 100644 --- a/codex-rs/rollout-trace/src/tool_dispatch.rs +++ b/codex-rs/rollout-trace/src/tool_dispatch.rs @@ -137,17 +137,15 @@ impl ToolDispatchTraceContext { /// Returns whether caller-side result conversion would be recorded. /// /// Core uses this to avoid formatting or cloning tool outputs when the - /// dispatch lifecycle is suppressed or tracing is disabled. + /// dispatch lifecycle is disabled. pub fn is_enabled(&self) -> bool { matches!(self.state, ToolDispatchTraceContextState::Enabled(_)) } /// Starts one dispatch-level lifecycle and returns the handle for its result. pub(crate) fn start(writer: Arc, invocation: ToolDispatchInvocation) -> Self { - if suppresses_tool_dispatch_trace(&invocation) { - return Self::disabled(); - } - + // An exec request can fail before a CodeCellStarted event. Record the + // dispatch independently so its caller-facing error survives in that case. let context = EnabledToolDispatchTraceContext { writer, thread_id: invocation.thread_id.clone(), @@ -191,12 +189,6 @@ impl ToolDispatchTraceContext { } } -fn suppresses_tool_dispatch_trace(invocation: &ToolDispatchInvocation) -> bool { - matches!(invocation.payload, ToolDispatchPayload::Custom { .. }) - && invocation.tool_namespace.is_none() - && invocation.tool_name == codex_code_mode::PUBLIC_TOOL_NAME -} - fn record_started(context: &EnabledToolDispatchTraceContext, invocation: ToolDispatchInvocation) { let tool_name = invocation.tool_name; let tool_namespace = invocation.tool_namespace; @@ -391,40 +383,6 @@ fn append_with_context_best_effort( mod tests { use super::*; - #[test] - fn suppresses_only_noncanonical_dispatch_boundaries() { - assert!(suppresses_tool_dispatch_trace(&invocation( - codex_code_mode::PUBLIC_TOOL_NAME, - /*tool_namespace*/ None, - ToolDispatchRequester::Model { - model_visible_call_id: "call-exec".to_string(), - }, - ToolDispatchPayload::Custom { - input: "1 + 1".to_string(), - }, - ))); - assert!(!suppresses_tool_dispatch_trace(&invocation( - "custom_tool", - /*tool_namespace*/ None, - ToolDispatchRequester::Model { - model_visible_call_id: "call-custom".to_string(), - }, - ToolDispatchPayload::Custom { - input: "payload".to_string(), - }, - ))); - assert!(!suppresses_tool_dispatch_trace(&invocation( - codex_code_mode::PUBLIC_TOOL_NAME, - Some("mcp__server".to_string()), - ToolDispatchRequester::Model { - model_visible_call_id: "call-namespaced".to_string(), - }, - ToolDispatchPayload::Custom { - input: "payload".to_string(), - }, - ))); - } - #[test] fn classifies_interrupt_agent_as_close_agent() { assert_eq!( @@ -450,21 +408,4 @@ mod tests { ToolCallKind::ImageGeneration ); } - - fn invocation( - tool_name: &str, - tool_namespace: Option, - requester: ToolDispatchRequester, - payload: ToolDispatchPayload, - ) -> ToolDispatchInvocation { - ToolDispatchInvocation { - thread_id: "thread-1".to_string(), - codex_turn_id: "turn-1".to_string(), - tool_call_id: "tool-call-1".to_string(), - tool_name: tool_name.to_string(), - tool_namespace, - requester, - payload, - } - } }