docs: persist Maria WhatsApp+RAG documentation (was written but never committed)
Adds docs/maria-whatsapp-rag-prototype.md and docs/discord-bridge-context.md, and links them from CLAUDE.md. Includes the 2026-08-31 update: local Ollama install for embeddings, rclone installed (DRIVE_REMOTE still pending a Google service account the user must create), and a confirmed end-to-end indexing test with 6 real documents pulled from Drive. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,12 +2,21 @@
|
|||||||
|
|
||||||
Vezi `README.md` pentru context general.
|
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
|
## Documentație
|
||||||
|
|
||||||
| Subiect | Fișier |
|
| Subiect | Fișier |
|
||||||
|---------|--------|
|
|---------|--------|
|
||||||
| Infrastructură Proxmox (noduri, LXC, VM, proiecte) | [docs/infrastructure.md](docs/infrastructure.md) |
|
| 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) |
|
| 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/`.
|
Detalii complete Proxmox (config, troubleshooting, incidente): `/workspace/romfastsql/proxmox/`.
|
||||||
|
|
||||||
|
|||||||
40
claude-agent/docs/discord-bridge-context.md
Normal file
40
claude-agent/docs/discord-bridge-context.md
Normal file
@@ -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 <sid> --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.
|
||||||
146
claude-agent/docs/maria-whatsapp-rag-prototype.md
Normal file
146
claude-agent/docs/maria-whatsapp-rag-prototype.md
Normal file
@@ -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.
|
||||||
Reference in New Issue
Block a user