Skip to content

[awf] api-proxy: OpenCode engine defaults to Anthropic routing instead of Copilot #1970

@lpcox

Description

@lpcox

Problem

The OpenCode API proxy in containers/api-proxy/server.js (port 10004) currently defaults to routing through Anthropic using ANTHROPIC_API_KEY. However, gh-aw#25830 introduces OpenCode as a first-class engine that defaults to Copilot routing via OPENAI_API_KEY (OpenAI-compatible Copilot API). The firewall's proxy is misaligned with the engine's default credential and provider expectations.

Additionally, the current proxy has no support for dynamic provider routing based on model prefix (e.g., anthropic/claude-3-5-sonnet → Anthropic API, copilot/gpt-4o → Copilot API, openai/gpt-4o → OpenAI API). This is a core feature of OpenCode (75+ models via BYOK).

Context

  • Upstream PR: gh-aw#25830 – feat: add OpenCode engine integration (re-apply PR #18403)
  • Current firewall implementation: containers/api-proxy/server.js:1030–1068
    • Port 10004 exists but activates only when ANTHROPIC_API_KEY is set
    • Injects x-api-key: ANTHROPIC_API_KEY + anthropic-version header
    • Routes to ANTHROPIC_API_TARGET
  • Type comment in src/types.ts:43–44 also incorrectly documents port 10004 as "routes to Anthropic by default"
  • No smoke-opencode.md or .lock.yml workflow exists in .github/workflows/

Root Cause

When the OpenCode port (10004) was added to server.js, it reused the Anthropic routing logic without anticipating that gh-aw would later set Copilot/OpenAI as the primary credential. The activation guard (if (ANTHROPIC_API_KEY)) will silently skip starting the proxy whenever OpenCode is invoked with Copilot tokens only (OPENAI_API_KEY from Copilot token exchange), causing all OpenCode agent requests to fail with connection refused on port 10004.

Proposed Solution

1. Update containers/api-proxy/server.js — OpenCode proxy (lines 1030–1068)

  • Change the activation guard from if (ANTHROPIC_API_KEY) to if (OPENAI_API_KEY || ANTHROPIC_API_KEY || COPILOT_GITHUB_TOKEN) to match the upstream engine's credential hierarchy.
  • Route by detected key priority:
    • If OPENAI_API_KEY (or Copilot token exchanged to OpenAI-compatible key): inject Authorization: Bearer \$\{OPENAI_API_KEY} and route to OPENAI_API_TARGET (default: api.githubcopilot.com).
    • If ANTHROPIC_API_KEY: inject x-api-key + anthropic-version, route to ANTHROPIC_API_TARGET.
  • Log the active routing target at startup.
  • Optionally: inspect the model field in the JSON request body to dynamically pick the provider — parse provider/model prefix and route accordingly (matches extractProviderFromModel() in gh-aw's domains.go).

2. Update src/types.ts

  • Line 43–44: Change the OPENCODE: 10004 JSDoc comment to: "OpenCode API proxy port (defaults to Copilot/OpenAI routing; falls back to Anthropic)".
  • Line 614: Update the inline comment in generateDockerCompose() to reflect the new default.

3. Add smoke-opencode.md workflow

Mirrors smoke-codex.md or smoke-claude.md structure with 5 tests (GitHub MCP, web-fetch, file write, bash, make build). Compile with gh-aw compile .github/workflows/smoke-opencode.md && npx tsx scripts/ci/postprocess-smoke-workflows.ts.

4. No breaking changes

The Anthropic fallback (ANTHROPIC_API_KEY) must be retained as OpenCode supports BYOK — some users will configure Anthropic keys directly. The change is additive: expand the credential hierarchy, do not replace it.

Generated by Firewall Issue Dispatcher · ● 1.2M ·

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions