Compare commits
5 Commits
5675c5e75a
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 520943689a | |||
| 5b240e8d95 | |||
|
|
1f357fe2e3 | ||
|
|
4425dcfd41 | ||
|
|
539d2eb4d6 |
134
README.md
134
README.md
@@ -1,39 +1,135 @@
|
|||||||
# app-opencode-experiment
|
# app-opencode
|
||||||
|
|
||||||
[opencode](https://opencode.ai/) in a Docker container, wired to [weave](https://weave.redpencil.io) as the model provider. Default model `weave/glm-5.2`. LSP baked in for TypeScript/JS and Python.
|
[opencode](https://opencode.ai/) packaged in a Docker container and wired to
|
||||||
|
[weave](https://weave.redpencil.io) as the model provider. It ships with an
|
||||||
|
LSP for TypeScript/JavaScript and Python baked in, so opencode gets real
|
||||||
|
type-aware navigation out of the box. The default model is `weave/glm-5.2`.
|
||||||
|
|
||||||
## Setup
|
The docs below are split into three parts: a **Getting started** walkthrough to
|
||||||
|
run it the first time, **How-to guides** for specific tasks, and a **Reference**
|
||||||
|
for the moving parts.
|
||||||
|
|
||||||
Create a `docker-compose.override.yml` (gitignored) with your weave key and repo mount:
|
## Getting started
|
||||||
|
|
||||||
```yaml
|
A first run from a clean checkout.
|
||||||
services:
|
|
||||||
|
1. **Get a weave API key.** You need an account on
|
||||||
|
[weave.redpencil.io](https://weave.redpencil.io/ui/) and/or an API key (ask us!).
|
||||||
|
|
||||||
|
2. **Create your local override.** `docker-compose.override.yml` is gitignored
|
||||||
|
and holds your key plus the repo you want opencode to work on. Create it with
|
||||||
|
your key and mount:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
opencode:
|
opencode:
|
||||||
environment:
|
environment:
|
||||||
WEAVE_API_KEY: "..."
|
WEAVE_API_KEY: "your-key-here"
|
||||||
volumes:
|
volumes:
|
||||||
- /path/to/your/repo:/workspace/repo
|
- /path/to/your/repo:/workspace/repo
|
||||||
```
|
```
|
||||||
|
|
||||||
Then:
|
3. **Start the container.**
|
||||||
|
|
||||||
```
|
```
|
||||||
drc up -d
|
drc up -d
|
||||||
drc exec opencode opencode
|
```
|
||||||
```
|
|
||||||
|
|
||||||
## TUI
|
4. **Open the TUI.**
|
||||||
|
|
||||||
In the TUI, type `/models` to select a model from the registered weave models.
|
```
|
||||||
|
drc exec opencode opencode
|
||||||
|
```
|
||||||
|
|
||||||
## Updating the config
|
You're now in opencode, talking to `weave/glm-5.2`. Type `/models` to switch
|
||||||
|
models, or just start prompting.
|
||||||
|
|
||||||
`opencode.json` is mounted into the container. After editing:
|
## How-to guides
|
||||||
|
|
||||||
|
### Switch the model in a session
|
||||||
|
|
||||||
|
In the TUI, type `/models` and pick from the registered weave models. This only
|
||||||
|
changes the current session; to change the default for every session, edit
|
||||||
|
`opencode.json` (see below).
|
||||||
|
|
||||||
|
### Change the default model
|
||||||
|
|
||||||
|
Edit `model` (and optionally `small_model`) in
|
||||||
|
[`config/opencode/opencode.json`](config/opencode/opencode.json), then apply the
|
||||||
|
change:
|
||||||
|
|
||||||
```
|
```
|
||||||
drc restart opencode
|
drc restart opencode
|
||||||
```
|
```
|
||||||
|
|
||||||
## Caveats
|
`opencode.json` is mounted into the container, so a restart is all that's
|
||||||
|
needed.
|
||||||
|
|
||||||
- Copy from the TUI is weird over Docker: To copy text out of the opencode TUI running in a container, I have to do `Shift`+click to select the text, then `Ctrl`+`Shift`+`C` to copy. Plain `COPY` doesn't work.
|
### Register a new weave model
|
||||||
|
|
||||||
|
Add the model under `provider.weave.models` in `opencode.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"provider": {
|
||||||
|
"weave": {
|
||||||
|
"models": {
|
||||||
|
"my-new-model": { "tools": true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then `drc restart opencode`. It will show up in the `/models` picker.
|
||||||
|
See the [model list on weave](https://weave.redpencil.io/ui/models-and-endpoints/) for an overview of available models. Need another model, please let us know :)
|
||||||
|
|
||||||
|
### Copy text out of the TUI
|
||||||
|
|
||||||
|
Copying from the opencode TUI over Docker is fiddly: `Shift`+click to select the
|
||||||
|
text, then `Ctrl`+`Shift`+`C` to copy. A plain copy doesn't work.
|
||||||
|
|
||||||
|
### Connect opencode to a (backend) service
|
||||||
|
|
||||||
|
To let opencode call a service over HTTP, e.g. a stack you've brought up in dev
|
||||||
|
mode and want the agent to follow up against, have that stack join opencode's
|
||||||
|
network instead of publishing ports or going via the host.
|
||||||
|
|
||||||
|
opencode's stack creates a default network named `app-opencode_default`. Attach the
|
||||||
|
dev-mode service to it as an external network:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# the dev-mode app stack
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- app-opencode_default
|
||||||
|
|
||||||
|
networks:
|
||||||
|
app-opencode_default:
|
||||||
|
external: true
|
||||||
|
```
|
||||||
|
|
||||||
|
opencode can then reach it at `http://app:<port>`, where `app` is the **service
|
||||||
|
name** from that stack's compose and `<port>` is the container's *internal* port.
|
||||||
|
|
||||||
|
> Note: Bring the opencode stack up first, so `app-opencode_default` exists before adding to your app.
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
### `opencode.json` keys
|
||||||
|
|
||||||
|
- **`model` / `small_model`** — default model and the model used for lighter
|
||||||
|
tasks. Both default to `weave/glm-5.2`.
|
||||||
|
- **`provider.weave`** — the weave provider, using the
|
||||||
|
`@ai-sdk/openai-compatible` adapter against `https://weave.redpencil.io/v1`
|
||||||
|
with the key from `WEAVE_API_KEY`.
|
||||||
|
- **`provider.weave.models`** — the models offered in `/models`.
|
||||||
|
- **`lsp`** — language servers baked into the image:
|
||||||
|
`typescript-language-server` for TS/JS and `pyright` for Python.
|
||||||
|
- **`permission`** — set to `ask` for read, edit, bash, and external-directory
|
||||||
|
actions, so opencode prompts before acting.
|
||||||
|
|
||||||
|
### Caveats
|
||||||
|
|
||||||
|
- Copy from the TUI over Docker needs the `Shift`+click / `Ctrl`+`Shift`+`C`
|
||||||
|
dance described above.
|
||||||
|
|||||||
@@ -38,109 +38,22 @@
|
|||||||
"apiKey": "{env:WEAVE_API_KEY}"
|
"apiKey": "{env:WEAVE_API_KEY}"
|
||||||
},
|
},
|
||||||
"models": {
|
"models": {
|
||||||
"claude-sonnet": {
|
"kimi-K2.7-code": {
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"claude-opus": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"claude-haiku": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"Mistral-Small-3.2-24B-Instruct-2506": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"phi-4": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"gemini-3.5-flash": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"gemini-3.1-pro": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"qwen3.6-35B-A3B": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"qwen3-coder-480B-A35B-Instruct": {
|
|
||||||
"tools": true
|
"tools": true
|
||||||
},
|
},
|
||||||
"glm-5.2": {
|
"glm-5.2": {
|
||||||
"tools": true
|
"tools": true
|
||||||
},
|
},
|
||||||
"scaleway-glm-5.2": {
|
"devstral": {
|
||||||
"tools": true,
|
|
||||||
"options": {
|
|
||||||
"max_tokens": 16384
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"kimi-K2.7-code": {
|
|
||||||
"tools": true
|
"tools": true
|
||||||
},
|
},
|
||||||
"MiniMax-M2.7": {
|
"local-qwen3.6:27b": {
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"DeepSeek-V4-Flash": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"DeepSeek-V4-Pro": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"nemotron-3-ultra": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"mimo-v2.5-pro": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"qwen3-max-thinking": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"gpt-oss-120b": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"mistral-large": {
|
|
||||||
"tools": true
|
"tools": true
|
||||||
},
|
},
|
||||||
"mistral-medium": {
|
"mistral-medium": {
|
||||||
"tools": true
|
"tools": true
|
||||||
},
|
},
|
||||||
"mistral-small": {
|
"claude-sonnet": {
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"magistral-medium": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"magistral-small": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"codestral": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"devstral": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"mistral-embed": {
|
|
||||||
"tools": false
|
|
||||||
},
|
|
||||||
"mistral-ocr": {
|
|
||||||
"tools": false
|
|
||||||
},
|
|
||||||
"ministral-14b": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"ministral-8b": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"ministral-3b": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"local-gemma3:27b-it-qat": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"local-gpt-oss:20b": {
|
|
||||||
"tools": true
|
|
||||||
},
|
|
||||||
"local-qwen3.6:27b": {
|
|
||||||
"tools": true
|
"tools": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
version: '3.7'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
opencode:
|
opencode:
|
||||||
image: redpencil/opencode:0.0.1
|
image: redpencil/opencode:0.0.1
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/opencode/share:/root/.local/share/opencode
|
- ./data/opencode/share:/root/.local/share/opencode
|
||||||
- ./config/opencode/opencode.json:/root/.config/opencode/opencode.json
|
- ./config/opencode/opencode.json:/root/.config/opencode/opencode.json
|
||||||
|
|||||||
Reference in New Issue
Block a user