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

No one assigned

    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