12 Commits

Author SHA1 Message Date
218dc1d0d1 update readme to reflect new config system 2026-10-22 10:09:29 +02:00
9246decc9f move permissions config to new v2 format 2026-10-21 10:09:46 +02:00
1ce6cea6c9 convert provider config to new v2 providers config 2026-10-20 15:13:02 +02:00
5b7c1f98bd use agents.title.model instead of small_model 2026-10-20 14:59:41 +02:00
5bd2eb398e config(opencode): drop lsp configuration 2026-10-20 14:58:22 +02:00
3e373104e7 update opencode image to feature-opencode-v2 tag 2026-10-20 14:57:30 +02:00
b98130e648 bump opencode container to 0.0.2
provides more tools in the base image
2026-10-07 07:32:31 +00:00
581e5ed5ac make glm-5.3-flash the default 2026-10-06 11:11:01 +00:00
ca7eaf3776 update model config
- made glm-5.3 the default
- added glm-5.3-flash as the small default
- replaced glm-5.2 with mistral glm-5.2
- dropped sonnet
2026-09-08 11:46:44 +02:00
4b430129e6 Revert "run opencode in "interactive shell" mode"
This reverts commit 520943689a.
2026-09-08 11:36:54 +02:00
520943689a run opencode in "interactive shell" mode
this should resolve any clipboard issues with copying and pasting text
2026-07-07 12:05:59 +00:00
5b240e8d95 improve readme readability and add some tutorials 2026-07-06 12:55:36 +02:00
3 changed files with 80 additions and 103 deletions

View File

@@ -9,10 +9,6 @@ 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.
> `drc` in the examples is shorthand for `docker compose`
> (`alias drc='docker compose'`). Substitute `docker compose` if you don't have
> the alias.
## Getting started
A first run from a clean checkout.
@@ -58,7 +54,7 @@ changes the current session; to change the default for every session, edit
### Change the default model
Edit `model` (and optionally `small_model`) in
Edit `model` (and optionally `agents.title.model`) in
[`config/opencode/opencode.json`](config/opencode/opencode.json), then apply the
change:
@@ -71,13 +67,17 @@ needed.
### Register a new weave model
Add the model under `provider.weave.models` in `opencode.json`:
Add the model under `providers.weave.models` in `opencode.json`:
```json
"provider": {
"weave": {
"models": {
"my-new-model": { "tools": true }
"my-new-model": {
"capabilities" {
"tools": true
}
}
}
}
}
@@ -114,39 +114,25 @@ networks:
```
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 —
no `ports:` publishing needed.
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.
### Executing docker commands from opencode
The stack runs a dedicated dind (docker in docker) container, and opencode can drive it as a client (`DOCKER_HOST=tcp://dind:2375`). So from inside opencode you can build images, run containers, and `docker compose up` a project's stack. The agent can spin up and test the services it's working on.
A few things that differ from a normal host, because the daemon lives in dind:
- Containers and published ports you start run on the **dind** daemon. Reach a running service at `dind:<port>`, **not** `localhost:<port>`. opencode does not
share dind's network namespace, so `localhost` won't reach the stack.
- The repo needs to be mounted at the same absolute path (`/workspace/repo`) in both the opencode and dind containers, so compose bind-mounts resolve correctly. Work on the checkout there; edits elsewhere won't be visible to the containers dind runs.
- The dind image store is cached in `./data/dind-cache`, so pulled images stay warm across restarts.
- To access the services from the host machine, you will need to connect to the dind container or publish the necessary ports from the dind container to your host.
> Note: Opencode itself doesn't run in a privileged container so it can't do privileged actions directly, but it can use the docker daemon in dind to do the same things. Because dind is privileged and in the host user namespace, a container started inside dind can mount the host's raw disk devices and reach the **entire** host filesystem, not only what you shared. This needs opencode to actively do it, but it's a well-known technique, not a theoretical edge case.
> 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`
- **`model`** — default model.
- **`agents.title.model`** — model used to generate session titles (replaces deprecated `small_model`)
- **`providers.weave`** — the weave provider, using the
`@opencode/ai/providers/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
- **`providers.weave.models`** — the models offered in `/models`.
- **`permissions`** — set to `ask` for read, edit, bash, and external-directory
actions, so opencode prompts before acting.
Check-out https://opencode.ai/v2/docs/config/ for more options.
### Caveats
- Copy from the TUI over Docker needs the `Shift`+click / `Ctrl`+`Shift`+`C`

View File

@@ -1,68 +1,83 @@
{
"$schema": "https://opencode.ai/config.json",
"model": "weave/glm-5.2",
"small_model": "weave/glm-5.2",
"lsp": {
"typescript": {
"command": [
"typescript-language-server",
"--stdio"
],
"extensions": [
".ts",
".tsx",
".js",
".jsx",
".mjs",
".cjs",
".mts",
".cts"
]
},
"pyright": {
"command": [
"pyright-langserver",
"--stdio"
],
"extensions": [
".py",
".pyi"
]
"model": "weave/glm-5.3-flash",
"agents": {
"title": {
"model": "weave/glm-5.3-flash"
}
},
"provider": {
"providers": {
"weave": {
"npm": "@ai-sdk/openai-compatible",
"options": {
"package": "@opencode/ai/providers/openai-compatible",
"settings": {
"baseURL": "https://weave.redpencil.io/v1",
"apiKey": "{env:WEAVE_API_KEY}"
},
"models": {
"kimi-K2.7-code": {
"tools": true
"capabilities": {
"tools": true
}
},
"glm-5.2": {
"tools": true
"glm-5.3": {
"capabilities": {
"tools": true
}
},
"glm-5.3-flash": {
"capabilities": {
"tools": true
}
},
"mistral-glm-5.2": {
"capabilities": {
"tools": true,
"reasoning": {
"supported": true
}
},
"settings": {
"reasoningEffort": "xhigh"
}
},
"devstral": {
"tools": true
"capabilities": {
"tools": true
}
},
"local-qwen3.6:27b": {
"tools": true
"capabilities": {
"tools": true
}
},
"mistral-medium": {
"tools": true
},
"claude-sonnet": {
"tools": true
"capabilities": {
"tools": true
}
}
}
}
},
"permission": {
"read": "ask",
"edit": "ask",
"bash": "ask",
"external_directory": "ask"
}
"permissions": [
{
"action": "read",
"resource": "*",
"effect": "ask",
},
{
"action": "edit",
"resource": "*",
"effect": "ask",
},
{
"action": "shell",
"resource": "*",
"effect": "ask",
},
{
"action": "external_directory",
"resource": "*",
"effect": "ask",
},
],
}

View File

@@ -1,30 +1,6 @@
services:
opencode:
image: redpencil/opencode:feature-with-docker
image: redpencil/opencode:feature-opencode-v2
volumes:
- ./data/opencode/share:/root/.local/share/opencode
- ./config/opencode/opencode.json:/root/.config/opencode/opencode.json
# - ./config/opencode:/root/.config/opencode
depends_on:
dind:
condition: service_healthy
environment:
DOCKER_HOST: "tcp://dind:2375"
dind:
image: docker:29.6-dind
privileged: true
# userns mode only required if you use user namespaces
userns_mode: "host"
environment:
DOCKER_TLS_CERTDIR: ""
volumes:
- ./data/dind-cache:/var/lib/docker
command:
- "--registry-mirror=https://docker-registry-mirror.redpencil.io"
healthcheck:
test: ["CMD", "docker", "info"]
interval: 5s
timeout: 3s
retries: 20
start_period: 10s