mirror of
https://github.com/openai/codex.git
synced 2026-05-24 04:54:52 +00:00
Deduplicate forked subagent developer instructions
This commit is contained in:
@@ -396,10 +396,9 @@ impl AgentControl {
|
||||
forked_rollout_items =
|
||||
truncate_rollout_to_last_n_fork_turns(&forked_rollout_items, *last_n_turns);
|
||||
}
|
||||
// MultiAgentV2 root/subagent usage hints are injected as standalone developer
|
||||
// messages at thread start. When forking history, drop hints from the parent
|
||||
// so the child gets a fresh hint that matches its own session source/config.
|
||||
let multi_agent_v2_usage_hint_texts_to_filter: Vec<String> =
|
||||
// Standalone developer items that the child reinjects at startup should not
|
||||
// survive the inherited forked history, or they appear twice in the child prompt.
|
||||
let mut forked_developer_texts_to_filter: Vec<String> =
|
||||
if let Some(parent_thread) = parent_thread.as_ref() {
|
||||
parent_thread
|
||||
.codex
|
||||
@@ -417,11 +416,16 @@ impl AgentControl {
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
if let Some(developer_instructions) = config.developer_instructions.as_deref()
|
||||
&& !developer_instructions.is_empty()
|
||||
{
|
||||
forked_developer_texts_to_filter.push(developer_instructions.to_string());
|
||||
}
|
||||
forked_rollout_items.retain(|item| {
|
||||
if let RolloutItem::ResponseItem(ResponseItem::Message { role, content, .. }) = item
|
||||
&& role == "developer"
|
||||
&& let [ContentItem::InputText { text }] = content.as_slice()
|
||||
&& multi_agent_v2_usage_hint_texts_to_filter
|
||||
&& forked_developer_texts_to_filter
|
||||
.iter()
|
||||
.any(|usage_hint_text| usage_hint_text == text)
|
||||
{
|
||||
|
||||
@@ -614,6 +614,7 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
|
||||
Some("Child root guidance.".to_string());
|
||||
child_config.multi_agent_v2.subagent_usage_hint_text =
|
||||
Some("Child subagent guidance.".to_string());
|
||||
child_config.developer_instructions = Some("Parent developer instructions.".to_string());
|
||||
let new_thread = harness
|
||||
.manager
|
||||
.start_thread(parent_config.clone())
|
||||
@@ -655,6 +656,14 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
|
||||
}],
|
||||
phase: None,
|
||||
},
|
||||
ResponseItem::Message {
|
||||
id: None,
|
||||
role: "developer".to_string(),
|
||||
content: vec![ContentItem::InputText {
|
||||
text: "Parent developer instructions.".to_string(),
|
||||
}],
|
||||
phase: None,
|
||||
},
|
||||
assistant_message("parent commentary", Some(MessagePhase::Commentary)),
|
||||
assistant_message("parent final answer", Some(MessagePhase::FinalAnswer)),
|
||||
assistant_message("parent unknown phase", /*phase*/ None),
|
||||
@@ -726,6 +735,15 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
|
||||
&expected_history,
|
||||
"forked child history should keep only parent user messages and assistant final answers"
|
||||
);
|
||||
let child_rollout_path = child_thread
|
||||
.rollout_path()
|
||||
.expect("forked child rollout path");
|
||||
let child_rollout = std::fs::read_to_string(&child_rollout_path)
|
||||
.expect("forked child rollout should be readable");
|
||||
assert!(
|
||||
!child_rollout.contains("Parent developer instructions."),
|
||||
"forked child rollout should not retain developer instructions that will be reinjected"
|
||||
);
|
||||
|
||||
let expected = (
|
||||
child_thread_id,
|
||||
|
||||
Reference in New Issue
Block a user