OpenCode
Add XField to OpenCode as an OpenAI-compatible provider, declare the models and their limits, and pick one with /models.
OpenCode can use any OpenAI-compatible API through a custom provider. You declare XField once in opencode.json, list the models you want with their limits, and they show up in the model picker next to everything else.
You need OpenCode installed and an API key from Settings › API keys. No key yet? Request access.
Setup
- Export your key
export XFIELD_API_KEY="sk-xf-v1-..."Put it in your shell profile. OpenCode reads it when it starts.
- Add the provider
Use
~/.config/opencode/opencode.jsonfor every project, oropencode.jsonin a project root for just that one.opencode.json { "$schema": "https://opencode.ai/config.json", "provider": { "field": { "npm": "@ai-sdk/openai-compatible", "name": "XField", "options": { "baseURL": "https://xfield.cloud.brutal.ai/api/v1", "apiKey": "{env:XFIELD_API_KEY}" }, "models": { "deepseek-v4.1-flash-1017-uncensored": { "name": "DeepSeek V4.1 Flash", "limit": { "context": 1000000, "output": 65536 } }, "glm-5.3-uncensored": { "name": "GLM 5.3", "limit": { "context": 1000000, "output": 131072 } }, "glm-5.3-flash-uncensored": { "name": "GLM 5.3 Flash", "limit": { "context": 1000000, "output": 32768 } }, "qwen-3.8-27b-uncensored": { "name": "Qwen 3.8 27B", "limit": { "context": 131072, "output": 32768 } } } } }, "model": "field/deepseek-v4.1-flash-1017-uncensored", "small_model": "field/glm-5.3-flash-uncensored" } - Start OpenCode
opencodeSend a prompt. If you get a 401, the key variable was empty when OpenCode started:
{env:...}resolves to an empty string when the variable is unset.
What the config does
provider.fieldis the provider id. Model references use it as a prefix:field/<model-id>.npmtells OpenCode to talk to the provider with the AI SDK's OpenAI-compatible client, which callshttps://xfield.cloud.brutal.ai/api/v1/chat/completions.apiKeyuses OpenCode's{env:NAME}substitution, so the key never sits in the file.modelskeys must match our model ids exactly.nameis only the label in the picker.limit.contextandlimit.outputtell OpenCode how much room is left and when to compact. Without them it guesses.modelis the default;small_modelhandles light work such as session titles, so it should be the cheap one.
Choosing a model
Run /models inside OpenCode and pick from the XField section. The choice applies to the current session.
| Job | Model |
|---|---|
| Coding agent, long runs | deepseek-v4.1-flash-1017-uncensored |
| Hard reasoning, security research | glm-5.3-uncensored |
| Batch edits, cheap background work | glm-5.3-flash-uncensored |
| Quick chat, screenshots as input | qwen-3.8-27b-uncensored |
See models for the current list and limits.
Reasoning effort
OpenCode passes per-model options to the provider. reasoningEffort becomes reasoning_effort on the request, which XField maps to each model's levels:
"glm-5.3-uncensored": {
"name": "GLM 5.3",
"limit": { "context": 1000000, "output": 131072 },
"options": { "reasoningEffort": "high" },
"variants": {
"max": { "reasoningEffort": "max" }
}
}Variants let you cycle effort from the keyboard without editing the file. DeepSeek V4.1 Flash already thinks at high effort with no options set. Qwen has thinking off by default.
Tips
- Keep
AGENTS.mdand your tool set stable during a session. Prompt caching is automatic and works best on an unchanging prefix. - Project config overrides global config, so a repo can pin a different default model without touching your global file.
- Reasoning text streams back with each turn; OpenCode shows it when the model sends it.