Skip to content

feat: recursive alias resolution with cycle protection in validateRequestedModel#6054

Merged
pelikhan merged 4 commits into
mainfrom
copilot/resolve-model-id-aliases
Jul 9, 2026
Merged

feat: recursive alias resolution with cycle protection in validateRequestedModel#6054
pelikhan merged 4 commits into
mainfrom
copilot/resolve-model-id-aliases

Conversation

Copilot AI commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

validateRequestedModel used an early direct string match (allModels.some(...)) before trying alias resolution — bypassing resolveModel's recursive chain and cycle detection entirely. This meant multi-hop aliases weren't followed and cyclic aliases weren't guarded at startup validation time.

Changes

containers/api-proxy/key-validation.js

  • New _resolveModelForValidation helper: delegates to resolveModel across all providers (fallback disabled), making it the single resolution path for both direct and alias cases
  • Removes early direct check: allModels.some(m => m.toLowerCase() === normalizedRequested) dropped — _resolveDirectMatch inside resolveModel covers this
  • Accurate resolved_via classification: checks alias-key presence in the map rather than comparing strings, correctly labels 'alias' even when alias and model names coincide
  • Debug logging: emits each resolution step as model_validation_step events, consistent with request-time resolution logging in makeModelBodyTransform
  • testHelpers export for unit testing via @internal convention

