Skip to content

fix(api-proxy): gpt-5.4-mini routed to /chat/completions instead of /responses#3212

Merged
lpcox merged 3 commits into
mainfrom
copilot/awf-fix-gpt-5-4-mini-endpoint
May 15, 2026
Merged

fix(api-proxy): gpt-5.4-mini routed to /chat/completions instead of /responses#3212
lpcox merged 3 commits into
mainfrom
copilot/awf-fix-gpt-5-4-mini-endpoint

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 15, 2026

Bug Fix

What was the bug?

GPT-5-family models (e.g. gpt-5.4-mini) require the /responses wire API but were routed to /chat/completions in strict AWF mode, producing 400 model "gpt-5.4-mini" is not accessible via the /chat/completions endpoint. Two interacting root causes:

  1. COPILOT_PROVIDER_WIRE_API=responses was only set inside the copilotApiKey branch in api-proxy-service.ts — bypassed when auth flows through COPILOT_GITHUB_TOKEN.
  2. resolveCopilotAuthToken() in copilot.js unconditionally preferred COPILOT_GITHUB_TOKEN over COPILOT_API_KEY, so even when a real BYOK key was configured alongside a GitHub token, the sidecar sent the GitHub OAuth token to the third-party provider.

How did you fix it?

api-proxy-service.ts (already applied in base): Moved COPILOT_PROVIDER_WIRE_API=responses out of the copilotApiKey-only branch into the copilotGithubToken || copilotApiKey block, keyed solely on requiresResponsesWireApi(copilotModel).

containers/api-proxy/providers/copilot.js: Reversed token-resolution priority in resolveCopilotAuthToken — real COPILOT_API_KEY now wins over COPILOT_GITHUB_TOKEN. The AWF placeholder is still filtered by resolveApiKey, so the standard GitHub Copilot path (dummy key + real GitHub token) is unchanged.

// Before — GitHub OAuth always wins, BYOK key ignored for inference
return stripBearerPrefix(env.COPILOT_GITHUB_TOKEN) || resolveApiKey(env);

// After — real BYOK key wins; placeholder falls through to GitHub token
return resolveApiKey(env) || stripBearerPrefix(env.COPILOT_GITHUB_TOKEN);

Testing

  • Updated two resolveCopilotAuthToken unit tests in server.auth.test.js to reflect the new priority order.
  • Added a test asserting COPILOT_API_KEY is used for inference in BYOK+token mode (non-/models path).
  • Added gpt-5.4-mini to the BYOK-mode COPILOT_PROVIDER_WIRE_API=responses parameterized test in api-proxy-service.test.ts, closing a coverage gap vs. the equivalent GitHub-token-mode test.

Copilot AI changed the title [WIP] Fix gpt-5.4-mini routing to /responses in strict mode fix(api-proxy): gpt-5.4-mini routed to /chat/completions instead of /responses May 15, 2026
Copilot finished work on behalf of lpcox May 15, 2026 14:02
Copilot AI requested a review from lpcox May 15, 2026 14:02
@lpcox
Copy link
Copy Markdown
Collaborator

lpcox commented May 15, 2026

@copilot address review feedback

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 15, 2026

@copilot address review feedback

Found one area to clean up: the test 'should fall back to COPILOT_API_KEY when COPILOT_GITHUB_TOKEN is whitespace-only' was written when COPILOT_GITHUB_TOKEN was the primary token (so COPILOT_API_KEY was truly a "fallback"). After the priority reversal, COPILOT_API_KEY is now the primary, making that description misleading. Addressed in the latest commit:

  • Renamed the test to 'should use COPILOT_API_KEY when COPILOT_GITHUB_TOKEN is whitespace-only'
  • Added the symmetric test 'should fall back to COPILOT_GITHUB_TOKEN when COPILOT_API_KEY is whitespace-only' to document the full priority chain explicitly

Copilot finished work on behalf of lpcox May 15, 2026 14:42
@lpcox lpcox marked this pull request as ready for review May 15, 2026 14:53
@lpcox lpcox requested a review from Mossaka as a code owner May 15, 2026 14:53
Copilot AI review requested due to automatic review settings May 15, 2026 14:53
@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results

Test Result Details
GitHub API ❌ FAIL gh CLI not authenticated (credential isolation by design)
Playwright ✅ PASS GitHub homepage title verified
File verify ✅ PASS smoke-test-claude-25923930390.txt readable

Summary: 2/3 PASS — Playwright navigation and file I/O working; GitHub API blocked by expected credential isolation.

💥 [THE END] — Illustrated by Smoke Claude

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK (Offline) Mode

