Skip to content

Commit a2f868c

Browse files
authored
feat: drop spawned-agent context instructions (#19127)
## Why MultiAgentV2 children should not receive an extra model-visible developer fragment just because they were spawned. The parent/configured developer instructions should carry through normally, but the dedicated `<spawned_agent_context>` block is no longer desired. ## What changed - Removed the `SpawnAgentInstructions` context fragment and its `<spawned_agent_context>` wrapper. - Stopped appending spawned-agent instructions in `codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs`. - Updated subagent notification coverage to assert inherited parent developer instructions without expecting the spawned-agent wrapper. ## Verification - `cargo test -p codex-core --test all spawned_multi_agent_v2_child_inherits_parent_developer_context -- --nocapture` - `cargo test -p codex-core --test all skills_toggle_skips_instructions_for_parent_and_spawned_child -- --nocapture` - `cargo test -p codex-core --test all subagent_notifications -- --nocapture`
1 parent e18bfee commit a2f868c

4 files changed

Lines changed: 7 additions & 54 deletions

File tree

codex-rs/core/src/context/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ mod realtime_end_instructions;
2020
mod realtime_start_instructions;
2121
mod realtime_start_with_instructions;
2222
mod skill_instructions;
23-
mod spawn_agent_instructions;
2423
mod subagent_notification;
2524
mod turn_aborted;
2625
mod user_instructions;
@@ -50,7 +49,6 @@ pub(crate) use realtime_end_instructions::RealtimeEndInstructions;
5049
pub(crate) use realtime_start_instructions::RealtimeStartInstructions;
5150
pub(crate) use realtime_start_with_instructions::RealtimeStartWithInstructions;
5251
pub(crate) use skill_instructions::SkillInstructions;
53-
pub(crate) use spawn_agent_instructions::SpawnAgentInstructions;
5452
pub(crate) use subagent_notification::SubagentNotification;
5553
pub(crate) use turn_aborted::TurnAborted;
5654
pub(crate) use user_instructions::UserInstructions;

codex-rs/core/src/context/spawn_agent_instructions.rs

Lines changed: 0 additions & 14 deletions
This file was deleted.

codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ use crate::agent::control::render_input_preview;
55
use crate::agent::next_thread_spawn_depth;
66
use crate::agent::role::DEFAULT_ROLE_NAME;
77
use crate::agent::role::apply_role_to_config;
8-
use crate::context::ContextualUserFragment;
9-
use crate::context::SpawnAgentInstructions;
108
use codex_protocol::AgentPath;
119
use codex_protocol::protocol::InterAgentCommunication;
1210
use codex_protocol::protocol::Op;
@@ -88,18 +86,6 @@ impl ToolHandler for Handler {
8886
}
8987
apply_spawn_agent_runtime_overrides(&mut config, turn.as_ref())?;
9088
apply_spawn_agent_overrides(&mut config, child_depth);
91-
let spawn_agent_instructions = SpawnAgentInstructions.render();
92-
config.developer_instructions = Some(
93-
if let Some(mut existing_instructions) = config.developer_instructions.take() {
94-
if !existing_instructions.ends_with('\n') {
95-
existing_instructions.push('\n');
96-
}
97-
existing_instructions.push_str(&spawn_agent_instructions);
98-
existing_instructions
99-
} else {
100-
spawn_agent_instructions
101-
},
102-
);
10389

10490
let spawn_source = thread_spawn_source(
10591
session.conversation_id,

codex-rs/core/tests/suite/subagent_notifications.rs

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ const REQUESTED_MODEL: &str = "gpt-5.4";
3737
const REQUESTED_REASONING_EFFORT: ReasoningEffort = ReasoningEffort::Low;
3838
const ROLE_MODEL: &str = "gpt-5.4";
3939
const ROLE_REASONING_EFFORT: ReasoningEffort = ReasoningEffort::High;
40-
const SPAWNED_AGENT_DEVELOPER_INSTRUCTIONS: &str = "You are a newly spawned agent in a team of agents collaborating to complete a task. You can spawn sub-agents to handle subtasks, and those sub-agents can spawn their own sub-agents. You are responsible for returning the response to your assigned task in the final channel. When you give your response, the contents of your response in the final channel will be immediately delivered back to your parent agent. The prior conversation history was forked from your parent agent. Treat the next user message as your assigned task, and use the forked history only as background context.";
4140

4241
fn body_contains(req: &wiremock::Request, text: &str) -> bool {
4342
let is_zstd = req
@@ -425,7 +424,7 @@ async fn spawn_agent_requested_model_and_reasoning_override_inherited_settings_w
425424
}
426425

427426
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
428-
async fn spawned_multi_agent_v2_child_receives_xml_tagged_developer_context() -> Result<()> {
427+
async fn spawned_multi_agent_v2_child_inherits_parent_developer_context() -> Result<()> {
429428
skip_if_no_network!(Ok(()));
430429

431430
let server = start_mock_server().await;
@@ -446,9 +445,7 @@ async fn spawned_multi_agent_v2_child_receives_xml_tagged_developer_context() ->
446445

447446
let _child_request_log = mount_sse_once_match(
448447
&server,
449-
|req: &wiremock::Request| {
450-
body_contains(req, CHILD_PROMPT) && body_contains(req, "<spawned_agent_context>")
451-
},
448+
|req: &wiremock::Request| body_contains(req, CHILD_PROMPT),
452449
sse(vec![
453450
ev_response_created("resp-child-1"),
454451
ev_completed("resp-child-1"),
@@ -459,9 +456,7 @@ async fn spawned_multi_agent_v2_child_receives_xml_tagged_developer_context() ->
459456
let _turn1_followup = mount_sse_once_match(
460457
&server,
461458
|req: &wiremock::Request| {
462-
body_contains(req, "function_call_output")
463-
&& body_contains(req, "/root/worker")
464-
&& !body_contains(req, "<spawned_agent_context>")
459+
body_contains(req, "function_call_output") && body_contains(req, "/root/worker")
465460
},
466461
sse(vec![
467462
ev_response_created("resp-turn1-2"),
@@ -494,9 +489,7 @@ async fn spawned_multi_agent_v2_child_receives_xml_tagged_developer_context() ->
494489
.unwrap_or_default()
495490
.into_iter()
496491
.find(|request| {
497-
body_contains(request, CHILD_PROMPT)
498-
&& body_contains(request, "<spawned_agent_context>")
499-
&& body_contains(request, SPAWNED_AGENT_DEVELOPER_INSTRUCTIONS)
492+
body_contains(request, CHILD_PROMPT) && !body_contains(request, SPAWN_CALL_ID)
500493
})
501494
{
502495
break request;
@@ -510,11 +503,6 @@ async fn spawned_multi_agent_v2_child_receives_xml_tagged_developer_context() ->
510503
&child_request,
511504
"Parent developer instructions."
512505
));
513-
assert!(body_contains(&child_request, "<spawned_agent_context>"));
514-
assert!(body_contains(
515-
&child_request,
516-
SPAWNED_AGENT_DEVELOPER_INSTRUCTIONS
517-
));
518506
assert!(body_contains(&child_request, CHILD_PROMPT));
519507

520508
Ok(())
@@ -542,9 +530,7 @@ async fn skills_toggle_skips_instructions_for_parent_and_spawned_child() -> Resu
542530

543531
let _child_request_log = mount_sse_once_match(
544532
&server,
545-
|req: &wiremock::Request| {
546-
body_contains(req, CHILD_PROMPT) && body_contains(req, "<spawned_agent_context>")
547-
},
533+
|req: &wiremock::Request| body_contains(req, CHILD_PROMPT),
548534
sse(vec![
549535
ev_response_created("resp-child-1"),
550536
ev_completed("resp-child-1"),
@@ -555,9 +541,7 @@ async fn skills_toggle_skips_instructions_for_parent_and_spawned_child() -> Resu
555541
let _turn1_followup = mount_sse_once_match(
556542
&server,
557543
|req: &wiremock::Request| {
558-
body_contains(req, "function_call_output")
559-
&& body_contains(req, "/root/worker")
560-
&& !body_contains(req, "<spawned_agent_context>")
544+
body_contains(req, "function_call_output") && body_contains(req, "/root/worker")
561545
},
562546
sse(vec![
563547
ev_response_created("resp-turn1-2"),
@@ -599,8 +583,7 @@ async fn skills_toggle_skips_instructions_for_parent_and_spawned_child() -> Resu
599583
.unwrap_or_default()
600584
.into_iter()
601585
.find(|request| {
602-
body_contains(request, CHILD_PROMPT)
603-
&& body_contains(request, "<spawned_agent_context>")
586+
body_contains(request, CHILD_PROMPT) && !body_contains(request, SPAWN_CALL_ID)
604587
})
605588
{
606589
break request;

0 commit comments

Comments
 (0)