Add batched executor capability discovery (#33852)

## Why

Selected capability roots can contribute plugins, MCP servers, connectors, and
skills. Discovering each contribution separately requires repeated access to the
executor filesystem.

## What changed

- Add the `capabilityRoots/discoverV1` exec-server RPC to scan selected roots and
  materialize recognized plugin manifests, configuration files, skill
  instructions, and skill metadata in one bounded request.
- Add the opt-in `executor_capability_discovery` feature, with a thread-scoped
  cache and per-step snapshot shared by MCP and skill discovery.
- Parse MCP, connector, and skill contributions from the materialized snapshot,
  including serving cached skill instructions without another filesystem read.

## Testing

- Cover discovery limits, manifest precedence, root-local failures, cache reuse,
  plugin contributions, and parity with the existing environment skill loader.

GitOrigin-RevId: f98fd2321cafb58c596db02da1f83c09d8eb375d
This commit is contained in:
Bryan Ashley authored and copyberry committed 2026-07-17 15:45:48 +00:00
1 parent caa6e554d6
commit 08e30a2e4e
47 files changed
+1957 -47

No files matched your search

@@ -1,4 +1,5 @@
use codex_config::McpServerConfig;
use codex_exec_server_protocol::ExecutorCapabilityDiscoverySnapshot;
use codex_protocol::capabilities::SelectedCapabilityRoot;
use crate::ExtensionData;
@@ -20,6 +21,8 @@ pub struct McpServerContributionContext<'a, C> {
originator: Option<&'a str>,
/// Selected roots resolved against ready environments for this exact step.
ready_selected_capability_roots: Option<&'a [SelectedCapabilityRoot]>,
/// Executor-materialized capability files shared by all consumers in this exact step.
executor_capability_discovery: Option<&'a ExecutorCapabilityDiscoverySnapshot>,
}
impl<C> Clone for McpServerContributionContext<'_, C> {
@@ -39,6 +42,7 @@ impl<'a, C> McpServerContributionContext<'a, C> {
thread_init: None,
originator: None,
ready_selected_capability_roots: None,
executor_capability_discovery: None,
}
}
@@ -49,6 +53,7 @@ impl<'a, C> McpServerContributionContext<'a, C> {
thread_store: &'a ExtensionData,
originator: &'a str,
ready_selected_capability_roots: &'a [SelectedCapabilityRoot],
executor_capability_discovery: Option<&'a ExecutorCapabilityDiscoverySnapshot>,
) -> Self {
Self {
config,
@@ -56,6 +61,7 @@ impl<'a, C> McpServerContributionContext<'a, C> {
thread_init: Some(thread_init),
originator: Some(originator),
ready_selected_capability_roots: Some(ready_selected_capability_roots),
executor_capability_discovery,
}
}
@@ -83,6 +89,11 @@ impl<'a, C> McpServerContributionContext<'a, C> {
pub fn ready_selected_capability_roots(&self) -> Option<&'a [SelectedCapabilityRoot]> {
self.ready_selected_capability_roots
}
/// Returns the executor-materialized capability files for this model step, when enabled.
pub fn executor_capability_discovery(&self) -> Option<&'a ExecutorCapabilityDiscoverySnapshot> {
self.executor_capability_discovery
}
}
/// One extension-owned overlay for the runtime MCP server configuration.
@@ -1,5 +1,6 @@
use std::sync::Arc;
use codex_exec_server_protocol::ExecutorCapabilityDiscoverySnapshot;
use codex_protocol::ThreadId;
use codex_protocol::capabilities::SelectedCapabilityRoot;
use codex_protocol::protocol::TurnEnvironmentSelection;
@@ -14,6 +15,8 @@ pub struct WorldStateContributionInput<'a> {
pub environments: &'a [TurnEnvironmentSelection],
/// Selected roots whose stable environments are ready in this sampling step.
pub ready_selected_capability_roots: &'a [SelectedCapabilityRoot],
/// Executor-materialized capability files shared by all consumers in this exact step.
pub executor_capability_discovery: Option<&'a ExecutorCapabilityDiscoverySnapshot>,
pub session_store: &'a ExtensionData,
pub thread_store: &'a ExtensionData,
pub turn_store: &'a ExtensionData,