mirror of
https://github.com/openai/codex.git
synced 2026-10-30 19:18:49 +00:00
Preserve refreshed Apps tools across MCP runtime updates (#35028)
## Why After a remote plugin install refreshes the Apps tool catalog, a later MCP runtime publication must not restore the catalog from the previous connection. ## What changed - Rebuild the MCP runtime with fresh connections when hard-refreshing Apps tools, using the latest desired runtime configuration. - Refresh the Apps catalog on the newly published connection so subsequent runtime updates retain it. ## Testing Extend the remote plugin install test to verify that both newly available and missing Apps tools remain consistent after an unrelated runtime configuration refresh. GitOrigin-RevId: 5b675d53d56379ab67fab09512fc2ad0ffcb8535
This commit is contained in:
@@ -3,6 +3,7 @@ use codex_exec_server::ExecutorCapabilityDiscoveryCache;
|
||||
use codex_exec_server::ExecutorCapabilityDiscoverySnapshot;
|
||||
use codex_exec_server::MAX_SELECTED_CAPABILITY_ROOTS;
|
||||
use codex_exec_server::ResolvedSelectedCapabilityRoot;
|
||||
use codex_mcp::CODEX_APPS_MCP_SERVER_NAME;
|
||||
use codex_mcp::ElicitationReviewRequest;
|
||||
use codex_mcp::ElicitationReviewer;
|
||||
use codex_mcp::ElicitationReviewerHandle;
|
||||
@@ -202,7 +203,7 @@ impl Session {
|
||||
}
|
||||
}
|
||||
|
||||
/// Refreshes the future Apps catalog without making an exact step a refresh owner.
|
||||
/// Reconnects the runtime so refreshed Apps tools belong to their new exact client.
|
||||
pub(crate) async fn hard_refresh_latest_codex_apps_tools(
|
||||
self: &Arc<Self>,
|
||||
) -> anyhow::Result<Vec<codex_mcp::ToolInfo>> {
|
||||
@@ -212,10 +213,43 @@ impl Session {
|
||||
.acquire()
|
||||
.await
|
||||
.map_err(|_| anyhow::anyhow!("MCP runtime refresh semaphore closed"))?;
|
||||
self.services
|
||||
.mcp_runtime
|
||||
.latest_hard_refresh_codex_apps_tools_cache()
|
||||
.await
|
||||
let desired = self.latest_mcp_desired_state().await;
|
||||
let selected_capability_roots = self
|
||||
.resolve_selected_capability_roots_for_step(&desired.environments)
|
||||
.await;
|
||||
let ready_selected_capability_roots =
|
||||
Self::ready_selected_capability_roots(&selected_capability_roots);
|
||||
let executor_capability_discovery = self
|
||||
.executor_capability_discovery_for_step(
|
||||
&desired.config,
|
||||
&ready_selected_capability_roots,
|
||||
)
|
||||
.await;
|
||||
let mcp_projection = self
|
||||
.services
|
||||
.mcp_manager
|
||||
.runtime_config_for_step(
|
||||
&desired.config,
|
||||
&self.services.mcp_thread_init,
|
||||
&self.services.thread_extension_data,
|
||||
&desired.originator,
|
||||
&ready_selected_capability_roots,
|
||||
executor_capability_discovery.as_deref(),
|
||||
)
|
||||
.await;
|
||||
let input = self
|
||||
.build_mcp_runtime_input(
|
||||
&desired,
|
||||
mcp_projection,
|
||||
&ready_selected_capability_roots,
|
||||
Some(self.mcp_elicitation_reviewer()),
|
||||
)
|
||||
.await;
|
||||
anyhow::ensure!(
|
||||
input.mcp_servers.contains_key(CODEX_APPS_MCP_SERVER_NAME),
|
||||
"unknown MCP server '{CODEX_APPS_MCP_SERVER_NAME}'"
|
||||
);
|
||||
self.services.mcp_runtime.replace_fresh(input).await
|
||||
}
|
||||
|
||||
pub(super) fn mark_mcp_runtime_dirty(&self) {
|
||||
|
||||
@@ -100,7 +100,7 @@ impl Session {
|
||||
self.services.mcp_runtime.replace(input).await;
|
||||
}
|
||||
|
||||
async fn build_mcp_runtime_input(
|
||||
pub(super) async fn build_mcp_runtime_input(
|
||||
&self,
|
||||
desired: &McpDesiredState,
|
||||
mcp_projection: McpRuntimeProjection,
|
||||
|
||||
Reference in New Issue
Block a user