Repository navigation
feat: add complete OpenCode Go support - #763
vcavichini wants to merge 3 commits into
Conversation
mycr0ft
left a comment
There was a problem hiding this comment.
I run opencode-go daily — the affinity design here is the right shape: catalog opt-in via compat, per-model transport metadata, and the api-key-without-OAuth fix for Anthropic-protocol Go models (unblocks the MiniMax/Qwen rows that currently error). The provider guide additions are honest about the usage/pricing limits Tau can't surface. A few concrete suggestions before this merges:
1. Unify the two affinity appliers before more formats appear. openai_compatible._apply_session_affinity_headers now understands openrouter/openai/opencode, while the new _apply_anthropic_session_affinity_headers understands only opencode. Two switches keyed by the same sessionAffinityFormat value will drift — the first new format added to one and not the other becomes a silent no-op on that transport. A single tau_ai-level helper (format → header mapping) called from both transports removes the failure mode.
2. Consider host-based detection for custom providers. The opt-in covers catalog providers, but a user-defined openai-compatible provider pointed at opencode.ai gets no affinity unless they know to set compat keys. Detecting the relay by hostname (as a fallback when no explicit affinity config exists) would cover that case without weakening the opt-in for unrelated gateways. I have a working implementation of this on my fork (opencode-affinity branch — provider-name prefix match plus opencode.ai host match, one merge point per transport) and am happy to extract it if useful.
3. Replace the opencode-go name check in provider_runtime with a compat field. if credential is None and provider.name != "opencode-go" hardcodes one provider into runtime logic. A catalog flag (e.g. anthropicAuth = "api-key", defaulting to current OAuth behavior) gives every key-based Anthropic-protocol gateway the same fix and keeps the config-driven philosophy from #241.
4. User-Agent scope. As written, tau/<version> is applied via _model_headers for opencode-go. Worth checking that the Responses-transport models (gpt-5.6-luna etc.) and the Anthropic-transport ones both end up sending it — the header takes a different path per transport. Longer-term, setting it as a default in create_async_client would make every request Tau emits self-identify (catalog refreshes, models.dev fetches), not just provider chat calls.
5. Question: should google/mistral transports learn sessionAffinityFormat too? Not needed for today's Go model list, but the config table in configuration.md currently implies the format is transport-independent while two transports ignore it.
Happy to test the branch against the relay (cache-warm behavior across turns is observable from here) if that's useful signal before merge.
Co-authored-by: vcavichini <vcavichini@users.noreply.github.com>
|
Thanks @mycr0ft for the detailed review! Pushed 8eddbe5:
For item 2, I'd be glad if you extract the host-based detection from your |
|
Confirmed against 8eddbe5: all three transports (completions, responses, Anthropic messages) now go through the single For the host-based detection follow-up: the shape that works is a fallback in the header builders — try explicit compat config first, then detect the relay by target (provider name starting One relay-behavior datapoint I will try to gather before merge from my Go setup: whether an |
|
@mycr0ft Thanks for confirming! A follow-up PR after this one merges sounds best, so this diff stays small. Looking forward to the relay result. |
OpenCode Go requires a stable
x-opencode-sessionheader, a client-specific User-Agent, and different API transports for different models. Tau previously sent every Go model through Chat Completions, which caused protocol errors for models such as Muse Spark 1.3.This PR:
tau/<version>User-Agent on all three documented Go transports; leaves OpenCode Zen and other providers unchanged.Validation:
uv run pytest tests/ -q(2,069 passed, 2 skipped), Ruff, and mypy. No live Go API request was made.The Go model list and plan details can change; protocol mapping follows the current OpenCode Go endpoint table.}