Compare commits
7 Commits
feature/do
...
feature/we
| Author | SHA1 | Date | |
|---|---|---|---|
| b0e2b6eeb8 | |||
| b98130e648 | |||
| 581e5ed5ac | |||
| ca7eaf3776 | |||
| 4b430129e6 | |||
| 520943689a | |||
| 5b240e8d95 |
136
README.md
136
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
|
||||
services:
|
||||
opencode:
|
||||
A first run from a clean checkout.
|
||||
|
||||
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:
|
||||
weave-proxy:
|
||||
environment:
|
||||
WEAVE_API_KEY: "..."
|
||||
WEAVE_API_KEY: "your-key-here"
|
||||
opencode:
|
||||
volumes:
|
||||
- /path/to/your/repo:/workspace/repo
|
||||
```
|
||||
```
|
||||
|
||||
Then:
|
||||
3. **Start the container.**
|
||||
|
||||
```
|
||||
drc up -d
|
||||
drc exec opencode opencode
|
||||
```
|
||||
```
|
||||
drc up -d
|
||||
```
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
## 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 `http://weave-proxy/v1`.
|
||||
- **`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.
|
||||
|
||||
11
config/nginx/templates/default.conf.template
Normal file
11
config/nginx/templates/default.conf.template
Normal file
@@ -0,0 +1,11 @@
|
||||
server {
|
||||
listen 80;
|
||||
location / {
|
||||
proxy_pass https://weave.redpencil.io;
|
||||
proxy_ssl_server_name on;
|
||||
proxy_set_header Host weave.redpencil.io;
|
||||
proxy_set_header Authorization "Bearer ${WEAVE_API_KEY}";
|
||||
proxy_buffering off; # SSE streaming
|
||||
proxy_read_timeout 600s; # match opencode's 5-min defaults
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"model": "weave/glm-5.2",
|
||||
"small_model": "weave/glm-5.2",
|
||||
"model": "weave/glm-5.3-flash",
|
||||
"small_model": "weave/glm-5.3-flash",
|
||||
"lsp": {
|
||||
"typescript": {
|
||||
"command": [
|
||||
@@ -34,16 +34,26 @@
|
||||
"weave": {
|
||||
"npm": "@ai-sdk/openai-compatible",
|
||||
"options": {
|
||||
"baseURL": "https://weave.redpencil.io/v1",
|
||||
"apiKey": "{env:WEAVE_API_KEY}"
|
||||
"baseURL": "http://weave-proxy/v1",
|
||||
"apiKey": "not-needed"
|
||||
},
|
||||
"models": {
|
||||
"kimi-K2.7-code": {
|
||||
"tools": true
|
||||
},
|
||||
"glm-5.2": {
|
||||
"glm-5.3": {
|
||||
"tools": true
|
||||
},
|
||||
"glm-5.3-flash": {
|
||||
"tools": true
|
||||
},
|
||||
"mistral-glm-5.2": {
|
||||
"tools": true,
|
||||
"reasoning": true,
|
||||
"options": {
|
||||
"reasoningEffort": "xhigh"
|
||||
}
|
||||
},
|
||||
"devstral": {
|
||||
"tools": true
|
||||
},
|
||||
@@ -52,9 +62,6 @@
|
||||
},
|
||||
"mistral-medium": {
|
||||
"tools": true
|
||||
},
|
||||
"claude-sonnet": {
|
||||
"tools": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
services:
|
||||
weave-proxy:
|
||||
image: nginx:1.31.7-alpine
|
||||
volumes:
|
||||
- ./config/nginx/templates:/etc/nginx/templates:ro
|
||||
opencode:
|
||||
image: redpencil/opencode:0.0.1
|
||||
image: redpencil/opencode:0.0.2
|
||||
volumes:
|
||||
- ./data/opencode/share:/root/.local/share/opencode
|
||||
- ./config/opencode/opencode.json:/root/.config/opencode/opencode.json
|
||||
|
||||
Reference in New Issue
Block a user