Skip to content

fix(api-proxy): OpenCode port 10004 defaults to Copilot/OpenAI routing instead of Anthropic#1979

Merged
lpcox merged 4 commits intomainfrom
copilot/fix-api-proxy-anthropic-default
Apr 15, 2026
Merged

fix(api-proxy): OpenCode port 10004 defaults to Copilot/OpenAI routing instead of Anthropic#1979
lpcox merged 4 commits intomainfrom
copilot/fix-api-proxy-anthropic-default

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 14, 2026

Port 10004 was gated on ANTHROPIC_API_KEY and hardwired to Anthropic, causing silent connection-refused failures when OpenCode runs with Copilot credentials (OPENAI_API_KEY from token exchange). This aligns port 10004 with the upstream engine's actual credential hierarchy.

Changes

  • containers/api-proxy/server.js — OpenCode proxy (port 10004)

    • Activation guard: if (ANTHROPIC_API_KEY)if (OPENAI_API_KEY || ANTHROPIC_API_KEY || COPILOT_AUTH_TOKEN)
    • Credential-priority routing (first match wins):
      1. OPENAI_API_KEYOPENAI_API_TARGET with Authorization: Bearer (Copilot/OpenAI default)
      2. ANTHROPIC_API_KEYANTHROPIC_API_TARGET with x-api-key (Anthropic BYOK fallback)
      3. COPILOT_AUTH_TOKENCOPILOT_API_TARGET with Authorization: Bearer
    • Base path forwarding and startup log now consistent with other proxy ports
  • src/types.ts — corrected JSDoc and generateDockerCompose() comment for OPENCODE: 10004 to reflect Copilot/OpenAI as the default, Anthropic as fallback

  • .github/workflows/smoke-opencode.md — new smoke test workflow (GitHub MCP, file write, bash, AWF build); compilation to .lock.yml is pending opencode engine support in gh-aw (currently not a valid engine in v0.68.1)

Copilot AI changed the title [WIP] Fix OpenCode engine default routing to use Copilot fix(api-proxy): OpenCode port 10004 defaults to Copilot/OpenAI routing instead of Anthropic Apr 14, 2026
Copilot AI requested a review from lpcox April 14, 2026 22:02
@lpcox lpcox marked this pull request as ready for review April 14, 2026 23:26
@lpcox lpcox requested a review from Mossaka as a code owner April 14, 2026 23:26
Copilot AI review requested due to automatic review settings April 14, 2026 23:26
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

Updates the api-proxy sidecar’s OpenCode port (10004) so it activates and routes based on the same credential priority OpenCode uses upstream, avoiding “connection refused” when only Copilot/OpenAI-style credentials are available.

Changes:

  • Adjust OpenCode (10004) proxy activation guard and add credential-priority routing across OpenAI/Copilot-compatible, Anthropic, and Copilot targets.
  • Update API_PROXY_PORTS.OPENCODE documentation to reflect the new default routing behavior.
  • Add a new (source) smoke workflow definition for the OpenCode engine.
Show a summary per file
File Description
containers/api-proxy/server.js Changes OpenCode (10004) proxy to start with broader credentials and dynamically route based on credential availability.
src/types.ts Updates JSDoc/comments to reflect OpenCode routing defaults and priority.
.github/workflows/smoke-opencode.md Adds an OpenCode smoke workflow source definition (not compiled to a .lock.yml in this PR).

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: 4

src/types.ts Outdated
* OpenCode API proxy port (routes to Anthropic by default)
* OpenCode is BYOK — defaults to Anthropic as the primary provider
* OpenCode API proxy port (defaults to Copilot/OpenAI routing; falls back to Anthropic)
* OpenCode is BYOK — credential priority: OPENAI_API_KEY > ANTHROPIC_API_KEY > COPILOT_AUTH_TOKEN
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

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

The API proxy docs mention COPILOT_AUTH_TOKEN in the OpenCode credential priority, but COPILOT_AUTH_TOKEN is an internal server.js-derived value (resolved from COPILOT_GITHUB_TOKEN/COPILOT_API_KEY) and isn't something users configure directly. Consider updating this comment to reference the actual env vars/config fields users can set, so the docs remain actionable.

Suggested change
* OpenCode is BYOK credential priority: OPENAI_API_KEY > ANTHROPIC_API_KEY > COPILOT_AUTH_TOKEN
* OpenCode is BYOK credential priority: OPENAI_API_KEY > ANTHROPIC_API_KEY > COPILOT_GITHUB_TOKEN/COPILOT_API_KEY

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +17
---
description: Smoke test workflow that validates OpenCode engine functionality by testing AWF firewall capabilities
on:
roles: all
schedule: every 12h
workflow_dispatch:
pull_request:
types: [opened, synchronize, reopened]
reaction: "rocket"
permissions:
contents: read
issues: read
pull-requests: read
discussions: read
name: Smoke OpenCode
engine: opencode
strict: true
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

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

