Add OpenCode Go provider - #54
Conversation
1071d2f to
8ba593c
Compare
8ba593c to
b283b25
Compare
|
Thanks! Review found the points below. Could you please check whether they are valid, especially against the live OpenCode Go stream shapes you observed? https://gist.github.com/raine/10bb94843909186b8ef670989c827981 |
|
Thanks — I verified all three findings against the PR head. 1. Tool call followed by text/reasoningConfirmed and fixed in The reducer used one The tool lifecycle is now explicit: Regression coverage now includes:
The original mock reproduced HTTP 502 before the fix. With the same upstream sequence, buffered and streaming HTTP routes now return 200. The streaming order is: I also checked the available live captures: 330 upstream SSE bodies in total, 154 with non-empty tool-call arrays across 10 models, and none contained non-empty text or reasoning after the first tool delta. So this was a reachable state-machine bug, but that ordering was not observed in the current live matrix. 2. OpenAI ingress loses
|
Add OpenCode Go provider
Closes #46.
Summary
opencode-go/<model-id>form for every model and bare IDs where they do not collide with an existing provider./v1/messagesand the opt-in/v1/chat/completionsand/v1/responsesroutes.tool_resultblocks when translating to OpenAI-compatible Chat Completions.Agent_0.Routing and authentication
The implementation registers the 18 mappings in OpenCode Go's published endpoint table instead of guessing a protocol from
/modelsor using models.dev.Authorization: Bearer ...grok-4.5,glm-5.2,glm-5.1,kimi-k3,kimi-k2.7-code,kimi-k2.6,deepseek-v4-pro,deepseek-v4-flash,mimo-v2.5,mimo-v2.5-pro,hy3Authorization: Bearer ...gpt-5.6-lunax-api-key+anthropic-versionminimax-m3,minimax-m2.7,minimax-m2.5,qwen3.7-max,qwen3.7-plus,qwen3.6-plusThe API key is resolved in this order:
CCP_OPENCODE_API_KEYOPENCODE_API_KEYopencode.apiKeyinconfig.jsonCCP_OPENCODE_BASE_URLoropencode.baseUrlcan override the defaulthttps://opencode.ai/zen/go/v1base URL.Bare IDs already owned by Codex, Grok, or Kimi keep their existing routing. For example,
kimi-k2.6remains a Kimi model whileopencode-go/kimi-k2.6selects OpenCode Go. The same rule applies togpt-5.6-luna,grok-4.5, andkimi-k3.Protocol handling
reasoning_content; DeepSeek assistant turns include the field even when it is empty, matching OpenCode's own transform.tool_choiceanddisable_parallel_tool_usemap totool_choiceandparallel_tool_callswithout changing other providers.tool_resultare converted toimage_urlparts. All matchingrole: toolmessages are emitted first, followed by onerole: uservision message, matching OpenCode's OpenAI-compatible adapter.Agent_0.429keepsRetry-After./v1/messages/count_tokensremains a local heuristic and does not send a request to OpenCode Go.The catalog is intentionally static. OpenCode's live
/modelsendpoint can expose IDs before the documentation assigns a wire protocol; those IDs remain unroutable until an endpoint mapping is published.Verification
cargo fmt --all -- --checkcargo clippy --offline --all-targets -- -D warningscargo test --offline --all-targets: 860 passed, 0 failedtool_use, accepted the matchingtool_result, and completed normally2.1.218completed both a subagent run and a one-agent Workflow throughopencode-go/glm-5.2Read,Read(image), andBashin parallel; upstream receivedassistant,tool,tool,tool,user(image_url)and returned HTTP 200 withPARALLEL_IMAGE_OK:circle:blue:7NESTED_OKdeepseek-v4-flashreached OpenCode and returned its account-level HTTP 403 requiring explicit China-hosting opt-inReferences