mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Use message string in v2 spawn_agent (#16406)
## Summary - switch MultiAgentV2 spawn_agent to accept a single message string instead of items - update v2 spawn tool schema and focused handler/spec tests ## Verification - cargo test -p codex-tools spawn_agent_tool_v2_requires_task_name_and_lists_visible_models - cargo test -p codex-core multi_agent_v2_spawn - just fix -p codex-tools - just fix -p codex-core - just argument-comment-lint Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
dedd1c386a
commit
d0474f2bc1
@@ -347,7 +347,7 @@ async fn multi_agent_v2_spawn_requires_task_name() {
|
||||
Arc::new(turn),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "inspect this repo"}]
|
||||
"message": "inspect this repo"
|
||||
})),
|
||||
);
|
||||
let Err(err) = SpawnAgentHandlerV2.handle(invocation).await else {
|
||||
@@ -360,7 +360,7 @@ async fn multi_agent_v2_spawn_requires_task_name() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn multi_agent_v2_spawn_rejects_legacy_message_field() {
|
||||
async fn multi_agent_v2_spawn_rejects_legacy_items_field() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
@@ -387,12 +387,12 @@ async fn multi_agent_v2_spawn_rejects_legacy_message_field() {
|
||||
})),
|
||||
);
|
||||
let Err(err) = SpawnAgentHandlerV2.handle(invocation).await else {
|
||||
panic!("legacy message field should be rejected");
|
||||
panic!("legacy items field should be rejected");
|
||||
};
|
||||
let FunctionCallError::RespondToModel(message) = err else {
|
||||
panic!("legacy message field should surface as a model-facing error");
|
||||
panic!("legacy items field should surface as a model-facing error");
|
||||
};
|
||||
assert!(message.contains("unknown field `message`"));
|
||||
assert!(message.contains("unknown field `items`"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -444,7 +444,7 @@ async fn multi_agent_v2_spawn_returns_path_and_send_message_accepts_relative_pat
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "inspect this repo"}],
|
||||
"message": "inspect this repo",
|
||||
"task_name": "test_process"
|
||||
})),
|
||||
))
|
||||
@@ -539,7 +539,7 @@ async fn multi_agent_v2_spawn_rejects_legacy_fork_context() {
|
||||
Arc::new(turn),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "inspect this repo"}],
|
||||
"message": "inspect this repo",
|
||||
"task_name": "worker",
|
||||
"fork_context": true
|
||||
})),
|
||||
@@ -578,7 +578,7 @@ async fn multi_agent_v2_spawn_rejects_invalid_fork_turns_string() {
|
||||
Arc::new(turn),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "inspect this repo"}],
|
||||
"message": "inspect this repo",
|
||||
"task_name": "worker",
|
||||
"fork_turns": "banana"
|
||||
})),
|
||||
@@ -617,7 +617,7 @@ async fn multi_agent_v2_spawn_rejects_zero_fork_turns() {
|
||||
Arc::new(turn),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "inspect this repo"}],
|
||||
"message": "inspect this repo",
|
||||
"task_name": "worker",
|
||||
"fork_turns": "0"
|
||||
})),
|
||||
@@ -731,7 +731,7 @@ async fn multi_agent_v2_list_agents_returns_completed_status_and_last_task_messa
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "inspect this repo"}],
|
||||
"message": "inspect this repo",
|
||||
"task_name": "worker"
|
||||
})),
|
||||
))
|
||||
@@ -909,7 +909,7 @@ async fn multi_agent_v2_list_agents_omits_closed_agents() {
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "inspect this repo"}],
|
||||
"message": "inspect this repo",
|
||||
"task_name": "worker"
|
||||
})),
|
||||
))
|
||||
@@ -973,7 +973,7 @@ async fn multi_agent_v2_send_message_rejects_structured_items() {
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "boot worker"}],
|
||||
"message": "boot worker",
|
||||
"task_name": "worker"
|
||||
})),
|
||||
))
|
||||
@@ -1031,7 +1031,7 @@ async fn multi_agent_v2_send_message_rejects_interrupt_parameter() {
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "boot worker"}],
|
||||
"message": "boot worker",
|
||||
"task_name": "worker"
|
||||
})),
|
||||
))
|
||||
@@ -1104,7 +1104,7 @@ async fn multi_agent_v2_assign_task_interrupts_busy_child_without_losing_message
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "boot worker"}],
|
||||
"message": "boot worker",
|
||||
"task_name": "worker"
|
||||
})),
|
||||
))
|
||||
@@ -1233,7 +1233,7 @@ async fn multi_agent_v2_assign_task_completion_notifies_parent_on_every_turn() {
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "boot worker"}],
|
||||
"message": "boot worker",
|
||||
"task_name": "worker"
|
||||
})),
|
||||
))
|
||||
@@ -1438,7 +1438,7 @@ async fn multi_agent_v2_spawn_includes_agent_id_key_when_named() {
|
||||
Arc::new(turn),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "inspect this repo"}],
|
||||
"message": "inspect this repo",
|
||||
"task_name": "test_process"
|
||||
})),
|
||||
))
|
||||
@@ -1476,7 +1476,7 @@ async fn multi_agent_v2_spawn_surfaces_task_name_validation_errors() {
|
||||
Arc::new(turn),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "inspect this repo"}],
|
||||
"message": "inspect this repo",
|
||||
"task_name": "BadName"
|
||||
})),
|
||||
);
|
||||
@@ -2103,7 +2103,7 @@ async fn multi_agent_v2_wait_agent_accepts_timeout_only_argument() {
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "boot worker"}],
|
||||
"message": "boot worker",
|
||||
"task_name": "worker"
|
||||
})),
|
||||
))
|
||||
@@ -2349,7 +2349,7 @@ async fn multi_agent_v2_wait_agent_returns_summary_for_mailbox_activity() {
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "inspect this repo"}],
|
||||
"message": "inspect this repo",
|
||||
"task_name": "test_process"
|
||||
})),
|
||||
))
|
||||
@@ -2440,7 +2440,7 @@ async fn multi_agent_v2_wait_agent_waits_for_new_mail_after_start() {
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "boot worker"}],
|
||||
"message": "boot worker",
|
||||
"task_name": "worker"
|
||||
})),
|
||||
))
|
||||
@@ -2540,7 +2540,7 @@ async fn multi_agent_v2_wait_agent_wakes_on_any_mailbox_notification() {
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": format!("boot {task_name}")}],
|
||||
"message": format!("boot {task_name}"),
|
||||
"task_name": task_name
|
||||
})),
|
||||
))
|
||||
@@ -2627,7 +2627,7 @@ async fn multi_agent_v2_wait_agent_does_not_return_completed_content() {
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "boot worker"}],
|
||||
"message": "boot worker",
|
||||
"task_name": "worker"
|
||||
})),
|
||||
))
|
||||
@@ -2713,7 +2713,7 @@ async fn multi_agent_v2_close_agent_accepts_task_name_target() {
|
||||
turn.clone(),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"items": [{"type": "text", "text": "inspect this repo"}],
|
||||
"message": "inspect this repo",
|
||||
"task_name": "worker"
|
||||
})),
|
||||
))
|
||||
|
||||
@@ -40,7 +40,7 @@ impl ToolHandler for Handler {
|
||||
.map(str::trim)
|
||||
.filter(|role| !role.is_empty());
|
||||
|
||||
let initial_operation = parse_collab_input(/*message*/ None, Some(args.items))?;
|
||||
let initial_operation = parse_collab_input(Some(args.message), /*items*/ None)?;
|
||||
let prompt = render_input_preview(&initial_operation);
|
||||
|
||||
let session_source = turn.session_source.clone();
|
||||
@@ -202,7 +202,7 @@ impl ToolHandler for Handler {
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct SpawnAgentArgs {
|
||||
items: Vec<UserInput>,
|
||||
message: String,
|
||||
task_name: String,
|
||||
agent_type: Option<String>,
|
||||
model: Option<String>,
|
||||
|
||||
@@ -497,13 +497,13 @@ fn test_build_specs_multi_agent_v2_uses_task_names_and_hides_resume() {
|
||||
panic!("spawn_agent should use object params");
|
||||
};
|
||||
assert!(properties.contains_key("task_name"));
|
||||
assert!(properties.contains_key("items"));
|
||||
assert!(properties.contains_key("message"));
|
||||
assert!(properties.contains_key("fork_turns"));
|
||||
assert!(!properties.contains_key("message"));
|
||||
assert!(!properties.contains_key("items"));
|
||||
assert!(!properties.contains_key("fork_context"));
|
||||
assert_eq!(
|
||||
required.as_ref(),
|
||||
Some(&vec!["task_name".to_string(), "items".to_string()])
|
||||
Some(&vec!["task_name".to_string(), "message".to_string()])
|
||||
);
|
||||
let output_schema = output_schema
|
||||
.as_ref()
|
||||
|
||||
@@ -66,7 +66,7 @@ pub fn create_spawn_agent_tool_v2(options: SpawnAgentToolOptions<'_>) -> ToolSpe
|
||||
defer_loading: None,
|
||||
parameters: JsonSchema::Object {
|
||||
properties,
|
||||
required: Some(vec!["task_name".to_string(), "items".to_string()]),
|
||||
required: Some(vec!["task_name".to_string(), "message".to_string()]),
|
||||
additional_properties: Some(false.into()),
|
||||
},
|
||||
output_schema: Some(spawn_agent_output_schema_v2()),
|
||||
@@ -585,7 +585,12 @@ fn spawn_agent_common_properties_v1(agent_type_description: &str) -> BTreeMap<St
|
||||
|
||||
fn spawn_agent_common_properties_v2(agent_type_description: &str) -> BTreeMap<String, JsonSchema> {
|
||||
BTreeMap::from([
|
||||
("items".to_string(), create_collab_input_items_schema()),
|
||||
(
|
||||
"message".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Initial plain-text task for the new agent.".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"agent_type".to_string(),
|
||||
JsonSchema::String {
|
||||
|
||||
@@ -56,9 +56,9 @@ fn spawn_agent_tool_v2_requires_task_name_and_lists_visible_models() {
|
||||
assert!(description.contains("visible display (`visible-model`)"));
|
||||
assert!(!description.contains("hidden display (`hidden-model`)"));
|
||||
assert!(properties.contains_key("task_name"));
|
||||
assert!(properties.contains_key("items"));
|
||||
assert!(properties.contains_key("message"));
|
||||
assert!(properties.contains_key("fork_turns"));
|
||||
assert!(!properties.contains_key("message"));
|
||||
assert!(!properties.contains_key("items"));
|
||||
assert!(!properties.contains_key("fork_context"));
|
||||
assert_eq!(
|
||||
properties.get("agent_type"),
|
||||
@@ -68,7 +68,7 @@ fn spawn_agent_tool_v2_requires_task_name_and_lists_visible_models() {
|
||||
);
|
||||
assert_eq!(
|
||||
required,
|
||||
Some(vec!["task_name".to_string(), "items".to_string()])
|
||||
Some(vec!["task_name".to_string(), "message".to_string()])
|
||||
);
|
||||
assert_eq!(
|
||||
output_schema.expect("spawn_agent output schema")["required"],
|
||||
|
||||
Reference in New Issue
Block a user