Skip to content

Resolve model aliases the same way on every engine - #69487

Merged
SivaKesava1 merged 23 commits into
mainfrom
copilot/resolve-model-aliases
Oct 18, 2026
Merged

SivaKesava1 merged 23 commits into
mainfrom
copilot/resolve-model-aliases

Conversation

Copilot AI commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Each engine handled model: differently, so an alias or a family pin that worked on Copilot failed elsewhere. For example, pi with model: copilot/opus failed with "opus" is not advertised while Copilot resolved opus to claude-opus-5.5. This PR generalises Copilot's resolver into one shared step and runs it in every harness before the CLI starts.

Shared resolution step (resolve_model_alias.cjs)

  • resolveConfiguredCopilotModel and the Copilot harness's single bounded /reflect refetch become resolveEngineModel. There is still only one resolver.
  • The rules are the same on every engine:
    • Aliases, and globs inside alias entries, resolve to the newest live match.
    • A provider/ prefix limits the lookup to that provider, so copilot/opus now also works on the Copilot engine.
    • Exact ids are never rewritten.
    • ?effort= carries through.
    • auto keeps each engine's current meaning.
  • Failures use Copilot's model_unavailable and catalog_unavailable causes with the fix(copilot): reject silent configured-model substitution #68819 wording. The sentence about the agentic-workflows integration appears only when the provider is Copilot.
  • Incomplete discovery: exact ids pass through, and aliases fail with catalog_unavailable after one refetch.

Harnesses

  • Copilot: behaviour is unchanged except that copilot/<alias> now resolves. aw_info.json model_selection is kept.
  • Pi:
    • The main model (pi_models_json.cjs) and sub-agents (pi_subagent_config.cjs) both use the shared step.
    • Sub-agent aliases no longer fall back to the Pi SDK's static model list.
    • Pi now gets the detect_agent_errors step, so its unavailable-model failure issue matches Copilot's.
  • Claude: non-auto values now resolve before Claude Code starts. The auto rule (Sonnet → Opus → Haiku) and the Claude on Copilot: pass Claude Code a modelOverrides map for Copilot's dotted Claude model ids #68839 model-id overrides still apply after resolution. sonnet, opus and haiku now use gh-aw's alias map instead of Claude Code's built-ins.
  • Codex: aliases resolve before the provider-prefix check. copilot/auto stays the gateway sentinel.
  • Agy: aliases resolve against the Gemini catalogue, and Agy receives the native slug.

Recording the result

  • Every harness logs model resolution: engine=… role=… configured=… resolved=… provider=… status=….
  • It also writes agent/model-resolution.json, which is added to the agent artifact.
  • unified_session.cjs projects that record into a runner-written model.resolution event in usage/aw_session.jsonl. This is spec §4.7, T-UAS-074, version 1.11.0, and the session schema is regenerated.

Compiler

  • models: now accepts alias keys. The reserved keys (allowed, blocked, providers, default-ai-credits-pricing) keep their meaning, and the V-MAF key rules apply.
  • The main workflow's alias map is merged last, so it overrides built-in and imported aliases, as spec §10.1 says. workflow_builder.go previously passed nil here.
  • Gemini and declarative engines get a warning, naming the engine and the alias, when given an alias.
engine: codex
model: copilot/fast-gpt   # resolves at runtime to the newest live gpt-5.6* (gpt-5.6-luna with the test fixture)
models:
  fast-gpt: ["copilot/gpt-5.6*"]

Tests

  • Every acceptance case from the issue has its named test, plus a new agy_harness.test.cjs.
  • All tests share one fixture recorded from the DDG run 38945917145 /reflect (fixtures/awf-reflect-ddg-38945917145.json). The incomplete-discovery variant (models_fetch_complete: false, Copilot models: null) is derived from it, and the tests say so.

