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 4fe6ac0e9..ee81b961e 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs @@ -9,8 +9,8 @@ use crate::state::TaskKind; use crate::tasks::SessionTask; use crate::tasks::SessionTaskContext; use crate::tools::context::ToolOutput; -use crate::tools::handlers::multi_agents_v2::AssignTaskHandler as AssignTaskHandlerV2; use crate::tools::handlers::multi_agents_v2::CloseAgentHandler as CloseAgentHandlerV2; +use crate::tools::handlers::multi_agents_v2::FollowupTaskHandler as FollowupTaskHandlerV2; use crate::tools::handlers::multi_agents_v2::ListAgentsHandler as ListAgentsHandlerV2; use crate::tools::handlers::multi_agents_v2::SendMessageHandler as SendMessageHandlerV2; use crate::tools::handlers::multi_agents_v2::SpawnAgentHandler as SpawnAgentHandlerV2; @@ -710,7 +710,7 @@ async fn multi_agent_v2_send_message_accepts_root_target_from_child() { } #[tokio::test] -async fn multi_agent_v2_assign_task_rejects_root_target_from_child() { +async fn multi_agent_v2_followup_task_rejects_root_target_from_child() { let (mut session, mut turn) = make_session_and_context().await; let manager = thread_manager(); let root = manager @@ -758,11 +758,11 @@ async fn multi_agent_v2_assign_task_rejects_root_target_from_child() { agent_role: None, }); - let err = AssignTaskHandlerV2 + let err = FollowupTaskHandlerV2 .handle(invocation( Arc::new(session), Arc::new(turn), - "assign_task", + "followup_task", function_payload(json!({ "target": "/root", "message": "run this", @@ -770,7 +770,7 @@ async fn multi_agent_v2_assign_task_rejects_root_target_from_child() { })), )) .await - .expect_err("assign_task should reject the root target"); + .expect_err("followup_task should reject the root target"); assert_eq!( err, @@ -1161,7 +1161,7 @@ async fn multi_agent_v2_send_message_rejects_interrupt_parameter() { } #[tokio::test] -async fn multi_agent_v2_assign_task_interrupts_busy_child_without_losing_message() { +async fn multi_agent_v2_followup_task_interrupts_busy_child_without_losing_message() { let (mut session, mut turn) = make_session_and_context().await; let manager = thread_manager(); let root = manager @@ -1213,11 +1213,11 @@ async fn multi_agent_v2_assign_task_interrupts_busy_child_without_losing_message ) .await; - AssignTaskHandlerV2 + FollowupTaskHandlerV2 .handle(invocation( session, turn, - "assign_task", + "followup_task", function_payload(json!({ "target": agent_id.to_string(), "message": "continue", @@ -1225,7 +1225,7 @@ async fn multi_agent_v2_assign_task_interrupts_busy_child_without_losing_message })), )) .await - .expect("interrupting v2 assign_task should succeed"); + .expect("interrupting v2 followup_task should succeed"); let ops = manager.captured_ops(); let ops_for_agent: Vec<&Op> = ops @@ -1281,7 +1281,7 @@ async fn multi_agent_v2_assign_task_interrupts_busy_child_without_losing_message } }) .await - .expect("interrupting v2 assign_task should preserve the redirected message"); + .expect("interrupting v2 followup_task should preserve the redirected message"); let _ = thread .submit(Op::Shutdown {}) @@ -1290,7 +1290,7 @@ async fn multi_agent_v2_assign_task_interrupts_busy_child_without_losing_message } #[tokio::test] -async fn multi_agent_v2_assign_task_completion_notifies_parent_on_every_turn() { +async fn multi_agent_v2_followup_task_completion_notifies_parent_on_every_turn() { let (mut session, mut turn) = make_session_and_context().await; let manager = thread_manager(); let root = manager @@ -1342,18 +1342,18 @@ async fn multi_agent_v2_assign_task_completion_notifies_parent_on_every_turn() { ) .await; - AssignTaskHandlerV2 + FollowupTaskHandlerV2 .handle(invocation( session, turn, - "assign_task", + "followup_task", function_payload(json!({ "target": agent_id.to_string(), "message": "continue", })), )) .await - .expect("assign_task should succeed"); + .expect("followup_task should succeed"); let second_turn = thread.codex.session.new_default_turn().await; thread @@ -1419,7 +1419,7 @@ async fn multi_agent_v2_assign_task_completion_notifies_parent_on_every_turn() { } #[tokio::test] -async fn multi_agent_v2_assign_task_rejects_legacy_items_field() { +async fn multi_agent_v2_followup_task_rejects_legacy_items_field() { let (mut session, mut turn) = make_session_and_context().await; let manager = thread_manager(); let root = manager @@ -1455,14 +1455,14 @@ async fn multi_agent_v2_assign_task_rejects_legacy_items_field() { let invocation = invocation( session, turn, - "assign_task", + "followup_task", function_payload(json!({ "target": agent_id.to_string(), "items": [{"type": "text", "text": "continue"}], })), ); - let Err(err) = AssignTaskHandlerV2.handle(invocation).await else { + let Err(err) = FollowupTaskHandlerV2.handle(invocation).await else { panic!("legacy items field should be rejected in v2"); }; let FunctionCallError::RespondToModel(message) = err else { diff --git a/codex-rs/core/src/tools/handlers/multi_agents_v2.rs b/codex-rs/core/src/tools/handlers/multi_agents_v2.rs index e572ec0af..44191ed85 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_v2.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_v2.rs @@ -28,15 +28,15 @@ use serde::Deserialize; use serde::Serialize; use serde_json::Value as JsonValue; -pub(crate) use assign_task::Handler as AssignTaskHandler; pub(crate) use close_agent::Handler as CloseAgentHandler; +pub(crate) use followup_task::Handler as FollowupTaskHandler; pub(crate) use list_agents::Handler as ListAgentsHandler; pub(crate) use send_message::Handler as SendMessageHandler; pub(crate) use spawn::Handler as SpawnAgentHandler; pub(crate) use wait::Handler as WaitAgentHandler; -mod assign_task; mod close_agent; +mod followup_task; mod list_agents; mod message_tool; mod send_message; diff --git a/codex-rs/core/src/tools/handlers/multi_agents_v2/assign_task.rs b/codex-rs/core/src/tools/handlers/multi_agents_v2/followup_task.rs similarity index 88% rename from codex-rs/core/src/tools/handlers/multi_agents_v2/assign_task.rs rename to codex-rs/core/src/tools/handlers/multi_agents_v2/followup_task.rs index c55c25d05..d0f87f342 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_v2/assign_task.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_v2/followup_task.rs @@ -1,4 +1,4 @@ -use super::message_tool::AssignTaskArgs; +use super::message_tool::FollowupTaskArgs; use super::message_tool::MessageDeliveryMode; use super::message_tool::MessageToolResult; use super::message_tool::handle_message_string_tool; @@ -20,7 +20,7 @@ impl ToolHandler for Handler { async fn handle(&self, invocation: ToolInvocation) -> Result { let arguments = function_arguments(invocation.payload.clone())?; - let args: AssignTaskArgs = parse_arguments(&arguments)?; + let args: FollowupTaskArgs = parse_arguments(&arguments)?; handle_message_string_tool( invocation, MessageDeliveryMode::TriggerTurn, 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 62835a12c..3123e93f4 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 @@ -1,6 +1,6 @@ //! Shared argument parsing and dispatch for the v2 text-only agent messaging tools. //! -//! `send_message` and `assign_task` share the same submission path and differ only in whether the +//! `send_message` and `followup_task` share the same submission path and differ only in whether the //! resulting `InterAgentCommunication` should wake the target immediately. use super::*; @@ -38,8 +38,8 @@ pub(crate) struct SendMessageArgs { #[derive(Debug, Deserialize)] #[serde(deny_unknown_fields)] -/// Input for the MultiAgentV2 `assign_task` tool. -pub(crate) struct AssignTaskArgs { +/// Input for the MultiAgentV2 `followup_task` tool. +pub(crate) struct FollowupTaskArgs { pub(crate) target: String, pub(crate) message: String, #[serde(default)] @@ -79,7 +79,7 @@ fn message_content(message: String) -> Result { Ok(message) } -/// Handles the shared MultiAgentV2 plain-text message flow for both `send_message` and `assign_task`. +/// Handles the shared MultiAgentV2 plain-text message flow for both `send_message` and `followup_task`. pub(crate) async fn handle_message_string_tool( invocation: ToolInvocation, mode: MessageDeliveryMode, diff --git a/codex-rs/core/src/tools/spec.rs b/codex-rs/core/src/tools/spec.rs index 341db2476..90b9a382a 100644 --- a/codex-rs/core/src/tools/spec.rs +++ b/codex-rs/core/src/tools/spec.rs @@ -60,8 +60,8 @@ pub(crate) fn build_specs_with_discoverable_tools( use crate::tools::handlers::multi_agents::SendInputHandler; use crate::tools::handlers::multi_agents::SpawnAgentHandler; use crate::tools::handlers::multi_agents::WaitAgentHandler; - use crate::tools::handlers::multi_agents_v2::AssignTaskHandler as AssignTaskHandlerV2; use crate::tools::handlers::multi_agents_v2::CloseAgentHandler as CloseAgentHandlerV2; + use crate::tools::handlers::multi_agents_v2::FollowupTaskHandler as FollowupTaskHandlerV2; use crate::tools::handlers::multi_agents_v2::ListAgentsHandler as ListAgentsHandlerV2; use crate::tools::handlers::multi_agents_v2::SendMessageHandler as SendMessageHandlerV2; use crate::tools::handlers::multi_agents_v2::SpawnAgentHandler as SpawnAgentHandlerV2; @@ -136,9 +136,6 @@ pub(crate) fn build_specs_with_discoverable_tools( ToolHandlerKind::ApplyPatch => { builder.register_handler(handler.name, apply_patch_handler.clone()); } - ToolHandlerKind::AssignTaskV2 => { - builder.register_handler(handler.name, Arc::new(AssignTaskHandlerV2)); - } ToolHandlerKind::CloseAgentV1 => { builder.register_handler(handler.name, Arc::new(CloseAgentHandler)); } @@ -154,6 +151,9 @@ pub(crate) fn build_specs_with_discoverable_tools( ToolHandlerKind::DynamicTool => { builder.register_handler(handler.name, dynamic_tool_handler.clone()); } + ToolHandlerKind::FollowupTaskV2 => { + builder.register_handler(handler.name, Arc::new(FollowupTaskHandlerV2)); + } ToolHandlerKind::JsRepl => { builder.register_handler(handler.name, js_repl_handler.clone()); } diff --git a/codex-rs/tools/src/agent_tool.rs b/codex-rs/tools/src/agent_tool.rs index b82084d51..017cc6e5e 100644 --- a/codex-rs/tools/src/agent_tool.rs +++ b/codex-rs/tools/src/agent_tool.rs @@ -150,7 +150,7 @@ pub fn create_send_message_tool() -> ToolSpec { }) } -pub fn create_assign_task_tool() -> ToolSpec { +pub fn create_followup_task_tool() -> ToolSpec { let properties = BTreeMap::from([ ( "target".to_string(), @@ -178,7 +178,7 @@ pub fn create_assign_task_tool() -> ToolSpec { ]); ToolSpec::Function(ResponsesApiTool { - name: "assign_task".to_string(), + name: "followup_task".to_string(), description: "Add a message to an existing non-root agent and trigger a turn in the target. Use interrupt=true to redirect work immediately. In MultiAgentV2, this tool currently supports text content only." .to_string(), strict: false, diff --git a/codex-rs/tools/src/agent_tool_tests.rs b/codex-rs/tools/src/agent_tool_tests.rs index 2277a5ec1..cd68fbd13 100644 --- a/codex-rs/tools/src/agent_tool_tests.rs +++ b/codex-rs/tools/src/agent_tool_tests.rs @@ -127,14 +127,14 @@ fn send_message_tool_requires_message_and_uses_submission_output() { } #[test] -fn assign_task_tool_requires_message_and_uses_submission_output() { +fn followup_task_tool_requires_message_and_uses_submission_output() { let ToolSpec::Function(ResponsesApiTool { parameters, output_schema, .. - }) = create_assign_task_tool() + }) = create_followup_task_tool() else { - panic!("assign_task should be a function tool"); + panic!("followup_task should be a function tool"); }; let JsonSchema::Object { properties, @@ -142,7 +142,7 @@ fn assign_task_tool_requires_message_and_uses_submission_output() { .. } = parameters else { - panic!("assign_task should use object params"); + panic!("followup_task should use object params"); }; assert!(properties.contains_key("target")); assert!(properties.contains_key("message")); @@ -153,7 +153,7 @@ fn assign_task_tool_requires_message_and_uses_submission_output() { Some(vec!["target".to_string(), "message".to_string()]) ); assert_eq!( - output_schema.expect("assign_task output schema")["required"], + output_schema.expect("followup_task output schema")["required"], json!(["submission_id"]) ); } diff --git a/codex-rs/tools/src/lib.rs b/codex-rs/tools/src/lib.rs index 91931e894..16e84700b 100644 --- a/codex-rs/tools/src/lib.rs +++ b/codex-rs/tools/src/lib.rs @@ -29,9 +29,9 @@ pub use agent_job_tool::create_report_agent_job_result_tool; pub use agent_job_tool::create_spawn_agents_on_csv_tool; pub use agent_tool::SpawnAgentToolOptions; pub use agent_tool::WaitAgentTimeoutOptions; -pub use agent_tool::create_assign_task_tool; pub use agent_tool::create_close_agent_tool_v1; pub use agent_tool::create_close_agent_tool_v2; +pub use agent_tool::create_followup_task_tool; pub use agent_tool::create_list_agents_tool; pub use agent_tool::create_resume_agent_tool; pub use agent_tool::create_send_input_tool_v1; diff --git a/codex-rs/tools/src/tool_registry_plan.rs b/codex-rs/tools/src/tool_registry_plan.rs index 314d93f55..cc706f24f 100644 --- a/codex-rs/tools/src/tool_registry_plan.rs +++ b/codex-rs/tools/src/tool_registry_plan.rs @@ -18,11 +18,11 @@ use crate::collect_tool_search_app_infos; use crate::collect_tool_suggest_entries; use crate::create_apply_patch_freeform_tool; use crate::create_apply_patch_json_tool; -use crate::create_assign_task_tool; use crate::create_close_agent_tool_v1; use crate::create_close_agent_tool_v2; use crate::create_code_mode_tool; use crate::create_exec_command_tool; +use crate::create_followup_task_tool; use crate::create_image_generation_tool; use crate::create_js_repl_reset_tool; use crate::create_js_repl_tool; @@ -358,7 +358,7 @@ pub fn build_tool_registry_plan( config.code_mode_enabled, ); plan.push_spec( - create_assign_task_tool(), + create_followup_task_tool(), /*supports_parallel_tool_calls*/ false, config.code_mode_enabled, ); @@ -379,7 +379,7 @@ pub fn build_tool_registry_plan( ); plan.register_handler("spawn_agent", ToolHandlerKind::SpawnAgentV2); plan.register_handler("send_message", ToolHandlerKind::SendMessageV2); - plan.register_handler("assign_task", ToolHandlerKind::AssignTaskV2); + plan.register_handler("followup_task", ToolHandlerKind::FollowupTaskV2); plan.register_handler("wait_agent", ToolHandlerKind::WaitAgentV2); plan.register_handler("close_agent", ToolHandlerKind::CloseAgentV2); plan.register_handler("list_agents", ToolHandlerKind::ListAgentsV2); diff --git a/codex-rs/tools/src/tool_registry_plan_tests.rs b/codex-rs/tools/src/tool_registry_plan_tests.rs index c2c4a0aea..fd7ab1007 100644 --- a/codex-rs/tools/src/tool_registry_plan_tests.rs +++ b/codex-rs/tools/src/tool_registry_plan_tests.rs @@ -207,7 +207,7 @@ fn test_build_specs_multi_agent_v2_uses_task_names_and_hides_resume() { &[ "spawn_agent", "send_message", - "assign_task", + "followup_task", "wait_agent", "close_agent", "list_agents", @@ -269,9 +269,9 @@ fn test_build_specs_multi_agent_v2_uses_task_names_and_hides_resume() { Some(&vec!["target".to_string(), "message".to_string()]) ); - let assign_task = find_tool(&tools, "assign_task"); - let ToolSpec::Function(ResponsesApiTool { parameters, .. }) = &assign_task.spec else { - panic!("assign_task should be a function tool"); + let followup_task = find_tool(&tools, "followup_task"); + let ToolSpec::Function(ResponsesApiTool { parameters, .. }) = &followup_task.spec else { + panic!("followup_task should be a function tool"); }; let JsonSchema::Object { properties, @@ -279,7 +279,7 @@ fn test_build_specs_multi_agent_v2_uses_task_names_and_hides_resume() { .. } = parameters else { - panic!("assign_task should use object params"); + panic!("followup_task should use object params"); }; assert!(properties.contains_key("target")); assert!(properties.contains_key("message")); diff --git a/codex-rs/tools/src/tool_registry_plan_types.rs b/codex-rs/tools/src/tool_registry_plan_types.rs index bdcb75acd..d15cf15d5 100644 --- a/codex-rs/tools/src/tool_registry_plan_types.rs +++ b/codex-rs/tools/src/tool_registry_plan_types.rs @@ -12,12 +12,12 @@ use std::collections::HashMap; pub enum ToolHandlerKind { AgentJobs, ApplyPatch, - AssignTaskV2, CloseAgentV1, CloseAgentV2, CodeModeExecute, CodeModeWait, DynamicTool, + FollowupTaskV2, JsRepl, JsReplReset, ListAgentsV2,