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:
Tom authored and GitHub committed 2026-04-30 21:24:59 -07:00
1 parent f50c02d7bc
commit fe05acad23
55 files changed
+1076 -514

No files matched your search

+28 -7
View File
@@ -25,9 +25,23 @@ pub type StateDbHandle = Arc<codex_state::StateRuntime>;
/// Initialize the state runtime for thread state persistence and backfill checks.
pub async fn init(config: &impl RolloutConfigView) -> Option<StateDbHandle> {
let config = RolloutConfig::from_view(config);
init_with_roots(
config.codex_home,
config.sqlite_home,
config.model_provider_id,
)
.await
}
/// Initialize the state runtime for a local thread store.
pub async fn init_with_roots(
codex_home: PathBuf,
sqlite_home: PathBuf,
default_model_provider_id: String,
) -> Option<StateDbHandle> {
let runtime = match codex_state::StateRuntime::init(
config.sqlite_home.clone(),
config.model_provider_id.clone(),
sqlite_home.clone(),
default_model_provider_id.clone(),
)
.await
{
@@ -35,7 +49,7 @@ pub async fn init(config: &impl RolloutConfigView) -> Option<StateDbHandle> {
Err(err) => {
warn!(
"failed to initialize state runtime at {}: {err}",
config.sqlite_home.display()
sqlite_home.display()
);
return None;
}
@@ -45,16 +59,20 @@ pub async fn init(config: &impl RolloutConfigView) -> Option<StateDbHandle> {
Err(err) => {
warn!(
"failed to read backfill state at {}: {err}",
config.codex_home.display()
codex_home.display()
);
return None;
}
};
if backfill_state.status != codex_state::BackfillStatus::Complete {
let runtime_for_backfill = runtime.clone();
let config = config.clone();
tokio::spawn(async move {
metadata::backfill_sessions(runtime_for_backfill.as_ref(), &config).await;
metadata::backfill_sessions(
runtime_for_backfill.as_ref(),
codex_home.as_path(),
default_model_provider_id.as_str(),
)
.await;
});
}
Some(runtime)
@@ -487,7 +505,7 @@ pub async fn read_repair_rollout_path(
pub async fn apply_rollout_items(
context: Option<&codex_state::StateRuntime>,
rollout_path: &Path,
_default_provider: &str,
default_provider: &str,
builder: Option<&ThreadMetadataBuilder>,
items: &[RolloutItem],
stage: &str,
@@ -511,6 +529,9 @@ pub async fn apply_rollout_items(
}
},
};
if builder.model_provider.is_none() {
builder.model_provider = Some(default_provider.to_string());
}
builder.rollout_path = rollout_path.to_path_buf();
builder.cwd = normalize_cwd_for_state_db(&builder.cwd);
if let Err(err) = ctx