mirror of
https://github.com/openai/codex.git
synced 2026-08-23 13:09:46 +00:00
Use the live parent history mode when forking agents (#34779)
## What changed - Require the parent thread to be live before forking its history. - Read the history mode and multi-agent usage hints from that live parent so the fork loads and filters history using the active configuration. - Verify that forking a legacy parent keeps the child in legacy history mode. GitOrigin-RevId: 79416b78544467a1801f21300d3fe8db4fef59df
This commit is contained in:
@@ -594,26 +594,17 @@ impl AgentControl {
|
||||
};
|
||||
|
||||
let parent_thread_id = *parent_thread_id;
|
||||
let parent_thread = state.get_thread(parent_thread_id).await.ok();
|
||||
if let Some(parent_thread) = parent_thread.as_ref() {
|
||||
// `record_conversation_items` only queues persistence writes asynchronously.
|
||||
// Flush before snapshotting store history for a fork.
|
||||
parent_thread.ensure_rollout_materialized().await;
|
||||
parent_thread.flush_rollout().await?;
|
||||
}
|
||||
let parent_metadata = state
|
||||
.read_stored_thread(ReadThreadParams {
|
||||
thread_id: parent_thread_id,
|
||||
include_archived: true,
|
||||
include_history: false,
|
||||
})
|
||||
.await?;
|
||||
let parent_thread = state.get_thread(parent_thread_id).await?;
|
||||
let parent_history_mode = parent_thread.config_snapshot().await.history_mode;
|
||||
// `record_conversation_items` only queues persistence writes asynchronously.
|
||||
// Flush before snapshotting store history for a fork.
|
||||
parent_thread.ensure_rollout_materialized().await;
|
||||
parent_thread.flush_rollout().await?;
|
||||
|
||||
let destination_history_mode =
|
||||
matches!(parent_metadata.history_mode, ThreadHistoryMode::Paginated)
|
||||
.then_some(ThreadHistoryMode::Paginated);
|
||||
let destination_history_mode = matches!(parent_history_mode, ThreadHistoryMode::Paginated)
|
||||
.then_some(ThreadHistoryMode::Paginated);
|
||||
let mut forked_rollout_items =
|
||||
load_agent_model_context(state, parent_thread_id, parent_metadata.history_mode)
|
||||
load_agent_model_context(state, parent_thread_id, parent_history_mode)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
CodexErr::Fatal(format!(
|
||||
@@ -635,29 +626,17 @@ impl AgentControl {
|
||||
truncate_rollout_to_last_n_fork_turns(&forked_rollout_items, *last_n_turns);
|
||||
}
|
||||
let multi_agent_v2_usage_hint_texts_to_filter: Vec<String> =
|
||||
if let Some(parent_thread) = parent_thread.as_ref() {
|
||||
if multi_agent_version == MultiAgentVersion::V2 {
|
||||
let parent_config = parent_thread.session.get_config().await;
|
||||
[
|
||||
parent_config
|
||||
.multi_agent_v2
|
||||
.root_agent_usage_hint_text
|
||||
.clone(),
|
||||
parent_config
|
||||
.multi_agent_v2
|
||||
.subagent_usage_hint_text
|
||||
.clone(),
|
||||
]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
} else if multi_agent_version == MultiAgentVersion::V2 {
|
||||
if multi_agent_version == MultiAgentVersion::V2 {
|
||||
let parent_config = parent_thread.session.get_config().await;
|
||||
[
|
||||
config.multi_agent_v2.root_agent_usage_hint_text.clone(),
|
||||
config.multi_agent_v2.subagent_usage_hint_text.clone(),
|
||||
parent_config
|
||||
.multi_agent_v2
|
||||
.root_agent_usage_hint_text
|
||||
.clone(),
|
||||
parent_config
|
||||
.multi_agent_v2
|
||||
.subagent_usage_hint_text
|
||||
.clone(),
|
||||
]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
|
||||
@@ -1323,6 +1323,10 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
|
||||
.await
|
||||
.expect("child thread should be registered");
|
||||
assert_ne!(child_thread_id, parent_thread_id);
|
||||
assert_eq!(
|
||||
child_thread.config_snapshot().await.history_mode,
|
||||
ThreadHistoryMode::Legacy
|
||||
);
|
||||
let history = child_thread.session.clone_history().await;
|
||||
let mut expected_final_answer =
|
||||
assistant_message("parent final answer", Some(MessagePhase::FinalAnswer));
|
||||
|
||||
Reference in New Issue
Block a user