Read executor skill packages directly (#38167)

## Why

Executor skills required a `skills.list` lookup before their contents could be
read, even when the catalog already identified the skill.

## What changed

- Render executor skill catalog entries as package locators, including shortened
  locators when skill roots are aliased.
- Tell the model to pass those packages directly to `skills.read`, while keeping
  `skills.list` as the fallback when no package is available.
- Use the shorter package locators when applying the skills context budget.

## Testing

Update catalog, aliasing, budget-pressure, and selected-skill coverage, including
an executor package ID containing a literal backslash.

GitOrigin-RevId: 2ace5e527dc4f29651a8f3214475ccc90d52c73f
This commit is contained in:
rphilizaire-openai authored and copyberry committed 2026-08-12 10:34:25 +00:00
1 parent 3fe19fcd81
commit 69ae78291d
7 files changed
+70 -50

No files matched your search

@@ -77,7 +77,7 @@ use pretty_assertions::assert_eq;
type TestResult = Result<(), Box<dyn std::error::Error>>;
static NEXT_CODEX_HOME_ID: AtomicUsize = AtomicUsize::new(0);
const SKILLS_INTRO_WITH_ABSOLUTE_PATHS: &str = "A skill is a set of instructions provided through a `SKILL.md` source. Below is the list of skills that can be used. Each entry includes a name, description, and source locator. `file` locators are on the host filesystem, `environment resource` locators are owned by an execution environment, `orchestrator package` locators are opaque package identifiers, and `custom resource` locators use their provider's access mechanism.";
const SKILLS_INTRO_WITH_ABSOLUTE_PATHS: &str = "A skill is a set of instructions provided through a `SKILL.md` source. Below is the list of skills that can be used. Each entry includes a name, description, and source locator. `file` locators are on the host filesystem, `executor package` locators are owned by their execution environment, `orchestrator package` locators are opaque package identifiers, and `custom resource` locators use their provider's access mechanism.";
const DEMO_SKILL_CONTENTS: &str =
"---\nname: demo\ndescription: Demo skill.\n---\n# Demo\n\nUse the demo skill.\n";
@@ -547,7 +547,7 @@ async fn executor_orchestrator_and_host_share_catalog_world_state_flow() -> Test
for (section_id, expected_line) in [
(
"skills",
"- executor-skill: Fix lint errors. (environment resource: skill://executor/executor-skill/SKILL.md)",
"- executor-skill: Fix lint errors. (executor package: executor/executor-skill)",
),
(
"orchestrator_skills",
@@ -922,7 +922,7 @@ async fn selected_executor_catalog_follows_step_availability_and_reuses_its_cach
assert!(
available_fragment
.body()
.contains("(environment resource: skill://executor/lint-fix/SKILL.md)")
.contains("(executor package: executor/lint-fix)")
);
let fragments = registry.turn_input_contributors()[0]
@@ -1198,7 +1198,7 @@ async fn moderate_budget_pressure_keeps_every_catalog_entry() -> TestResult {
let package_id = format!("{source}/{name}");
let line_prefix = format!("- {name}: ");
let line_suffix = if source == "executor" {
format!(" (environment resource: skill://{package_id}/SKILL.md)")
format!(" (executor package: {package_id})")
} else {
format!(" (orchestrator package: {package_id})")
};
@@ -1319,7 +1319,7 @@ async fn extreme_budget_pressure_removes_descriptions_before_omitting_entries()
assert!(
executor
.body()
.contains("- executor-skill-039: (environment resource:")
.contains("- executor-skill-039: (executor package:")
);
assert!(
orchestrator