Generalize skill locator aliases across providers (#37488)

## What changed

- Compact executor and orchestrator skill locators under metadata pressure, using provider-specific `e` and `o` aliases alongside host `r` aliases.
- Derive alias roots from executor discovery paths and orchestrator namespaces while preserving host plugin root handling.
- Centralize alias ordering, deduplication, and longest-prefix matching across skill providers.

## Testing

- Cover alias planning, cross-platform executor roots, and host plugin discovery.

GitOrigin-RevId: e7d15bd3891c08ae20170e96c4ad45c76d353707
This commit is contained in:
rphilizaire-openai authored and copyberry committed 2026-08-07 19:04:39 +00:00
1 parent 27e4a05cd3
commit ce22ea9712
12 files changed
+458 -218

No files matched your search

+59 -156
View File
@@ -1,20 +1,17 @@
use std::borrow::Cow;
use std::collections::HashMap;
use std::collections::HashSet;
use std::path::Component;
use std::path::Path;
use std::path::PathBuf;
use codex_core_skills::MAX_SKILL_PROMPT_BYTES;
use codex_protocol::protocol::SkillScope;
use codex_utils_string::approx_token_count;
use codex_utils_string::take_bytes_at_char_boundary;
use crate::aliases::AliasPlan;
use crate::catalog::SkillCatalog;
use crate::catalog::SkillCatalogEntry;
use crate::catalog::SkillSourceKind;
use crate::catalog_prompt::render_available_skills_body;
use crate::fragments::AvailableSkillsInstructions;
use crate::host_aliases::shared_host_alias_roots;
const DEFAULT_SKILL_METADATA_CHAR_BUDGET: usize = 8_000;
const SKILL_METADATA_CONTEXT_WINDOW_PERCENT: usize = 2;
@@ -693,12 +690,14 @@ fn build_aliased_combined_catalog(
host_entries: &[&SkillCatalogEntry],
budget: SkillMetadataBudget,
) -> Option<CombinedAvailableSkillsRender> {
let plan = build_alias_plan(host_entries, budget)?;
if plan.table_cost >= budget.limit() {
let plan = build_alias_plan(host_entries)?;
let skill_root_lines = plan.root_lines();
let table_cost = aliased_metadata_overhead_cost(budget, &skill_root_lines);
if table_cost >= budget.limit() {
return None;
}
let adjusted_limit = budget.limit().saturating_sub(plan.table_cost);
let adjusted_limit = budget.limit().saturating_sub(table_cost);
let adjusted_budget = match budget {
SkillMetadataBudget::Tokens(_) => SkillMetadataBudget::Tokens(adjusted_limit),
SkillMetadataBudget::Characters(_) => SkillMetadataBudget::Characters(adjusted_limit),
@@ -717,7 +716,7 @@ fn build_aliased_combined_catalog(
SkillLine::with_locator(
entry,
SkillCatalogRenderPolicy::CoreCompatible,
render_skill_path_with_aliases(entry, &plan),
render_skill_locator_with_aliases(entry, &plan),
)
})
.collect();
@@ -726,7 +725,7 @@ fn build_aliased_combined_catalog(
orchestrator_lines,
host_lines,
adjusted_budget,
plan.skill_root_lines,
skill_root_lines,
))
}
@@ -904,47 +903,12 @@ fn available_skills_fragment(
.into_fragment(include_skills_usage_instructions)
}
struct AliasPlan {
skill_root_lines: Vec<String>,
alias_root_by_display_root: HashMap<String, String>,
root_aliases: HashMap<String, String>,
table_cost: usize,
}
fn build_aliased_catalog(
entries: &[&SkillCatalogEntry],
policy: SkillCatalogRenderPolicy,
budget: SkillMetadataBudget,
) -> Option<RenderedCatalog> {
let plan = build_alias_plan(entries, budget)?;
if plan.table_cost >= budget.limit() {
return None;
}
let adjusted_limit = budget.limit().saturating_sub(plan.table_cost);
let adjusted_budget = match budget {
SkillMetadataBudget::Tokens(_) => SkillMetadataBudget::Tokens(adjusted_limit),
SkillMetadataBudget::Characters(_) => SkillMetadataBudget::Characters(adjusted_limit),
};
let skill_lines = entries
.iter()
.map(|entry| {
SkillLine::with_locator(entry, policy, render_skill_path_with_aliases(entry, &plan))
})
.collect();
Some(render_catalog(
skill_lines,
adjusted_budget,
plan.skill_root_lines,
policy,
))
}
fn build_alias_plan(
entries: &[&SkillCatalogEntry],
budget: SkillMetadataBudget,
) -> Option<AliasPlan> {
// The shared alias prompt only describes host filesystem skills.
// Alias instructions currently describe only host filesystem skills.
if entries
.iter()
.any(|entry| entry.authority.kind != SkillSourceKind::Host)
@@ -952,132 +916,71 @@ fn build_alias_plan(
return None;
}
let plugin_version_skill_counts = plugin_version_skill_counts_for_entries(entries);
let mut alias_root_by_display_root = HashMap::new();
let mut alias_roots = Vec::new();
let mut seen = HashSet::new();
let mut alias_ordered_entries = entries.to_vec();
alias_ordered_entries
.sort_by_key(|entry| entry.display_path_root_order().unwrap_or(usize::MAX));
for entry in alias_ordered_entries {
if entry.authority.kind != SkillSourceKind::Host {
continue;
}
let Some(display_root) = entry.display_path_root() else {
continue;
};
let alias_root =
alias_root_for_display_root(Path::new(display_root), &plugin_version_skill_counts)
.to_string_lossy()
.replace('\\', "/");
alias_root_by_display_root.insert(display_root.to_string(), alias_root.clone());
if seen.insert(alias_root.clone()) {
alias_roots.push(alias_root);
}
}
if alias_roots.is_empty() {
let plan = build_alias_plan(entries)?;
let skill_root_lines = plan.root_lines();
let table_cost = aliased_metadata_overhead_cost(budget, &skill_root_lines);
if table_cost >= budget.limit() {
return None;
}
let root_aliases = alias_roots
let adjusted_limit = budget.limit().saturating_sub(table_cost);
let adjusted_budget = match budget {
SkillMetadataBudget::Tokens(_) => SkillMetadataBudget::Tokens(adjusted_limit),
SkillMetadataBudget::Characters(_) => SkillMetadataBudget::Characters(adjusted_limit),
};
let skill_lines = entries
.iter()
.enumerate()
.map(|(index, root)| (root.clone(), format!("r{index}")))
.map(|entry| {
SkillLine::with_locator(
entry,
policy,
render_skill_locator_with_aliases(entry, &plan),
)
})
.collect();
let skill_root_lines = alias_roots
.iter()
.enumerate()
.map(|(index, root)| format!("- `r{index}` = `{root}`"))
.collect::<Vec<_>>();
let table_cost = aliased_metadata_overhead_cost(budget, &skill_root_lines);
Some(AliasPlan {
Some(render_catalog(
skill_lines,
adjusted_budget,
skill_root_lines,
alias_root_by_display_root,
root_aliases,
table_cost,
})
policy,
))
}
fn plugin_version_skill_counts_for_entries(
entries: &[&SkillCatalogEntry],
) -> HashMap<PathBuf, usize> {
let mut counts = HashMap::new();
for root in entries.iter().filter_map(|entry| {
(entry.authority.kind == SkillSourceKind::Host)
.then(|| entry.display_path_root())
.flatten()
}) {
if let Some(plugin_version_base) = plugin_version_base(Path::new(root)) {
let count = counts.entry(plugin_version_base).or_insert(0usize);
*count = count.saturating_add(1);
}
fn build_alias_plan(entries: &[&SkillCatalogEntry]) -> Option<AliasPlan> {
let source = &entries.first()?.authority.kind;
if entries.iter().any(|entry| &entry.authority.kind != source) {
return None;
}
counts
}
fn alias_root_for_display_root(
root: &Path,
plugin_version_skill_counts: &HashMap<PathBuf, usize>,
) -> PathBuf {
let Some(plugin_version_base) = plugin_version_base(root) else {
return root.to_path_buf();
let prefix = match source {
SkillSourceKind::Host => "r",
SkillSourceKind::Executor => "e",
SkillSourceKind::Orchestrator => "o",
SkillSourceKind::Custom(_) => return None,
};
let skill_count = plugin_version_skill_counts
.get(&plugin_version_base)
.copied()
.unwrap_or_default();
if skill_count > 1 {
root.to_path_buf()
} else {
plugin_marketplace_base(root).unwrap_or_else(|| root.to_path_buf())
}
}
fn plugin_marketplace_base(path: &Path) -> Option<PathBuf> {
let mut candidate = path;
while let Some(parent) = candidate.parent() {
if parent.file_name()?.to_str()? == "cache"
&& parent.parent()?.file_name()?.to_str()? == "plugins"
{
return Some(candidate.to_path_buf());
}
candidate = parent;
}
None
}
fn plugin_version_base(path: &Path) -> Option<PathBuf> {
let marketplace_base = plugin_marketplace_base(path)?;
let mut relative_components = path.strip_prefix(&marketplace_base).ok()?.components();
let plugin = match relative_components.next()? {
Component::Normal(plugin) => plugin,
_ => return None,
let mut alias_ordered_entries = entries.to_vec();
alias_ordered_entries.sort_by_key(|entry| entry.alias_root_order().unwrap_or(usize::MAX));
let roots = match source {
SkillSourceKind::Host => shared_host_alias_roots(&alias_ordered_entries),
SkillSourceKind::Executor | SkillSourceKind::Orchestrator => alias_ordered_entries
.iter()
.filter_map(|entry| entry.alias_root())
.map(str::to_string)
.collect(),
SkillSourceKind::Custom(_) => return None,
};
let version = match relative_components.next()? {
Component::Normal(version) => version,
_ => return None,
};
Some(marketplace_base.join(plugin).join(version))
let roots = roots.iter().map(String::as_str).collect::<Vec<_>>();
AliasPlan::build(prefix, &roots)
}
fn render_skill_path_with_aliases(entry: &SkillCatalogEntry, plan: &AliasPlan) -> String {
if entry.authority.kind != SkillSourceKind::Host {
fn render_skill_locator_with_aliases(entry: &SkillCatalogEntry, plan: &AliasPlan) -> String {
if entry.alias_root().is_none() {
return entry.rendered_path().to_string();
}
let Some(display_root) = entry.display_path_root() else {
return entry.rendered_path().to_string();
};
let Some(alias_root) = plan.alias_root_by_display_root.get(display_root) else {
return entry.rendered_path().to_string();
};
let Some(alias) = plan.root_aliases.get(alias_root) else {
return entry.rendered_path().to_string();
};
let Ok(relative_path) = Path::new(entry.rendered_path()).strip_prefix(alias_root) else {
return entry.rendered_path().to_string();
};
let relative_path = relative_path.to_string_lossy().replace('\\', "/");
format!("{alias}/{relative_path}")
let locator = entry.rendered_path().replace('\\', "/");
plan.shorten(&locator)
.unwrap_or_else(|| entry.rendered_path().to_string())
}
fn aliased_metadata_overhead_cost(