mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
@@ -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(())
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user