mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Share the skills budget across host and executor catalogs (#35769)
## Why Rendering host and executor skill catalogs independently allows their combined metadata to exceed the skills context budget. ## What changed - Allocate one budget across both catalogs when both contain model-visible skills. - Prefer retaining executor skills when budget pressure requires omissions, while preserving an executor omission marker and reporting when all host skills were omitted. - Evaluate absolute and aliased host paths under the shared budget and select the rendering that best preserves executor entries, total entries, and descriptions, in that order. ## Testing Added renderer and production-turn coverage for shared-budget description shortening, host-first omission, executor omission markers, and alias selection. GitOrigin-RevId: 30041736a76aa173cb641aa98a876a306cb437d2
This commit is contained in:
1 parent
a68d0a74bd
commit
f6160ca5b3
6 files changed
+688
-110
No files matched your search
@@ -323,6 +323,135 @@ fn mixed_catalogs_keep_absolute_authority_aware_rendering_under_budget_pressure(
|
||||
assert!(!body.contains("additional skills omitted"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mixed_catalog_reserves_executor_omission_marker_by_omitting_host_first() {
|
||||
let host_catalog = SkillCatalog {
|
||||
entries: vec![entry_with_path(
|
||||
"h", "", /*short_description*/ None, "/h",
|
||||
)],
|
||||
warnings: Vec::new(),
|
||||
};
|
||||
let executor_entry = |name: &str, resource: &str| {
|
||||
SkillCatalogEntry::new(
|
||||
SkillPackageId(name.to_string()),
|
||||
SkillAuthority::new(SkillSourceKind::Executor, "env-1"),
|
||||
name,
|
||||
"",
|
||||
SkillResourceId::new(resource),
|
||||
)
|
||||
.with_display_path(resource)
|
||||
};
|
||||
let executor_catalog = SkillCatalog {
|
||||
entries: vec![
|
||||
executor_entry("e1", "skill://executor/one"),
|
||||
executor_entry(
|
||||
"e2",
|
||||
"skill://executor/this-resource-is-intentionally-too-long",
|
||||
),
|
||||
],
|
||||
warnings: Vec::new(),
|
||||
};
|
||||
|
||||
let (host, executor) = render_combined_available_skills(
|
||||
&host_catalog,
|
||||
&executor_catalog,
|
||||
SkillMetadataBudget::Tokens(28),
|
||||
);
|
||||
let host = host.expect("host catalog should render");
|
||||
let executor = executor.expect("executor catalog should render");
|
||||
|
||||
assert_eq!(
|
||||
host.report,
|
||||
SkillRenderReport {
|
||||
total_count: 1,
|
||||
included_count: 0,
|
||||
omitted_count: 1,
|
||||
truncated_description_chars: 0,
|
||||
truncated_description_count: 0,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
executor.report,
|
||||
SkillRenderReport {
|
||||
total_count: 2,
|
||||
included_count: 1,
|
||||
omitted_count: 1,
|
||||
truncated_description_chars: 0,
|
||||
truncated_description_count: 0,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
executor.skill_lines,
|
||||
vec![
|
||||
"- e1: (environment resource: skill://executor/one)".to_string(),
|
||||
"- 1 additional skill omitted from this bounded skills list.".to_string(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mixed_catalog_prefers_executor_inclusion_over_total_aliased_inclusion() {
|
||||
let root = format!("/{}", "r".repeat(219));
|
||||
let host_catalog = SkillCatalog {
|
||||
entries: ["h1", "h2"]
|
||||
.into_iter()
|
||||
.map(|name| {
|
||||
entry(name, "", /*short_description*/ None)
|
||||
.with_display_path(format!("{root}/{name}/SKILL.md"))
|
||||
.with_display_path_root(root.as_str())
|
||||
})
|
||||
.collect(),
|
||||
warnings: Vec::new(),
|
||||
};
|
||||
let executor_entry = |name: &str, resource: &str| {
|
||||
SkillCatalogEntry::new(
|
||||
SkillPackageId(name.to_string()),
|
||||
SkillAuthority::new(SkillSourceKind::Executor, "env-1"),
|
||||
name,
|
||||
"",
|
||||
SkillResourceId::new(resource),
|
||||
)
|
||||
.with_display_path(resource)
|
||||
};
|
||||
let executor_catalog = SkillCatalog {
|
||||
entries: vec![
|
||||
executor_entry("e1", "skill://executor/one"),
|
||||
executor_entry("e2", &format!("skill://{}", "e".repeat(132))),
|
||||
],
|
||||
warnings: Vec::new(),
|
||||
};
|
||||
|
||||
let (host, executor) = render_combined_available_skills(
|
||||
&host_catalog,
|
||||
&executor_catalog,
|
||||
SkillMetadataBudget::Tokens(74),
|
||||
);
|
||||
let host = host.expect("host catalog should render");
|
||||
let executor = executor.expect("executor catalog should render");
|
||||
|
||||
assert_eq!(
|
||||
executor.report,
|
||||
SkillRenderReport {
|
||||
total_count: 2,
|
||||
included_count: 2,
|
||||
omitted_count: 0,
|
||||
truncated_description_chars: 0,
|
||||
truncated_description_count: 0,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
host.report,
|
||||
SkillRenderReport {
|
||||
total_count: 2,
|
||||
included_count: 0,
|
||||
omitted_count: 2,
|
||||
truncated_description_chars: 0,
|
||||
truncated_description_count: 0,
|
||||
}
|
||||
);
|
||||
assert_eq!(host.skill_root_lines, Vec::<String>::new());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn singleton_plugin_versions_share_the_marketplace_alias_root() {
|
||||
let github_root = "/Users/test/.codex/plugins/cache/openai-curated/github/hash123/skills";
|
||||
|
||||
Reference in new issue
Block a user