Codex Handbook
core/src/context/available_plugins_instructions.rs 59 lines
use codex_plugin::PluginCapabilitySummary;use codex_protocol::protocol::PLUGINS_INSTRUCTIONS_CLOSE_TAG;use codex_protocol::protocol::PLUGINS_INSTRUCTIONS_OPEN_TAG;use super::ContextualUserFragment;#[derive(Debug, Clone, PartialEq)]pub(crate) struct AvailablePluginsInstructions {    plugins: Vec<PluginCapabilitySummary>,}impl AvailablePluginsInstructions {    pub(crate) fn from_plugins(plugins: &[PluginCapabilitySummary]) -> Option<Self> {        if plugins.is_empty() {            return None;        }        Some(Self {            plugins: plugins.to_vec(),        })    }}impl ContextualUserFragment for AvailablePluginsInstructions {    fn role(&self) -> &'static str {        "developer"    }    fn markers(&self) -> (&'static str, &'static str) {        Self::type_markers()    }    fn type_markers() -> (&'static str, &'static str) {        (            PLUGINS_INSTRUCTIONS_OPEN_TAG,            PLUGINS_INSTRUCTIONS_CLOSE_TAG,        )    }    fn body(&self) -> String {        let mut lines = vec![            "## Plugins".to_string(),            "A plugin is a local bundle of skills, MCP servers, and apps.".to_string(),        ];        lines.push("### How to use plugins".to_string());        lines.push(            r###"- Skill naming: If a plugin contributes skills, those skill entries are prefixed with `plugin_name:` in the Skills list.- MCP naming: Plugin-provided MCP tools keep standard MCP identifiers such as `mcp__server__tool`; use tool provenance to tell which plugin they come from.- Trigger rules: If the user explicitly names a plugin, prefer capabilities associated with that plugin for that turn.- Relationship to capabilities: Plugins are not invoked directly. Use their underlying skills, MCP tools, and app tools to help solve the task.- Relevance: Determine what a plugin can help with from explicit user mention or from the plugin-associated skills, MCP tools, and apps exposed elsewhere in this turn.- Missing/blocked: If the user requests a plugin that does not have relevant callable capabilities for the task, say so briefly and continue with the best fallback."###                .to_string(),        );        format!("\n{}\n", lines.join("\n"))    }}