mirror of
https://github.com/openai/codex.git
synced 2026-11-05 16:29:31 +00:00
Add developer instructions for persistent mode (#41050)
## What changed - Add bundled proactivity and follow-up guidance when `ReasoningEffort::Persistent` is selected. - Allow model metadata to override or disable the guidance with `persistent_instructions`. - Track the instructions as world state so effort and model changes replace or retire stale guidance without duplicating unchanged context. - Tailor approval guidance to `send_user_message_async` availability, rebuild it for forked agents and rolled-back history, and exclude Guardian sessions. ## Testing - Cover default, overridden, disabled, replaced, and retired instructions. - Cover model changes, history transitions, agent forks, Guardian sessions, and asynchronous-message tool availability. GitOrigin-RevId: 78e05d0335a70b385bd069b45edcd4ba570cef91
This commit is contained in:
1 parent
72c96598c6
commit
f1433fc71f
24 files changed
+565
-9
No files matched your search
@@ -1461,6 +1461,8 @@ async fn spawn_agent_numeric_fork_from_compacted_paginated_parent_clamps_to_prov
|
||||
#[tokio::test]
|
||||
async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
|
||||
let managed_fragment = "<managed_developer_instructions>\nParent developer instructions.\n</managed_developer_instructions>";
|
||||
let persistent_fragment =
|
||||
"<persistent_mode>\nParent developer instructions.\n</persistent_mode>";
|
||||
let harness = AgentControlHarness::new().await;
|
||||
let mut parent_config = harness.config.clone();
|
||||
let _ = parent_config.features.enable(Feature::MultiAgentV2);
|
||||
@@ -1558,6 +1560,9 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
|
||||
ContentItem::InputText {
|
||||
text: managed_fragment.to_string(),
|
||||
},
|
||||
ContentItem::InputText {
|
||||
text: persistent_fragment.to_string(),
|
||||
},
|
||||
],
|
||||
phase: None,
|
||||
internal_chat_message_metadata_passthrough: Some(
|
||||
@@ -1567,6 +1572,7 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
|
||||
ContentItemKind("multi_agent.mode_instructions".to_string()),
|
||||
ContentItemKind("generic.developer_policy".to_string()),
|
||||
ContentItemKind("managed_config.developer_instructions".to_string()),
|
||||
ContentItemKind("persistent_mode.instructions".to_string()),
|
||||
]),
|
||||
..Default::default()
|
||||
},
|
||||
@@ -1677,6 +1683,9 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
|
||||
ContentItem::InputText {
|
||||
text: managed_fragment.to_string(),
|
||||
},
|
||||
ContentItem::InputText {
|
||||
text: persistent_fragment.to_string(),
|
||||
},
|
||||
],
|
||||
phase: None,
|
||||
internal_chat_message_metadata_passthrough: Some(
|
||||
@@ -1685,6 +1694,7 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
|
||||
ContentItemKind("generic.developer_instructions".to_string()),
|
||||
ContentItemKind("generic.developer_policy".to_string()),
|
||||
ContentItemKind("managed_config.developer_instructions".to_string()),
|
||||
ContentItemKind("persistent_mode.instructions".to_string()),
|
||||
]),
|
||||
..Default::default()
|
||||
},
|
||||
@@ -1769,8 +1779,9 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
|
||||
"empty child developer instructions should remove parent developer instructions"
|
||||
);
|
||||
assert!(
|
||||
history_contains_text(no_hint_history.raw_items(), managed_fragment),
|
||||
"clearing child instructions must preserve an overlapping managed policy"
|
||||
history_contains_text(no_hint_history.raw_items(), managed_fragment)
|
||||
&& history_contains_text(no_hint_history.raw_items(), persistent_fragment),
|
||||
"clearing child instructions must preserve overlapping managed and persistent instructions"
|
||||
);
|
||||
assert!(
|
||||
history_contains_text(
|
||||
@@ -2660,6 +2671,8 @@ async fn spawn_agent_fork_last_n_turns_drops_parent_startup_prefix_when_under_li
|
||||
|
||||
#[tokio::test]
|
||||
async fn spawn_agent_fork_last_n_turns_strips_parent_usage_hints() {
|
||||
let persistent_fragment =
|
||||
"<persistent_mode>\nParent persistent instructions.\n</persistent_mode>";
|
||||
let harness = AgentControlHarness::new().await;
|
||||
let mut parent_config = harness.config.clone();
|
||||
let _ = parent_config.features.enable(Feature::MultiAgentV2);
|
||||
@@ -2710,6 +2723,9 @@ async fn spawn_agent_fork_last_n_turns_strips_parent_usage_hints() {
|
||||
ContentItem::InputText {
|
||||
text: "Preserved bounded developer context.".to_string(),
|
||||
},
|
||||
ContentItem::InputText {
|
||||
text: persistent_fragment.to_string(),
|
||||
},
|
||||
],
|
||||
phase: None,
|
||||
internal_chat_message_metadata_passthrough: None,
|
||||
@@ -2772,6 +2788,10 @@ async fn spawn_agent_fork_last_n_turns_strips_parent_usage_hints() {
|
||||
!history_contains_text(history.raw_items(), "Child developer instructions."),
|
||||
"bounded fork should not inject child instructions before its canonical context rebuild"
|
||||
);
|
||||
assert!(
|
||||
!history_contains_text(history.raw_items(), persistent_fragment),
|
||||
"bounded fork should remove persistent instructions before rebuilding context for the child's effort"
|
||||
);
|
||||
assert!(
|
||||
history_contains_text(history.raw_items(), "Preserved bounded developer context."),
|
||||
"bounded fork should preserve unrelated developer fragments"
|
||||
|
||||
Reference in new issue
Block a user