docs(opencode): document v2 config, mark v1 deprecated

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
haylanandClaude Bot committed 2026-10-05 21:32:58 +02:00
1 parent 17747694bd
commit d9fc3418a1
1 file changed
+109 -33
+109 -33
View File
@@ -2,18 +2,114 @@
[← back to overview](index.md) [← back to overview](index.md)
> **Source of truth:** [OpenCode's docs](https://opencode.ai/docs/) for config keys; the [overview](index.md) for the gateway endpoint and context size. If this page disagrees with them, they win. > **Source of truth:** [OpenCode v2 docs](https://opencode.ai/v2/docs) for config keys; the [overview](index.md) for the gateway endpoint and context size. If this page disagrees with them, they win. The v1 config is [deprecated](#v1-config-deprecated) but kept for installs that haven't migrated.
Confirmed project: **`anomalyco/opencode`** (renamed from `sst/opencode` — don't confuse with the unrelated `opencode-ai/opencode` Go TUI). Docs: https://opencode.ai/docs/ OpenCode is **`anomalyco/opencode`** (renamed from `sst/opencode`). Don't confuse it with the unrelated `opencode-ai/opencode` Go TUI. It speaks plain **OpenAI Chat Completions**, so it talks to the gateway like any other OpenAI-compatible client.
## Install
**Install**:
```bash ```bash
curl -fsSL https://opencode.ai/install | bash curl -fsSL https://opencode.ai/v2/install | bash
``` ```
**Config** (`opencode.json`, project root or `~/.config/opencode/opencode.json`): Homebrew, npm, bun, pnpm, yarn and AUR also work. See the [v2 docs](https://opencode.ai/v2/docs).
```json ## Config (v2)
`opencode.json` or `opencode.jsonc`, in the project root (or `.opencode/`) or globally at `~/.config/opencode/opencode.json`. OpenCode searches upward from the current directory and merges, closest file wins.
```jsonc
{
"$schema": "https://opencode.ai/config.json",
"providers": {
"omniroute": {
"name": "OmniRoute",
"package": "aisdk:@ai-sdk/openai-compatible",
"settings": {
"baseURL": "https://<YOUR-OMNIROUTE-PROXY>/v1",
"apiKey": "<token>"
},
"models": {
"qwen3.8-27b": {
"modelID": "qwen3.8-27b-local//models/Qwen3.8-27B-UD-Q4_K_XL.gguf",
"name": "Qwen3.8-27B",
"capabilities": { "tools": true, "input": ["text"], "output": ["text"] },
"compatibility": { "reasoningField": "reasoning_content" },
"limit": { "context": 260000, "output": 32000 },
"cost": { "input": 0.4, "output": 3 },
"body": {
"temperature": 1,
"top_p": 0.95,
"top_k": 20,
"min_p": 0,
"presence_penalty": 0,
"chat_template_kwargs": { "reasoning_effort": "xhigh" }
},
"variants": [
{ "id": "medium", "body": { "chat_template_kwargs": { "reasoning_effort": "medium" } } },
{ "id": "fast", "body": { "chat_template_kwargs": { "reasoning_effort": "low" } } },
{
"id": "instruct",
"body": {
"temperature": 0.7,
"top_p": 0.8,
"presence_penalty": 1.5,
"chat_template_kwargs": { "enable_thinking": false }
}
}
]
}
}
}
}
}
```
### What each part does
| Key | Purpose |
|---|---|
| `providers` | Plural in v2 (v1: `provider`). The key (`omniroute`) is the prefix in model references. |
| `package` | The adapter for the API shape. This stack uses an OpenAI-compatible one. |
| `settings.baseURL` | The gateway URL, up to and including `/v1`. |
| `settings.apiKey` | The gateway API key issued to OpenCode ([gateway → API keys](../gateway.md#api-keys)). The v2 docs' own examples use an `env` list instead, to keep the key out of the file. |
| `models.<key>` | The short name you select. `modelID` is the id the gateway exposes, which the key doesn't have to match. |
| `capabilities` | Declares tool calling and input/output modalities. |
| `compatibility.reasoningField` | Where the backend returns reasoning text. llama.cpp uses `reasoning_content`. |
| `limit` | OpenCode's own context bookkeeping. The server doesn't read it. See [overview](index.md) for the number to use. |
| `body` | Extra request fields, sent on every call. Sampling values and `chat_template_kwargs` go here. |
| `variants` | Named overrides on top of `body`. |
### Selecting a model and variant
Format: `provider/model#variant`. The provider ends at the first `/`.
```bash
opencode run --model omniroute/qwen3.8-27b # default: xhigh reasoning
opencode run --model omniroute/qwen3.8-27b#medium
opencode run --model omniroute/qwen3.8-27b#fast # low reasoning effort
opencode run --model omniroute/qwen3.8-27b#instruct # thinking off, instruct sampling
```
### Notes
- **Unverified keys:** the v2 docs show `"package": "@opencode/ai/providers/openai-compatible"` for custom providers, while this config uses the `aisdk:@ai-sdk/openai-compatible` form. The docs pages I could read don't confirm that prefix. If OpenCode rejects the provider, switch `package` to the documented value.
- **Variants:** the v2 docs' own variant example puts settings under `settings`. This config uses `body`, which the models page lists as valid for provider-specific request fields.
- **`limit.context`:** [overview](index.md) explains how per-slot context is derived. The example above uses a larger value than a plain per-slot division gives.
## OpenCode-specific risks
On top of the shared Qwen3.8-27B tool-calling risk (see [overview](index.md)):
- Relies on the backend's `--jinja` flag ([architecture → llama-server](../architecture.md#llama-server)). Without it, OpenCode's unconditional tool-call scaffolding gets a 500.
- [anomalyco/opencode#20669](https://github.com/anomalyco/opencode/issues/20669) (closed as "not planned", so a live, unfixed risk): OpenCode's `bash` tool crashes if the model omits the optional `description` field on a tool call. Some local backends return `finish_reason: tool_calls` with an empty array, which can hang the agent loop instead of stopping it.
- Reasoning control goes through `chat_template_kwargs` in `body`, not OpenCode's native `reasoningEffort`. The native key has no effect against llama.cpp.
## V1 config (deprecated)
Use this only on OpenCode v1. It is no longer maintained here. Differences from v2: `provider` (singular), `npm` instead of `package`, `options` instead of `settings`, and a flat `reasoning` / `interleaved` block instead of `capabilities` / `compatibility`, and no `variants` or `body` in this config.
```jsonc
{ {
"$schema": "https://opencode.ai/config.json", "$schema": "https://opencode.ai/config.json",
"model": "omniroute/qwen3.8-27b-local//models/Qwen3.8-27B-UD-Q4_K_XL.gguf", "model": "omniroute/qwen3.8-27b-local//models/Qwen3.8-27B-UD-Q4_K_XL.gguf",
@@ -21,43 +117,23 @@ curl -fsSL https://opencode.ai/install | bash
"omniroute": { "omniroute": {
"npm": "@ai-sdk/openai-compatible", "npm": "@ai-sdk/openai-compatible",
"name": "OmniRoute", "name": "OmniRoute",
"options": { "options": { "baseURL": "https://<YOUR-OMNIROUTE-PROXY>/v1" },
"baseURL": "https://<YOUR-OMNIROUTE-PROXY>/v1"
},
"models": { "models": {
"qwen3.8-27b-local//models/Qwen3.8-27B-UD-Q4_K_XL.gguf": { "qwen3.8-27b-local//models/Qwen3.8-27B-UD-Q4_K_XL.gguf": {
"name": "Qwen3.8-27B", "name": "Qwen3.8-27B",
"reasoning": true, "reasoning": true,
"interleaved": { "interleaved": { "field": "reasoning_content" },
"field": "reasoning_content" "limit": { "context": 131000, "output": 65536 },
}, "cost": { "input": 0.4, "output": 3.0, "cache": { "read": 0.04, "write": 0 } }
"limit": {
"context": 131000,
"output": 65536
},
"cost": {
"input": 0.4,
"output": 3.0,
"cache": {
"read": 0.04,
"write": 0
} }
} }
} }
} }
} }
}
}
``` ```
`limit.context` is the per-slot context ([overview](index.md)). OpenCode uses it for its own context bookkeeping; the server doesn't read it. Select the model with `omniroute/<model-key>`. The v1 install script is `curl -fsSL https://opencode.ai/install | bash`.
Select the model with `llm-server/qwen3.8-27b-local`. ## Further reading
**OpenCode-specific risks** (on top of the shared Qwen3.8-27B tool-calling risk — see [overview](index.md)): [`research/opencode-cli-setup.md`](../research/opencode-cli-setup.md) (v1-era, base URL predates the gateway), [`research/opencode-auto-compact.md`](../research/opencode-auto-compact.md).
- Relies on the backend's `--jinja` flag ([architecture → llama-server](../architecture.md#llama-server)); without it, OpenCode's unconditional tool-call scaffolding gets a 500.
- [anomalyco/opencode#20669](https://github.com/anomalyco/opencode/issues/20669) (closed as "not planned" — a live, unfixed risk): OpenCode's `bash` tool crashes if the model omits the optional `description` field on a tool call; some local backends return `finish_reason: tool_calls` with an empty array, which can hang the agent loop instead of stopping cleanly.
- Thinking-mode handling (`options.reasoningEffort`) is undocumented for models that emit inline `<think>` tags rather than a native reasoning API field — expect no effect from that config on this model; untested.
Further reading: [`research/opencode-cli-setup.md`](../research/opencode-cli-setup.md) (its base URL example predates the gateway), [`research/opencode-auto-compact.md`](../research/opencode-auto-compact.md).