Test Result
GitHub MCP connectivity ❌ (401 — MCP unauthenticated in this context)
GitHub.com HTTP ⚠️ Pre-step data not expanded (template vars unresolved)
File write/read ⚠️ Pre-step data not expanded (template vars unresolved)
BYOK inference (api-proxy → api.githubcopilot.com)

Running in BYOK offline mode (COPILOT_OFFLINE=true) via api-proxy → api.githubcopilot.com.

Overall: PARTIAL — BYOK inference confirmed ✅; pre-step template variables were not expanded into the prompt.

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions
Copy link
Copy Markdown
Contributor

🔬 Smoke Test Results — Copilot Engine

Test Result
GitHub MCP connectivity ✅ (MCP tools reachable; GitHub API auth via MCP read-only)
GitHub.com HTTP connectivity ✅ HTTP 200
File write/read /tmp/gh-aw/agent/smoke-test-copilot-25923930382.txt verified

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot

@github-actions
Copy link
Copy Markdown
Contributor

✅ GitHub PR review: Refactor api-proxy SIGTERM/SIGINT shutdown flow into a shared handler; Cap /reflect effective-token totals at configured maxEffectiveTokens
❌ safeinputs-gh: command unavailable
✅ Playwright: GitHub title verified
❌ Tavily: no search tools exposed
✅ File/bash: file created and read back
⚠️ Discussion: query tool unavailable, skipped
✅ Build: npm ci && npm run build
Overall: FAIL

Warning

Firewall blocked 1 domain

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

  • registry.npmjs.org

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

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

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex

@github-actions
Copy link
Copy Markdown
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3
Node.js v24.15.0 v20.20.2
Go go1.22.12 go1.22.12

Result: Some versions differ between host and chroot. Go matches, but Python and Node.js are on different versions.

Tested by Smoke Chroot

@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 1/1 passed ✅ PASS
Go env 1/1 passed ✅ PASS
Go uuid 1/1 passed ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
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: 8/8 ecosystems passed — ✅ PASS

Generated by Build Test Suite for issue #3212 · ● 7.4M ·

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request fixes Copilot BYOK + strict AWF-mode failures for GPT‑5-family models by ensuring the sidecar uses the correct wire API (/responses) and by adjusting Copilot credential selection so a real BYOK API key is used for inference when both BYOK and GitHub OAuth tokens are present.

Changes:

  • Expanded BYOK-mode wire-API test coverage to include gpt-5.4-mini for COPILOT_PROVIDER_WIRE_API=responses.
  • Updated Copilot provider auth-token resolution to prefer COPILOT_API_KEY over COPILOT_GITHUB_TOKEN (while still treating the AWF placeholder key as absent).
  • Updated/added unit tests to reflect and validate the new auth-token precedence.
Show a summary per file
File Description
src/services/api-proxy-service.test.ts Adds gpt-5.4-mini to the BYOK responses-wire-API parameterized test to close a coverage gap.
containers/api-proxy/server.auth.test.js Updates tests for the new auth-token precedence and adds coverage for BYOK+token inference header selection.
containers/api-proxy/providers/copilot.js Changes token resolution order so a real BYOK key is preferred over a GitHub OAuth token.

Copilot's findings

Tip

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

  • Files reviewed: 3/3 changed files
  • Comments generated: 1

Comment on lines 350 to 352
* The Copilot /models endpoint only accepts COPILOT_GITHUB_TOKEN (GitHub OAuth).
* All other requests use the resolved auth token (COPILOT_GITHUB_TOKEN or COPILOT_API_KEY).
* All other requests use the resolved auth token (COPILOT_API_KEY when real, otherwise COPILOT_GITHUB_TOKEN).
*
@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results

  • Redis PING: ❌ timeout (no response on host.docker.internal:6379)
  • PostgreSQL pg_isready: ❌ no response on host.docker.internal:5432
  • PostgreSQL SELECT 1: ❌ skipped (pg_isready failed)

Overall: FAIL — service containers appear unreachable from this runner environment.

🔌 Service connectivity validated by Smoke Services

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results (Gemini)

  • GitHub MCP Testing: ❌ (401 Bad credentials)
  • GitHub.com Connectivity: ❌ (SSL handshake failed/Squid error)
  • File Writing Testing: ✅
  • Bash Tool Testing: ✅

Overall Status: FAIL

Merged PRs found:

  1. refactor: [Export Audit] Remove test-only re-exports from barrel modules (refactor: [Export Audit] Remove test-only re-exports from barrel modules #3169)

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

@lpcox lpcox merged commit ddb6e5d into main May 15, 2026
69 of 72 checks passed
@lpcox lpcox deleted the copilot/awf-fix-gpt-5-4-mini-endpoint branch May 15, 2026 15:15
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.

[awf] api-proxy: gpt-5.4-mini routed to /chat/completions instead of /responses in strict mode

3 participants