chore: default multi-agent v2 fork to all (#18873)

Default sub-agents v2 to `all` for the fork mode
This commit is contained in:
jif-oai
2026-04-21 21:54:58 +01:00
committed by GitHub
Unverified
parent 6f6997758a
commit 15b8cde2a4
5 changed files with 26 additions and 23 deletions
+4 -4
View File
@@ -117,10 +117,10 @@ fn keep_forked_rollout_item(item: &RolloutItem) -> bool {
| ResponseItem::Other,
) => false,
RolloutItem::SessionState(_) => false,
RolloutItem::Compacted(_)
| RolloutItem::EventMsg(_)
| RolloutItem::SessionMeta(_)
| RolloutItem::TurnContext(_) => true,
// A forked child gets its own runtime config, including spawned-agent
// instructions, so it must establish a fresh context diff baseline.
RolloutItem::TurnContext(_) => false,
RolloutItem::Compacted(_) | RolloutItem::EventMsg(_) | RolloutItem::SessionMeta(_) => true,
}
}
@@ -243,7 +243,7 @@ pub(crate) fn reject_full_fork_spawn_overrides(
) -> Result<(), FunctionCallError> {
if agent_type.is_some() || model.is_some() || reasoning_effort.is_some() {
return Err(FunctionCallError::RespondToModel(
"Full-history forked agents inherit the parent agent type, model, and reasoning effort; omit agent_type, model, and reasoning_effort, or spawn without fork_context/fork_turns=all.".to_string(),
"Full-history forked agents inherit the parent agent type, model, and reasoning effort; omit agent_type, model, and reasoning_effort, or spawn without a full-history fork.".to_string(),
));
}
Ok(())
@@ -431,7 +431,7 @@ async fn spawn_agent_fork_context_rejects_agent_type_override() {
assert_eq!(
err,
FunctionCallError::RespondToModel(
"Full-history forked agents inherit the parent agent type, model, and reasoning effort; omit agent_type, model, and reasoning_effort, or spawn without fork_context/fork_turns=all.".to_string(),
"Full-history forked agents inherit the parent agent type, model, and reasoning effort; omit agent_type, model, and reasoning_effort, or spawn without a full-history fork.".to_string(),
)
);
}
@@ -465,7 +465,7 @@ async fn spawn_agent_fork_context_rejects_child_model_overrides() {
assert_eq!(
err,
FunctionCallError::RespondToModel(
"Full-history forked agents inherit the parent agent type, model, and reasoning effort; omit agent_type, model, and reasoning_effort, or spawn without fork_context/fork_turns=all.".to_string(),
"Full-history forked agents inherit the parent agent type, model, and reasoning effort; omit agent_type, model, and reasoning_effort, or spawn without a full-history fork.".to_string(),
)
);
}
@@ -509,13 +509,13 @@ async fn multi_agent_v2_spawn_fork_turns_all_rejects_agent_type_override() {
assert_eq!(
err,
FunctionCallError::RespondToModel(
"Full-history forked agents inherit the parent agent type, model, and reasoning effort; omit agent_type, model, and reasoning_effort, or spawn without fork_context/fork_turns=all.".to_string(),
"Full-history forked agents inherit the parent agent type, model, and reasoning effort; omit agent_type, model, and reasoning_effort, or spawn without a full-history fork.".to_string(),
)
);
}
#[tokio::test]
async fn multi_agent_v2_spawn_fork_turns_rejects_child_model_overrides() {
async fn multi_agent_v2_spawn_defaults_to_full_fork_and_rejects_child_model_overrides() {
let (mut session, mut turn) = make_session_and_context().await;
let manager = thread_manager();
let root = manager
@@ -540,17 +540,16 @@ async fn multi_agent_v2_spawn_fork_turns_rejects_child_model_overrides() {
"message": "inspect this repo",
"task_name": "fork_context_v2",
"model": "gpt-5-child-override",
"reasoning_effort": "low",
"fork_turns": "all"
"reasoning_effort": "low"
})),
))
.await
.expect_err("forked spawn should reject child model overrides");
.expect_err("default full fork should reject child model overrides");
assert_eq!(
err,
FunctionCallError::RespondToModel(
"Full-history forked agents inherit the parent agent type, model, and reasoning effort; omit agent_type, model, and reasoning_effort, or spawn without fork_context/fork_turns=all.".to_string(),
"Full-history forked agents inherit the parent agent type, model, and reasoning effort; omit agent_type, model, and reasoning_effort, or spawn without a full-history fork.".to_string(),
)
);
}
@@ -244,14 +244,12 @@ impl SpawnAgentArgs {
));
}
let Some(fork_turns) = self
let fork_turns = self
.fork_turns
.as_deref()
.map(str::trim)
.filter(|fork_turns| !fork_turns.is_empty())
else {
return Ok(None);
};
.unwrap_or("all");
if fork_turns.eq_ignore_ascii_case("none") {
return Ok(None);
@@ -447,7 +447,7 @@ async fn spawned_multi_agent_v2_child_receives_xml_tagged_developer_context() ->
let _child_request_log = mount_sse_once_match(
&server,
|req: &wiremock::Request| {
body_contains(req, CHILD_PROMPT) && !body_contains(req, SPAWN_CALL_ID)
body_contains(req, CHILD_PROMPT) && body_contains(req, "<spawned_agent_context>")
},
sse(vec![
ev_response_created("resp-child-1"),
@@ -458,7 +458,11 @@ async fn spawned_multi_agent_v2_child_receives_xml_tagged_developer_context() ->
let _turn1_followup = mount_sse_once_match(
&server,
|req: &wiremock::Request| body_contains(req, SPAWN_CALL_ID),
|req: &wiremock::Request| {
body_contains(req, "function_call_output")
&& body_contains(req, "/root/worker")
&& !body_contains(req, "<spawned_agent_context>")
},
sse(vec![
ev_response_created("resp-turn1-2"),
ev_assistant_message("msg-turn1-2", "parent done"),
@@ -493,7 +497,6 @@ async fn spawned_multi_agent_v2_child_receives_xml_tagged_developer_context() ->
body_contains(request, CHILD_PROMPT)
&& body_contains(request, "<spawned_agent_context>")
&& body_contains(request, SPAWNED_AGENT_DEVELOPER_INSTRUCTIONS)
&& !body_contains(request, SPAWN_CALL_ID)
})
{
break request;
@@ -540,7 +543,7 @@ async fn skills_toggle_skips_instructions_for_parent_and_spawned_child() -> Resu
let _child_request_log = mount_sse_once_match(
&server,
|req: &wiremock::Request| {
body_contains(req, CHILD_PROMPT) && !body_contains(req, SPAWN_CALL_ID)
body_contains(req, CHILD_PROMPT) && body_contains(req, "<spawned_agent_context>")
},
sse(vec![
ev_response_created("resp-child-1"),
@@ -551,7 +554,11 @@ async fn skills_toggle_skips_instructions_for_parent_and_spawned_child() -> Resu
let _turn1_followup = mount_sse_once_match(
&server,
|req: &wiremock::Request| body_contains(req, SPAWN_CALL_ID),
|req: &wiremock::Request| {
body_contains(req, "function_call_output")
&& body_contains(req, "/root/worker")
&& !body_contains(req, "<spawned_agent_context>")
},
sse(vec![
ev_response_created("resp-turn1-2"),
ev_assistant_message("msg-turn1-2", "parent done"),
@@ -594,7 +601,6 @@ async fn skills_toggle_skips_instructions_for_parent_and_spawned_child() -> Resu
.find(|request| {
body_contains(request, CHILD_PROMPT)
&& body_contains(request, "<spawned_agent_context>")
&& !body_contains(request, SPAWN_CALL_ID)
})
{
break request;