95 lines
6.0 KiB
Markdown
95 lines
6.0 KiB
Markdown
# Agenti opencode (DeepSeek V4.1 Flash) orchestrati din Claude Code
|
|
|
|
Verificat live 15.09.2026, opencode 1.18.31. Docs: https://opencode.ai/docs/server/
|
|
|
|
## Model
|
|
`opencode-go/deepseek-v4.1-flash` (abonament opencode go). In API: `{"providerID":"opencode-go","modelID":"deepseek-v4.1-flash"}`.
|
|
|
|
## Varianta 1: one-shot (fara comunicare pe parcurs)
|
|
```
|
|
opencode run -m opencode-go/deepseek-v4.1-flash --title <lane> "<sarcina>"
|
|
opencode run -s <sessionID> "<mesaj urmator>" # continua aceeasi sesiune dupa ce s-a oprit
|
|
```
|
|
|
|
## Varianta 2: server + HTTP (mesaje in timpul lucrului) — recomandat
|
|
Pornire (un server per proiect, pentru toate lane-urile lui, in directorul proiectului):
|
|
```
|
|
opencode serve --port <port proiect> # 127.0.0.1, fundal
|
|
```
|
|
Serverele lungi (`opencode serve`, `archon serve`) se pornesc cu `Start-Process` (proces propriu), nu ca task
|
|
de fundal al sesiunii Claude Code: acela e omorat cand memoria e putina.
|
|
**Port fix per proiect.** Proiectele ROA ruleaza in paralel; pe acelasi port, oprirea serverului dintr-un proiect
|
|
opreste lane-urile celuilalt si le poate muta directorul de lucru (verificat 15.09.2026: lane ROACONT ajuns in ROAFACTURARE).
|
|
|
|
| Proiect | Port |
|
|
|---|---|
|
|
| ROAFACTURARE | 4096 |
|
|
| ROACONT | 4196 |
|
|
| ROAIMOB | 4296 |
|
|
|
|
Proiect nou: urmatorul port liber din tabel (+100), trecut aici inainte de pornire. In API trimite si `?directory=<radacina proiectului>`.
|
|
| Actiune | Apel |
|
|
|---|---|
|
|
| Sesiune noua | `POST /session` `{title}` → `id` |
|
|
| Sarcina (nu asteapta) | `POST /session/:id/prompt_async` `{model, parts:[{type:"text",text}]}` |
|
|
| Mesaj in timpul lucrului | acelasi `prompt_async` pe sesiunea ocupata |
|
|
| Stare | `GET /session/status` → `{id:{type:"busy"}}`; sesiunea lipseste cand e libera |
|
|
| Rezultat | `GET /session/:id/message` (parts cu `type=text`) |
|
|
| Oprire | `POST /session/:id/abort` |
|
|
| Evenimente live | `GET /event` (SSE) |
|
|
| Interfata vizuala | `opencode attach http://127.0.0.1:<port proiect>` (Marius poate urmari sesiunile) |
|
|
|
|
**Comportament verificat:** mesajul trimis cat agentul e `busy` intra in coada si e preluat la
|
|
pasul urmator (dupa apelul de tool curent), in aceeasi sesiune; agentul l-a respectat.
|
|
Nu intrerupe un tool aflat in executie. Pentru oprire imediata: `abort`, apoi mesaj nou.
|
|
|
|
## Prompt initial (obligatoriu)
|
|
opencode incarca singur `CLAUDE.md` din proiect si `~/.claude/CLAUDE.md`, dar acolo scrie cum sa
|
|
orchestreze Claude (delegare, gstack), nu cum sa execute. De aceea fiecare sesiune primeste
|
|
`COMUN\docs\opencode_prompt_initial.md` in campul `system` (verificat: agentul il respecta):
|
|
```powershell
|
|
$sys = [IO.File]::ReadAllText('D:\ROA\<PROIECT>\COMUN\docs\opencode_prompt_initial.md')
|
|
$b = @{model=$m; system=$sys; parts=@(@{type='text';text="Lane: <nume>. <sarcina>"})} | ConvertTo-Json -Depth 5
|
|
Invoke-RestMethod -Method Post "$u/session/$sid/prompt_async" -ContentType 'application/json; charset=utf-8' -Body ([Text.Encoding]::UTF8.GetBytes($b))
|
|
```
|
|
Cu `opencode run`, fara server: pui promptul ca fisier atasat, `-f COMUN\docs\opencode_prompt_initial.md`.
|
|
Promptul impune: rol de executant, citirea `reguli_lucru.md`, interdictiile (commit, write-back,
|
|
binare, `sed -i`), censul cp1250 + CRLF, raportul `docs\raport_<lane>.md` si ultimul mesaj
|
|
`GATA <lane>` / `BLOCAT <lane>: motiv`.
|
|
|
|
## Permisiuni
|
|
Fara configurare, agentul se opreste la fiecare acces in afara proiectului (scratchpad, `D:\ROA\UTIL`) si asteapta
|
|
aprobare. Configurarea e globala, pentru toate proiectele, in `%USERPROFILE%\.config\opencode\opencode.jsonc`:
|
|
```jsonc
|
|
"permission": { "edit": "allow", "bash": "allow", "webfetch": "allow", "external_directory": "allow" }
|
|
```
|
|
Se aplica la pornirea serverului (`opencode serve`); un server deja pornit trebuie repornit.
|
|
O cerere ramasa in asteptare se aproba prin API: `GET /permission` → `POST /session/:id/permissions/:permissionID` `{"response":"always"}`.
|
|
|
|
## Flux standard pe o lucrare (plan -> executie -> review -> aprobare)
|
|
1. **Plan** (orchestratorul, Opus): `docs\plan_<subiect>.md` exact - pasii, codul de inserat, locul (`fisier:linie`),
|
|
pasul 0 = baseline curat (`*.pre_runda1.bak` == `svn cat`), testul cu cazurile lui, verificarile da/nu, livrarea.
|
|
Executantul nu redeseneaza; un brief vag produce cod in plus.
|
|
2. **Executie**: sesiune opencode noua, `Lane: <x>. Executa EXACT planul din ...`. Livreaza patch + raport + `GATA`.
|
|
3. **Verificare orchestrator** (asserturi, nu citire): 0 x `EF BF BD`, CRLF pe toate liniile (numarat cu
|
|
`perl -ne '$c++ if /\r\n$/'`; `grep -c $'\r$'` din Git Bash numara gresit), liniile cu octeti
|
|
>0x7F identice cu baseline, `git diff --no-index` citit o data fata de plan, testul trecut.
|
|
4. **Review**: sesiune opencode NOUA (nu executantul), rol de reviewer, nu modifica cod. Brief
|
|
`docs\brief_review_<subiect>.md` cu: intrarile (plan, patch, cod, test), cele 5 verificari - fidelitate fata de plan,
|
|
corectitudine pe fluxul real (apelanti, alias selectat, cursoare inchise, NULL, ramurile neatinse raman identice),
|
|
conventii (`reguli_lucru.md` 2-3), octeti/CRLF, testul rulat de el -, livrare `docs\review_<subiect>.md` cu
|
|
BLOCANT/MAJOR/MINOR + `fisier:linie` + dovada; ce nu poate dovedi marcheaza "ipoteza".
|
|
Ultimul mesaj `REVIEW GATA: <n> BLOCANT, <n> MAJOR, <n> MINOR`.
|
|
5. BLOCANT/MAJOR -> corectie in sesiunea executantului (sau una noua cu handoff), apoi review din nou.
|
|
BLOCANT de doua ori sau verificarea de la 3 pica de doua ori -> escaladare Opus.
|
|
6. **Aprobare Marius** pe patch; abia apoi commit.
|
|
|
|
Prag context per sesiune opencode: ca la subagenti (~200-250k); peste -> abort, handoff pe disc, sesiune noua.
|
|
Contextul curent: `input + cache.read` din `info.tokens` al ultimului mesaj (`GET /session/:id/message`).
|
|
|
|
## Reguli pentru lane-uri
|
|
- Sarcina contine numele lane-ului, fisierele exacte si criteriul de terminare.
|
|
- Orchestratorul verifica dupa fiecare lane: diff, octeti cp1252, CRLF, teste.
|
|
- Dupa lucru: opreste serverul (PID-ul real e cel care asculta pe port, nu cel din `Start-Process`):
|
|
`Stop-Process -Id (Get-NetTCPConnection -LocalPort <port proiect> -State Listen).OwningProcess` - doar portul propriu.
|