Repository navigation
Description
Summary
OpenCode Desktop's custom OpenAI-compatible provider form only collects a provider ID, name, base URL, API key, and a model ID plus display name. There is no way to set a model's context window or max output tokens, no reasoning/effort controls, and no way to fetch the endpoint's model list. Once #50650 (the form currently cannot submit at all) is fixed, a provider created this way would still describe its models with nothing but a display name.
Environment
- opencode version: Desktop 2.0.32 (bundled CLI 2.0.32)
- OS: Windows 11 Pro, Windows_NT 10.0.26300.0 x64
- Terminal: Unavailable: this is the Desktop (Electron) UI
- Shell: cmd.exe
- Install/channel: release, desktop auto-updater (
app-update.yml→ generic, channellatest) - Active plugins: none found in config
Reproduction
- Launch OpenCode Desktop 2.0.32.
- Open Settings → Providers and select the custom OpenAI-compatible provider entry.
- Inspect the form: it offers provider ID, name, base URL, API key, a list of models (ID + name only), and optional request headers.
- Look for a context-window field, a max-output-tokens field, a reasoning/effort control, or a "fetch models" action. None of them exist.
- (Optional) Submit. This currently always fails per desktop: custom provider save always throws "unavailable on this server" #50650, so the payload cannot be observed at runtime; the shape below is read from the shipped bundle instead.
Expected Behavior
A custom OpenAI-compatible provider form should be able to describe models the way the config file already can:
limit.contextandlimit.outputper model (context window and max output tokens).capabilities.reasoningplus reasoning effort selection, orvariantscarryingsettings.reasoningEffort.- Populate the model list automatically from
GET {baseURL}/models, instead of requiring every model ID to be typed by hand. - Write the V2 config shape (
package/settings), not the V1npm/optionsshape.
Actual Behavior
The form cannot express any of that. The models result is built with the display name only:
h = Object.fromEntries(form.models.map((m) => [m.id.trim(), { name: m.name.trim() }]))and the submitted config uses the V1 shape:
result: {
providerID,
name,
key,
config: {
npm: K,
name,
...(env ? { env: [env] } : {}),
options: { baseURL, ...(headers ? { headers } : {}) },
models: h,
},
}Consequences:
- Context window / max output tokens: no fields, and no
limitis written, so every custom model falls back to unknown/default limits. - Reasoning effort: no
capabilities.reasoning, novariants, no effort picker. A reasoning-capable gateway model is added as non-reasoning. - Auto-fetch: the component contains no
fetch(call and no reference to/models, so the model list can only be typed manually and can drift from the endpoint. - Wrong config shape:
npm/optionsare V1 keys. V2 readspackage/settings, so this payload is dropped even if the submit path is fixed (see Config: custom provider under "providers" is accepted but silently drops npm and options.baseURL (v2.0.32) #56816).
The translation keys back this up: the only provider.custom.* field keys are providerID, name, baseURL, apiKey, models.id, models.name, models.add, models.remove, and headers.*. There is no key for limits, reasoning, or discovery, so the gap is in the UI surface, not just the handler.
Additional Context
- The submit handler itself is a separate, already-tracked bug: desktop: custom provider save always throws "unavailable on this server" #50650 (also reported on 2.0.32 Windows). This issue is about the form's field coverage, which survives that fix.
- Related: Config: custom provider under "providers" is accepted but silently drops npm and options.baseURL (v2.0.32) #56816 (
npm/optionsaccepted but dropped in v2 config), [FEATURE]: Support explicit cost tiers for custom provider models #50713 (cost tiers for custom models), core: flatten reasoningEffort settings for custom OpenAI-compatible providers #48183 (reasoningEfforton custom providers), desktop: custom provider models missing from /models dialog #50726 (custom provider models missing from the desktop model picker). - Workaround that does work today: define the provider by hand in
~/.config/opencode/opencode.json, where limits, capabilities and variants are all available.
{
"$schema": "https://opencode.ai/config.json",
"providers": {
"myprovider": {
"name": "My Provider",
"package": "@opencode/ai/providers/openai-compatible",
"settings": { "baseURL": "https://api.example.com/v1", "apiKey": "{env:MYPROVIDER_API_KEY}" },
"models": {
"my-model": {
"name": "My Model",
"limit": { "context": 200000, "output": 64000 },
"capabilities": {
"tools": true,
"input": ["text", "image"],
"output": ["text"],
"reasoning": { "supported": true, "effort": ["low", "high", "max"] }
},
"variants": [
{ "id": "high", "settings": { "reasoningEffort": "high" } }
]
}
}
}
}
}- Suggestion: either widen the form to cover
limit,capabilities,variants, and model discovery, or keep the form minimal and point users at the config file instead of shipping a form that can only capture a fraction of a model's definition.
Activity
opencode-agent commentedon Oct 20, 2026
Thanks for the detailed write-up, @leoporoluo!
Your request: the Desktop custom OpenAI-compatible provider form should let you set each model's context window and max output tokens, set reasoning capability and effort (or variants), and fetch the model list from
GET {baseURL}/modelsinstead of typing every ID by hand. The form was built with only the fields it has now, so we're treating this as a feature request. Maintainers will consider it.The bugs you point out are tracked separately:
npm/optionskeys are accepted but dropped in v2 configRelated requests:
/connect)/modelsendpointreasoningEfforton custom OpenAI-compatible providersFor now, the workaround you described works: define the provider in
opencode.jsonwithlimit,capabilitiesandvariants.