diff --git a/claude-agent/CLAUDE.md b/claude-agent/CLAUDE.md index 908bf95..3121578 100644 --- a/claude-agent/CLAUDE.md +++ b/claude-agent/CLAUDE.md @@ -2,12 +2,21 @@ Vezi `README.md` pentru context general. +## Canal principal + +Utilizatorul comunică cu acest agent în principal prin **Discord**, prin puntea Discord → Claude Code +(cod sursă: `romfastsql/proxmox/lxc171-claude-agent/discord-bridge/`, vezi și `docs/echo-roa2web.md` +pentru diferența față de Echo/MoltBot). Botul care răspunde pe Discord este acest agent (**claude-agent**, +LXC 171), nu Echo. Atașamentele (imagini, fișiere) trimise pe Discord nu sunt încă citite automat de +punte — doar textul mesajului ajunge la Claude (vezi limitarea cunoscută mai jos, în lucru). + ## Documentație | Subiect | Fișier | |---------|--------| | Infrastructură Proxmox (noduri, LXC, VM, proiecte) | [docs/infrastructure.md](docs/infrastructure.md) | | Echo (LXC 110 moltbot) — acces și comenzi pentru roa2web | [docs/echo-roa2web.md](docs/echo-roa2web.md) | +| Maria — punte WhatsApp + RAG (LXC 171, servicii + dashboard comun) | [docs/maria-whatsapp-rag-prototype.md](docs/maria-whatsapp-rag-prototype.md) | Detalii complete Proxmox (config, troubleshooting, incidente): `/workspace/romfastsql/proxmox/`. diff --git a/claude-agent/docs/discord-bridge-context.md b/claude-agent/docs/discord-bridge-context.md new file mode 100644 index 0000000..9b1d891 --- /dev/null +++ b/claude-agent/docs/discord-bridge-context.md @@ -0,0 +1,40 @@ +# Puntea Discord — cum se acumulează și se golește contextul + +Sursă: `romfastsql/proxmox/lxc171-claude-agent/discord-bridge/` (`bot.py`, `runner.py`, `session_store.py`). + +## Model + +Fiecare fir de Discord (thread) e mapat pe o sesiune Claude Code reală, nu pe o +fereastră de memorie proprie (spre deosebire de chatbot-ul Maria/Flowise, care +folosește Buffer Window Memory cu `k=5`). + +- `session_store.py` ține în `state.json` câte o înregistrare per `thread_id`, + cu câmpul `sid` = session id-ul Claude Code. +- La fiecare tur nou pe același fir, `runner.py` pornește procesul cu + `claude --resume --autocompact auto` — deci **contextul se acumulează + la nesfârșit** în sesiunea Claude Code, cu compactare automată (`--autocompact + auto`) gestionată de Claude Code însuși când se apropie de limita de context + (nu e o ștergere, e un sumar intern). +- Dacă procesul moare/repornește, se reia cu `--resume` pe același `sid` — + contextul supraviețuiește restart-urilor botului. + +## Când se golește efectiv + +Nu există curățare automată pe timp (nu e un TTL/cron). Contextul unui fir se +resetează DOAR manual, din Discord: + +- **`/new`** — pornește o sesiune nouă (`sid = None`), fir „curat". +- **`/new fork:True`** — sesiune nouă, dar pornită dintr-un fork al + contextului curent (păstrează istoricul până la acel punct, apoi ramifică). + +`bot.py:645` apelează `runner.reset(tid, fork=...)`, care în `runner.py:333` +oprește procesul curent și șterge `proc.sid` (la fork, marchează following +`--resume` cu fork în loc de resume simplu). + +## De reținut + +- Nu confunda acest mecanism cu Maria (Flowise): acolo fereastra e fixă (ultimele + 5 schimburi, per `sessionId`), aici fereastra e "tot" + auto-compact intern + Claude Code, golit doar la `/new`. +- Comanda `/cleanup` (`cleanup.py`) NU are legătură cu contextul conversației — + curăță procese orfane rămase în urma firelor (memorie RAM), nu istoricul de chat. diff --git a/claude-agent/docs/maria-whatsapp-rag-prototype.md b/claude-agent/docs/maria-whatsapp-rag-prototype.md new file mode 100644 index 0000000..6fccc68 --- /dev/null +++ b/claude-agent/docs/maria-whatsapp-rag-prototype.md @@ -0,0 +1,146 @@ +# Maria — punte WhatsApp + RAG (LXC 171), acum serviciu în git + +Sursa: `romfastsql/proxmox/lxc171-claude-agent/maria-whatsapp-bridge/` (repo +`ROMFASTSQL`, commit „Add Maria WhatsApp+RAG bridge as a service (LXC 171)"). + +A pornit ca prototip nefinalizat în `/tmp/maria-bridge/` (fără git, fără +serviciu systemd — vezi istoricul acestei conversații). A fost mutat integral +în git, ca proiect sibling lui `discord-bridge/`, cu servicii `systemctl --user` +proprii și dashboard de control. + +Nu trebuie confundat cu: +- **Maria pe Flowise** (`vfp_roaauto/COMUN/utile/chatbot/`) — chatbot web, + memorie Buffer Window (`k=5`) în Flowise. +- **Echo / `echo-whatsapp-bridge.service`** (LXC 110 moltbot) — bridge WhatsApp + Baileys separat, al lui Echo Core (Claude Opus 4.5). +- **Punte Discord -> Claude Code** (`discord-bridge/`, același container) — + alt scop (comandă Claude Code de pe Discord), vezi + [`discord-bridge-context.md`](discord-bridge-context.md). + +## Arhitectură + +``` +WhatsApp (self-chat implicit) + -> whatsapp/index.js (Baileys, port 8099) + -> rag/consumer.py (polling, RAG STATELESS — fara chat_history) + -> rag/store.py (depozit .txt/.md in ~/.maria-bridge/documents/) + -> rag/indexer.py (chunking + embeddings Ollama -> rag_index.json) + -> rag/sync.py (rclone pull din Google Drive + reindexare conditionata) +dashboard/api.py (stdlib, port 18792) — control total din browser +``` + +## Servicii `systemctl --user` (pe LXC 171, sub `~/.config/systemd/user/`) + +| Unitate | Rol | +|---|---| +| `maria-whatsapp.service` | Puntea Baileys (Node), port 8099 | +| `maria-rag.service` | Consumer RAG (Python venv), răspunde la mesaje | +| `maria-sync.service` + `maria-sync.timer` | Sincronizare Drive + reindexare, la 10 min | + +Instalare: `ops/install.sh` (idempotent, mirror al `discord-bridge/ops/install.sh` +— creează `~/.maria-bridge/`, venv, `npm install`, symlink-uri unit, +`systemctl --user enable`). Bridge-ul **nu pornește automat** — cere scanarea +unui cod QR (pas manual, o singură dată); vezi `README.md` din proiect. + +## Control — dashboard COMUN cu puntea Discord (nu unul separat) + +**Decizie ulterioară** (la cererea explicită a utilizatorului): Maria NU are +dashboard propriu. Controlul se face din **dashboard-ul punții Discord** +(`discord-bridge/dashboard/`, `https://claude-agent.tailf7372d.ts.net/claude`), +secțiunea „Maria — WhatsApp + RAG", adăugată direct în `dashboard/api.py` și +`index.html` ale acelui proiect. Rutele Maria (`/api/maria/*`) rulează în +ACELAȘI proces Python ca puntea Discord, dar comunică cu Maria doar prin +subprocess (`systemctl`, scripturi din `rag/`) și HTTP către bridge — fără +import de module Python din `maria-whatsapp-bridge`, ca să nu coliseze cu +`discord-bridge/config.py` (ambele s-ar numi `config`). + +Ce oferă secțiunea Maria din acel panou: +- start/stop/restart pentru `maria-whatsapp` și `maria-rag` (unități fixe, + aceeași protecție ca la Discord — niciun nume de unit nu vine din request) +- stare conexiune WhatsApp + cod QR de asociere (când nu e conectat) +- listă documente din depozit, adăugare/ștergere text, reindexare manuală +- buton „sincronizează din Drive acum" (`rag/sync.py`, apelat și de timer) +- loguri (tail) pentru `whatsapp.log`/`rag.log` + +Autentificare: aceeași sesiune/cookie ca restul dashboard-ului Discord +(`DASHBOARD_TOKEN` din `~/.claude-discord/env`) — un singur login pentru +ambele punți. + +## Depozit de documente + Google Drive + +Documentele (`.txt`/`.md`) stau în `~/.maria-bridge/documents/` pe container. +Se pot administra manual din dashboard, sau sincroniza automat cu dosarul +Google Drive de pe Windows (`D:\GoogleDrive\romfast\document_store`) prin +**rclone cu un cont de serviciu Google** (nu OAuth interactiv — containerul +e headless). Pași de configurare completi în README-ul proiectului +(`maria-whatsapp-bridge/README.md`, secțiunea „Sincronizare cu Google Drive"). +`DRIVE_REMOTE` gol în env = sincronizare dezactivată, doar upload manual. + +## Context conversațional — neschimbat față de prototip + +`rag/consumer.py` tot NU ține memorie între mesaje — fiecare întrebare e o +interogare RAG independentă (system prompt + top-K chunk-uri din index + +întrebare). Nu există nimic de "golit"; comparativ: +- Maria/Flowise: fereastră fixă de 5 schimburi; +- Discord bridge: context nelimitat (autocompact), golit doar cu `/new`; +- Maria WhatsApp+RAG: zero memorie, fiecare mesaj e independent. + +## Embeddings — Ollama local pe LXC 171 + +Inițial `OLLAMA_URL=http://127.0.0.1:11434` din `env` era un placeholder +nefuncțional (niciun Ollama instalat nicăieri, nici local nici pe alt LXC — +verificat explicit, nu există server Ollama documentat în infrastructură). +**Rezolvat 2026-08-31**: instalat Ollama direct pe acest container +(`curl -fsSL https://ollama.com/install.sh | sh`, plus `zstd` ca dependință), +pornit ca `ollama.service` (systemd la nivel de sistem, nu `--user`), și +tras modelul `nomic-embed-text` (`ollama pull nomic-embed-text`, ~274 MB, +rulează CPU-only, fără GPU pe container). Cu asta `rag/indexer.py` și +`rag/consumer.py` au un backend de embeddings funcțional local, fără nicio +dependință externă de rețea. + +## Sincronizare Google Drive — status real + +`rclone` a fost instalat pe container (`apt-get install rclone`), dar +`DRIVE_REMOTE` rămâne **negol configurat**: pasul care lipsește e crearea +unui cont de serviciu Google (GCP Console → IAM → Service Accounts) și +partajarea folderului `document_store` cu adresa lui de email — acțiuni +care cer acces la consola Google Cloud a utilizatorului, deci nu pot fi +automatizate din container. Vezi README, secțiunea „Sincronizare cu Google +Drive", pentru pașii exacți rămași. + +**Testare imediată a indexării** (fără să aștepte configurarea rclone): +s-au adus manual 6 documente reale din folderul Drive `document_store` +(`romfast_info.md`, `erori_generale_knowledge.md`, `bilant_knowledge.md`, +`import_knowledge.md`, `roafacturare_manual.md`, `spv_semnatura_knowledge.md`) +folosind uneltele MCP Google Drive disponibile agentului (cont +`mmarius28@gmail.com`, folder id `1C4e75zgH1_7ZK-_oBP5ZZBvUPh3iEo1O`), scrise +direct în `~/.maria-bridge/documents/` și indexate cu `rag/indexer.py` — +**25 de chunk-uri, index de ~400 KB, reconstruit cu succes** folosind Ollama-ul +local de mai sus. Asta confirmă că pipeline-ul store → indexer → embeddings +funcționează capăt-la-capăt; rămâne doar conectarea automată la Drive prin +`rclone` (pasul manual al utilizatorului, de mai sus). + +## Stare la momentul scrierii (actualizat 2026-08-31) + +`maria-whatsapp`, `maria-rag` și `maria-sync.timer` sunt `active (running)`/ +`enabled`. Dashboard-ul propriu (`maria-dashboard.service`) a fost **oprit, +dezactivat și eliminat din cod** — controlul e acum consolidat în +dashboard-ul punții Discord (secțiunea „Maria — WhatsApp + RAG", verificată +funcțională prin `curl` direct pe `/api/maria/status`). Bridge-ul a generat +cod QR și așteaptă scanarea din telefon (`connected: false` până atunci). + +Rămâne de făcut manual: +- **scanarea codului QR** din dashboard (cardul „Conectare WhatsApp") — pas fizic, + nu poate fi automatizat; +- **contul de serviciu Google + `DRIVE_REMOTE`** — vezi secțiunea de mai sus; + fără el, sincronizarea automată din Drive rămâne inactivă (dar upload-ul + manual de documente + reindexare funcționează deja, testat); +- **file picker în dashboard** — cerut explicit de utilizator: secțiunea + „Adaugă document" din panoul Maria permite azi doar scrierea manuală de + text într-un textarea; de înlocuit/completat cu un input de tip fișier + care acceptă selecția mai multor fișiere deodată (upload multipart, nu + JSON), pentru administrare mai rapidă a depozitului. **Neimplementat încă.** + +Bug reparat în timpul instalării inițiale (înainte de consolidare): `install.sh` +lega unitatea dashboard-ului propriu la o cale greșită — devenit irelevant +odată cu eliminarea acelui dashboard.