This adds a new agentic workflow source file under .github/workflows/, but there is no corresponding compiled .lock.yml workflow checked in (unlike the other smoke workflows, e.g. smoke-copilot.md → smoke-copilot.lock.yml). As-is, this won't run in GitHub Actions and may be easy to overlook; consider either including the compiled lock file once supported, or adding an explicit note in the frontmatter/body that compilation is pending and the workflow is not yet active.

Copilot uses AI. Check for mistakes.
const anthropicHeaders = { 'x-api-key': ANTHROPIC_API_KEY };
if (!req.headers['anthropic-version']) {
anthropicHeaders['anthropic-version'] = '2023-06-01';

Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

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

The OpenCode (10004) HTTP handler doesn't apply rate limiting (unlike the other HTTP proxies that call checkRateLimit() before proxyRequest()). This makes the "per-engine rate limiting" comment inaccurate and allows unlimited HTTP traffic on 10004 even when AWF rate limiting is enabled. Consider computing content-length and calling checkRateLimit(req, res, 'opencode', contentLength) before routing/proxyRequest().

Suggested change
const parsedContentLength = Number(req.headers['content-length']);
const contentLength = Number.isFinite(parsedContentLength) && parsedContentLength > 0 ? parsedContentLength : 0;
if (!checkRateLimit(req, res, 'opencode', contentLength)) {
return;
}

Copilot uses AI. Check for mistakes.
Comment on lines 1055 to 1082
if (OPENAI_API_KEY) {
logRequest('info', 'opencode_proxy_header_injection', {
message: '[OpenCode Proxy] Routing to OpenAI/Copilot via OPENAI_API_KEY',
target: OPENAI_API_TARGET,
});
proxyRequest(req, res, OPENAI_API_TARGET, {
'Authorization': `Bearer ${OPENAI_API_KEY}`,
}, 'opencode', OPENAI_API_BASE_PATH);
} else if (ANTHROPIC_API_KEY) {
logRequest('info', 'opencode_proxy_header_injection', {
message: '[OpenCode Proxy] Routing to Anthropic via ANTHROPIC_API_KEY',
target: ANTHROPIC_API_TARGET,
});
const anthropicHeaders = { 'x-api-key': ANTHROPIC_API_KEY };
if (!req.headers['anthropic-version']) {
anthropicHeaders['anthropic-version'] = '2023-06-01';
}
proxyRequest(req, res, ANTHROPIC_API_TARGET, anthropicHeaders, 'opencode', ANTHROPIC_API_BASE_PATH);
} else {
// COPILOT_AUTH_TOKEN only — route to Copilot API target
logRequest('info', 'opencode_proxy_header_injection', {
message: '[OpenCode Proxy] Routing to Copilot via COPILOT_AUTH_TOKEN',
target: COPILOT_API_TARGET,
});
proxyRequest(req, res, COPILOT_API_TARGET, {
'Authorization': `Bearer ${COPILOT_AUTH_TOKEN}`,
}, 'opencode');
}
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

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

New provider-routing behavior for the OpenCode proxy (OPENAI_API_KEY vs ANTHROPIC_API_KEY vs COPILOT_AUTH_TOKEN) isn't covered by tests. Since this repo already has containers/api-proxy/server.test.js, please add unit/integration coverage for the 10004 routing priority and header injection for each credential scenario (and WebSocket upgrade routing if applicable).

Copilot uses AI. Check for mistakes.
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Copilot AI added a commit that referenced this pull request Apr 15, 2026
- types.ts: correct credential priority comment to reference
  user-configurable vars COPILOT_GITHUB_TOKEN/COPILOT_API_KEY
  instead of internal COPILOT_AUTH_TOKEN
- smoke-opencode.md: add note that lock file compilation is pending
  until opencode engine support lands in gh-aw
- server.js: add rate limiting to OpenCode (port 10004) HTTP handler
  using content-length-aware checkRateLimit() call
- server.js: extract resolveOpenCodeRoute() helper for testability
  and refactor handler to use it
- server.test.js: add 8 unit tests covering all OpenCode routing
  priority scenarios and header injection

Agent-Logs-Url: https://github.com/github/gh-aw-firewall/sessions/a0621fda-d1a3-449b-a3da-a9d0331c4c76
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@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 ❌ NO
Node.js v24.14.1 v20.20.2 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Result: ❌ Not all tests passed — Python and Node.js versions differ between host and chroot environments.

Tested by Smoke Chroot

@github-actions

This comment has been minimized.

lpcox added a commit that referenced this pull request Apr 15, 2026
#1984)

* Initial plan

* fix: update OpenCode proxy to default to Copilot/OpenAI routing

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

* fix: address code review - correct comment to use COPILOT_AUTH_TOKEN

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

* fix: address review comments from PR #1979

- types.ts: correct credential priority comment to reference
  user-configurable vars COPILOT_GITHUB_TOKEN/COPILOT_API_KEY
  instead of internal COPILOT_AUTH_TOKEN
- smoke-opencode.md: add note that lock file compilation is pending
  until opencode engine support lands in gh-aw
- server.js: add rate limiting to OpenCode (port 10004) HTTP handler
  using content-length-aware checkRateLimit() call
- server.js: extract resolveOpenCodeRoute() helper for testability
  and refactor handler to use it
- server.test.js: add 8 unit tests covering all OpenCode routing
  priority scenarios and header injection

Agent-Logs-Url: https://github.com/github/gh-aw-firewall/sessions/a0621fda-d1a3-449b-a3da-a9d0331c4c76

* fix: handle null route with 503 response in OpenCode proxy handlers

Agent-Logs-Url: https://github.com/github/gh-aw-firewall/sessions/a0621fda-d1a3-449b-a3da-a9d0331c4c76

* refactor: eliminate code duplication in OpenCode proxy routing

- Add needsAnthropicVersion flag to resolveOpenCodeRoute return value
  to centralize anthropic-version header logic
- Use resolveOpenCodeRoute() for startup guard instead of repeating
  the credential availability check
- Update tests to assert needsAnthropicVersion for all scenarios

Agent-Logs-Url: https://github.com/github/gh-aw-firewall/sessions/a0621fda-d1a3-449b-a3da-a9d0331c4c76

* Update containers/api-proxy/server.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update containers/api-proxy/server.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: Landon Cox <landon.cox@microsoft.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@lpcox lpcox merged commit 14bfa81 into main Apr 15, 2026
12 of 13 checks passed
@lpcox lpcox deleted the copilot/fix-api-proxy-anthropic-default branch April 15, 2026 04:30
@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results

Test Result
GitHub API (latest merged PR: #1984)
GitHub.com connectivity (HTTP 200)
File write/read (pre-step vars not expanded) ⚠️ N/A

Overall: PASS

PR: fix(api-proxy): OpenCode port 10004 defaults to Copilot/OpenAI routing instead of Anthropic
Author: @app/copilot-swe-agent | Assignees: @lpcox, @Copilot

📰 BREAKING: Report filed by Smoke Copilot

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results (run 24436400540)

✅ GitHub MCP — Last 2 merged PRs: fix(api-proxy): address review comments on OpenCode port 10004 routing (#1984), fix(api-proxy): OpenCode port 10004 defaults to Copilot/OpenAI routing instead of Anthropic (#1979)
✅ Playwright — github.com title contains "GitHub"
✅ File Write — /tmp/gh-aw/agent/smoke-test-claude-24436400540.txt created
✅ Bash — file content verified

Overall: PASS

💥 [THE END] — Illustrated by Smoke Claude

@github-actions
Copy link
Copy Markdown
Contributor

Smoke test results (run 24436400712)
PR titles: fix(api-proxy): OpenCode port 10004 defaults to Copilot/OpenAI routing instead of Anthropic; fix(api-proxy): address review comments on OpenCode port 10004 routing
GitHub MCP: ✅
Safe Inputs GH CLI (safeinputs-gh): ❌
Playwright (github.com title contains "GitHub"): ✅
Tavily web search: ❌
File write + bash cat verify: ✅
Discussion oracle comment: ✅ (posted to discussion #1980; query tool unavailable)
Build (npm ci && npm run build): ✅
Overall status: FAIL

🔮 The oracle has spoken through Smoke Codex

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: GitHub Actions Services Connectivity ✅

All checks passed against host.docker.internal:

Check Result
Redis PING (port 6379) +PONG
PostgreSQL ready (port 5432) accepting connections
PostgreSQL SELECT 1 (db: smoketest, user: postgres) ✅ Returns 1

Note: redis-cli was not installed; Redis was tested via nc with the Redis wire protocol.

🔌 Service connectivity validated by Smoke Services

@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 all passed ✅ PASS
Node.js execa all passed ✅ PASS
Node.js p-limit all 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 #1979 · ● 527.2K ·

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: OpenCode engine defaults to Anthropic routing instead of Copilot

3 participants