Scale skill metadata budgets with model context windows (#34626)

## Why

A fixed character limit does not account for the different context-window sizes supported by models.

## What changed

- Budget extension-rendered skill metadata at 2% of the resolved model context window, capped at 4,000 tokens.
- Keep the existing 8,000-character fallback when model context metadata is unavailable.
- Include the omission marker in the budget and still emit it when no skill entry fits.
- Apply the same resolved budget to executor and host skill catalogs assembled for a turn.

## Testing

- Cover proportional and capped budgets, multibyte fallback accounting, and omission-marker behavior.
- Verify through the production turn path that larger model context windows include more catalog entries without exceeding the computed budget.

GitOrigin-RevId: 4667293f1594de4dd605b32b9fa4255d26772c0f
This commit is contained in:
felixxia-oai authored and copyberry committed 2026-07-21 22:16:27 +00:00
1 parent bbad09a83b
commit 37eef7bacc
10 files changed
+454 -31

No files matched your search

+109
View File
@@ -35,12 +35,14 @@ fn description_selection_follows_render_policy() {
&catalog,
/*include_skills_usage_instructions*/ false,
SkillCatalogRenderPolicy::CoreCompatible,
SkillMetadataBudget::Characters(8_000),
)
.expect("catalog should render");
let extension = available_skills_fragment(
&catalog,
/*include_skills_usage_instructions*/ false,
SkillCatalogRenderPolicy::ExtensionCompatible,
SkillMetadataBudget::Characters(8_000),
)
.expect("catalog should render");
@@ -65,3 +67,110 @@ fn description_selection_follows_render_policy() {
)
);
}
#[test]
fn catalog_budget_uses_capped_context_percentage_or_character_fallback() {
assert_eq!(
capped_skill_metadata_budget(Some(100_000)),
SkillMetadataBudget::Tokens(2_000)
);
assert_eq!(
capped_skill_metadata_budget(Some(400_000)),
SkillMetadataBudget::Tokens(4_000)
);
assert_eq!(
capped_skill_metadata_budget(/*context_window*/ None),
SkillMetadataBudget::Characters(8_000)
);
}
#[test]
fn omission_marker_is_charged_to_catalog_budget() {
let catalog = SkillCatalog {
entries: (0..20)
.map(|index| {
entry(
&format!("skill-{index:02}"),
"A description long enough to put the catalog under budget pressure.",
/*short_description*/ None,
)
})
.collect(),
warnings: Vec::new(),
};
let fragment = available_skills_fragment(
&catalog,
/*include_skills_usage_instructions*/ false,
SkillCatalogRenderPolicy::ExtensionCompatible,
SkillMetadataBudget::Tokens(100),
)
.expect("catalog should render");
let rendered_metadata_cost = fragment
.body()
.lines()
.filter(|line| line.starts_with("- "))
.map(|line| approx_token_count(&format!("{line}\n")))
.sum::<usize>();
assert!(fragment.body().contains("additional skills omitted"));
assert!(rendered_metadata_cost <= 100);
}
#[test]
fn character_fallback_counts_multibyte_metadata_by_characters() {
let description = "💡".repeat(MAX_CATALOG_SKILL_DESCRIPTION_CHARS);
let catalog = SkillCatalog {
entries: vec![
entry(
"multibyte-one",
&description,
/*short_description*/ None,
),
entry(
"multibyte-two",
&description,
/*short_description*/ None,
),
],
warnings: Vec::new(),
};
let fragment = available_skills_fragment(
&catalog,
/*include_skills_usage_instructions*/ false,
SkillCatalogRenderPolicy::ExtensionCompatible,
SkillMetadataBudget::Characters(8_000),
)
.expect("catalog should render");
assert!(fragment.body().contains("multibyte-one"));
assert!(fragment.body().contains("multibyte-two"));
assert!(!fragment.body().contains("additional skills omitted"));
}
#[test]
fn catalog_emits_omission_marker_when_every_skill_exceeds_budget() {
let catalog = SkillCatalog {
entries: vec![entry(
"oversized",
&"x".repeat(MAX_CATALOG_SKILL_DESCRIPTION_CHARS),
/*short_description*/ None,
)],
warnings: Vec::new(),
};
let fragment = available_skills_fragment(
&catalog,
/*include_skills_usage_instructions*/ false,
SkillCatalogRenderPolicy::ExtensionCompatible,
SkillMetadataBudget::Tokens(100),
)
.expect("omission marker should fit");
assert!(!fragment.body().contains("- oversized:"));
assert!(
fragment
.body()
.contains("- 1 additional skill omitted from this bounded skills list.")
);
}