containers/api-proxy/server.startup-model-validation.test.js

  • Recursive chain test: top-alias → mid-alias → copilot/*claude* — verifies multi-hop resolution and correct debug step count
  • Cycle detection test: cycle-a ↔ cycle-b — verifies loop breaks surface as model_unavailable_at_startup with no false-positive success event
  • Debug step test: asserts model_validation_step events carry provider context

Copilot AI added 2 commits July 9, 2026 04:04
…uestedModel

- Add _resolveModelForValidation helper that uses resolveModel() for
  proper recursive alias resolution with cycle detection
- Remove early direct model-ID check — resolveModel handles direct
  matches via _resolveDirectMatch, so the pre-check was redundant
- Log each resolution step at debug level (model_validation_step)
- Add tests for recursive alias chains and cycle detection
- Use alias-key presence check for accurate resolved_via classification
- Use descriptive fixture names (top-alias/mid-alias, cycle-a/cycle-b)
- Assert number of debug log steps for multi-hop alias chain
- Assert no success log is emitted when cycle breaks resolution
@pelikhan

pelikhan commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

@copilot add test suite for model alias resolution with complex trees of model ids.

Copilot AI commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@copilot add test suite for model alias resolution with complex trees of model ids.

Added a resolveModel — complex alias trees describe block to containers/api-proxy/model-resolver.test.js with 17 tests covering the full range of complex tree topologies:

  • Deep chains (4-level, 5-level)
  • Fan-out — alias branching to multiple sub-aliases, candidates merged and version-sorted at each level
  • Partial branch — one branch has no matches, resolution succeeds via the other
  • Cycle detection — 3-node cycle (A→B→C→A), mid-chain cycle (A→B→C→B), and diamond cycle (all branches eventually loop)
  • Mixed valid + cyclic — direct provider-pattern leaf alongside a cyclic sub-alias branch
  • Cross-provider filtering — patterns for a different provider are skipped cleanly
  • Deduplication — two branches converging on the same model
  • Sibling trees at different depths
  • Default "" alias as an intermediate node
  • Wide flat tree (4 sub-aliases in one fan-out)
  • Mixed leaf types — provider-pattern and sub-alias leaves in one alias
  • Log accumulation across levels
  • Case-insensitive keys at every depth

Commit: 8a88e18

Copilot AI requested a review from pelikhan July 9, 2026 04:25
@pelikhan pelikhan marked this pull request as ready for review July 9, 2026 04:59
Copilot AI review requested due to automatic review settings July 9, 2026 04:59
@pelikhan pelikhan enabled auto-merge (squash) July 9, 2026 04:59
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 98.99% 99.03% 📈 +0.04%
Statements 98.96% 98.99% 📈 +0.03%
Functions 99.45% 99.45% ➡️ +0.00%
Branches 95.71% 95.71% ➡️ +0.00%
📁 Per-file Coverage Changes (1 files)
File Lines (Before → After) Statements (Before → After)
src/log-directory-setup.ts 96.2% → 100.0% (+3.78%) 96.3% → 100.0% (+3.71%)

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

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.

Pull request overview

This PR aligns startup-time AWF_REQUESTED_MODEL validation with request-time model resolution by routing validation through resolveModel (including recursive alias chains and cycle detection), and adds tests to cover deeper alias graphs and cycles.

Changes:

  • Refactors startup validation to use a single resolution path (resolveModel) across providers (with middle-power fallback disabled) and adds per-step debug logging (model_validation_step).
  • Improves resolved_via classification by detecting alias-key usage (instead of relying only on string equality).
  • Expands unit test coverage for multi-hop alias chains, cyclic aliases, and larger alias trees.
Show a summary per file
File Description
containers/api-proxy/key-validation.js Adds _resolveModelForValidation, removes the early direct-match bypass, emits stepwise debug logs, and refines resolved_via logic.
containers/api-proxy/server.startup-model-validation.test.js Adds startup validation tests for recursive alias chains, cycles, and debug-step logging payloads.
containers/api-proxy/model-resolver.test.js Adds a comprehensive test suite for deep/wide alias trees, branching, dedupe, and multiple cycle shapes.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Low

Comment on lines +188 to +190
// Confirm model_validation_step debug entries cover both alias hops
const debugCalls = isolatedLog.mock.calls.filter(c => c[1] === 'model_validation_step');
expect(debugCalls.length).toBeGreaterThanOrEqual(2);
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

⏳ Copilot review left inline comments.

@copilot To proceed:

  1. Ask @copilot to address the review feedback (reply to this comment or the review thread)
  2. Once the fix is pushed, add the ready-for-aw label to trigger agentic CI smoke tests

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🔑 Smoke Copilot PAT PAT auth validated. All systems operational. ✅

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Claude passed

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Contribution Check completed successfully!

PR #6054 follows the applicable CONTRIBUTING.md guidelines based on the prefetched metadata, diff, and contribution guidance; no review comment needed.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Gemini completed. All facets verified. 💎

Smoke test completed. Connectivity and GitHub MCP tool were unreachable/missing. File writing and bash tools passed. Overall status: FAIL.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🔌 Smoke Services — All services reachable! ✅

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🚀 Security Guard has started processing this pull request

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Build Test Suite completed successfully!

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK reports failed. BYOK mode investigation needed...

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK AOAI (Entra) completed. Copilot AOAI BYOK (Entra) mode operational. 🔓

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🔑 Smoke Copilot BYOK AOAI (api-key) is testing Azure OpenAI BYOK (api-key) mode on this pull request...

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Test\n- fix: mock accessSync in workdir-setup test to avoid macOS false failure ✅\n- fix: validate COPILOT_MODEL after alias resolution, not before ✅\n- GitHub query checks ✅\n- Playwright title check ✅\n- Temp file write ✅\n- Build (npm ci && npm run build) ✅\n- Overall: PASS

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • awmgmcpg
  • registry.npmjs.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"
    - "registry.npmjs.org"

See Network Configuration for more information.

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

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot PAT Auth

Test Result
GitHub MCP connectivity ✅ (PR #6054 context confirmed)
GitHub.com HTTP ✅ 200
File write/read ⚠️ template vars unresolved in CI

Overall: PASS (core connectivity verified)
Auth mode: PAT (COPILOT_GITHUB_TOKEN)
@lpcox

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🔑 PAT report filed by Smoke Copilot PAT
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Claude Engine Validation

Check Result
API Status ✅ PASS
GH Check ✅ PASS
File Status ✅ PASS

Overall Result: PASS

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

Generated by Smoke Claude for #6054 · 55.1 AIC · ⊞ 3.3K ·
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Services Connectivity

  • Redis PING: ❌ Network is unreachable
  • PostgreSQL pg_isready: ❌ No response
  • PostgreSQL SELECT 1: ❌ Network is unreachable

Overall: FAILhost.docker.internal (172.17.0.1) is not reachable from this runner. Service containers may not be running or network bridging is unavailable.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🔌 Service connectivity validated by Smoke Services
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Test Results

  • GitHub MCP: ❌ (Tool not found)
  • GitHub Connectivity: ❌ (Network unreachable)
  • File Writing: ✅
  • Bash Tool: ✅

Overall Status: FAIL

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • localhost

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "localhost"

See Network Configuration for more information.

💎 Faceted by Smoke Gemini
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🔥 Smoke Test Results

Test Result
GitHub MCP connectivity
GitHub.com HTTP ✅ 200
File write/read

Overall: PASS

Thanks @lpcox!

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

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

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3 ❌ NO
Node.js v24.18.0 v22.23.1 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Overall: ❌ Not all tests passed. Python minor version differs (3.12.13 vs 3.12.3) and Node.js major version differs (v24 vs v22). The smoke-chroot label was not applied.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

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

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: API Proxy OpenTelemetry Tracing

Scenario Result Notes
S1: Module Loading ✅ Pass otel.js loads; exports: startRequestSpan, setTokenAttributes, setBudgetAttributes, endSpan, endSpanError, shutdown, isEnabled, plus private helpers
S2: Test Suite ✅ Pass 59 tests passing across otel.test.js + otel-fanout.test.js (2 suites)
S3: Env Var Forwarding ✅ Pass src/services/api-proxy-env-config.ts forwards OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, GITHUB_AW_OTEL_TRACE_ID, GITHUB_AW_OTEL_PARENT_SPAN_ID, OTEL_SERVICE_NAME (defaults to awf-api-proxy)
S4: Token Tracker Integration ✅ Pass onUsage callback present in token-tracker-http.js (line 285); invoked after normalized usage is extracted
S5: OTEL Diagnostics ✅ Pass No span export errors; graceful degradation when endpoint not configured

All 5 scenarios pass. 🎉

Warning

Firewall blocked 4 domains

The following domains were blocked by the firewall during workflow execution:

  • 127.0.0.1
  • api.example.com
  • api.openai.com
  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "127.0.0.1"
    - "api.example.com"
    - "api.openai.com"
    - "awmgmcpg"

See Network Configuration for more information.

📡 OTel tracing validated by Smoke OTel Tracing
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@lpcox

  • GitHub MCP Testing: ✅
  • GitHub.com Connectivity: ✅
  • File Write/Read Test: ✅
  • BYOK Inference Test: ✅

Running in direct BYOK mode (AWF_AUTH_TYPE=github-oidc + AWF_AUTH_AZURE_* + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw) authenticated via Microsoft Entra

Overall Status: PASS

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)
Add label ready-for-aw to run again

@pelikhan pelikhan merged commit faac97f into main Jul 9, 2026
82 of 87 checks passed
@pelikhan pelikhan deleted the copilot/resolve-model-id-aliases branch July 9, 2026 10:03
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.

4 participants