Summary
V2 next (opencode2 v0.0.0-next-15363) fails to start a chat completion for any
custom openai-compatible provider that the equivalent V1 config can use. The
session hangs with no error and only emits after timeout, and the documented
aisdk:@ai-sdk/openai-compatible package path is the only working shape — but
settings.baseURL is silently ignored when the V1-style options.baseURL is
used, producing a request to undefined/chat/completions. A V1 provider block
that worked for the same OpenAI-compatible gateway is rejected by V2.
Environment
- opencode version: opencode2 v0.0.0-next-15363
- OS: Linux 7.0.10-arch1-1 (linux x64)
- Terminal: tmux (
TERM=tmux-256color, COLORTERM=truecolor)
- Shell: /usr/bin/bash
- Install/channel: next
- Active plugins:
~/.config/opencode/plugins/gk-hooks.js
Reproduction
-
Use this V1 config that works on V1 with an OpenAI-compatible gateway
exposing a custom acme/acme-m3 model:
-
Translate to the V2 shape per
https://v2.opencode.ai/providers.md#provider-packages:
-
Run any request:
opencode2 api post /api/generate \
--data '{"model":{"providerID":"acme","id":"acme-m3"},"prompt":"ping"}'
Expected Behavior
- Either the V1
provider / options shape is accepted and translated, or
V2 returns a clear migration error.
- The V2 config above sends the request to
https://gateway.example.com/v1/chat/completions and returns a normal
model response (the endpoint is reachable, GET /v1/models returns the
model catalog, and curl with the same Bearer token works).
Actual Behavior
-
First error reported by opencode2 api post /api/generate:
Unsupported package for acme/acme-m3: @opencode-ai/llm/providers/openai-compatible
The V2 docs say the native package is the recommended path, but the runtime
refuses it. Switching to aisdk:@ai-sdk/openai-compatible is required but
undocumented as the only working choice.
-
After switching to aisdk:@ai-sdk/openai-compatible, the request hangs and
the TUI never produces a response. A test against the same V2 build using
the openai-compatible V2 native package fails with a parse error:
"undefined/chat/completions" cannot be parsed as a URL.
settings.baseURL is being dropped, so the package sends to undefined.
-
Disabling reasoning via a none variant
(settings: { reasoningEffort: "none" }) makes it worse — the upstream
gateway rejects both reasoning_effort and thinking with
UnsupportedParamsError: openai does not support parameters: ['reasoning_effort', 'thinking'], because OpenCode V2 still sends them
even when the provider/model doesn't declare reasoning support.
Additional Context
- The same gateway endpoint responds fine to a direct
curl against
https://gateway.example.com/v1/chat/completions with the API key.
- V1 (
opencode-ai v0.x) ran this provider block end-to-end without hangs.
- Workarounds attempted in V2:
package: "@opencode-ai/llm/providers/openai-compatible" (native) →
rejected as "Unsupported package".
package: "aisdk:@ai-sdk/openai-compatible" + settings.baseURL →
hangs / sends to undefined depending on which field is present.
options.baseURL (V1 spelling) → ignored entirely.
- Adding a
none variant with reasoningEffort: none → upstream rejects
the unsupported parameters and returns 400.
- Likely root causes: (1) the V2 native
openai-compatible package
(@opencode-ai/llm/providers/openai-compatible) is documented but
unregistered / unsupported at runtime; (2) settings.baseURL is not
forwarded to the aisdk:@ai-sdk/openai-compatible provider, and the
error surface for missing config is a silent hang or a confusing
"undefined/chat/completions" parse error instead of a clear validation
message; (3) reasoning-related fields are not stripped or detected
per-provider.
- A real
opencode.json (with the key redacted) is sufficient to reproduce
using any OpenAI-compatible gateway and a custom model name.
Summary
V2 next (
opencode2 v0.0.0-next-15363) fails to start a chat completion for anycustom openai-compatible provider that the equivalent V1 config can use. The
session hangs with no error and only emits after timeout, and the documented
aisdk:@ai-sdk/openai-compatiblepackage path is the only working shape — butsettings.baseURLis silently ignored when the V1-styleoptions.baseURLisused, producing a request to
undefined/chat/completions. A V1 provider blockthat worked for the same OpenAI-compatible gateway is rejected by V2.
Environment
TERM=tmux-256color,COLORTERM=truecolor)~/.config/opencode/plugins/gk-hooks.jsReproduction
Use this V1 config that works on V1 with an OpenAI-compatible gateway
exposing a custom
acme/acme-m3model:{ "$schema": "https://opencode.ai/config.json", "provider": { "acme": { "npm": "@ai-sdk/openai-compatible", "name": "Acme Gateway", "options": { "baseURL": "https://gateway.example.com/v1" }, "models": { "acme-m3": { "name": "Acme M3" } } } } }Translate to the V2 shape per
https://v2.opencode.ai/providers.md#provider-packages:{ "$schema": "https://opencode.ai/config.json", "providers": { "acme": { "name": "Acme Gateway", "env": ["ACME_API_KEY"], "package": "aisdk:@ai-sdk/openai-compatible", "settings": { "baseURL": "https://gateway.example.com/v1" }, "models": { "acme-m3": { "name": "Acme M3", "capabilities": { "tools": true, "input": ["text"], "output": ["text"] }, "limit": { "context": 200000, "output": 32000 } } } } } }Run any request:
opencode2 api post /api/generate \ --data '{"model":{"providerID":"acme","id":"acme-m3"},"prompt":"ping"}'Expected Behavior
provider/optionsshape is accepted and translated, orV2 returns a clear migration error.
https://gateway.example.com/v1/chat/completionsand returns a normalmodel response (the endpoint is reachable,
GET /v1/modelsreturns themodel catalog, and
curlwith the same Bearer token works).Actual Behavior
First error reported by
opencode2 api post /api/generate:The V2 docs say the native package is the recommended path, but the runtime
refuses it. Switching to
aisdk:@ai-sdk/openai-compatibleis required butundocumented as the only working choice.
After switching to
aisdk:@ai-sdk/openai-compatible, the request hangs andthe TUI never produces a response. A test against the same V2 build using
the
openai-compatibleV2 native package fails with a parse error:settings.baseURLis being dropped, so the package sends toundefined.Disabling reasoning via a
nonevariant(
settings: { reasoningEffort: "none" }) makes it worse — the upstreamgateway rejects both
reasoning_effortandthinkingwithUnsupportedParamsError: openai does not support parameters: ['reasoning_effort', 'thinking'], because OpenCode V2 still sends themeven when the provider/model doesn't declare reasoning support.
Additional Context
curlagainsthttps://gateway.example.com/v1/chat/completionswith the API key.opencode-aiv0.x) ran this provider block end-to-end without hangs.package: "@opencode-ai/llm/providers/openai-compatible"(native) →rejected as "Unsupported package".
package: "aisdk:@ai-sdk/openai-compatible"+settings.baseURL→hangs / sends to
undefineddepending on which field is present.options.baseURL(V1 spelling) → ignored entirely.nonevariant withreasoningEffort: none→ upstream rejectsthe unsupported parameters and returns 400.
openai-compatiblepackage(
@opencode-ai/llm/providers/openai-compatible) is documented butunregistered / unsupported at runtime; (2)
settings.baseURLis notforwarded to the
aisdk:@ai-sdk/openai-compatibleprovider, and theerror surface for missing config is a silent hang or a confusing
"undefined/chat/completions" parse error instead of a clear validation
message; (3) reasoning-related fields are not stripped or detected
per-provider.
opencode.json(with the key redacted) is sufficient to reproduceusing any OpenAI-compatible gateway and a custom model name.