feat: default hide_spawn_agent_metadata to true (#26114)

For MAv2 CBv9
This commit is contained in:
jif
2026-06-03 12:22:23 +02:00
committed by GitHub
Unverified
parent d36a3ead3c
commit 668703c23f
7 changed files with 27 additions and 7 deletions
+1
View File
@@ -9914,6 +9914,7 @@ enabled = true
.unwrap_or_default()
.contains("maximum concurrency"),
);
assert!(config.multi_agent_v2.hide_spawn_agent_metadata);
assert!(config.multi_agent_v2.non_code_mode_only);
Ok(())
+1 -1
View File
@@ -1065,7 +1065,7 @@ impl Default for MultiAgentV2Config {
DEFAULT_MULTI_AGENT_V2_SUBAGENT_USAGE_HINT_TEXT.to_string(),
),
tool_namespace: None,
hide_spawn_agent_metadata: false,
hide_spawn_agent_metadata: true,
non_code_mode_only: true,
}
}
@@ -48,6 +48,8 @@ impl Default for WaitAgentTimeoutOptions {
pub fn create_spawn_agent_tool_v1(options: SpawnAgentToolOptions) -> ToolSpec {
let available_models_description = (!options.hide_agent_type_model_reasoning)
.then(|| spawn_agent_models_description(&options.available_models));
let inherited_model_guidance =
(!options.hide_agent_type_model_reasoning).then_some(SPAWN_AGENT_INHERITED_MODEL_GUIDANCE);
let return_value_description =
"Returns the spawned agent id plus the user-facing nickname when available.";
let mut properties = spawn_agent_common_properties_v1(&options.agent_type_description);
@@ -62,6 +64,7 @@ pub fn create_spawn_agent_tool_v1(options: SpawnAgentToolOptions) -> ToolSpec {
name: "spawn_agent".to_string(),
description: spawn_agent_tool_description(
available_models_description.as_deref(),
inherited_model_guidance,
return_value_description,
options.include_usage_hint,
options.usage_hint_text,
@@ -77,6 +80,8 @@ pub fn create_spawn_agent_tool_v1(options: SpawnAgentToolOptions) -> ToolSpec {
pub fn create_spawn_agent_tool_v2(options: SpawnAgentToolOptions) -> ToolSpec {
let available_models_description = (!options.hide_agent_type_model_reasoning)
.then(|| spawn_agent_models_description(&options.available_models));
let inherited_model_guidance =
(!options.hide_agent_type_model_reasoning).then_some(SPAWN_AGENT_INHERITED_MODEL_GUIDANCE);
let mut properties = spawn_agent_common_properties_v2(&options.agent_type_description);
if options.hide_agent_type_model_reasoning {
hide_spawn_agent_metadata_options(&mut properties);
@@ -93,6 +98,7 @@ pub fn create_spawn_agent_tool_v2(options: SpawnAgentToolOptions) -> ToolSpec {
name: "spawn_agent".to_string(),
description: spawn_agent_tool_description_v2(
available_models_description.as_deref(),
inherited_model_guidance,
options.include_usage_hint,
options.usage_hint_text,
options.max_concurrent_threads_per_session,
@@ -632,16 +638,18 @@ fn hide_spawn_agent_metadata_options(properties: &mut BTreeMap<String, JsonSchem
fn spawn_agent_tool_description(
available_models_description: Option<&str>,
inherited_model_guidance: Option<&str>,
return_value_description: &str,
include_usage_hint: bool,
usage_hint_text: Option<String>,
) -> String {
let agent_role_guidance = available_models_description.unwrap_or_default();
let inherited_model_guidance = inherited_model_guidance.unwrap_or_default();
let tool_description = format!(
r#"
{agent_role_guidance}
Spawn a sub-agent for a well-scoped task. {return_value_description} {SPAWN_AGENT_INHERITED_MODEL_GUIDANCE}"#
Spawn a sub-agent for a well-scoped task. {return_value_description} {inherited_model_guidance}"#
);
if !include_usage_hint {
@@ -701,11 +709,13 @@ Requests for depth, thoroughness, research, investigation, or detailed codebase
fn spawn_agent_tool_description_v2(
available_models_description: Option<&str>,
inherited_model_guidance: 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 inherited_model_guidance = inherited_model_guidance.unwrap_or_default();
let concurrency_guidance = max_concurrent_threads_per_session
.map(|limit| {
format!(
@@ -720,7 +730,7 @@ fn spawn_agent_tool_description_v2(
Spawns an agent to work on the specified task. If your current task is `/root/task1` and you spawn_agent with task_name "task_3" the agent will have canonical task name `/root/task1/task_3`.
You are then able to refer to this agent as `task_3` or `/root/task1/task_3` interchangeably. However an agent `/root/task2/task_3` would only be able to communicate with this agent via its canonical name `/root/task1/task_3`.
The spawned agent will have the same tools as you and the ability to spawn its own subagents.
{SPAWN_AGENT_INHERITED_MODEL_GUIDANCE}
{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.
{concurrency_guidance}"#
@@ -197,7 +197,12 @@ fn spawn_agent_tool_hides_service_tier_with_spawn_metadata() {
max_concurrent_threads_per_session: Some(4),
});
let ToolSpec::Function(ResponsesApiTool { parameters, .. }) = tool else {
let ToolSpec::Function(ResponsesApiTool {
description,
parameters,
..
}) = tool
else {
panic!("spawn_agent should be a function tool");
};
let properties = parameters
@@ -209,6 +214,8 @@ fn spawn_agent_tool_hides_service_tier_with_spawn_metadata() {
assert!(!properties.contains_key("model"));
assert!(!properties.contains_key("reasoning_effort"));
assert!(!properties.contains_key("service_tier"));
assert!(!description.contains(SPAWN_AGENT_INHERITED_MODEL_GUIDANCE));
assert!(!description.contains("Available model overrides"));
}
#[test]
@@ -1161,7 +1161,7 @@ async fn multi_agent_v2_spawn_returns_path_and_send_message_accepts_relative_pat
let spawn_result: SpawnAgentResult =
serde_json::from_str(&content).expect("spawn result should parse");
assert_eq!(spawn_result.task_name, "/root/test_process");
assert!(spawn_result.nickname.is_some());
assert_eq!(spawn_result.nickname, None);
let child_thread_id = session
.services
@@ -2179,7 +2179,7 @@ async fn multi_agent_v2_spawn_omits_agent_id_when_named() {
assert!(result.get("agent_id").is_none());
assert_eq!(result["task_name"], "/root/test_process");
assert!(result.get("nickname").is_some());
assert!(result.get("nickname").is_none());
assert_eq!(success, Some(true));
}
@@ -2436,7 +2436,7 @@ async fn multi_agent_v2_spawn_agent_ignores_configured_max_depth() {
let result: SpawnAgentResult =
serde_json::from_str(&content).expect("spawn_agent result should be json");
assert_eq!(result.task_name, "/root/parent/child");
assert!(result.nickname.is_some());
assert_eq!(result.nickname, None);
assert_eq!(success, Some(true));
}
@@ -165,6 +165,7 @@ async fn spawn_agent_description_lists_visible_models_and_reasoning_efforts() ->
.features
.enable(Feature::Collab)
.expect("test config should allow feature update");
config.multi_agent_v2.hide_spawn_agent_metadata = false;
});
let test = builder.build(&server).await?;
wait_for_model_available(&test.thread_manager.get_models_manager(), "visible-model").await;
@@ -1184,6 +1184,7 @@ async fn spawn_agent_tool_description_mentions_role_locked_settings() -> Result<
.features
.enable(Feature::Collab)
.expect("test config should allow feature update");
config.multi_agent_v2.hide_spawn_agent_metadata = false;
let role_path = config.codex_home.join("custom-role.toml");
std::fs::write(
&role_path,