Attribute executor skill invocations to plugins (#39309)

## What changed

- Carry selected plugin identities from MCP discovery into per-turn extension data, limited to capability roots that are ready for the turn.
- Annotate executor skill catalog entries with the matching plugin ID and `user` scope.
- Include that attribution in `skill_invocation` analytics for both explicit and implicit executor skill invocations.

## Testing

- Extend the executor skills app-server test to verify plugin ID, skill scope, and invocation type for explicit and implicit analytics events.

GitOrigin-RevId: 9345600ae29bcb8eb894fffd2d6f7b05f22ebf74
This commit is contained in:
rphilizaire-openai authored and copyberry committed 2026-08-18 22:53:31 +00:00
1 parent c97bd2dcb5
commit 280d56b1d8
17 files changed
+129 -18

No files matched your search

+5 -10
View File
@@ -18,6 +18,7 @@ use codex_extension_api::ExtensionMetrics;
use codex_extension_api::ExtensionRegistryBuilder;
use codex_extension_api::ExtensionWarning;
use codex_extension_api::PromptFragment;
use codex_extension_api::SelectedPluginSnapshot;
use codex_extension_api::SkillInvocationContributor;
use codex_extension_api::SkillInvocationInput;
use codex_extension_api::SkillInvocationKind;
@@ -276,6 +277,7 @@ where
session_store,
thread_store,
/*executor_query*/ None,
/*selected_plugins*/ None,
/*sandbox_contexts*/ None,
)
}
@@ -310,6 +312,7 @@ where
session_store,
thread_store,
executor_query,
step_store.get::<SelectedPluginSnapshot>(),
step_store.get::<HashMap<String, FileSystemSandboxContext>>(),
)
}
@@ -550,23 +553,15 @@ impl<C> SkillsExtension<C> {
session_store: &ExtensionData,
thread_store: &ExtensionData,
executor_query: Option<SkillListQuery>,
selected_plugins: Option<Arc<SelectedPluginSnapshot>>,
sandbox_contexts: Option<Arc<HashMap<String, FileSystemSandboxContext>>>,
) -> Vec<Arc<dyn ToolExecutor<ToolCall>>> {
let Some(thread_state) = thread_store.get::<SkillsThreadState>() else {
return Vec::new();
};
let orchestrator_available = self.providers.has_orchestrator_provider()
&& thread_state.orchestrator_skills_enabled();
if !orchestrator_available && executor_query.is_none() {
return Vec::new();
}
skill_tools(
self.providers.clone(),
session_store,
thread_store,
orchestrator_available,
executor_query,
selected_plugins,
sandbox_contexts,
Arc::clone(&self.shadow_selection),
)