pi_coder_2/SINGLE_SERVER_PLAN.md
dschlueter 3cf9ef928b init: pi_coder_v2 — Single-Server (Option B)
Beide Rollen (Coder + Judge) auf einem llama.cpp-Server (Port 8001).
switchModel wechselt zwischen qwen3.5-coder und qwen3.5-judge via
llama-cpp-single-Provider ohne Server-Neustart. start-single.sh startet
den gemeinsamen Server, GPU wählbar per GPU_DEVICE-Env-Variable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 01:04:55 +02:00

150 lines
4.8 KiB
Markdown

# Plan: pi_coder_v2 — Single-Server (Option B)
## Kontext
pi_coder verwendet zwei llama.cpp-Server für Coder (GPU 1) und Judge (GPU 2),
die aber dasselbe GGUF-Modell ausführen. Die Rollentrennung entsteht ausschließlich
durch System-Prompts. Wenn nur eine GPU verfügbar ist, kann ein einziger Server
beide Rollen übernehmen — Rollenwechsel per Prompt statt per Server-Neustart.
**pi_coder bleibt unverändert.** Die Umsetzung erfolgt im neuen Verzeichnis `~/pi_coder_v2`.
---
## Schritt 1: Verzeichnis anlegen und Dateien kopieren
```bash
mkdir ~/pi_coder_v2
cp ~/pi_coder/pi-coder-judge-extension.ts ~/pi_coder_v2/
cp ~/pi_coder/models.json ~/pi_coder_v2/
cp ~/pi_coder/start-coder.sh ~/pi_coder_v2/
cp ~/pi_coder/start-judge.sh ~/pi_coder_v2/
cp ~/pi_coder/start-servers.sh ~/pi_coder_v2/
cp ~/pi_coder/stop-servers.sh ~/pi_coder_v2/
cp ~/pi_coder/status.sh ~/pi_coder_v2/
cp ~/pi_coder/install_servers_and_pi_coder_extension.sh ~/pi_coder_v2/
cp ~/pi_coder/README.md ~/pi_coder_v2/
cp ~/pi_coder/BEDIENUNGSANLEITUNG.md ~/pi_coder_v2/
cp ~/pi_coder/CLAUDE.md ~/pi_coder_v2/
# Plan-Datei ebenfalls kopieren
cp <dieser-plan> ~/pi_coder_v2/SINGLE_SERVER_PLAN.md
# git init
cd ~/pi_coder_v2 && git init && git add -A && git commit -m "init: kopiert aus pi_coder"
```
Nicht kopieren: `run-tests.sh`, `test-utils.ts`, `examples/` (nicht relevant für Kernfunktion).
---
## Schritt 2: `start-single.sh` anlegen
Basiert auf `start-coder.sh` mit folgenden Änderungen:
| Parameter | Alt (coder) | Neu (single) |
|---|---|---|
| `CONTAINER_NAME` | `qwen36-27b-coder` | `qwen36-27b-single` |
| `HOST_PORT` | 8001 | 8001 |
| `MODEL_ALIAS` | `qwen3.5-coder` | `qwen3.5-single` |
| `--temp` | 0.6 | 0.65 (Kompromiss) |
| `--gpus` | `"device=1"` | `"device=1"` (oder konfigurierbar) |
Der Server registriert sich unter dem Alias `qwen3.5-single`.
---
## Schritt 3: `models.json` anpassen
Neuen Provider `llama-cpp-single` hinzufügen mit **beiden** Modell-IDs auf Port 8001:
```json
"llama-cpp-single": {
"baseUrl": "http://127.0.0.1:8001/v1",
"api": "openai-completions",
"apiKey": "none",
"compat": {
"supportsDeveloperRole": false,
"supportsReasoningEffort": false,
"maxTokensField": "max_tokens",
"thinkingFormat": "qwen-chat-template"
},
"models": [
{
"id": "qwen3.5-coder",
"name": "Qwen3.6 27B Single-Server Coder (llama.cpp :8001)",
"reasoning": true,
"input": ["text"],
"contextWindow": 262144,
"maxTokens": 16384,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
},
{
"id": "qwen3.5-judge",
"name": "Qwen3.6 27B Single-Server Judge (llama.cpp :8001)",
"reasoning": true,
"input": ["text"],
"contextWindow": 262144,
"maxTokens": 16384,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
}
]
}
```
Die bestehenden Provider `llama-cpp-coder` und `llama-cpp-judge` bleiben erhalten
(für Kompatibilität), werden aber nicht aktiv genutzt.
---
## Schritt 4: `pi-coder-judge-extension.ts` — switchModel-Aufrufe
Alle Aufrufe von `switchModel(pi, ctx, "llama-cpp-coder", "qwen3.5-coder")`
und `switchModel(pi, ctx, "llama-cpp-judge", "qwen3.5-judge")` werden auf
`"llama-cpp-single"` umgestellt. Der Modell-ID-Parameter (`"qwen3.5-coder"` /
`"qwen3.5-judge"`) bleibt unverändert — so bleiben die Registry-Wechsel erhalten,
sind aber sofort (kein Server-Neustart).
Betroffene Stellen (ca. 8):
- `/coder` handler
- `/judge` handler
- `/fix` handler
- `/shipit` handler
- `/optimize` loop (Coder-Kickoff, Judge-Phase, Fix-Phase, ShipIt-Phase)
- `/patch` handler
- `/quick_check` handler
- `/plan` handler
---
## Schritt 5: `install_servers_and_pi_coder_extension.sh` anpassen
Pfade auf `pi_coder_v2` anpassen (falls nötig — Skript referenziert vermutlich `$REPO`
als relatives Verzeichnis, was automatisch korrekt ist).
---
## Schritt 6: `waitUntilModelReady` im `--continue`-Modus
Im `--continue`-Modus prüft die Extension beide Server parallel:
```typescript
const [coderReady, judgeReady] = await Promise.all([
waitUntilModelReady(pi, ctx, 8001, "qwen3.5-coder"),
waitUntilModelReady(pi, ctx, 8002, "qwen3.5-judge"),
]);
```
Dies muss auf einen einzigen Check umgestellt werden:
```typescript
const ready = await waitUntilModelReady(pi, ctx, 8001, "qwen3.5-single");
```
---
## Verifikation
1. `cd ~/pi_coder_v2 && ./start-single.sh` → Server startet auf Port 8001
2. `nvidia-smi` → nur eine GPU belegt, ~20 GB VRAM
3. `./install_servers_and_pi_coder_extension.sh` → Extension in `~/.pi/agent/` deployen
4. In pi: `/reload` → Extension neu laden
5. `/optimize <kleiner Testauftrag>` → Loop läuft durch
6. In der Statuszeile: `switchModel` wechselt ohne spürbare Pause
7. Qualitätscheck: Judge-Urteil und Coder-Fix verhalten sich wie erwartet