diff --git a/codex-rs/app-server/src/codex_message_processor.rs b/codex-rs/app-server/src/codex_message_processor.rs index 51b1c48c8..501fcad99 100644 --- a/codex-rs/app-server/src/codex_message_processor.rs +++ b/codex-rs/app-server/src/codex_message_processor.rs @@ -337,6 +337,7 @@ use codex_thread_store::ArchiveThreadParams as StoreArchiveThreadParams; use codex_thread_store::ListThreadsParams as StoreListThreadsParams; use codex_thread_store::LocalThreadStore; use codex_thread_store::ReadThreadParams as StoreReadThreadParams; +use codex_thread_store::RemoteThreadStore; use codex_thread_store::SortDirection as StoreSortDirection; use codex_thread_store::StoredThread; use codex_thread_store::ThreadMetadataPatch as StoreThreadMetadataPatch; @@ -474,7 +475,7 @@ pub(crate) struct CodexMessageProcessor { analytics_events_client: AnalyticsEventsClient, arg0_paths: Arg0DispatchPaths, config: Arc, - thread_store: LocalThreadStore, + thread_store: Arc, cli_overrides: Arc>>, runtime_feature_enablement: Arc>>, cloud_requirements: Arc>, @@ -642,6 +643,15 @@ pub(crate) struct CodexMessageProcessorArgs { pub(crate) log_db: Option, } +fn configured_thread_store(config: &Config) -> Arc { + match config.experimental_thread_store_endpoint.as_deref() { + Some(endpoint) => Arc::new(RemoteThreadStore::new(endpoint)), + None => Arc::new(LocalThreadStore::new( + codex_rollout::RolloutConfig::from_view(config), + )), + } +} + impl CodexMessageProcessor { async fn instruction_sources_from_config(config: &Config) -> Vec { codex_core::AgentsMdManager::new(config) @@ -725,7 +735,7 @@ impl CodexMessageProcessor { outgoing: outgoing.clone(), analytics_events_client, arg0_paths, - thread_store: LocalThreadStore::new(codex_rollout::RolloutConfig::from_view(&config)), + thread_store: configured_thread_store(&config), config, cli_overrides, runtime_feature_enablement, diff --git a/codex-rs/config/src/config_toml.rs b/codex-rs/config/src/config_toml.rs index 6556ca73e..35e213bc8 100644 --- a/codex-rs/config/src/config_toml.rs +++ b/codex-rs/config/src/config_toml.rs @@ -302,6 +302,10 @@ pub struct ConfigToml { /// instructions inserted into developer messages when realtime becomes /// active. pub experimental_realtime_start_instructions: Option, + + /// Experimental / do not use. When set, app-server uses a remote thread + /// store at this endpoint instead of the local filesystem/SQLite store. + pub experimental_thread_store_endpoint: Option, pub projects: Option>, /// Controls the web search tool mode: disabled, cached, or live. diff --git a/codex-rs/core/config.schema.json b/codex-rs/core/config.schema.json index a2d7b28a8..996e9428e 100644 --- a/codex-rs/core/config.schema.json +++ b/codex-rs/core/config.schema.json @@ -2299,6 +2299,10 @@ "description": "Experimental / do not use. Replaces the synthesized realtime startup context appended to websocket session instructions. An empty string disables startup context injection entirely.", "type": "string" }, + "experimental_thread_store_endpoint": { + "description": "Experimental / do not use. When set, app-server uses a remote thread store at this endpoint instead of the local filesystem/SQLite store.", + "type": "string" + }, "experimental_use_freeform_apply_patch": { "type": "boolean" }, @@ -2957,4 +2961,4 @@ }, "title": "ConfigToml", "type": "object" -} +} \ No newline at end of file diff --git a/codex-rs/core/src/config/config_tests.rs b/codex-rs/core/src/config/config_tests.rs index 413423518..7ee5b7df2 100644 --- a/codex-rs/core/src/config/config_tests.rs +++ b/codex-rs/core/src/config/config_tests.rs @@ -4887,6 +4887,7 @@ async fn test_precedence_fixture_with_o3_profile() -> std::io::Result<()> { realtime: RealtimeConfig::default(), experimental_realtime_ws_backend_prompt: None, experimental_realtime_ws_startup_context: None, + experimental_thread_store_endpoint: None, base_instructions: None, developer_instructions: None, guardian_policy_config: None, @@ -5038,6 +5039,7 @@ async fn test_precedence_fixture_with_gpt3_profile() -> std::io::Result<()> { realtime: RealtimeConfig::default(), experimental_realtime_ws_backend_prompt: None, experimental_realtime_ws_startup_context: None, + experimental_thread_store_endpoint: None, base_instructions: None, developer_instructions: None, guardian_policy_config: None, @@ -5187,6 +5189,7 @@ async fn test_precedence_fixture_with_zdr_profile() -> std::io::Result<()> { realtime: RealtimeConfig::default(), experimental_realtime_ws_backend_prompt: None, experimental_realtime_ws_startup_context: None, + experimental_thread_store_endpoint: None, base_instructions: None, developer_instructions: None, guardian_policy_config: None, @@ -5321,6 +5324,7 @@ async fn test_precedence_fixture_with_gpt5_profile() -> std::io::Result<()> { realtime: RealtimeConfig::default(), experimental_realtime_ws_backend_prompt: None, experimental_realtime_ws_startup_context: None, + experimental_thread_store_endpoint: None, base_instructions: None, developer_instructions: None, guardian_policy_config: None, diff --git a/codex-rs/core/src/config/mod.rs b/codex-rs/core/src/config/mod.rs index 2fef40a42..74421832d 100644 --- a/codex-rs/core/src/config/mod.rs +++ b/codex-rs/core/src/config/mod.rs @@ -527,6 +527,10 @@ pub struct Config { /// instructions inserted into developer messages when realtime becomes /// active. pub experimental_realtime_start_instructions: Option, + + /// Experimental / do not use. When set, app-server uses a remote thread + /// store at this endpoint instead of the local filesystem/SQLite store. + pub experimental_thread_store_endpoint: Option, /// When set, restricts ChatGPT login to a specific workspace identifier. pub forced_chatgpt_workspace_id: Option, @@ -2273,6 +2277,7 @@ impl Config { experimental_realtime_ws_backend_prompt: cfg.experimental_realtime_ws_backend_prompt, experimental_realtime_ws_startup_context: cfg.experimental_realtime_ws_startup_context, experimental_realtime_start_instructions: cfg.experimental_realtime_start_instructions, + experimental_thread_store_endpoint: cfg.experimental_thread_store_endpoint, forced_chatgpt_workspace_id, forced_login_method, include_apply_patch_tool: include_apply_patch_tool_flag,