mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Make thread store process-scoped (#19474)
- Build one app-server process ThreadStore from startup config and share it with ThreadManager and CodexMessageProcessor. - Remove per-thread/fork store reconstruction so effective thread config cannot switch the persistence backend. - Add params to ThreadStore create/resume for specifying thread metadata, since otherwise the metadata from store creation would be used (incorrectly).
This commit is contained in:
@@ -430,6 +430,7 @@ impl TestCodexBuilder {
|
||||
SessionSource::Exec,
|
||||
Arc::clone(&environment_manager),
|
||||
/*analytics_events_client*/ None,
|
||||
thread_store_from_config(&config),
|
||||
)
|
||||
} else {
|
||||
codex_core::test_support::thread_manager_with_models_provider_and_home(
|
||||
@@ -449,7 +450,6 @@ impl TestCodexBuilder {
|
||||
codex_core::test_support::resume_thread_from_rollout_with_user_shell_override(
|
||||
thread_manager.as_ref(),
|
||||
config.clone(),
|
||||
thread_store_from_config(&config),
|
||||
path,
|
||||
auth_manager,
|
||||
user_shell_override,
|
||||
@@ -461,7 +461,6 @@ impl TestCodexBuilder {
|
||||
let auth_manager = codex_core::test_support::auth_manager_from_auth(auth);
|
||||
Box::pin(thread_manager.resume_thread_from_rollout(
|
||||
config.clone(),
|
||||
thread_store_from_config(&config),
|
||||
path,
|
||||
auth_manager,
|
||||
/*parent_trace*/ None,
|
||||
@@ -473,18 +472,12 @@ impl TestCodexBuilder {
|
||||
codex_core::test_support::start_thread_with_user_shell_override(
|
||||
thread_manager.as_ref(),
|
||||
config.clone(),
|
||||
thread_store_from_config(&config),
|
||||
user_shell_override,
|
||||
),
|
||||
)
|
||||
.await?
|
||||
}
|
||||
(None, None) => {
|
||||
Box::pin(
|
||||
thread_manager.start_thread(config.clone(), thread_store_from_config(&config)),
|
||||
)
|
||||
.await?
|
||||
}
|
||||
(None, None) => Box::pin(thread_manager.start_thread(config.clone())).await?,
|
||||
};
|
||||
|
||||
Ok(TestCodex {
|
||||
|
||||
@@ -1107,9 +1107,10 @@ async fn prefers_apikey_when_config_prefers_apikey_even_with_chatgpt_tokens() {
|
||||
SessionSource::Exec,
|
||||
Arc::new(codex_exec_server::EnvironmentManager::default_for_tests()),
|
||||
/*analytics_events_client*/ None,
|
||||
thread_store_from_config(&config),
|
||||
);
|
||||
let NewThread { thread: codex, .. } = thread_manager
|
||||
.start_thread(config.clone(), thread_store_from_config(&config))
|
||||
.start_thread(config.clone())
|
||||
.await
|
||||
.expect("create new conversation");
|
||||
|
||||
|
||||
@@ -2556,7 +2556,6 @@ async fn code_mode_can_call_hidden_dynamic_tools() -> Result<()> {
|
||||
.thread_manager
|
||||
.start_thread_with_tools(
|
||||
base_test.config.clone(),
|
||||
codex_core::thread_store_from_config(&base_test.config),
|
||||
vec![DynamicToolSpec {
|
||||
namespace: Some("codex_app".to_string()),
|
||||
name: "hidden_dynamic_tool".to_string(),
|
||||
|
||||
@@ -445,7 +445,6 @@ async fn remote_compact_filters_deferred_dynamic_tools() -> Result<()> {
|
||||
.thread_manager
|
||||
.start_thread_with_tools(
|
||||
test.config.clone(),
|
||||
codex_core::thread_store_from_config(&test.config),
|
||||
dynamic_tools,
|
||||
/*persist_extended_history*/ false,
|
||||
)
|
||||
|
||||
@@ -149,6 +149,7 @@ async fn compact_resume_and_fork_preserve_model_history_view() {
|
||||
"compact+resume test expects base path {base_path:?} to exist",
|
||||
);
|
||||
|
||||
shutdown_conversation(&base).await;
|
||||
let resumed = resume_conversation(&manager, &config, base_path).await;
|
||||
user_turn(&resumed, "AFTER_RESUME").await;
|
||||
let resumed_path = fetch_conversation_path(&resumed);
|
||||
@@ -304,6 +305,7 @@ async fn compact_resume_after_second_compaction_preserves_history() -> Result<()
|
||||
"second compact test expects base path {base_path:?} to exist",
|
||||
);
|
||||
|
||||
shutdown_conversation(&base).await;
|
||||
let resumed = resume_conversation(&manager, &config, base_path).await;
|
||||
user_turn(&resumed, "AFTER_RESUME").await;
|
||||
let resumed_path = fetch_conversation_path(&resumed);
|
||||
@@ -323,6 +325,7 @@ async fn compact_resume_after_second_compaction_preserves_history() -> Result<()
|
||||
"second compact test expects forked path {forked_path:?} to exist",
|
||||
);
|
||||
|
||||
shutdown_conversation(&forked).await;
|
||||
let resumed_again = resume_conversation(&manager, &config, forked_path).await;
|
||||
user_turn(&resumed_again, AFTER_SECOND_RESUME).await;
|
||||
|
||||
@@ -815,6 +818,13 @@ fn fetch_conversation_path(conversation: &Arc<CodexThread>) -> std::path::PathBu
|
||||
conversation.rollout_path().expect("rollout path")
|
||||
}
|
||||
|
||||
async fn shutdown_conversation(conversation: &Arc<CodexThread>) {
|
||||
conversation
|
||||
.shutdown_and_wait()
|
||||
.await
|
||||
.expect("shutdown conversation");
|
||||
}
|
||||
|
||||
async fn resume_conversation(
|
||||
manager: &ThreadManager,
|
||||
config: &Config,
|
||||
@@ -825,7 +835,6 @@ async fn resume_conversation(
|
||||
);
|
||||
Box::pin(manager.resume_thread_from_rollout(
|
||||
config.clone(),
|
||||
codex_core::thread_store_from_config(config),
|
||||
path,
|
||||
auth_manager,
|
||||
/*parent_trace*/ None,
|
||||
@@ -845,7 +854,6 @@ async fn fork_thread(
|
||||
Box::pin(manager.fork_thread(
|
||||
nth_user_message,
|
||||
config.clone(),
|
||||
codex_core::thread_store_from_config(config),
|
||||
path,
|
||||
/*persist_extended_history*/ false,
|
||||
/*parent_trace*/ None,
|
||||
|
||||
@@ -100,7 +100,6 @@ async fn fork_thread_twice_drops_to_first_message() {
|
||||
.fork_thread(
|
||||
ForkSnapshot::TruncateBeforeNthUserMessage(1),
|
||||
config_for_fork.clone(),
|
||||
codex_core::thread_store_from_config(&config_for_fork),
|
||||
base_path.clone(),
|
||||
/*persist_extended_history*/ false,
|
||||
/*parent_trace*/ None,
|
||||
@@ -125,7 +124,6 @@ async fn fork_thread_twice_drops_to_first_message() {
|
||||
.fork_thread(
|
||||
ForkSnapshot::TruncateBeforeNthUserMessage(0),
|
||||
config_for_fork.clone(),
|
||||
codex_core::thread_store_from_config(&config_for_fork),
|
||||
fork1_path.clone(),
|
||||
/*persist_extended_history*/ false,
|
||||
/*parent_trace*/ None,
|
||||
@@ -194,7 +192,6 @@ async fn fork_thread_from_history_does_not_require_source_rollout_path() {
|
||||
.fork_thread_from_history(
|
||||
ForkSnapshot::Interrupted,
|
||||
test.config.clone(),
|
||||
codex_core::thread_store_from_config(&test.config),
|
||||
InitialHistory::Resumed(ResumedHistory {
|
||||
conversation_id: test.session_configured.session_id,
|
||||
history: source_items.clone(),
|
||||
|
||||
@@ -496,7 +496,6 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> {
|
||||
.fork_thread(
|
||||
ForkSnapshot::Interrupted,
|
||||
fork_config.clone(),
|
||||
codex_core::thread_store_from_config(&fork_config),
|
||||
rollout_path,
|
||||
/*persist_extended_history*/ false,
|
||||
/*parent_trace*/ None,
|
||||
|
||||
@@ -1671,7 +1671,6 @@ async fn conversation_startup_context_current_thread_selects_many_turns_by_budge
|
||||
.thread_manager
|
||||
.resume_thread_with_history(
|
||||
test.config.clone(),
|
||||
codex_core::thread_store_from_config(&test.config),
|
||||
InitialHistory::Forked(history),
|
||||
auth_manager_from_auth(CodexAuth::from_api_key("dummy")),
|
||||
/*persist_extended_history*/ false,
|
||||
|
||||
@@ -106,7 +106,6 @@ async fn emits_warning_when_resumed_model_differs() {
|
||||
} = thread_manager
|
||||
.resume_thread_with_history(
|
||||
config.clone(),
|
||||
codex_core::thread_store_from_config(&config),
|
||||
initial_history,
|
||||
auth_manager,
|
||||
/*persist_extended_history*/ false,
|
||||
|
||||
@@ -793,7 +793,6 @@ async fn tool_search_returns_deferred_dynamic_tool_and_routes_follow_up_call() -
|
||||
.thread_manager
|
||||
.start_thread_with_tools(
|
||||
base_test.config.clone(),
|
||||
codex_core::thread_store_from_config(&base_test.config),
|
||||
vec![dynamic_tool],
|
||||
/*persist_extended_history*/ false,
|
||||
)
|
||||
|
||||
@@ -246,10 +246,9 @@ async fn list_skills_skips_cwd_roots_when_environment_disabled() -> Result<()> {
|
||||
)?,
|
||||
)),
|
||||
/*analytics_events_client*/ None,
|
||||
thread_store_from_config(&config),
|
||||
);
|
||||
let new_thread = thread_manager
|
||||
.start_thread(config.clone(), thread_store_from_config(&config))
|
||||
.await?;
|
||||
let new_thread = thread_manager.start_thread(config.clone()).await?;
|
||||
let cwd = config.cwd.to_path_buf();
|
||||
|
||||
new_thread
|
||||
|
||||
@@ -44,7 +44,6 @@ async fn emits_warning_when_unstable_features_enabled_via_config() {
|
||||
} = thread_manager
|
||||
.resume_thread_with_history(
|
||||
config.clone(),
|
||||
codex_core::thread_store_from_config(&config),
|
||||
InitialHistory::New,
|
||||
auth_manager,
|
||||
/*persist_extended_history*/ false,
|
||||
@@ -92,7 +91,6 @@ async fn suppresses_warning_when_configured() {
|
||||
} = thread_manager
|
||||
.resume_thread_with_history(
|
||||
config.clone(),
|
||||
codex_core::thread_store_from_config(&config),
|
||||
InitialHistory::New,
|
||||
auth_manager,
|
||||
/*persist_extended_history*/ false,
|
||||
|
||||
@@ -71,7 +71,6 @@ async fn window_id_advances_after_compact_persists_on_resume_and_resets_on_fork(
|
||||
.fork_thread(
|
||||
/*snapshot*/ 0usize,
|
||||
resumed.config.clone(),
|
||||
codex_core::thread_store_from_config(&resumed.config),
|
||||
rollout_path,
|
||||
/*persist_extended_history*/ false,
|
||||
/*parent_trace*/ None,
|
||||
|
||||
Reference in New Issue
Block a user