Allow extensions to skip host skill discovery (#40631)

## What changed

- Add the under-development `skip_host_skill_discovery` feature to bypass host
  skill snapshots during session warmup and turn setup.
- Let skill invocation contributors declare whether they require host-owned
  skills. Preserve host discovery when no contributors are registered or any
  contributor requires it.
- Keep executor and orchestrator skill catalogs and instruction loading
  available when host discovery is skipped.

## Testing

- Cover executor-only, orchestrator, mixed-contributor, and legacy host-skill
  behavior.

GitOrigin-RevId: 48169403090b234e1a304c6523633fd867df454a
This commit is contained in:
Alex Zamoshchin authored and copyberry committed 2026-08-25 16:00:02 +00:00
1 parent a63cb33e8d
commit 304c8de4c6
9 files changed
+515 -28

No files matched your search

+24 -14
View File
@@ -25,6 +25,7 @@ use codex_protocol::protocol::ThreadHistoryMode;
use codex_protocol::protocol::TurnEnvironmentSelection;
use codex_sandboxing::policy_transforms::effective_permission_profile;
use codex_skills_extension::HostSkillsSnapshot;
use codex_skills_extension::SkillLoadOutcome;
use codex_utils_path_uri::PathUri;
use futures::FutureExt;
use futures::future::BoxFuture;
@@ -914,20 +915,29 @@ impl Session {
&plugin_outcome,
per_turn_config.codex_home.as_path(),
);
let effective_skill_roots = plugin_outcome.effective_plugin_skill_roots();
let plugin_skill_snapshots = self
.services
.plugins_manager
.plugin_skill_snapshots_for_config(&plugins_input);
let skills_input = skills_load_input_from_config(&per_turn_config, effective_skill_roots)
.with_plugin_skill_snapshots(plugin_skill_snapshots);
let fs = primary_turn_environment
.map(|turn_environment| turn_environment.environment.get_filesystem());
let skills_snapshot = self
.services
.skills_service
.snapshot_for_config(&skills_input, fs)
.await;
let skills_snapshot = if per_turn_config
.features
.enabled(Feature::SkipHostSkillDiscovery)
&& !self.services.extensions.requires_host_skill_discovery()
{
// Executor and orchestrator catalogs are supplied independently of host skills.
HostSkillsSnapshot::new(Arc::new(SkillLoadOutcome::default()))
} else {
let effective_skill_roots = plugin_outcome.effective_plugin_skill_roots();
let plugin_skill_snapshots = self
.services
.plugins_manager
.plugin_skill_snapshots_for_config(&plugins_input);
let skills_input =
skills_load_input_from_config(&per_turn_config, effective_skill_roots)
.with_plugin_skill_snapshots(plugin_skill_snapshots);
let fs = primary_turn_environment
.map(|turn_environment| turn_environment.environment.get_filesystem());
self.services
.skills_service
.snapshot_for_config(&skills_input, fs)
.await
};
let mut turn_context: TurnContext = Self::make_turn_context(
self.thread_id(),
self.session_id(),