Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion codex-rs/core/src/config/config_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9808,13 +9808,16 @@ max_concurrent_threads_per_session = 17

let config = resolve_multi_agent_v2_config(&config_toml);
let concurrency_guidance = "There are 17 available concurrency slots, meaning that up to 17 agents can be active at once, including you.";
let expected_suffix = format!(
"{DEFAULT_MULTI_AGENT_V2_SHARED_USAGE_HINT_TEXT}\n{concurrency_guidance}\n\n{DEFAULT_MULTI_AGENT_V2_NO_SPAWN_HINT_TEXT}"
);
assert!(
[
config.root_agent_usage_hint_text,
config.subagent_usage_hint_text,
]
.into_iter()
.all(|hint| hint.is_some_and(|hint| hint.ends_with(concurrency_guidance)))
.all(|hint| hint.is_some_and(|hint| hint.ends_with(expected_suffix.as_str())))
);
}

Expand Down
14 changes: 11 additions & 3 deletions codex-rs/core/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ All agents in the team, including the agents that you can assign tasks to, are e
You can use `spawn_agent` to create a new agent, `followup_task` to give an existing agent a new task and trigger a turn, and `send_message` to pass a message to a running agent without triggering a turn.
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.
Do not spawn sub-agents unless the user explicitly asks for sub-agents, delegation, or parallel agent work.

You will receive messages in the analysis channel in the form:
```
Expand All @@ -222,7 +221,6 @@ You can spawn sub-agents to handle subtasks, and those sub-agents can spawn thei

You can use `spawn_agent` to create a new agent, `followup_task` to give an existing agent a new task and trigger a turn, and `send_message` to pass a message to a running agent.
Child agents can also spawn their own sub-agents.
Do not spawn sub-agents unless the user explicitly asks for sub-agents, delegation, or parallel agent work.

When you provide a response in the final channel, that content is immediately delivered back to your parent agent.

Expand All @@ -236,10 +234,20 @@ Payload:
```
You may also see them addressed as to=/root/..., which indicates your identity is /root/...
"#;
const DEFAULT_MULTI_AGENT_V2_SHARED_USAGE_HINT_TEXT: &str = r#"Note that collaboration tools cannot be called from inside `functions.exec`. Call `spawn_agent`, `send_message`, `followup_task`, `wait_agent`, `interrupt_agent`, and `list_agents` only as direct tool calls using the recipient shown in their tool definitions, such as `to=functions.spawn_agent` without a configured namespace or `to=functions.agents.spawn_agent` with `tool_namespace = "agents"`, since they are intentionally absent from the `functions.exec` `tools.*` namespace. Available tools in `functions.exec` are explicitly described with a `tools` namespace in the developer message.

The goal is to correctly solve the problem in as little time as possible. Therefore, if at any point you can parallelize work by delegating tasks to another agent, you should do so to save time.

All agents share the same directory. In detail:
- All agents have access to the same container and filesystem as you.
- All agents use the same current working directory.
- As a result, edits made by one agent are immediately visible to all other agents.
"#;
const DEFAULT_MULTI_AGENT_V2_NO_SPAWN_HINT_TEXT: &str = "Do not spawn sub-agents unless the user explicitly asks for sub-agents, delegation, or parallel agent work.";

fn default_multi_agent_v2_usage_hint_text(usage_hint_text: &str, max_concurrency: usize) -> String {
format!(
"{usage_hint_text}\nThere are {max_concurrency} available concurrency slots, meaning that up to {max_concurrency} agents can be active at once, including you."
"{usage_hint_text}\n{DEFAULT_MULTI_AGENT_V2_SHARED_USAGE_HINT_TEXT}\nThere are {max_concurrency} available concurrency slots, meaning that up to {max_concurrency} agents can be active at once, including you.\n\n{DEFAULT_MULTI_AGENT_V2_NO_SPAWN_HINT_TEXT}"
Comment thread
jif-oai marked this conversation as resolved.
Comment thread
jif-oai marked this conversation as resolved.
Comment thread
jif-oai marked this conversation as resolved.
)
}

Expand Down
4 changes: 3 additions & 1 deletion codex-rs/core/src/tools/handlers/multi_agents_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,9 @@ The spawned agent will have the same tools as you and the ability to spawn its o
{inherited_model_guidance}
Only call this tool for a concrete, bounded subtask that can run independently alongside useful local work; otherwise continue locally.
It will be able to send you and other running agents messages, and its final answer will be provided to you when it finishes.
The new agent's canonical task name will be provided to it along with the message."#
The new agent's canonical task name will be provided to it along with the message.

Note that passing `fork_turns="none"` will not pass any surrounding context to the spawned subagent, which may cause the agent to lack the context it needs to complete its task, whereas `fork_turns="all"` will provide the subagent with all surrounding context."#
Comment thread
jif-oai marked this conversation as resolved.
Comment thread
jif-oai marked this conversation as resolved.
);

if !include_usage_hint {
Expand Down
3 changes: 3 additions & 0 deletions codex-rs/core/src/tools/spec_plan_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,9 @@ async fn multi_agent_feature_selects_one_agent_tool_family() {
other => panic!("expected spawn_agent function spec, got {other:?}"),
};
assert!(!spawn_agent_description.contains("max_concurrent_threads_per_session"));
assert!(spawn_agent_description.contains(
"Note that passing `fork_turns=\"none\"` will not pass any surrounding context to the spawned subagent"
));

let direct_model_only = probe(|turn| {
set_features(
Expand Down
Loading