chore: clarify plugin + app copy in model instructions (#14541)

- clarify app mentions are in user messages
- clarify what it means for tools to be provided via `codex_apps` MCP
- add plugin descriptions (with basic sanitization) to top-level `##
Plugins` section alongside the corresponding plugin names
- explain that skills from plugins are prefixed with `plugin_name:` in
top-level `##Plugins` section

changes to more logically organize `Apps`, `Skills`, and `Plugins`
instructions will be in a separate PR, as that shuffles dev + user
instructions in ways that change tests broadly.

### Tests
confirmed in local rollout, some new tests.
This commit is contained in:
sayan-oai
2026-03-13 10:57:41 -07:00
committed by GitHub
parent 59b588b8ec
commit 9f2da5a9ce
7 changed files with 121 additions and 5 deletions

View File

@@ -270,6 +270,73 @@ fn plugin_telemetry_metadata_uses_default_mcp_config_path() {
);
}
#[test]
fn capability_summary_sanitizes_plugin_descriptions_to_one_line() {
let codex_home = TempDir::new().unwrap();
let plugin_root = codex_home
.path()
.join("plugins/cache")
.join("test/sample/local");
write_file(
&plugin_root.join(".codex-plugin/plugin.json"),
r#"{
"name": "sample",
"description": "Plugin that\n includes the sample\tserver"
}"#,
);
write_file(
&plugin_root.join("skills/sample-search/SKILL.md"),
"---\nname: sample-search\ndescription: search sample data\n---\n",
);
let outcome = load_plugins_from_config(&plugin_config_toml(true, true), codex_home.path());
assert_eq!(
outcome.plugins[0].manifest_description.as_deref(),
Some("Plugin that\n includes the sample\tserver")
);
assert_eq!(
outcome.capability_summaries()[0].description.as_deref(),
Some("Plugin that includes the sample server")
);
}
#[test]
fn capability_summary_truncates_overlong_plugin_descriptions() {
let codex_home = TempDir::new().unwrap();
let plugin_root = codex_home
.path()
.join("plugins/cache")
.join("test/sample/local");
let too_long = "x".repeat(MAX_CAPABILITY_SUMMARY_DESCRIPTION_LEN + 1);
write_file(
&plugin_root.join(".codex-plugin/plugin.json"),
&format!(
r#"{{
"name": "sample",
"description": "{too_long}"
}}"#
),
);
write_file(
&plugin_root.join("skills/sample-search/SKILL.md"),
"---\nname: sample-search\ndescription: search sample data\n---\n",
);
let outcome = load_plugins_from_config(&plugin_config_toml(true, true), codex_home.path());
assert_eq!(
outcome.plugins[0].manifest_description.as_deref(),
Some(too_long.as_str())
);
assert_eq!(
outcome.capability_summaries()[0].description,
Some("x".repeat(MAX_CAPABILITY_SUMMARY_DESCRIPTION_LEN))
);
}
#[test]
fn load_plugins_uses_manifest_configured_component_paths() {
let codex_home = TempDir::new().unwrap();