Problem
Currently, the api-proxy sidecar only starts listeners on ports where the corresponding API key is configured:
- Port 10000 (OpenAI) — only if
OPENAI_API_KEY is set
- Port 10001 (Anthropic) — only if
ANTHROPIC_API_KEY is set
- Port 10002 (Copilot) — only if
COPILOT_GITHUB_TOKEN or COPILOT_API_KEY is set
- Port 10003 (Gemini) — only if
GEMINI_API_KEY is set
- Port 10004 (OpenCode) — only if any credential is present +
AWF_ENABLE_OPENCODE
Similarly, the AWF CLI only sets *_BASE_URL environment variables in the agent container when the matching key is present (src/docker-manager.ts:1854-1940), and iptables rules may only allow traffic to ports that are actively configured.
This creates problems:
- Model aliasing breaks across providers — if a workflow configures
apiProxy.models to alias a model name to a different provider's model, the target port may not be listening because that provider's key wasn't explicitly configured.
- Dynamic routing is impossible — the model-resolver can resolve
"fast" → claude-haiku-4.5 but if only OPENAI_API_KEY was provided, port 10001 isn't running.
- Credential discovery at runtime — tools like Copilot CLI may dynamically acquire tokens (e.g., via OAuth) and attempt to use a provider port that was never started.
- Startup complexity — the server has complex conditional logic tracking which listeners to expect for healthcheck readiness (
expectedListeners at line 1610).
Proposal
1. Always start all port listeners in api-proxy
All five ports (10000–10004) should always be listening when --enable-api-proxy is active:
Port 10000 — OpenAI-compatible API (always listening)
Port 10001 — Anthropic API (always listening)
Port 10002 — Copilot API (always listening)
Port 10003 — Gemini API (always listening)
Port 10004 — OpenCode/generic (always listening)
When a request arrives on a port without a configured credential, the proxy should return a clear error (e.g., 503 Service Unavailable with body {"error": "No API key configured for this provider"}) rather than refusing the TCP connection.
2. Always set all *_BASE_URL env vars in agent
Remove the conditional if (config.openaiApiKey) / if (config.anthropicApiKey) / etc. guards in src/docker-manager.ts:1854-1940. Always point all provider base URLs at the sidecar:
OPENAI_BASE_URL=http://172.30.0.30:10000
ANTHROPIC_BASE_URL=http://172.30.0.30:10001
COPILOT_API_URL=http://172.30.0.30:10002
GEMINI_API_BASE_URL=http://172.30.0.30:10003
3. Allow all api-proxy ports in iptables
Ensure setup-iptables.sh allows agent→api-proxy traffic on all ports (10000–10004), not just ports for configured providers. Currently AWF_API_PROXY_IP is used — verify traffic to all ports on that IP is permitted.
4. Simplify healthcheck
With all ports always listening, the healthcheck can simply hit port 10000 /health without the expectedListeners counting logic.
Files to Change
| File |
Change |
containers/api-proxy/server.js |
Remove conditional listener startup; always bind all ports; return 503 for unconfigured providers |
src/docker-manager.ts:1854-1940 |
Remove if (config.*Key) guards; always set all *_BASE_URL vars |
containers/agent/setup-iptables.sh |
Verify all api-proxy ports are allowed (likely already covered by IP-based rule) |
src/types.ts |
No change needed (ports already defined) |
Benefits
- Model aliasing works across providers — resolver can route to any port
- Simpler startup logic — no conditional listener counting
- Future-proof — new providers/credentials can be added at runtime without restart
- Better error messages — 503 with explanation vs TCP connection refused
- Credential placeholder simplification — always set placeholders for all providers
Backward Compatibility
- Agent tools that check for
*_BASE_URL to detect provider availability may need updating if they use presence of the env var as a "provider is configured" signal
- Placeholder API keys should still be set for all providers to satisfy CLI credential validation
Problem
Currently, the api-proxy sidecar only starts listeners on ports where the corresponding API key is configured:
OPENAI_API_KEYis setANTHROPIC_API_KEYis setCOPILOT_GITHUB_TOKENorCOPILOT_API_KEYis setGEMINI_API_KEYis setAWF_ENABLE_OPENCODESimilarly, the AWF CLI only sets
*_BASE_URLenvironment variables in the agent container when the matching key is present (src/docker-manager.ts:1854-1940), and iptables rules may only allow traffic to ports that are actively configured.This creates problems:
apiProxy.modelsto alias a model name to a different provider's model, the target port may not be listening because that provider's key wasn't explicitly configured."fast"→claude-haiku-4.5but if onlyOPENAI_API_KEYwas provided, port 10001 isn't running.expectedListenersat line 1610).Proposal
1. Always start all port listeners in api-proxy
All five ports (10000–10004) should always be listening when
--enable-api-proxyis active:When a request arrives on a port without a configured credential, the proxy should return a clear error (e.g.,
503 Service Unavailablewith body{"error": "No API key configured for this provider"}) rather than refusing the TCP connection.2. Always set all
*_BASE_URLenv vars in agentRemove the conditional
if (config.openaiApiKey)/if (config.anthropicApiKey)/ etc. guards insrc/docker-manager.ts:1854-1940. Always point all provider base URLs at the sidecar:3. Allow all api-proxy ports in iptables
Ensure
setup-iptables.shallows agent→api-proxy traffic on all ports (10000–10004), not just ports for configured providers. CurrentlyAWF_API_PROXY_IPis used — verify traffic to all ports on that IP is permitted.4. Simplify healthcheck
With all ports always listening, the healthcheck can simply hit port 10000
/healthwithout theexpectedListenerscounting logic.Files to Change
containers/api-proxy/server.jssrc/docker-manager.ts:1854-1940if (config.*Key)guards; always set all*_BASE_URLvarscontainers/agent/setup-iptables.shsrc/types.tsBenefits
Backward Compatibility
*_BASE_URLto detect provider availability may need updating if they use presence of the env var as a "provider is configured" signal