docs(plans): add opencc agent proxy poc plan
This commit is contained in:
parent
66d979e543
commit
ec6f993d95
217
.plans/opencc-agent-proxy-plan.md
Normal file
217
.plans/opencc-agent-proxy-plan.md
Normal 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.
|
||||
Loading…
Reference in New Issue
Block a user