From 68e16baabe79a1f48c7d93c9a3d6e234a9b2c9b7 Mon Sep 17 00:00:00 2001 From: jif-oai Date: Tue, 7 Apr 2026 12:26:36 +0200 Subject: [PATCH] chore: send_message and followup_task do not return anything (#17008) --- .../src/tools/handlers/multi_agents_tests.rs | 6 ++-- .../handlers/multi_agents_v2/followup_task.rs | 4 +-- .../handlers/multi_agents_v2/message_tool.rs | 35 +++---------------- .../handlers/multi_agents_v2/send_message.rs | 4 +-- codex-rs/tools/src/agent_tool.rs | 4 +-- codex-rs/tools/src/agent_tool_tests.rs | 14 +++----- .../tools/src/tool_registry_plan_tests.rs | 16 +++++++-- 7 files changed, 33 insertions(+), 50 deletions(-) diff --git a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs index 1e2fad9f0..923f7a6b7 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs @@ -757,7 +757,7 @@ async fn multi_agent_v2_followup_task_rejects_root_target_from_child() { agent_role: None, }); - let err = FollowupTaskHandlerV2 + let Err(err) = FollowupTaskHandlerV2 .handle(invocation( Arc::new(session), Arc::new(turn), @@ -769,7 +769,9 @@ async fn multi_agent_v2_followup_task_rejects_root_target_from_child() { })), )) .await - .expect_err("followup_task should reject the root target"); + else { + panic!("followup_task should reject the root target"); + }; assert_eq!( err, diff --git a/codex-rs/core/src/tools/handlers/multi_agents_v2/followup_task.rs b/codex-rs/core/src/tools/handlers/multi_agents_v2/followup_task.rs index 312e17a31..e618f5da2 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_v2/followup_task.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_v2/followup_task.rs @@ -1,13 +1,13 @@ use super::message_tool::FollowupTaskArgs; use super::message_tool::MessageDeliveryMode; -use super::message_tool::MessageToolResult; use super::message_tool::handle_message_string_tool; use super::*; +use crate::tools::context::FunctionToolOutput; pub(crate) struct Handler; impl ToolHandler for Handler { - type Output = MessageToolResult; + type Output = FunctionToolOutput; fn kind(&self) -> ToolKind { ToolKind::Function diff --git a/codex-rs/core/src/tools/handlers/multi_agents_v2/message_tool.rs b/codex-rs/core/src/tools/handlers/multi_agents_v2/message_tool.rs index 3123e93f4..c9c2fda51 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_v2/message_tool.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_v2/message_tool.rs @@ -4,6 +4,7 @@ //! resulting `InterAgentCommunication` should wake the target immediately. use super::*; +use crate::tools::context::FunctionToolOutput; use codex_protocol::protocol::InterAgentCommunication; #[derive(Clone, Copy, PartialEq, Eq)] @@ -46,30 +47,6 @@ pub(crate) struct FollowupTaskArgs { pub(crate) interrupt: bool, } -#[derive(Debug, Serialize)] -/// Tool result shared by the MultiAgentV2 message-delivery tools. -pub(crate) struct MessageToolResult { - submission_id: String, -} - -impl ToolOutput for MessageToolResult { - fn log_preview(&self) -> String { - tool_output_json_text(self, "multi_agent_message") - } - - fn success_for_logging(&self) -> bool { - true - } - - fn to_response_item(&self, call_id: &str, payload: &ToolPayload) -> ResponseInputItem { - tool_output_response_item(call_id, payload, self, Some(true), "multi_agent_message") - } - - fn code_mode_result(&self, _payload: &ToolPayload) -> JsonValue { - tool_output_code_mode_result(self, "multi_agent_message") - } -} - fn message_content(message: String) -> Result { if message.trim().is_empty() { return Err(FunctionCallError::RespondToModel( @@ -86,7 +63,7 @@ pub(crate) async fn handle_message_string_tool( target: String, message: String, interrupt: bool, -) -> Result { +) -> Result { handle_message_submission( invocation, mode, @@ -103,15 +80,13 @@ async fn handle_message_submission( target: String, prompt: String, interrupt: bool, -) -> Result { +) -> Result { let ToolInvocation { session, turn, - payload, call_id, .. } = invocation; - let _ = payload; let receiver_thread_id = resolve_agent_target(&session, &turn, &target).await?; let receiver_agent = session .services @@ -186,7 +161,7 @@ async fn handle_message_submission( .into(), ) .await; - let submission_id = result?; + result?; - Ok(MessageToolResult { submission_id }) + Ok(FunctionToolOutput::from_text(String::new(), Some(true))) } diff --git a/codex-rs/core/src/tools/handlers/multi_agents_v2/send_message.rs b/codex-rs/core/src/tools/handlers/multi_agents_v2/send_message.rs index a490d1100..0d142623a 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_v2/send_message.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_v2/send_message.rs @@ -1,13 +1,13 @@ use super::message_tool::MessageDeliveryMode; -use super::message_tool::MessageToolResult; use super::message_tool::SendMessageArgs; use super::message_tool::handle_message_string_tool; use super::*; +use crate::tools::context::FunctionToolOutput; pub(crate) struct Handler; impl ToolHandler for Handler { - type Output = MessageToolResult; + type Output = FunctionToolOutput; fn kind(&self) -> ToolKind { ToolKind::Function diff --git a/codex-rs/tools/src/agent_tool.rs b/codex-rs/tools/src/agent_tool.rs index 317813eb7..4a767dbc0 100644 --- a/codex-rs/tools/src/agent_tool.rs +++ b/codex-rs/tools/src/agent_tool.rs @@ -155,7 +155,7 @@ pub fn create_send_message_tool() -> ToolSpec { required: Some(vec!["target".to_string(), "message".to_string()]), additional_properties: Some(false.into()), }, - output_schema: Some(send_input_output_schema()), + output_schema: None, }) } @@ -197,7 +197,7 @@ pub fn create_followup_task_tool() -> ToolSpec { required: Some(vec!["target".to_string(), "message".to_string()]), additional_properties: Some(false.into()), }, - output_schema: Some(send_input_output_schema()), + output_schema: None, }) } diff --git a/codex-rs/tools/src/agent_tool_tests.rs b/codex-rs/tools/src/agent_tool_tests.rs index 77ed3ded0..fc1de7bc7 100644 --- a/codex-rs/tools/src/agent_tool_tests.rs +++ b/codex-rs/tools/src/agent_tool_tests.rs @@ -97,7 +97,7 @@ fn spawn_agent_tool_v1_keeps_legacy_fork_context_field() { } #[test] -fn send_message_tool_requires_message_and_uses_submission_output() { +fn send_message_tool_requires_message_and_has_no_output_schema() { let ToolSpec::Function(ResponsesApiTool { parameters, output_schema, @@ -122,14 +122,11 @@ fn send_message_tool_requires_message_and_uses_submission_output() { required, Some(vec!["target".to_string(), "message".to_string()]) ); - assert_eq!( - output_schema.expect("send_message output schema")["required"], - json!(["submission_id"]) - ); + assert_eq!(output_schema, None); } #[test] -fn followup_task_tool_requires_message_and_uses_submission_output() { +fn followup_task_tool_requires_message_and_has_no_output_schema() { let ToolSpec::Function(ResponsesApiTool { parameters, output_schema, @@ -154,10 +151,7 @@ fn followup_task_tool_requires_message_and_uses_submission_output() { required, Some(vec!["target".to_string(), "message".to_string()]) ); - assert_eq!( - output_schema.expect("followup_task output schema")["required"], - json!(["submission_id"]) - ); + assert_eq!(output_schema, None); } #[test] diff --git a/codex-rs/tools/src/tool_registry_plan_tests.rs b/codex-rs/tools/src/tool_registry_plan_tests.rs index 3a6c52fb8..9e5fac1fc 100644 --- a/codex-rs/tools/src/tool_registry_plan_tests.rs +++ b/codex-rs/tools/src/tool_registry_plan_tests.rs @@ -246,9 +246,15 @@ fn test_build_specs_multi_agent_v2_uses_task_names_and_hides_resume() { assert_eq!(output_schema["required"], json!(["task_name", "nickname"])); let send_message = find_tool(&tools, "send_message"); - let ToolSpec::Function(ResponsesApiTool { parameters, .. }) = &send_message.spec else { + let ToolSpec::Function(ResponsesApiTool { + parameters, + output_schema, + .. + }) = &send_message.spec + else { panic!("send_message should be a function tool"); }; + assert_eq!(output_schema, &None); let JsonSchema::Object { properties, required, @@ -267,9 +273,15 @@ fn test_build_specs_multi_agent_v2_uses_task_names_and_hides_resume() { ); let followup_task = find_tool(&tools, "followup_task"); - let ToolSpec::Function(ResponsesApiTool { parameters, .. }) = &followup_task.spec else { + let ToolSpec::Function(ResponsesApiTool { + parameters, + output_schema, + .. + }) = &followup_task.spec + else { panic!("followup_task should be a function tool"); }; + assert_eq!(output_schema, &None); let JsonSchema::Object { properties, required,