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
2026-07-17 15:45:48 +00:00
committed by copyberry
parent caa6e554d6
commit 08e30a2e4e
47 changed files with 1957 additions and 47 deletions
+8
View File
@@ -170,6 +170,8 @@ pub enum Feature {
ToolSuggest,
/// Enable plugins.
Plugins,
/// Discover selected-root plugin and skill manifests through one high-level exec-server RPC.
ExecutorCapabilityDiscovery,
/// Removed compatibility flag for plugin-bundled lifecycle hooks.
PluginHooks,
/// Allow the in-app browser pane in desktop apps.
@@ -1116,6 +1118,12 @@ pub const FEATURES: &[FeatureSpec] = &[
stage: Stage::Stable,
default_enabled: true,
},
FeatureSpec {
id: Feature::ExecutorCapabilityDiscovery,
key: "executor_capability_discovery",
stage: Stage::UnderDevelopment,
default_enabled: false,
},
FeatureSpec {
id: Feature::PluginHooks,
key: "plugin_hooks",
+13
View File
@@ -27,6 +27,19 @@ fn under_development_features_are_disabled_by_default() {
}
}
#[test]
fn executor_capability_discovery_is_an_opt_in_map_feature() {
let mut features = Features::with_defaults();
assert!(!features.enabled(Feature::ExecutorCapabilityDiscovery));
features.apply_map(&BTreeMap::from([(
"executor_capability_discovery".to_string(),
true,
)]));
assert!(features.enabled(Feature::ExecutorCapabilityDiscovery));
}
#[test]
fn default_enabled_features_are_stable() {
for spec in crate::FEATURES {