Skip to content

Unify model resolution around canonical provider-qualified identities - #10681

Merged
lpcox merged 7 commits into
mainfrom
copilot/unify-model-name-resolution
Oct 28, 2026
Merged

lpcox merged 7 commits into
mainfrom
copilot/unify-model-name-resolution

Conversation

Copilot AI commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Request resolution and downstream consumers interpreted model names independently. This change connects them to canonical identity contracts while keeping naming, pricing authority, and execution availability separate.

  • Shared identity boundary: Reuses canonical matchers for exact IDs, scoped aliases, and family exceptions. Returns requested name, canonical identity, wire ID, and match provenance.
  • Consistent consumers: Integrates request rewriting, selectors, policy, retirement, routing, fallback, and pricing. Preserves recursive/glob routing aliases, direct-ID precedence, parameters, and explicit cross-provider fallback.
  • Bounded corrections: Rejects ambiguous aliases, prevents retired descendants from reactivating synthesized fallback, protects specialized GPT variants from implicit family capture, and avoids stripping native prefixes twice.
  • Generated ownership: Bundles deterministic naming views and shared contracts for host and proxy execution. Publication v1 remains unchanged: pricing refreshes cannot update naming rules or establish availability.
  • Regression coverage: Exercises scoped matching, downstream guards, recursive fallback, accounting compatibility, generated drift, and execution outside the checkout.
Request:   Copilot/gpt-5.3-codex?effort=high
Identity:  copilot/gpt-5.3-codex
Wire ID:   gpt-5.3-codex
Forwarded: gpt-5.3-codex?effort=high

Broader eligibility/compiler migration and remote naming transport remain out of scope.

Copilot AI changed the title [WIP] Connect model-name resolution to canonical provider-qualified identities Unify model resolution around canonical provider-qualified identities Oct 26, 2026
Copilot AI requested a review from lpcox October 26, 2026 17:51
@lpcox
lpcox marked this pull request as ready for review October 26, 2026 19:25
Copilot AI max review requested due to automatic review settings October 26, 2026 19:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Provider-native identity handling and alias error paths still cause functional regressions in pricing, request acceptance, and management endpoints.

5 open issues
What changed in this PR

Connects AWF’s host and API-proxy model handling to shared, provider-qualified identities for #10670, while keeping bundled naming rules separate from remotely refreshed pricing.

Changes:

  • Generate and package deterministic naming views and shared resolution contracts.
  • Integrate canonical identity handling into requests, selectors, policy, retirement, fallback, and pricing.
  • Add compatibility and packaged-execution coverage, and document publication v1 boundaries.
File Description
tsconfig.json Includes bundled JavaScript contracts in host builds.
src/​model-information.naming.generated.json Supplies generated naming data for host consumers.
src/​model-information-resolution.test.ts Tests scoped matching, ambiguity, and family rules.
src/​model-information-contract/​resolution.js Bundles shared identity resolution for host execution.
src/​model-information-contract/​resolution.d.ts Defines host resolution types.
src/​model-information-contract/​identity.js Bundles canonical identity matching for host execution.
src/​model-information-contract/​identity.d.ts Defines host identity types.
src/​copilot-model.ts Uses shared resolution for CLI validation.
src/​copilot-model.test.ts Preserves CLI-specific model syntax restrictions.
shared/​model-information/​resolution.js Implements the shared identity-resolution boundary.
shared/​model-information/​resolution.d.ts Defines shared resolution inputs and results.
shared/​model-information/​naming.generated.json Provides the deterministic reviewed naming projection.
scripts/​model-information/​publication.test.ts Includes new assets in publication checks.
scripts/​model-information/​compile.test.ts Tests generated ownership, consistency, and packaging.
scripts/​model-information/​compile.cjs Generates naming views and copies shared contracts.
eslint.config.mjs Supports bundled CommonJS contract files.
docs/​model-catalogue-publication.md Explains bundled naming versus refreshed pricing.
containers/​api-proxy/​routing-candidates.test.js Tests retired-candidate filtering and native mappings.
containers/​api-proxy/​routing-candidates.js Excludes retired Copilot routing candidates.
containers/​api-proxy/​model-utils.js Re-exports shared provider-prefix normalization.
containers/​api-proxy/​model-selector.js Adds canonical identity metadata to selections.
containers/​api-proxy/​model-resolver.js Integrates identity lookup, lifecycle guards, and provenance.
containers/​api-proxy/​model-information.naming.generated.json Supplies generated naming data for the proxy.
containers/​api-proxy/​model-identity.js Connects scoped identities to discovered wire IDs.
containers/​api-proxy/​model-identity-resolution.test.js Covers request integration, compatibility, and Docker staging.
containers/​api-proxy/​model-fallback-chain.test.js Preserves legacy fallback provider aliases.
containers/​api-proxy/​model-fallback-chain.js Resolves explicit fallback entries through canonical naming.
containers/​api-proxy/​model-fallback-chain.identity.test.js Tests identity-aware policy, retirement, and fallback.
containers/​api-proxy/​model-config.js Attaches resolved identity to requests.
containers/​api-proxy/​model-body-rewriter.js Returns identity and provenance alongside rewritten bodies.
containers/​api-proxy/​guards/​retired-model-guard.test.js Tests qualified and parameterized retired names.
containers/​api-proxy/​guards/​retired-model-guard.js Resolves naming before retirement lookup.
containers/​api-proxy/​guards/​model-policy-guard.js Matches policy rules against canonical identities and aliases.
containers/​api-proxy/​Dockerfile Packages proxy naming data and identity helpers.
containers/​api-proxy/​catalogue-pricing.test.js Tests canonical pricing association and compatibility boundaries.
containers/​api-proxy/​catalogue-pricing.js Associates feed tariffs with resolved identities.
containers/​api-proxy/​catalogue-contract/​resolution.js Bundles shared resolution for proxy execution.
containers/​api-proxy/​catalogue-contract/​resolution.d.ts Defines packaged proxy resolution types.
containers/​api-proxy/​catalogue-contract/​identity.d.ts Adds packaged identity declarations.
containers/​api-proxy/​catalogue-contract/​contracts.d.ts Adds packaged contract-validation declarations.

