Skip to content

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

Open
Copilot wants to merge 3 commits intomainfrom
copilot/fix-api-proxy-anthropic-default
Open

fix(api-proxy): OpenCode port 10004 defaults to Copilot/OpenAI routing instead of Anthropic#1979
Copilot wants to merge 3 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

* 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
Copy link
Copy Markdown
Contributor

🔥 Smoke Test Results

Test Status
GitHub MCP (latest merged PR: #1978 "fix: add size-based filtering to --env-all to prevent E2BIG")
GitHub.com connectivity (HTTP 200)
File write/read (smoke-test-copilot-24425093424.txt)

Overall: PASS 🎉

PR by @app/copilot-swe-agent, assigned to @lpcox and @Copilot.

📰 BREAKING: Report filed by Smoke Copilot

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results

✅ GitHub MCP: "fix: add size-based filtering to --env-all to prevent E2BIG" / "fix: recover toolchain env vars from $GITHUB_ENV file"
✅ Playwright: github.com title contains "GitHub"
✅ File write: /tmp/gh-aw/agent/smoke-test-claude-24425093415.txt created
✅ Bash read: file contents verified

Overall: PASS

💥 [THE END] — Illustrated by Smoke Claude

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: GitHub Actions Services Connectivity ✅

All checks passed:

Check Command Result
Redis PING nc host.docker.internal 6379 (PING) +PONG
PostgreSQL ready pg_isready -h host.docker.internal -p 5432 accepting connections
PostgreSQL query psql ... -c "SELECT 1" on smoketest DB ✅ Returns 1

Note: redis-cli was unavailable (no apt access in sandbox), so Redis was tested via raw TCP with nc.

🔌 Service connectivity validated by Smoke Services

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Status

  • fix: add size-based filtering to --env-all to prevent E2BIG
  • fix: recover toolchain env vars from $GITHUB_ENV file
  • GitHub MCP: ✅ | safeinputs-gh PR query: ❌ | Playwright title: ✅ | Tavily search: ❌
  • File write: ✅ | Bash cat verify: ✅ | Discussion comment: ❌ | npm ci && npm run build: ✅
  • Overall: FAIL

🔮 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 ❌ 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
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

Note (Java): Maven's default local repository at ~/.m2/repository was owned by root (not writable). Tests ran successfully using -Dmaven.repo.local=/tmp/gh-aw/agent/m2-repo as a workaround.

Generated by Build Test Suite for issue #1979 · ● 760.1K ·

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