diff --git a/codex-rs/core/src/tools/handlers/multi_agents_spec.rs b/codex-rs/core/src/tools/handlers/multi_agents_spec.rs index 22bc8d5d1..ba74c2280 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_spec.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_spec.rs @@ -179,7 +179,7 @@ pub fn create_send_message_tool() -> ToolSpec { }) } -pub fn create_followup_task_tool() -> ToolSpec { +pub fn create_assign_task_tool() -> ToolSpec { let properties = BTreeMap::from([ ( "target".to_string(), @@ -196,7 +196,7 @@ pub fn create_followup_task_tool() -> ToolSpec { ]); ToolSpec::Function(ResponsesApiTool { - name: "followup_task".to_string(), + name: "assign_task".to_string(), description: "Send a message to an existing non-root target agent and trigger a turn in that target. If the target is currently mid-turn, the message is queued and will be used to start the target's next turn, after the current turn completes." .to_string(), strict: false, diff --git a/codex-rs/core/src/tools/handlers/multi_agents_spec_tests.rs b/codex-rs/core/src/tools/handlers/multi_agents_spec_tests.rs index a29056a12..b8b845a72 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_spec_tests.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_spec_tests.rs @@ -247,15 +247,17 @@ fn send_message_tool_requires_message_and_has_no_output_schema() { } #[test] -fn followup_task_tool_requires_message_and_has_no_output_schema() { +fn assign_task_tool_requires_message_and_has_no_output_schema() { let ToolSpec::Function(ResponsesApiTool { + name, parameters, output_schema, .. - }) = create_followup_task_tool() + }) = create_assign_task_tool() else { - panic!("followup_task should be a function tool"); + panic!("assign_task should be a function tool"); }; + assert_eq!(name, "assign_task"); assert_eq!( parameters.schema_type, Some(JsonSchemaType::Single(JsonSchemaPrimitiveType::Object)) @@ -263,7 +265,7 @@ fn followup_task_tool_requires_message_and_has_no_output_schema() { let properties = parameters .properties .as_ref() - .expect("followup_task should use object params"); + .expect("assign_task should use object params"); assert!(properties.contains_key("target")); assert!(properties.contains_key("message")); assert!(!properties.contains_key("items")); 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 164d5410e..9fed92258 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs @@ -8,8 +8,8 @@ use crate::session::tests::make_session_and_context; use crate::session_prefix::format_subagent_notification_message; use crate::thread_manager::thread_store_from_config; 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; @@ -1413,7 +1413,7 @@ async fn multi_agent_v2_send_message_accepts_root_target_from_child() { } #[tokio::test] -async fn multi_agent_v2_followup_task_rejects_root_target_from_child() { +async fn multi_agent_v2_assign_task_rejects_root_target_from_child() { let (mut session, mut turn) = make_session_and_context().await; let manager = thread_manager(); let root = manager @@ -1461,11 +1461,11 @@ async fn multi_agent_v2_followup_task_rejects_root_target_from_child() { agent_role: None, }); - let Err(err) = FollowupTaskHandlerV2 + let Err(err) = AssignTaskHandlerV2 .handle(invocation( Arc::new(session), Arc::new(turn), - "followup_task", + "assign_task", function_payload(json!({ "target": "/root", "message": "run this", @@ -1473,7 +1473,7 @@ async fn multi_agent_v2_followup_task_rejects_root_target_from_child() { )) .await else { - panic!("followup_task should reject the root target"); + panic!("assign_task should reject the root target"); }; assert_eq!( @@ -1868,7 +1868,7 @@ async fn multi_agent_v2_send_message_rejects_interrupt_parameter() { } #[tokio::test] -async fn multi_agent_v2_followup_task_completion_notifies_parent_on_every_turn() { +async fn multi_agent_v2_assign_task_completion_notifies_parent_on_every_turn() { let (mut session, mut turn) = make_session_and_context().await; let manager = thread_manager(); let root = manager @@ -1923,18 +1923,18 @@ async fn multi_agent_v2_followup_task_completion_notifies_parent_on_every_turn() ) .await; - FollowupTaskHandlerV2 + AssignTaskHandlerV2 .handle(invocation( session, turn, - "followup_task", + "assign_task", function_payload(json!({ "target": agent_id.to_string(), "message": "continue", })), )) .await - .expect("followup_task should succeed"); + .expect("assign_task should succeed"); let second_turn = thread.codex.session.new_default_turn().await; thread @@ -2003,7 +2003,7 @@ async fn multi_agent_v2_followup_task_completion_notifies_parent_on_every_turn() } #[tokio::test] -async fn multi_agent_v2_followup_task_rejects_legacy_items_field() { +async fn multi_agent_v2_assign_task_rejects_legacy_items_field() { let (mut session, mut turn) = make_session_and_context().await; let manager = thread_manager(); let root = manager @@ -2039,14 +2039,14 @@ async fn multi_agent_v2_followup_task_rejects_legacy_items_field() { let invocation = invocation( session, turn, - "followup_task", + "assign_task", function_payload(json!({ "target": agent_id.to_string(), "items": [{"type": "text", "text": "continue"}], })), ); - let Err(err) = FollowupTaskHandlerV2.handle(invocation).await else { + let Err(err) = AssignTaskHandlerV2.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 068f39337..7612213cc 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/followup_task.rs b/codex-rs/core/src/tools/handlers/multi_agents_v2/assign_task.rs similarity index 78% rename from codex-rs/core/src/tools/handlers/multi_agents_v2/followup_task.rs rename to codex-rs/core/src/tools/handlers/multi_agents_v2/assign_task.rs index 2fe09f5f2..932c7a6e6 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_v2/followup_task.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_v2/assign_task.rs @@ -1,8 +1,8 @@ -use super::message_tool::FollowupTaskArgs; +use super::message_tool::AssignTaskArgs; use super::message_tool::MessageDeliveryMode; use super::message_tool::handle_message_string_tool; use super::*; -use crate::tools::handlers::multi_agents_spec::create_followup_task_tool; +use crate::tools::handlers::multi_agents_spec::create_assign_task_tool; use codex_tools::ToolSpec; pub(crate) struct Handler; @@ -10,11 +10,11 @@ pub(crate) struct Handler; #[async_trait::async_trait] impl ToolExecutor for Handler { fn tool_name(&self) -> ToolName { - ToolName::plain("followup_task") + ToolName::plain("assign_task") } fn spec(&self) -> ToolSpec { - create_followup_task_tool() + create_assign_task_tool() } async fn handle( @@ -22,7 +22,7 @@ impl ToolExecutor for Handler { invocation: ToolInvocation, ) -> Result, FunctionCallError> { let arguments = function_arguments(invocation.payload.clone())?; - let args: FollowupTaskArgs = parse_arguments(&arguments)?; + let args: AssignTaskArgs = 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 dcf1a1e58..e50ace847 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 `followup_task` share the same submission path and differ only in whether the +//! `send_message` and `assign_task` share the same submission path and differ only in whether the //! resulting `InterAgentCommunication` should wake the target immediately. use super::*; @@ -40,8 +40,8 @@ pub(crate) struct SendMessageArgs { #[derive(Debug, Deserialize)] #[serde(deny_unknown_fields)] -/// Input for the MultiAgentV2 `followup_task` tool. -pub(crate) struct FollowupTaskArgs { +/// Input for the MultiAgentV2 `assign_task` tool. +pub(crate) struct AssignTaskArgs { pub(crate) target: String, pub(crate) message: String, } @@ -55,7 +55,7 @@ fn message_content(message: String) -> Result { Ok(message) } -/// Handles the shared MultiAgentV2 plain-text message flow for both `send_message` and `followup_task`. +/// Handles the shared MultiAgentV2 plain-text message flow for both `send_message` and `assign_task`. pub(crate) async fn handle_message_string_tool( invocation: ToolInvocation, mode: MessageDeliveryMode, diff --git a/codex-rs/core/src/tools/spec_plan.rs b/codex-rs/core/src/tools/spec_plan.rs index 3c8abf8f1..facef69cb 100644 --- a/codex-rs/core/src/tools/spec_plan.rs +++ b/codex-rs/core/src/tools/spec_plan.rs @@ -38,8 +38,8 @@ use crate::tools::handlers::multi_agents_common::MAX_WAIT_TIMEOUT_MS; use crate::tools::handlers::multi_agents_common::MIN_WAIT_TIMEOUT_MS; use crate::tools::handlers::multi_agents_spec::SpawnAgentToolOptions; use crate::tools::handlers::multi_agents_spec::WaitAgentTimeoutOptions; +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; @@ -686,7 +686,7 @@ fn add_collaboration_tools(context: &CoreToolPlanContext<'_>, planned_tools: &mu exposure, )); planned_tools.add_arc(override_tool_exposure( - multi_agent_v2_handler(FollowupTaskHandlerV2, tool_namespace), + multi_agent_v2_handler(AssignTaskHandlerV2, tool_namespace), exposure, )); planned_tools.add_arc(override_tool_exposure( diff --git a/codex-rs/core/src/tools/spec_plan_tests.rs b/codex-rs/core/src/tools/spec_plan_tests.rs index 45b965763..e2b14b5b1 100644 --- a/codex-rs/core/src/tools/spec_plan_tests.rs +++ b/codex-rs/core/src/tools/spec_plan_tests.rs @@ -766,7 +766,7 @@ async fn multi_agent_feature_selects_one_agent_tool_family() { "wait_agent", "close_agent", "send_message", - "followup_task", + "assign_task", "list_agents", ]); assert_eq!( @@ -790,7 +790,7 @@ async fn multi_agent_feature_selects_one_agent_tool_family() { v2.assert_visible_contains(&[ "spawn_agent", "send_message", - "followup_task", + "assign_task", "wait_agent", "close_agent", "list_agents", @@ -895,7 +895,7 @@ async fn multi_agent_v2_can_use_configured_tool_namespace() { for tool_name in [ "spawn_agent", "send_message", - "followup_task", + "assign_task", "wait_agent", "close_agent", "list_agents", @@ -969,7 +969,7 @@ async fn code_mode_only_can_expose_namespaced_multi_agent_v2_as_normal_tools() { for tool_name in [ "spawn_agent", "send_message", - "followup_task", + "assign_task", "wait_agent", "close_agent", "list_agents", diff --git a/codex-rs/rollout-trace/README.md b/codex-rs/rollout-trace/README.md index 540a49463..39ec9838e 100644 --- a/codex-rs/rollout-trace/README.md +++ b/codex-rs/rollout-trace/README.md @@ -177,7 +177,7 @@ the edges between them. ```mermaid flowchart LR - RootTool["root ToolCall\nspawn_agent / followup_task / send_message"] + RootTool["root ToolCall\nspawn_agent / assign_task / send_message"] ChildInput["child ConversationItem\ninjected task/message"] ChildThread["child AgentThread"] ChildResult["child assistant ConversationItem\nresult message"] diff --git a/codex-rs/rollout-trace/src/tool_dispatch.rs b/codex-rs/rollout-trace/src/tool_dispatch.rs index 12d058c43..ae793bc67 100644 --- a/codex-rs/rollout-trace/src/tool_dispatch.rs +++ b/codex-rs/rollout-trace/src/tool_dispatch.rs @@ -267,7 +267,7 @@ fn dispatched_tool_kind(tool_name: &str, _payload: &ToolDispatchPayload) -> Tool "image_generation" | "image_query" => ToolCallKind::ImageGeneration, "spawn_agent" => ToolCallKind::SpawnAgent, "send_message" => ToolCallKind::SendMessage, - "followup_task" => ToolCallKind::AssignAgentTask, + "assign_task" | "followup_task" => ToolCallKind::AssignAgentTask, "wait_agent" => ToolCallKind::WaitAgent, "close_agent" => ToolCallKind::CloseAgent, other => ToolCallKind::Other {