From 6f11784e8b71369dd69f65be040038963f5e70b5 Mon Sep 17 00:00:00 2001 From: Andrei Hasna Date: Thu, 23 Jul 2026 15:59:33 +0300 Subject: [PATCH] feat(prompt): guide agents to hold for sub-agents, expect auto-notify, and use inter-agent messages Expand the shared multi-agent v2 usage hints (the model-facing agent system prompt for multi-agent sessions) with a full coordination loop that integrates with #364's push-based completion guidance instead of duplicating it: - After spawning, do not busy-poll: never loop wait_agent/list_agents, and do not emit repeated "waiting for agents" / "no agents completed yet" messages. - Completion is push-based (#364 wake_if_idle): a finishing sub-agent's FINAL_ANSWER is delivered to you automatically and an idle parent is woken, so it is safe to stop and wait. Call wait_agent once, only when genuinely blocked on a specific result. - Coordinate mid-flight with send_message (injects a message into the target agent's session, no turn) or followup_task (new task + wakes an idle target); these work parent->child, child->parent, and peer-to-peer (#377). Applied to both DEFAULT_MULTI_AGENT_V2_ROOT_AGENT_USAGE_HINT_TEXT and DEFAULT_MULTI_AGENT_V2_SUBAGENT_USAGE_HINT_TEXT in codex-core config -- the single, model-independent location that every root and sub-agent inherits (no per-model-family prompt variant carries multi-agent guidance). Also note in the send_message tool description that the message is injected into the target agent's session and works in all directions. Verified on a warm Blacksmith box (codex-core): rustfmt --check clean on both files; just test -p codex-core = 2893 passed with an identical pass/fail set with and without this patch (75 pre-existing environmental sandbox/landlock/MCP failures, zero in config or multi_agents). The only clippy red is pre-existing and unrelated, in code-mode/src/runtime/mod.rs (untouched here). --- codex-rs/core/src/config/mod.rs | 8 ++++++-- codex-rs/core/src/tools/handlers/multi_agents_spec.rs | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/codex-rs/core/src/config/mod.rs b/codex-rs/core/src/config/mod.rs index ab9d1e58c..576696a5e 100644 --- a/codex-rs/core/src/config/mod.rs +++ b/codex-rs/core/src/config/mod.rs @@ -516,7 +516,9 @@ Child agents can also spawn their own sub-agents. You can decide how much context you want to propagate to your sub-agents with the `fork_turns` parameter. Use multi-agent capabilities only when there is a real reason to split the work; handle trivial or simple tasks directly. -Sub-agent completion is push-based: after spawning, do other work or end your turn — you will be woken with each agent's FINAL_ANSWER as it finishes. Do not busy-wait with `wait_agent`. +Sub-agent completion is push-based, so you never need to poll: after spawning, keep doing other useful work or end your turn. When a sub-agent finishes, its FINAL_ANSWER is delivered to you automatically, and if you have already ended your turn you are woken with the result — so it is safe to stop and wait. +Call `wait_agent` only when you genuinely cannot proceed without a specific result; it holds until an update arrives. Never busy-poll: do not call `wait_agent` or `list_agents` repeatedly in a loop, and do not emit repeated "waiting for agents" or "no agents completed yet" messages. +To coordinate while agents are still running, message them: `send_message` injects your message into the target agent's session without starting a turn, and `followup_task` does the same but starts a turn when the target is idle. These reach children, your parent, and peers alike — use them to steer an agent, delegate a follow-up sub-task, or answer a running agent's question. You will receive messages in the analysis channel in the form: ``` @@ -535,7 +537,9 @@ You can use `spawn_agent` to create a new agent, `followup_task` to give an exis Child agents can also spawn their own sub-agents. Use multi-agent capabilities only when there is a real reason to split the work; handle trivial or simple tasks directly. -Sub-agent completion is push-based: after spawning, do other work or end your turn — you will be woken with each agent's FINAL_ANSWER as it finishes. Do not busy-wait with `wait_agent`. +Sub-agent completion is push-based, so you never need to poll: after spawning, keep doing other useful work or end your turn. When a sub-agent finishes, its FINAL_ANSWER is delivered to you automatically, and if you have already ended your turn you are woken with the result — so it is safe to stop and wait. +Call `wait_agent` only when you genuinely cannot proceed without a specific result; it holds until an update arrives. Never busy-poll: do not call `wait_agent` or `list_agents` repeatedly in a loop, and do not emit repeated "waiting for agents" or "no agents completed yet" messages. +To coordinate while agents are still running, message them: `send_message` injects your message into the target agent's session without starting a turn, and `followup_task` does the same but starts a turn when the target is idle. These reach children, your parent, and peers alike — use them to steer an agent, delegate a follow-up sub-task, or answer a running agent's question. When you provide a response in the final channel, that content is immediately delivered back to your parent agent. 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 c21eff00f..f26e4f7c8 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_spec.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_spec.rs @@ -176,7 +176,7 @@ pub fn create_send_message_tool() -> ToolSpec { ToolSpec::Function(ResponsesApiTool { name: "send_message".to_string(), - description: "Send a message to an existing agent. The message will be delivered promptly. Does not trigger a new turn." + description: "Send a message to an existing agent; it is injected into the target agent's session and delivered promptly. Works parent-to-child, child-to-parent, and between peers. Does not trigger a new turn." .to_string(), strict: false, defer_loading: None,