Review effort: Max

(entry.identity.rawId === model || entry.identity.lookupId === model ||
entry.identity.key === model));
const scope = { provider, channel, deployment: context.deployment };
const requested = resolveModelIdentity(model, provider, { scope });
Comment on lines +414 to +418
if (entries.length > 1) {
const error = new Error(`Ambiguous routing alias "${key}"; use unique case-insensitive alias names`);
error.code = 'ambiguous_model_alias';
error.statusCode = 400;
throw error;
Comment on lines +35 to +40
const prefix = getProviderAliases('copilot')
.find(alias => model.toLowerCase().startsWith(`${alias}/`));
const nativeModel = prefix ? stripRedundantProviderPrefix(model, prefix) : model;
const key = resolveModelIdentity(nativeModel, 'copilot', {
policy: { providerPrefix: false },
}).wireId.toLowerCase();
Comment on lines +264 to +265
const effectiveCandidates = candidates.length > 0 ? candidates
: resolutionState.blocked ? [] : synthesizedCandidates;
Comment thread containers/api-proxy/model-resolver.js Outdated
Comment on lines +457 to +460
if (currentProvider === 'copilot' && getRetiredModelBlockState(baseModel)) {
resolutionState.blocked = true;
return null;
}
@lpcox

lpcox commented Oct 27, 2026

Copy link
Copy Markdown
Collaborator

@copilot @address review feedback

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

Copilot AI commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

@copilot @address review feedback

Addressed the review feedback in 9a2b927. The focused regression suites pass (194 tests); the full API-proxy run has one token-tracker.schema failure from extra OTel records, while that suite passes in isolation. CodeQL reported no alerts, but skipped analysis because the database was too large.

@lpcox

lpcox commented Oct 27, 2026

Copy link
Copy Markdown
Collaborator

@copilot merge main and resolve conflicts

…ame-resolution

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

Copilot AI commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

@copilot merge main and resolve conflicts

Merged main without conflicts in 5121608.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Copilot review passed with no inline comments.

@copilot Add the ready-for-aw label to this PR to trigger agentic CI smoke tests.

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Documentation Preview

Documentation has been built for this PR.

Download preview artifact

To view locally:

  1. Download the docs-preview-pr-10681 artifact from the workflow run
  2. Unzip and open index.html in your browser

Built from commit 3a01e51

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Coverage Regression Detected

This PR decreases test coverage. Please add tests to maintain coverage levels.

Overall Coverage

Metric Base PR Delta
Lines 93.62% 93.63% ➡️ +0.01%
Statements 92.11% 92.12% 📈 +0.01%
Functions 91.22% 91.21% 📉 -0.01%
Branches 86.18% 86.20% 📈 +0.02%
📁 Per-file Coverage Changes (2 files)
File Lines (Before → After) Statements (Before → After)
src/enclave/host-executor-server.ts 91.2% → 91.2% (+0.00%) 90.1% → 89.8% (-0.29%)
src/nvx/one-shot-adapter.ts 82.9% → 83.4% (+0.56%) 80.2% → 80.7% (+0.52%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

✅ Smoke Copilot BYOK AOAI (api-key) completed. Copilot AOAI BYOK (api-key) mode operational. 🔓

🔑 BYOK (AOAI api-key) report filed by Smoke Copilot BYOK AOAI (api-key)

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Security Guard has started processing this pull request

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.

Tested by Smoke Chroot

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Smoke Cloud Hypervisor completed. Cloud Hypervisor + Copilot passed.

Cloud Hypervisor + Copilot smoke test by Smoke Cloud Hypervisor

@github-actions

Copy link
Copy Markdown
Contributor

🪪 Smoke Copilot BYOK AOAI (Entra) is testing Azure OpenAI BYOK (Entra / GitHub OIDC) mode on this pull request...

@github-actions

Copy link
Copy Markdown
Contributor

📡 Smoke OTel Tracing is starting OTel tracing validation...

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

✅ Smoke Claude passed

Generated by Smoke Claude for #10681

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

✅ Build Test Suite completed successfully!

Generated by Build Test Suite for #10681

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

🛡️ Smoke Copilot Network Isolation confirmed the egress allowlist is enforced. ✅

🛡️ Egress verdict from Smoke Copilot Network Isolation

@github-actions

Copy link
Copy Markdown
Contributor

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 93.63% 93.63% ➡️ +0.00%
Statements 92.12% 92.12% ➡️ +0.00%
Functions 91.22% 91.22% ➡️ +0.00%
Branches 86.19% 86.20% 📈 +0.01%
📁 Per-file Coverage Changes (1 files)
File Lines (Before → After) Statements (Before → After)
src/enclave/host-executor-server.ts 91.2% → 91.2% (+0.00%) 89.8% → 90.1% (+0.29%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Copilot: PR "fix: skip stream_options injection for Claude on Vertex"

  • GitHub MCP ✅
  • GitHub.com connectivity ✅
  • File write/read ✅

Overall: PASS — @Copilot @lpcox

📰 BREAKING: Report filed by Smoke Copilot
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test

  • chore: upgrade gh-aw workflows to v1.0.1 ✅
  • chore: refresh canonical model sources ✅
  • GitHub PR details ✅
  • Playwright title check ❌
  • Temp file write/read ✅
  • AWF build ✅
  • Overall status: FAIL

🔮 The oracle has spoken through Smoke Codex
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Cloud Hypervisor + Copilot smoke test

  1. Merged PR lookup: PASS
  2. github.com connectivity: PASS (HTTP 200)
  3. File write/read: PASS
  4. example.com blocked: PASS (HTTP 000)

Overall: PASS

Cloud Hypervisor + Copilot smoke test by Smoke Cloud Hypervisor
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia ✅ 1/1 passed ✅ PASS
Bun hono ✅ 1/1 passed ✅ PASS
C++ fmt ✅ N/A ✅ PASS
C++ json ✅ N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world ✅ N/A ✅ PASS
.NET json-parse ✅ N/A ✅ PASS
Go color ✅ all passed ✅ PASS
Go env ✅ all passed ✅ PASS
Go uuid ✅ all passed ✅ PASS
Java gson ❌ 0/0 (not run) ❌ FAIL
Java caffeine ❌ 0/0 (not run) ❌ FAIL
Node.js clsx ✅ passed ✅ PASS
Node.js execa ✅ passed ✅ PASS
Node.js p-limit ✅ passed ✅ PASS
Rust fd ✅ 1/1 passed ✅ PASS
Rust zoxide ✅ 1/1 passed ✅ PASS

Overall: 7/8 ecosystems passed — FAIL

Java failure details: Maven could not resolve plugins (maven-resources-plugin:3.4.0) from https://repo.maven.apache.org/maven2. Through the squid-proxy:3128 proxy in ~/.m2/settings.xml it failed with (internal_error) Unexpected error. The default ~/.m2 was also read-only (owned by root), so I used -Dmaven.repo.local=/tmp/gh-aw/agent/m2.

Notes: .NET initially failed because /run/user/1001 was missing. Setting XDG_RUNTIME_DIR fixed it.

Generated by Build Test Suite for #10681 · copilot · auto · ~26 AIC · ⊞ 5.7K · ◷
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Claude Results

  • API status: ✅ PASS
  • gh check: ✅ PASS
  • File status: ✅ PASS

Overall result: PASS

Generated by Smoke Claude for #10681 · claude · haiku45 · ~35 AIC · ⊞ 6.1K · ◷
Add label ready-for-aw to run again

@lpcox
lpcox deployed to aoai-model October 28, 2026 00:08 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown
Contributor

EGRESS_RESULT allow=pass deny=pass

  • ✅ Allowed domain (api.github.com): HTTP 200
  • ✅ Blocked domain (example.com): blocked
  • Overall: PASS (PR by @lpcox)

🛡️ Egress verdict from Smoke Copilot Network Isolation
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Chroot Version Comparison

Runtime Host Version Chroot Version Match?
Python Python 3.12.15 Python 3.12.15 ✅
Node.js v24.21.0 v26.11.1 ❌
Go go1.22.12 go1.22.12 ✅

Result: Not all tests passed (Node.js version mismatch), so the smoke-chroot label was not added.

Tested by Smoke Chroot
Add label ready-for-aw to run again

This branch had an error being deployed

1 failed deployment
aoai-model — dc09a4e8 Deployed Oct 28, 2026 by lpcox via conclusion #2191
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unify model-name resolution with canonical provider-qualified catalogue identities

3 participants