docs(plans): add opencc agent proxy poc plan

This commit is contained in:
Guillaume ARM 2026-06-08 17:11:17 +02:00
parent 66d979e543
commit ec6f993d95

View File

@ -0,0 +1,217 @@
# Plan - PoC `cc-agent-proxy` + programme Lua `opencc`
> A executer ailleurs, pas sur cette machine. Deploiement HTTPS, reverse proxy, firewall et exposition publique geres separement par Guillaume.
## 1. Objectif
Piloter un agent OpenCode depuis une turtle ComputerCraft sur Minecraft / ATM10.
```text
Turtle --HTTP + token--> cc-agent-proxy --HTTP Basic Auth--> opencode serve
opencc.lua Node/TypeScript proxy OpenCode headless
```
## 2. Faisabilite
`opencode serve` lance un serveur HTTP headless exposant une spec OpenAPI 3.1 sur `/doc`.
Routes utiles pour le PoC :
| Methode | Route | Usage |
|---|---|---|
| `GET` | `/global/health` | healthcheck amont |
| `POST` | `/session` | cree une session |
| `POST` | `/session/:id/message` | envoie un message et attend la reponse |
| `POST` | `/session/:id/prompt_async` | envoie en asynchrone |
| `GET` | `/session/:id/message` | liste les messages |
| `GET` | `/event` | flux SSE |
Conclusion : le proxy n'est pas strictement necessaire, mais il rend le client Lua beaucoup plus simple.
## 3. Pourquoi garder le proxy
- Expose une API turtle simple : `POST /ask { prompt, sessionId? }` vers `{ sessionId, reply }`.
- Gere le Basic Auth OpenCode cote Node.
- Garde cote turtle un token Bearer simple.
- Aplatit les reponses OpenCode pour limiter RAM et complexite Lua.
- Permet plus tard async, polling, logs, quotas ou allowlist sans changer le programme Lua.
## 4. Partie A - `cc-agent-proxy`
Creer un dossier `cc-agent-proxy/` dans le repo.
Stack :
- Node 20+.
- TypeScript strict.
- Fastify.
- Vitest.
- Zod.
- Config via env validee, avec `.env.example`.
Arborescence :
```text
cc-agent-proxy/
package.json
tsconfig.json
.env.example
src/
config.ts
opencode.ts
auth.ts
server.ts
index.ts
test/
config.test.ts
opencode.test.ts
auth.test.ts
server.test.ts
```
Config :
| Variable | Defaut | Role |
|---|---|---|
| `PROXY_HOST` | `0.0.0.0` | interface d'ecoute |
| `PROXY_PORT` | `7070` | port du proxy |
| `PROXY_TOKEN` | requis | secret turtle <-> proxy |
| `OPENCODE_BASE_URL` | `http://127.0.0.1:4096` | URL OpenCode |
| `OPENCODE_USERNAME` | `opencode` | user Basic Auth |
| `OPENCODE_PASSWORD` | requis | password Basic Auth |
| `OPENCODE_MODEL` | optionnel | modele a passer a OpenCode |
Routes proxy :
| Methode | Route | Auth | Usage |
|---|---|---|---|
| `GET` | `/health` | non | etat proxy + `opencode.health()` |
| `POST` | `/ask` | oui | cree/reutilise session, envoie prompt, retourne reponse |
| `POST` | `/session` | oui, optionnel | cree une session explicite |
Client OpenCode :
- `health()` appelle `GET /global/health`.
- `createSession(title?)` appelle `POST /session`.
- `sendMessage(sessionId, text)` appelle `POST /session/:id/message`.
- `Authorization: Basic base64(username:password)`.
- Body message : `{ parts: [{ type: "text", text }], model?: ... }`.
- Extraire les `parts` texte de la reponse.
- A valider au premier run reel : format exact des `parts`.
Auth proxy :
- Accepter `Authorization: Bearer <token>`.
- Accepter aussi `X-Proxy-Token` pour simplicite CC si besoin.
- Comparaison constant-time avec `crypto.timingSafeEqual`.
- Reponse `401` si absent ou invalide.
- Ne jamais logger le token.
Tests Node en scope du PoC :
- `config.test.ts` : valeurs par defaut, erreurs si secrets manquants.
- `opencode.test.ts` : `fetch` mocke pour health/session/message/parsing.
- `auth.test.ts` : token valide, invalide, absent.
- `server.test.ts` : `app.inject()` pour `/health`, `/ask`, `401` sans token.
## 5. Partie B - programme Lua `opencc`
Creer :
```text
apis/libopencc.lua
programs/opencc.lua
tests/opencc.lua
```
Programme :
- `opencc --help`.
- `opencc --version`.
- `opencc "prompt"` ou prompt interactif via `read()`.
- Appelle `http://<host>:<port>/ask`.
- Header `Content-Type: application/json`.
- Header `Authorization: Bearer <token>`.
- Body `textutils.serialiseJSON({ prompt = prompt, sessionId = sessionId })`.
- Parse la reponse JSON.
- Affiche `reply`.
- Memorise `sessionId` pour reutilisation si on choisit une session persistante.
Config Lua :
- Utiliser `settings` ComputerCraft en priorite :
- `opencc.proxy_url`.
- `opencc.proxy_token`.
- `opencc.session_id`.
- `opencc.timeout`, si applicable.
- Autoriser un fallback hardcode uniquement pour PoC local, mais ne pas committer de secret reel.
- Stockage session possible dans un petit fichier local, par exemple `/.opencc-session`, si plus simple que `settings`.
Tests Lua :
- En scope si simple : tester `libopencc` sans vraie requete HTTP via injection d'un faux client `http`.
- Tester construction URL, headers, body JSON, parsing succes, parsing erreur.
- Hors scope PoC si trop couteux : test end-to-end avec vrai proxy Node et vrai OpenCode.
- Le test reel HTTP se fera manuellement via CraftOS-PC puis en jeu.
Note repo :
- Le reseau existant `apis/net.lua` est oriente modem/rednet/router, pas HTTP sortant.
- Pour ce PoC, garder `http.post` direct cote Lua est le bon choix.
- Le packaging existant du repo est `ccpm` / `packages/*/ccpm.json`, pas `cube`.
- Ne pas integrer au packaging tant que le PoC n'est pas valide ; ajouter ensuite un package dedie type `tos-agent` si utile.
## 6. Pre-requis CC:Tweaked / ATM10
- API `http` activee.
- Hote/IP du proxy autorise dans les `http.rules` cote serveur ATM10.
- Pas de CORS, car ce n'est pas un navigateur.
- Prompts courts pour le PoC, car `POST /session/:id/message` peut etre long.
Evolution hors PoC :
- Proxy utilise `prompt_async`.
- Turtle appelle `POST /ask` puis poll `GET /ask/:id/status`.
- Le proxy ecoute eventuellement `/event` SSE cote OpenCode.
## 7. Ordre d'execution
1. Bootstrap `cc-agent-proxy`.
2. Implementer `config.ts` + tests.
3. Implementer `opencode.ts` + tests avec `fetch` mocke.
4. Implementer `auth.ts`, `server.ts`, `/health`, `/ask` + tests `app.inject()`.
5. Valider manuellement avec `opencode serve` + `curl`.
6. Implementer `apis/libopencc.lua` + `programs/opencc.lua`.
7. Ajouter `tests/opencc.lua` si l'injection HTTP reste simple.
8. Tester via CraftOS-PC.
9. Tester en jeu sur ATM10 apres configuration `http.rules`.
10. Documenter les commandes de lancement et les pre-requis.
## 8. Validation manuelle
```bash
OPENCODE_SERVER_PASSWORD=xxx opencode serve \
--hostname 127.0.0.1 \
--port 4096
```
```bash
curl -s http://localhost:7070/health
```
```bash
curl -s -X POST http://localhost:7070/ask \
-H "Authorization: Bearer $PROXY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"prompt":"dis bonjour"}'
```
## 9. Points de vigilance
- Format reel des `parts` OpenCode a valider au premier run.
- OpenCode doit avoir un provider authentifie.
- Timeouts longs cote agent vs limites HTTP CC:Tweaked.
- `http.rules` cote serveur ATM10.
- `PROXY_TOKEN` jamais committe.
- `OPENCODE_PASSWORD` jamais committe.
- Le proxy doit rester minimal tant que le PoC n'a pas prouve la boucle complete.