mirror of
https://github.com/openai/codex.git
synced 2026-10-21 14:23:14 +00:00
Refresh current-time reminders for full-history subagents (#38446)
## What changed - Exclude current-time reminder developer messages when copying parent history into a full-history subagent. - Keep the child's newly generated reminder, preventing inherited reminders from accumulating while preserving the rest of the forked context. ## Testing - Extend the full-history V2 spawn test to verify that two reminders in the parent become one fresh reminder in the child request. GitOrigin-RevId: fb61c72f7f0d61d1068f2c599a8b8caf1788b7e2
This commit is contained in:
@@ -2,6 +2,8 @@ use super::residency::is_v2_resident_session_source;
|
||||
use super::*;
|
||||
use crate::agent::role::apply_role_to_config_for_multi_agent_v2;
|
||||
use crate::config::PermissionProfileSnapshot;
|
||||
use crate::context::ContextualUserFragment;
|
||||
use crate::context::CurrentTimeReminder;
|
||||
use codex_extension_api::ExtensionDataInit;
|
||||
|
||||
const AGENT_NAMES: &str = include_str!("../agent_names.txt");
|
||||
@@ -81,7 +83,7 @@ fn keep_forked_rollout_item(item: &RolloutItem, preserve_reference_context_item:
|
||||
}
|
||||
}
|
||||
|
||||
fn is_multi_agent_v2_usage_hint_message(item: &ResponseItem, usage_hint_texts: &[String]) -> bool {
|
||||
fn is_fork_excluded_developer_message(item: &ResponseItem, usage_hint_texts: &[String]) -> bool {
|
||||
let ResponseItem::Message { role, content, .. } = item else {
|
||||
return false;
|
||||
};
|
||||
@@ -92,9 +94,10 @@ fn is_multi_agent_v2_usage_hint_message(item: &ResponseItem, usage_hint_texts: &
|
||||
return false;
|
||||
};
|
||||
|
||||
usage_hint_texts
|
||||
.iter()
|
||||
.any(|usage_hint_text| usage_hint_text == text)
|
||||
CurrentTimeReminder::matches_text(text)
|
||||
|| usage_hint_texts
|
||||
.iter()
|
||||
.any(|usage_hint_text| usage_hint_text == text)
|
||||
}
|
||||
|
||||
async fn load_agent_model_context(
|
||||
@@ -720,7 +723,7 @@ impl AgentControl {
|
||||
if matches!(response_item, ResponseItem::AgentMessage { .. }) {
|
||||
return false;
|
||||
}
|
||||
if is_multi_agent_v2_usage_hint_message(
|
||||
if is_fork_excluded_developer_message(
|
||||
response_item,
|
||||
&multi_agent_v2_usage_hint_texts_to_filter,
|
||||
) {
|
||||
|
||||
@@ -3,6 +3,7 @@ use codex_core::StartThreadOptions;
|
||||
use codex_core::ThreadConfigSnapshot;
|
||||
use codex_core::TurnInputRequest;
|
||||
use codex_core::config::AgentRoleConfig;
|
||||
use codex_core::config::CurrentTimeReminderConfig;
|
||||
use codex_features::Feature;
|
||||
use codex_history::RolloutItem;
|
||||
use codex_models_manager::bundled_models_response;
|
||||
@@ -1046,11 +1047,13 @@ enum FullHistoryV2ModelSelection {
|
||||
ConfiguredDefault,
|
||||
ExplicitOverride,
|
||||
WorldStateIdentity,
|
||||
CurrentTimeReminders,
|
||||
}
|
||||
|
||||
#[test_case(FullHistoryV2ModelSelection::ConfiguredDefault; "configured default with omitted fork_turns")]
|
||||
#[test_case(FullHistoryV2ModelSelection::ExplicitOverride; "explicit override with fork_turns all")]
|
||||
#[test_case(FullHistoryV2ModelSelection::WorldStateIdentity; "world state appends context window when agent identity changes")]
|
||||
#[test_case(FullHistoryV2ModelSelection::CurrentTimeReminders; "full fork drops inherited current-time reminders")]
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn spawned_full_history_v2_child_uses_model_precedence_without_dropping_context(
|
||||
selection: FullHistoryV2ModelSelection,
|
||||
@@ -1070,7 +1073,8 @@ async fn spawned_full_history_v2_child_uses_model_precedence_without_dropping_co
|
||||
.await;
|
||||
let (spawn_args, expected_model, expected_reasoning_effort) = match selection {
|
||||
FullHistoryV2ModelSelection::ConfiguredDefault
|
||||
| FullHistoryV2ModelSelection::WorldStateIdentity => (
|
||||
| FullHistoryV2ModelSelection::WorldStateIdentity
|
||||
| FullHistoryV2ModelSelection::CurrentTimeReminders => (
|
||||
json!({
|
||||
"message": CHILD_PROMPT,
|
||||
"task_name": "worker",
|
||||
@@ -1144,6 +1148,16 @@ async fn spawned_full_history_v2_child_uses_model_precedence_without_dropping_co
|
||||
.expect("test config should allow feature update");
|
||||
config.model_context_window = Some(128_000);
|
||||
}
|
||||
if matches!(selection, FullHistoryV2ModelSelection::CurrentTimeReminders) {
|
||||
config
|
||||
.features
|
||||
.enable(Feature::CurrentTimeReminder)
|
||||
.expect("test config should allow feature update");
|
||||
config.current_time_reminder = Some(CurrentTimeReminderConfig {
|
||||
reminder_interval_seconds: 0,
|
||||
..CurrentTimeReminderConfig::default()
|
||||
});
|
||||
}
|
||||
config.model = Some(INHERITED_MODEL.to_string());
|
||||
config.model_reasoning_effort = Some(INHERITED_REASONING_EFFORT);
|
||||
config.agent_default_subagent_model = Some(V2_DEFAULT_MODEL.to_string());
|
||||
@@ -1164,10 +1178,21 @@ async fn spawned_full_history_v2_child_uses_model_precedence_without_dropping_co
|
||||
test.submit_turn(TURN_0_FORK_PROMPT).await?;
|
||||
let _ = seed_turn.single_request();
|
||||
test.submit_turn(TURN_1_PROMPT).await?;
|
||||
let _ = spawn_turn.single_request();
|
||||
let parent_request = spawn_turn.single_request();
|
||||
|
||||
let child_request = wait_for_request_with_model(&child_request_log, expected_model).await?;
|
||||
assert!(child_request.body_contains_text(TURN_0_FORK_PROMPT));
|
||||
if matches!(selection, FullHistoryV2ModelSelection::CurrentTimeReminders) {
|
||||
let reminder_count = |request: &ResponsesRequest| {
|
||||
request
|
||||
.message_input_texts("developer")
|
||||
.into_iter()
|
||||
.filter(|text| text.starts_with("<current_time_reminder>"))
|
||||
.count()
|
||||
};
|
||||
assert_eq!(reminder_count(&parent_request), 2);
|
||||
assert_eq!(reminder_count(&child_request), 1);
|
||||
}
|
||||
let child_body = child_request.body_json();
|
||||
if matches!(selection, FullHistoryV2ModelSelection::WorldStateIdentity) {
|
||||
let child_thread_id = ThreadId::from_string(
|
||||
|
||||
Reference in New Issue
Block a user