Extract connector runtime snapshot management (#32698)

## What changed

- Move the Codex Apps tool cache into a reusable `codex-connectors` runtime manager keyed by account and workspace.
- Represent cached tools as atomically published snapshots with refresh timestamps while preserving the newest accepted fetch generation.
- Harden disk persistence with bounded reads, atomic file replacement, and serialized writes so an older fetch cannot overwrite newer state.

## Testing

Add coverage for identity isolation, snapshot timestamps, oversized cache files, atomic replacement, and concurrent persistence ordering.

GitOrigin-RevId: 5ea2234469daae3abf54b030244c3251de62ca5a
This commit is contained in:
Matthew Zeng authored and copyberry committed 2026-07-13 05:02:52 +00:00
1 parent c888e8e75a
commit 2f7d89b141
20 files changed
+1028 -512

No files matched your search

+7 -6
View File
@@ -27,7 +27,9 @@ use codex_config::McpServerTransportConfig;
use codex_config::types::AppToolApproval;
use codex_config::types::AuthKeyringBackendKind;
use codex_config::types::OAuthCredentialsStoreMode;
use codex_connectors::ConnectorRuntimeManager;
use codex_connectors::ConnectorSnapshot;
use codex_connectors::connector_runtime_context_key;
use codex_login::CodexAuth;
use codex_model_provider::CHATGPT_CODEX_BASE_URL;
use codex_protocol::mcp::McpServerInfo;
@@ -44,11 +46,10 @@ use serde_json::Value;
use tokio_util::sync::CancellationToken;
use crate::ResolvedMcpCatalog;
use crate::codex_apps_cache::CodexAppsToolsCache;
use crate::codex_apps_cache::codex_apps_tools_cache_key;
use crate::connection_manager::McpConnectionManager;
use crate::runtime::McpRuntimeContext;
use crate::server::EffectiveMcpServer;
use crate::tools::ToolInfo;
pub const CODEX_APPS_MCP_SERVER_NAME: &str = "codex_apps";
const DEFAULT_CODEX_APPS_MCP_PRODUCT_SKU: &str = "codex";
@@ -303,7 +304,7 @@ pub async fn read_mcp_resource(
config: &McpConfig,
auth: Option<&CodexAuth>,
runtime_context: McpRuntimeContext,
codex_apps_tools_cache: CodexAppsToolsCache,
codex_apps_tools_cache: ConnectorRuntimeManager<ToolInfo>,
server: &str,
uri: &str,
) -> anyhow::Result<ReadResourceResult> {
@@ -333,7 +334,7 @@ pub async fn read_mcp_resource(
runtime_context,
config.codex_home.clone(),
codex_apps_tools_cache,
codex_apps_tools_cache_key(auth),
connector_runtime_context_key(auth),
config.prefix_mcp_tool_names,
config.client_elicitation_capability.clone(),
/*supports_openai_form_elicitation*/ false,
@@ -368,7 +369,7 @@ pub async fn collect_mcp_server_status_snapshot_with_detail(
auth: Option<&CodexAuth>,
submit_id: String,
runtime_context: McpRuntimeContext,
codex_apps_tools_cache: CodexAppsToolsCache,
codex_apps_tools_cache: ConnectorRuntimeManager<ToolInfo>,
detail: McpSnapshotDetail,
) -> McpServerStatusSnapshot {
let mcp_servers = effective_mcp_servers(config, auth);
@@ -412,7 +413,7 @@ pub async fn collect_mcp_server_status_snapshot_with_detail(
runtime_context,
config.codex_home.clone(),
codex_apps_tools_cache,
codex_apps_tools_cache_key(auth),
connector_runtime_context_key(auth),
config.prefix_mcp_tool_names,
config.client_elicitation_capability.clone(),
/*supports_openai_form_elicitation*/ false,