Test developer instruction inheritance for multi-agent workers (#35653)

## Testing

- Verify full, compacted, and bounded history forks preserve developer messages while removing stale parent usage hints.
- Add an app-server regression test that cold-resumes a root thread and confirms a roleless worker retains inherited developer instructions when lazily reloaded for follow-up work.

GitOrigin-RevId: 40e454a2a2b721ea645cbc607b17a3ae6b617bd9
This commit is contained in:
Adam Perry @ OpenAI authored and copyberry committed 2026-07-27 18:12:42 +00:00
1 parent 462ed19a05
commit 9f82ffed1b
3 files changed
+347

No files matched your search

+91
View File
@@ -1209,6 +1209,7 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
let harness = AgentControlHarness::new().await;
let mut parent_config = harness.config.clone();
let _ = parent_config.features.enable(Feature::MultiAgentV2);
parent_config.developer_instructions = Some("Parent developer instructions.".to_string());
parent_config.multi_agent_v2.root_agent_usage_hint_text =
Some("Parent root guidance.".to_string());
parent_config.multi_agent_v2.subagent_usage_hint_text =
@@ -1269,6 +1270,20 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
phase: None,
internal_chat_message_metadata_passthrough: None,
},
ResponseItem::Message {
id: None,
role: "developer".to_string(),
content: vec![
ContentItem::InputText {
text: "Parent developer instructions.".to_string(),
},
ContentItem::InputText {
text: "Preserved developer context.".to_string(),
},
],
phase: None,
internal_chat_message_metadata_passthrough: None,
},
assistant_message("parent commentary", Some(MessagePhase::Commentary)),
assistant_message("parent final answer", Some(MessagePhase::FinalAnswer)),
assistant_message("parent unknown phase", /*phase*/ None),
@@ -1333,8 +1348,24 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
let mut expected_final_answer =
assistant_message("parent final answer", Some(MessagePhase::FinalAnswer));
expected_final_answer.set_turn_id_if_missing(&turn_context.sub_id);
let mut expected_developer_message = ResponseItem::Message {
id: None,
role: "developer".to_string(),
content: vec![
ContentItem::InputText {
text: "Parent developer instructions.".to_string(),
},
ContentItem::InputText {
text: "Preserved developer context.".to_string(),
},
],
phase: None,
internal_chat_message_metadata_passthrough: None,
};
expected_developer_message.set_turn_id_if_missing(&turn_context.sub_id);
let expected_history = [
expected_parent_seed,
expected_developer_message,
expected_final_answer,
ResponseItem::Message {
id: None,
@@ -1393,6 +1424,17 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
!history_contains_text(no_hint_history.raw_items(), "Child subagent guidance."),
"full-history forked child should not add empty subagent guidance"
);
assert!(
history_contains_text(
no_hint_history.raw_items(),
"Parent developer instructions."
),
"full-history forked child should inherit parent developer instructions"
);
assert!(
history_contains_text(no_hint_history.raw_items(), "Preserved developer context."),
"full-history forked child should preserve unrelated developer fragments"
);
let expected = (
child_thread_id,
@@ -1435,6 +1477,7 @@ async fn spawn_agent_fork_strips_parent_usage_hints_from_compacted_history() {
let harness = AgentControlHarness::new().await;
let mut parent_config = harness.config.clone();
let _ = parent_config.features.enable(Feature::MultiAgentV2);
parent_config.developer_instructions = Some("Parent developer instructions.".to_string());
parent_config.multi_agent_v2.root_agent_usage_hint_text =
Some("Parent root guidance.".to_string());
parent_config.multi_agent_v2.subagent_usage_hint_text =
@@ -1473,6 +1516,20 @@ async fn spawn_agent_fork_strips_parent_usage_hints_from_compacted_history() {
phase: None,
internal_chat_message_metadata_passthrough: None,
},
ResponseItem::Message {
id: None,
role: "developer".to_string(),
content: vec![
ContentItem::InputText {
text: "Parent developer instructions.".to_string(),
},
ContentItem::InputText {
text: "Preserved compacted developer context.".to_string(),
},
],
phase: None,
internal_chat_message_metadata_passthrough: None,
},
];
parent_thread
.session
@@ -1532,6 +1589,17 @@ async fn spawn_agent_fork_strips_parent_usage_hints_from_compacted_history() {
!history_contains_text(history.raw_items(), "Parent root guidance."),
"forked child history should strip stale parent hints from compacted replacement history"
);
assert!(
history_contains_text(history.raw_items(), "Parent developer instructions."),
"forked child history should inherit compacted parent developer instructions"
);
assert!(
history_contains_text(
history.raw_items(),
"Preserved compacted developer context."
),
"forked child history should preserve unrelated compacted developer fragments"
);
assert!(
history_contains_text(history.raw_items(), "Child subagent guidance."),
"full-history forked child should add the child subagent hint after compacted-history sanitization"
@@ -1861,6 +1929,7 @@ async fn spawn_agent_fork_last_n_turns_strips_parent_usage_hints() {
let harness = AgentControlHarness::new().await;
let mut parent_config = harness.config.clone();
let _ = parent_config.features.enable(Feature::MultiAgentV2);
parent_config.developer_instructions = Some("Parent developer instructions.".to_string());
parent_config.multi_agent_v2.root_agent_usage_hint_text =
Some("Parent root guidance.".to_string());
let mut child_config = harness.config.clone();
@@ -1893,6 +1962,20 @@ async fn spawn_agent_fork_last_n_turns_strips_parent_usage_hints() {
phase: None,
internal_chat_message_metadata_passthrough: None,
},
ResponseItem::Message {
id: None,
role: "developer".to_string(),
content: vec![
ContentItem::InputText {
text: "Parent developer instructions.".to_string(),
},
ContentItem::InputText {
text: "Preserved bounded developer context.".to_string(),
},
],
phase: None,
internal_chat_message_metadata_passthrough: None,
},
spawn_agent_call(&parent_spawn_call_id),
],
)
@@ -1940,6 +2023,14 @@ async fn spawn_agent_fork_last_n_turns_strips_parent_usage_hints() {
!history_contains_text(history.raw_items(), "Parent root guidance."),
"bounded fork should strip stale parent root hints before the child rebuilds startup context"
);
assert!(
history_contains_text(history.raw_items(), "Parent developer instructions."),
"bounded fork should inherit parent developer instructions from retained turns"
);
assert!(
history_contains_text(history.raw_items(), "Preserved bounded developer context."),
"bounded fork should preserve unrelated developer fragments"
);
let _ = harness
.control