mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat: surface multi-agent thread limit in spawn description (#19360)
## Summary - Thread `agent_max_threads` into `ToolsConfig` and `SpawnAgentToolOptions`. - Render the configured `max_concurrent_threads_per_session` value in the MultiAgentV2 `spawn_agent` description. - Cover the description text in `codex-tools` unit tests and `codex-core` tool spec tests. ## Validation - `just fmt` - `cargo test -p codex-tools` - `cargo test -p codex-core spawn_agent_description` - `git diff --check` ## Notes - `cargo test -p codex-core` was also attempted, but unrelated environment-sensitive tests failed with the active local environment. Examples: approvals reviewer defaults observed `AutoReview` instead of `User`, request-permissions event tests did not emit events, and proxy-env tests saw `http://127.0.0.1:50604` from the active proxy environment. Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
9eadff9713
commit
deb4509302
@@ -51,6 +51,7 @@ pub(super) async fn spawn_review_thread(
|
||||
.with_spawn_agent_usage_hint(config.multi_agent_v2.usage_hint_enabled)
|
||||
.with_spawn_agent_usage_hint_text(config.multi_agent_v2.usage_hint_text.clone())
|
||||
.with_hide_spawn_agent_metadata(config.multi_agent_v2.hide_spawn_agent_metadata)
|
||||
.with_max_concurrent_threads_per_session(config.agent_max_threads)
|
||||
.with_agent_type_description(crate::agent::role::spawn_tool_spec::build(
|
||||
&config.agent_roles,
|
||||
));
|
||||
|
||||
@@ -181,6 +181,7 @@ impl TurnContext {
|
||||
.with_spawn_agent_usage_hint(config.multi_agent_v2.usage_hint_enabled)
|
||||
.with_spawn_agent_usage_hint_text(config.multi_agent_v2.usage_hint_text.clone())
|
||||
.with_hide_spawn_agent_metadata(config.multi_agent_v2.hide_spawn_agent_metadata)
|
||||
.with_max_concurrent_threads_per_session(config.agent_max_threads)
|
||||
.with_agent_type_description(crate::agent::role::spawn_tool_spec::build(
|
||||
&config.agent_roles,
|
||||
));
|
||||
@@ -442,6 +443,7 @@ impl Session {
|
||||
.with_spawn_agent_usage_hint(per_turn_config.multi_agent_v2.usage_hint_enabled)
|
||||
.with_spawn_agent_usage_hint_text(per_turn_config.multi_agent_v2.usage_hint_text.clone())
|
||||
.with_hide_spawn_agent_metadata(per_turn_config.multi_agent_v2.hide_spawn_agent_metadata)
|
||||
.with_max_concurrent_threads_per_session(per_turn_config.agent_max_threads)
|
||||
.with_agent_type_description(crate::agent::role::spawn_tool_spec::build(
|
||||
&per_turn_config.agent_roles,
|
||||
));
|
||||
|
||||
@@ -233,6 +233,7 @@ async fn multi_agent_v2_tools_config() -> ToolsConfig {
|
||||
sandbox_policy: &SandboxPolicy::DangerFullAccess,
|
||||
windows_sandbox_level: WindowsSandboxLevel::Disabled,
|
||||
})
|
||||
.with_max_concurrent_threads_per_session(Some(4))
|
||||
}
|
||||
|
||||
fn multi_agent_v2_spawn_agent_description(tools_config: &ToolsConfig) -> String {
|
||||
@@ -749,6 +750,7 @@ async fn spawn_agent_description_omits_usage_hint_when_disabled() {
|
||||
\s+Spawned\ agents\ inherit\ your\ current\ model\ by\ default\.\ Omit\ `model`\ to\ use\ that\ preferred\ default;\ set\ `model`\ only\ when\ an\ explicit\ override\ is\ needed\.
|
||||
\s+It\ will\ be\ able\ to\ send\ you\ and\ other\ running\ agents\ messages,\ and\ its\ final\ answer\ will\ be\ provided\ to\ you\ when\ it\ finishes\.
|
||||
\s+The\ new\ agent's\ canonical\ task\ name\ will\ be\ provided\ to\ it\ along\ with\ the\ message\.
|
||||
\s+This\ session\ is\ configured\ with\ `max_concurrent_threads_per_session\ =\ 4`\ for\ concurrently\ open\ agent\ threads\.
|
||||
\s*$
|
||||
"#,
|
||||
&description,
|
||||
@@ -774,6 +776,7 @@ async fn spawn_agent_description_uses_configured_usage_hint_text() {
|
||||
\s+Spawned\ agents\ inherit\ your\ current\ model\ by\ default\.\ Omit\ `model`\ to\ use\ that\ preferred\ default;\ set\ `model`\ only\ when\ an\ explicit\ override\ is\ needed\.
|
||||
\s+It\ will\ be\ able\ to\ send\ you\ and\ other\ running\ agents\ messages,\ and\ its\ final\ answer\ will\ be\ provided\ to\ you\ when\ it\ finishes\.
|
||||
\s+The\ new\ agent's\ canonical\ task\ name\ will\ be\ provided\ to\ it\ along\ with\ the\ message\.
|
||||
\s+This\ session\ is\ configured\ with\ `max_concurrent_threads_per_session\ =\ 4`\ for\ concurrently\ open\ agent\ threads\.
|
||||
\s+Custom\ delegation\ guidance\ only\.
|
||||
\s*$
|
||||
"#,
|
||||
|
||||
@@ -16,6 +16,7 @@ pub struct SpawnAgentToolOptions<'a> {
|
||||
pub hide_agent_type_model_reasoning: bool,
|
||||
pub include_usage_hint: bool,
|
||||
pub usage_hint_text: Option<String>,
|
||||
pub max_concurrent_threads_per_session: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
@@ -71,6 +72,7 @@ pub fn create_spawn_agent_tool_v2(options: SpawnAgentToolOptions<'_>) -> ToolSpe
|
||||
available_models_description.as_deref(),
|
||||
options.include_usage_hint,
|
||||
options.usage_hint_text,
|
||||
options.max_concurrent_threads_per_session,
|
||||
),
|
||||
strict: false,
|
||||
defer_loading: None,
|
||||
@@ -655,8 +657,16 @@ fn spawn_agent_tool_description_v2(
|
||||
available_models_description: Option<&str>,
|
||||
include_usage_hint: bool,
|
||||
usage_hint_text: Option<String>,
|
||||
max_concurrent_threads_per_session: Option<usize>,
|
||||
) -> String {
|
||||
let agent_role_guidance = available_models_description.unwrap_or_default();
|
||||
let concurrency_guidance = max_concurrent_threads_per_session
|
||||
.map(|limit| {
|
||||
format!(
|
||||
"This session is configured with `max_concurrent_threads_per_session = {limit}` for concurrently open agent threads."
|
||||
)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let tool_description = format!(
|
||||
r#"
|
||||
@@ -666,7 +676,8 @@ You are then able to refer to this agent as `task_3` or `/root/task1/task_3` int
|
||||
The spawned agent will have the same tools as you and the ability to spawn its own subagents.
|
||||
{SPAWN_AGENT_INHERITED_MODEL_GUIDANCE}
|
||||
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.
|
||||
{concurrency_guidance}"#
|
||||
);
|
||||
|
||||
if !include_usage_hint {
|
||||
|
||||
@@ -40,6 +40,7 @@ fn spawn_agent_tool_v2_requires_task_name_and_lists_visible_models() {
|
||||
hide_agent_type_model_reasoning: false,
|
||||
include_usage_hint: true,
|
||||
usage_hint_text: None,
|
||||
max_concurrent_threads_per_session: Some(4),
|
||||
});
|
||||
|
||||
let ToolSpec::Function(ResponsesApiTool {
|
||||
@@ -61,6 +62,7 @@ fn spawn_agent_tool_v2_requires_task_name_and_lists_visible_models() {
|
||||
.expect("spawn_agent should use object params");
|
||||
assert!(description.contains("Spawns an agent to work on the specified task."));
|
||||
assert!(description.contains("The spawned agent will have the same tools as you"));
|
||||
assert!(description.contains("`max_concurrent_threads_per_session = 4`"));
|
||||
assert!(description.contains(SPAWN_AGENT_INHERITED_MODEL_GUIDANCE));
|
||||
assert!(
|
||||
description
|
||||
@@ -101,6 +103,7 @@ fn spawn_agent_tool_v1_keeps_legacy_fork_context_field() {
|
||||
hide_agent_type_model_reasoning: false,
|
||||
include_usage_hint: true,
|
||||
usage_hint_text: None,
|
||||
max_concurrent_threads_per_session: None,
|
||||
});
|
||||
|
||||
let ToolSpec::Function(ResponsesApiTool { parameters, .. }) = tool else {
|
||||
|
||||
@@ -107,6 +107,7 @@ pub struct ToolsConfig {
|
||||
pub hide_spawn_agent_metadata: bool,
|
||||
pub spawn_agent_usage_hint: bool,
|
||||
pub spawn_agent_usage_hint_text: Option<String>,
|
||||
pub max_concurrent_threads_per_session: Option<usize>,
|
||||
pub default_mode_request_user_input: bool,
|
||||
pub experimental_supported_tools: Vec<String>,
|
||||
pub agent_jobs_tools: bool,
|
||||
@@ -228,6 +229,7 @@ impl ToolsConfig {
|
||||
hide_spawn_agent_metadata: false,
|
||||
spawn_agent_usage_hint: true,
|
||||
spawn_agent_usage_hint_text: None,
|
||||
max_concurrent_threads_per_session: None,
|
||||
default_mode_request_user_input: include_default_mode_request_user_input,
|
||||
experimental_supported_tools: model_info.experimental_supported_tools.clone(),
|
||||
agent_jobs_tools: include_agent_jobs,
|
||||
@@ -259,6 +261,14 @@ impl ToolsConfig {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_max_concurrent_threads_per_session(
|
||||
mut self,
|
||||
max_concurrent_threads_per_session: Option<usize>,
|
||||
) -> Self {
|
||||
self.max_concurrent_threads_per_session = max_concurrent_threads_per_session;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_allow_login_shell(mut self, allow_login_shell: bool) -> Self {
|
||||
self.allow_login_shell = allow_login_shell;
|
||||
self
|
||||
|
||||
@@ -400,6 +400,7 @@ pub fn build_tool_registry_plan(
|
||||
hide_agent_type_model_reasoning: config.hide_spawn_agent_metadata,
|
||||
include_usage_hint: config.spawn_agent_usage_hint,
|
||||
usage_hint_text: config.spawn_agent_usage_hint_text.clone(),
|
||||
max_concurrent_threads_per_session: config.max_concurrent_threads_per_session,
|
||||
}),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
@@ -445,6 +446,7 @@ pub fn build_tool_registry_plan(
|
||||
hide_agent_type_model_reasoning: config.hide_spawn_agent_metadata,
|
||||
include_usage_hint: config.spawn_agent_usage_hint,
|
||||
usage_hint_text: config.spawn_agent_usage_hint_text.clone(),
|
||||
max_concurrent_threads_per_session: config.max_concurrent_threads_per_session,
|
||||
}),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
|
||||
@@ -2200,6 +2200,7 @@ fn spawn_agent_tool_options(config: &ToolsConfig) -> SpawnAgentToolOptions<'_> {
|
||||
hide_agent_type_model_reasoning: config.hide_spawn_agent_metadata,
|
||||
include_usage_hint: config.spawn_agent_usage_hint,
|
||||
usage_hint_text: config.spawn_agent_usage_hint_text.clone(),
|
||||
max_concurrent_threads_per_session: config.max_concurrent_threads_per_session,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user