mirror of
https://github.com/openai/codex.git
synced 2026-11-06 00:30:29 +00:00
Support leaf models in multi-agent v2 (#36892)
## What changed - Allow multi-agent v2 parents to spawn any visible model that has not explicitly disabled multi-agent support. - Expose collaboration tools to child agents only when their selected model supports multi-agent v2, keeping legacy models as leaf workers. - Preserve a worker's selected model when reloading it into residency. - Propagate multi-agent capability metadata to Amazon Bedrock model entries so delegation is gated consistently. ## Testing - Cover model selection, leaf-worker tool visibility, Bedrock capability handling, and model preservation after reload. GitOrigin-RevId: 1457adb1a09806d1f0621311d5a42a6815b9dd4e
This commit is contained in:
1 parent
1669c2403f
commit
6d4d9442c7
11 files changed
+131
-61
No files matched your search
@@ -100,17 +100,19 @@ async fn v2_nested_spawn_checks_shared_active_execution_capacity() -> Result<()>
|
||||
)
|
||||
.await;
|
||||
|
||||
let mut builder = test_codex().with_model("koffing").with_config(|config| {
|
||||
config
|
||||
.features
|
||||
.enable(Feature::Collab)
|
||||
.expect("test config should allow feature update");
|
||||
config
|
||||
.features
|
||||
.enable(Feature::MultiAgentV2)
|
||||
.expect("test config should allow feature update");
|
||||
config.multi_agent_v2.max_concurrent_threads_per_session = 2;
|
||||
});
|
||||
let mut builder = test_codex()
|
||||
.with_model("gpt-5.6-sol")
|
||||
.with_config(|config| {
|
||||
config
|
||||
.features
|
||||
.enable(Feature::Collab)
|
||||
.expect("test config should allow feature update");
|
||||
config
|
||||
.features
|
||||
.enable(Feature::MultiAgentV2)
|
||||
.expect("test config should allow feature update");
|
||||
config.multi_agent_v2.max_concurrent_threads_per_session = 2;
|
||||
});
|
||||
let test = builder.build(&server).await?;
|
||||
test.submit_turn(FIRST_PROMPT).await?;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ const SIBLING_FOLLOWUP_TASK: &str = "verify the surviving worker";
|
||||
const INTERRUPT_PROMPT: &str = "release the interrupted worker";
|
||||
const SIBLING_NAME: &str = "survivor";
|
||||
const ROLE_NAME: &str = "durable_worker";
|
||||
const ROLE_MODEL: &str = "gpt-5.4";
|
||||
const ROLE_MODEL: &str = "gpt-5.6-sol";
|
||||
const ROLE_MODEL_PROVIDER_ID: &str = "mock";
|
||||
const ROLE_DEVELOPER_INSTRUCTIONS: &str = "Keep the durable worker role configuration.";
|
||||
const SUBAGENT_DEVELOPER_INSTRUCTIONS: &str = "Use the default durable worker instructions.";
|
||||
|
||||
@@ -1400,10 +1400,15 @@ async fn spawned_multi_agent_v2_child_inherits_parent_developer_context() -> Res
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(false; "encrypted")]
|
||||
#[test_case(true; "plaintext")]
|
||||
#[test_case(None, false; "encrypted")]
|
||||
#[test_case(None, true; "plaintext")]
|
||||
#[test_case(Some("gpt-5.6-luna"), false; "luna encrypted leaf")]
|
||||
#[test_case(Some("gpt-5.5"), false; "legacy encrypted leaf")]
|
||||
#[tokio::test]
|
||||
async fn multi_agent_v2_spawn_sends_agent_message_to_child(plaintext: bool) -> Result<()> {
|
||||
async fn multi_agent_v2_spawn_sends_agent_message_to_child(
|
||||
model: Option<&str>,
|
||||
plaintext: bool,
|
||||
) -> Result<()> {
|
||||
let output: &'static Mutex<Vec<u8>> = Box::leak(Box::new(Mutex::new(Vec::new())));
|
||||
let subscriber = tracing_subscriber::fmt()
|
||||
.with_ansi(false)
|
||||
@@ -1418,10 +1423,17 @@ async fn multi_agent_v2_spawn_sends_agent_message_to_child(plaintext: bool) -> R
|
||||
} else {
|
||||
"opaque-encrypted-message"
|
||||
};
|
||||
let spawn_args = serde_json::to_string(&json!({
|
||||
let mut spawn_args = json!({
|
||||
"message": message,
|
||||
"task_name": "worker",
|
||||
}))?;
|
||||
});
|
||||
if let Some(model) = model {
|
||||
spawn_args["model"] = json!(model);
|
||||
if model == "gpt-5.5" {
|
||||
spawn_args["fork_turns"] = json!("none");
|
||||
}
|
||||
}
|
||||
let spawn_args = serde_json::to_string(&spawn_args)?;
|
||||
let mut spawn_event = ev_function_call_with_namespace(
|
||||
SPAWN_CALL_ID,
|
||||
MULTI_AGENT_V2_NAMESPACE,
|
||||
@@ -1463,7 +1475,12 @@ async fn multi_agent_v2_spawn_sends_agent_message_to_child(plaintext: bool) -> R
|
||||
)
|
||||
.await;
|
||||
|
||||
let mut builder = test_codex().with_model("koffing").with_config(|config| {
|
||||
let parent_model = if model.is_some() {
|
||||
"gpt-5.6-sol"
|
||||
} else {
|
||||
"koffing"
|
||||
};
|
||||
let mut builder = test_codex().with_model(parent_model).with_config(|config| {
|
||||
config
|
||||
.features
|
||||
.enable(Feature::Collab)
|
||||
@@ -1524,6 +1541,16 @@ async fn multi_agent_v2_spawn_sends_agent_message_to_child(plaintext: bool) -> R
|
||||
"content": content,
|
||||
})])
|
||||
);
|
||||
if let Some(model) = model {
|
||||
assert_eq!(child_request.body_json()["model"], json!(model));
|
||||
assert!(
|
||||
!child_request
|
||||
.body_json()
|
||||
.to_string()
|
||||
.contains("\"name\":\"collaboration\""),
|
||||
"leaf workers must not receive collaboration tools",
|
||||
);
|
||||
}
|
||||
if plaintext {
|
||||
assert!(
|
||||
parent_request_log.requests().into_iter().any(|request| {
|
||||
|
||||
Reference in new issue
Block a user