diff --git a/deploy/opencode/README.md b/deploy/opencode/README.md new file mode 100644 index 0000000..dd6fc9c --- /dev/null +++ b/deploy/opencode/README.md @@ -0,0 +1,55 @@ +# OpenCode-Seite: ein Regelwerk, zwei Auslöser + +Tagsüber tippst du in **Zed** (PC), nachts ruft ein **Hermes-Cron** dasselbe (Box). +Beide Wege benutzen dieselbe OpenCode-Version, dieselbe Mannschaft, dasselbe Plugin +und denselben Token-Wächter. Der einzige Unterschied ist die Adresse des Governors. + +## Was wohin gehört + +| Datei hier | Ziel auf dem PC | Ziel auf der Box | +|---|---|---| +| `opencode.pc.json` | `~/.config/opencode/opencode.json` | — | +| `opencode.box.json` | — | `~/.config/opencode/opencode.json` | +| `plugin/mc2-governor.ts` | `~/.config/opencode/plugin/` | `~/.config/opencode/plugin/` | +| `VERIFY.template` | — | wird von `gitea-repo-create.sh` in **jedes neue Repo** als `VERIFY` gesät | + +Der Governor selbst liegt in `../governor/` (Proxy + systemd-Unit), der unbeaufsichtigte +Läufer in `../opencode-lauf.sh`. + +## Die Mannschaft + +| Rolle | Modell | Gemessen (25.07.2026) | Warum | +|---|---|---|---| +| `plan` + `build` | `coder` — Qwen3-Coder-Next | **51,5 t/s** | Hält den Faden, verteilt Zuarbeit. MoE mit 3B aktiv → schnell auf Strix Halo. | +| `explore` | `hermes` — Qwen3.6-35B | **69,6 t/s** | Ohnehin dauerwarm → kostet **null** zusätzlichen Speicher. Sucht, liest, meldet kurz zurück. | +| `review` | `kritiker` — Devstral-Small-2 | **15,0 t/s** | Bewusst eine **fremde Modellfamilie** (Mistral statt Qwen) → andere blinde Flecken. Dicht = langsam beim Schreiben, aber ein Kritiker liest viel und schreibt wenig. | + +`heavy` (gpt-oss-120b, 63 GB) ist **nicht** mehr in der Tagesrolle: es würde beim Laden +das ganze warme Set verdrängen. Es bleibt der Nacht-Gutachter (4:30-Cron). + +## Nach einer Änderung + +Die Dateien hier sind **Vorlagen**, keine Live-Konfiguration. Nach einer Änderung +verteilen: + +```bash +# Box +scp deploy/opencode/opencode.box.json hitonabi@192.168.178.151:~/.config/opencode/opencode.json +scp deploy/opencode/plugin/*.ts hitonabi@192.168.178.151:~/.config/opencode/plugin/ +# PC (aus dem Repo heraus) +cp deploy/opencode/opencode.pc.json ~/.config/opencode/opencode.json +cp deploy/opencode/plugin/*.ts ~/.config/opencode/plugin/ +``` + +**Zed muss danach neu gestartet werden** — OpenCode liest seine Konfiguration nur beim Start. + +## Fallen, die Zeit gekostet haben + +- **Kein `_comment`-Schlüssel in `opencode.json`.** OpenCode validiert streng und + verweigert den Start mit „Unrecognized key". Kommentare gehören in dieses README. +- **Das Plugin läuft auf Windows UND Linux.** Deshalb `node:fs` statt `cat` und Buns + `${{ raw: cmd }}` statt `bash -lc` — beides fehlt auf Windows bzw. verschluckt den Befehl. +- **Bei `opencode run` beendet sich der Prozess, bevor `session.idle` fertig ist** + (gemessen 25.07.). Für unbeaufsichtigte Läufe liegt die Prüf-Schleife deshalb + zusätzlich in `opencode-lauf.sh`, wo sie den Prozess überlebt. In Zed greift das Plugin. +- **Plugin-Verzeichnis:** `plugin/` und `plugins/` werden beide erkannt; wir nutzen `plugin/`. diff --git a/deploy/opencode/opencode.pc.json b/deploy/opencode/opencode.pc.json new file mode 100644 index 0000000..ef3026d --- /dev/null +++ b/deploy/opencode/opencode.pc.json @@ -0,0 +1,67 @@ +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "aibox": { + "npm": "@ai-sdk/openai-compatible", + "name": "AI-Box ueber Governor (192.168.178.151:8100)", + "options": { + "baseURL": "http://192.168.178.151:8100/v1", + "apiKey": "local" + }, + "models": { + "heavy": { + "name": "heavy — Planer (gpt-oss-120b, 32k)", + "limit": { "context": 32768, "output": 8192 } + }, + "coder": { + "name": "coder — Bauen (Qwen3-Coder-Next, 131k)", + "limit": { "context": 131072, "output": 16384 } + }, + "hermes": { + "name": "hermes — Erkunden (Qwen3.6, immer warm, 69,6 t/s)", + "limit": { "context": 65536, "output": 8192 } + }, + "kritiker": { + "name": "kritiker — Gegenlesen (Devstral-2, Mistral, 15,0 t/s)", + "limit": { "context": 65536, "output": 8192 } + } + } + } + }, + "model": "aibox/coder", + "small_model": "aibox/hermes", + "agent": { + "plan": { + "model": "aibox/coder", + "permission": { "edit": "deny", "bash": "deny" } + }, + "build": { + "model": "aibox/coder", + "permission": { + "edit": "allow", + "webfetch": "allow", + "bash": { + "*": "allow", + "ssh *": "deny", + "scp *": "deny", + "sftp *": "deny", + "ssh arcane@192.168.178.162 *": "allow", + "ssh -o StrictHostKeyChecking=no arcane@192.168.178.162 *": "allow", + "scp *arcane@192.168.178.162*": "allow" + } + } + }, + "explore": { + "mode": "subagent", + "description": "Codebase schnell durchsuchen, Dateien finden, Fragen zum Code beantworten — nur lesen, läuft auf dem immer warmen Hirn", + "model": "aibox/hermes", + "permission": { "edit": "deny", "bash": "deny" } + }, + "review": { + "mode": "subagent", + "description": "Kritischer Code-Review nach jeder Etappe (Pflicht laut AGENTS.md): sucht erfundene APIs/CLI-Flags, stille Abweichungen vom KONZEPT, fehlende Tests, toten Code — meldet Befunde, ändert nichts. Läuft bewusst auf einer FREMDEN Modellfamilie (Mistral/Devstral statt Qwen), damit er andere blinde Flecken hat als der Coder.", + "model": "aibox/kritiker", + "permission": { "edit": "deny", "bash": "deny" } + } + } +}