Smokes changed for the end-to-end checks

  • smoke-pi-sub-agents: main model copilot/gpt-5.3-codex → copilot/gpt-5.3. This is an alias that resolves to gpt-5.3-codex.
  • smoke-claude-on-copilot: claude-haiku-4.5 → copilot/haiku.
  • Lock-file changes from the recompile are limited to:
    • the new artifact path;
    • the Pi detect_agent_errors step and its conclusion env vars;
    • model.resolution added to aider's interpreted event types;
    • the two smoke model changes;
    • dynamic --model in three pi locks that use a gpt-5.4 alias.

Docs

  • reference/engines.md has a new "Model aliases" section, and the six engine pages each describe their engine's handling.
  • model-tables.md and glossary.md are corrected: custom aliases now work, and resolution happens at runtime.
  • model-alias-specification.md is now 1.3.0: it adds §8.8 on provider-prefixed aliases, adds the reserved-keys note, and corrects the V-MAF-020 file mapping in §14.

Validation status

  • CI: green on the last conflict-free head (12ba3ffcba, 41 checks). Lock files re-conflict whenever main recompiles every workflow (for example Bump MCP Gateway to v0.4.35 #69581); they are resolved by make merge-main + make recompile only.
  • make agent-finish (round 5, on a merge with main including AWF v0.28.62): stops at test-js; with make -k, deps-dev, fmt, lint, build, build-wasm, Go tests (0 failures), test-wasm-golden, test-guidance and validate-otel pass. JS: 6 of 22,269 tests fail: copilot_sdk_mcp_config (2), copilot_sdk_tool_config (1) and work_queue_control_performance (2 timeouts) also fail on main; awf_reflect_summary "returns null when file does not exist" fails on main too in our WSL runs (a race between test files writing the same fixture). collect_usage_artifact_files_test.sh also fails on main.
  • Custom Go lint: fixed in fc81544567.
  • End-to-end smokes on this branch (all green; model.resolution events in each run's usage/aw_session.jsonl): see Resolve model aliases the same way on every engine #69487 (comment). After round 4's precedence fix, smoke-pi-sub-agents 39050461861 at eb5498e64f records copilot/gpt-5-mini → gpt-5-mini (exact), copilot/gpt-5.3 → gpt-5.3-codex (resolved).
  • Precedence (round 4): a configured value that exactly matches a live model id for its provider stays exact even when an alias has the same name (for example gpt-5-mini, gemini-3.8-flash); the alias is used only when there is no exact live match.

Out of scope

  • The session collector rejects /reflect files with routing_models: null as invalid_model_inventory.
  • AWF's sandbox.agent.model-fallback behaviour.

Copilot AI and others added 4 commits October 16, 2026 21:03
Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
…lution

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix model aliases resolution on every engine Resolve model aliases the same way on every engine Oct 16, 2026
Copilot AI requested a review from SivaKesava1 October 16, 2026 21:50
@pelikhan

Copy link
Copy Markdown
Collaborator

Make sure resolution is tracked in agent unified session file

@SivaKesava1

Copy link
Copy Markdown
Collaborator

@pelikhan It is: the shared resolver (resolve_model_alias.cjs, used by every harness) writes agent/model-resolution.json, and unified_session.cjs projects each record into usage/aw_session.jsonl as a runner-written model.resolution event (engine, role, configured and resolved model, provider, status, cause). It's specified as T-UAS-074 in the session spec (1.11.0). Once Copilot's current round finishes, we'll dispatch the routed and alias smokes on this branch and confirm the event in each run's aw_session.jsonl before review.

Copilot AI and others added 6 commits October 16, 2026 22:07
Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
…-aliases

# Conflicts:
#	pkg/workflow/agy_harness_test.go

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
…navailable message

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
…mport cache

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
…west live match

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
Copilot AI and others added 2 commits October 16, 2026 23:22
Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
…-aliases

# Conflicts:
#	.github/workflows/duplicate-code-detector.lock.yml

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
@SivaKesava1

Copy link
Copy Markdown
Collaborator

Verified at 12ba3ffcba. CI is green (41 checks), and Go and JS tests show no new failures compared with main in our WSL runs.

End-to-end smokes, dispatched on this branch (all green); model.resolution events from each run's usage/aw_session.jsonl:

Smoke model.resolution
smoke-copilot-small 38995408127 copilot main: small → claude-haiku-5.5 (resolved)
smoke-claude-on-copilot 38995410124 claude main: haiku → claude-haiku-5.5 (resolved)
smoke-github-codex 38995411989 codex main: auto → auto (exact)
smoke-pi-sub-agents 38995413652 pi main: copilot/gpt-5.3 → gpt-5.3-codex; sub-agents copilot/gpt-4o-mini and copilot/claude-haiku-4.5 exact; copilot/gpt-5-mini → gpt-5.4-mini (resolved)
smoke-pi-routed-claude 38995415359 none (routed run; the router picks the model)

Blocking: an exact model id is rewritten. gpt-5-mini is a live Copilot model (/models lists both gpt-5-mini and gpt-5.4-mini) and also a built-in alias name ("gpt-5-mini": ["copilot/gpt-5*mini*", …]). With the new provider-prefix rule, copilot/gpt-5-mini is looked up as an alias and becomes gpt-5.4-mini, which breaks #69484's rule that exact ids are never rewritten. On main that sub-agent runs on gpt-5-mini and smoke-pi-sub-agents checks for it; commit eaa00da488 changed the smoke's expectation instead of the behaviour. Other alias names that are also live ids (for example gemini-3.8-flash) would behave the same way.

Not blocking: every run reports the known invalid_model_inventory collection warning, which is out of scope here.

@pelikhan

Copy link
Copy Markdown
Collaborator

@SivaKesava1 just push this PR in when you think it is ready. would be good to think about some QA test strategy for all this.

Copilot AI and others added 2 commits October 17, 2026 19:27
Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot address the following outstanding work in one pass:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes.

Push the necessary fixes, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved. Use the pr-finisher skill and stop when only human review or CI remains; do not trigger CI.

Sous-chef head: 2e35838
Sous-chef work:
Sous-chef state: 54811d7fa47150ffe106e842319b51cd9bee37f347ba4bec3f07900e734d1880

Generated by 👨‍🍳 PR Sous Chef · pi · haiku45 · 2.96 AIC · ⌖ 9.38 AIC · ⊞ 1.1K · ◷
Comment /souschef to run again

…-aliases

# Conflicts:
#	pkg/workflow/testdata/TestWasmGolden_AllEngines/pi.golden

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address the following outstanding work in one pass:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes....

Pushed merge commit 2ba9099 with latest main cbc3269 via make merge-main. Regenerated the conflicting Pi WASM golden fixture, preserving both model-error outputs and main’s new output fields. All 344 workflows recompiled; formatting, make lint, targeted alias/WASM tests, impacted Go tests, and 1,334 JavaScript tests passed. The final progress gate still fails on the same ten custom-linter findings reproduced before the merge. Secret scan passed; read-only merge review found no significant issues. Automated review was unavailable and CodeQL timed out. The three listed review threads already have answers, so I did not duplicate replies; thread-resolution tooling is unavailable here. No CI was triggered and the PR was not merged; CI on the new head remains unverified.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot address the following outstanding work in one pass:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes.
  2. Fix failing check build-wasm (FAILURE): https://github.com/github/gh-aw/actions/runs/39065904990/job/117567636145.
  3. Fix failing check impacted-go-tests (FAILURE): https://github.com/github/gh-aw/actions/runs/39065904990/job/117567636054.
  4. Fix failing check JS Tests (shard 4/4) (FAILURE): https://github.com/github/gh-aw/actions/runs/39065905028/job/117567625864.

Push the necessary fixes, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved. Use the pr-finisher skill and stop when only human review or CI remains; do not trigger CI.

Sous-chef head: 2ba9099
Sous-chef work: 31f7e812d45f0792093269b7b90445aa9803225a204ec130694b9ceb0227d7cc 42e5d572d9d75b7168fe7d0aeda0717cc07e65ed240f6d299e6fec661214f1ac 8acb61a077717e3a460018aacdfde96fd489f77606cd36169e2328d9079b75bb
Sous-chef state: 1dc37694cf023c3564e7c7328c83b4827e4e8d74f81e09643adc61738be92548

Generated by 👨‍🍳 PR Sous Chef · pi · haiku45 · 11.4 AIC · ⌖ 7.6 AIC · ⊞ 1.1K · ◷
Comment /souschef to run again

…-aliases

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address the following outstanding work in one pass:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes....

Merged the latest main with make merge-main; commit da192adb27 is pushed. The three reported failures are fixed by that merge: make build-wasm and make test-wasm-golden pass, the previously failing Go test passes, and setup_sh_file_lists.test.cjs passes (20 tests). No CI was triggered. The final progress gate still stops at the previously observed custom Go-linter findings, and CodeQL timed out. The three review threads already contain substantive replies; the available tools here do not expose thread resolution, so they remain unresolved.

Copilot AI commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address the following outstanding work in one pass:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes....

Round 9: the branch is at da192adb27, which merges main 6fc2e077f2. This round needed no new commit. The merge had no conflicts, and make recompile changed nothing.

  • setup_sh_file_lists.test.cjs: the only missing file was work_queue_native_creation_delivery.cjs, which came from main, not the model-alias files. It passes (20/20) after the merge. No setup.sh list contains resolve_model_alias.cjs, and it cannot be reached from the MCP scripts or safe-outputs entry points. model_aliases.json is already copied by the *.json loop. setup.sh is unchanged.
  • WASM goldens: the EXPIRES_HOURS 168/12 difference was fixed on main (e9aa2e5). make update-wasm-golden produces no diff, and make test-wasm passes 4/4. Golden diffs against main contain only this PR's changes.
  • Go tests: the four tests you listed pass on this branch and on main.
  • make agent-finish:
    • TestSessionParserSourcesIncludeLocalDependencies fails, and also fails on main (CGO run 39083980901).
    • pkg/cli failed in two runs with different, unrelated tests: a cobra concurrent-map race, then a tuistory test when run without -short. Re-run exactly as make test-integration runs it, pkg/cli passes.

I updated only the description's validation section.

@SivaKesava1
SivaKesava1 merged commit 10f9281 into main Oct 18, 2026
49 checks passed
@SivaKesava1
SivaKesava1 deleted the copilot/resolve-model-aliases branch October 18, 2026 05:15
Copilot AI added a commit that referenced this pull request Oct 18, 2026
* Initial plan

* Add shared /reflect fixture for model resolution

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Resolve configured model aliases with one shared step on every engine

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Switch smokes to aliases, recompile locks, document shared model resolution

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Apply remaining changes

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Remove stray import cache file committed from a test run

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Keep pi's audit-classified startup phrase ahead of the shared model_unavailable message

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Restore pkg/workflow/.github files from main removed with the stray import cache

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Fix typecheck errors in shared model resolution callers

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Expect the pi smoke's gpt-5-mini sub-agent alias to resolve to the newest live match

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Keep buildInitialWorkflowData at main's length for largefunc lint

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Prefer a live exact model id over an alias with the same name; restore pi smoke gpt-5-mini expectation

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Merge main; regenerate frontmatter docs for models: aliases

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Pass bundled model ids through without AWF, emit GH_AW_MODEL_ALIASES for every harness, validate imported aliases

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Ship built-in model aliases with the setup action; emit only workflow aliases

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Recompile lock files without built-in alias maps

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

* Fix resolver JSDoc types; document alias env var reduction

Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.92.6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resolve model: aliases the same way on every engine

5 participants