feat(maria): asociere prin cod de telefon si citirea capturilor cu erori
Doua lucruri cerute de utilizator, ambele pe acelasi drum: sa poti lega
puntea fara sa ai un ecran de scanat, si sa poti trimite Mariei o poza cu
eroarea in loc sa transcrii mesajul.
Asociere prin cod de 8 caractere (alternativa la QR):
- endpoint-ul /pair exista, dar nu era folosibil: fara `browser` explicit
WhatsApp refuza codul, iar dupa introducerea lui corecta serverul cere un
restart (515) care consuma din bugetul de reincercari si putea opri puntea.
Acum descriptorul e Browsers.ubuntu('Chrome') si restartRequired reconecteaza
imediat, fara sa numere.
- codul are TTL de 3 minute, iar /status il da doar cat timp e valabil —
un cod expirat afisat in dashboard trimite omul sa tasteze degeaba.
- dashboard: camp pentru numar + buton, in acelasi card cu QR-ul.
Imagini cu erori (capturi de ecran):
- puntea descarca imaginile in ~/.maria-bridge/media/ (imageMessage sau
document cu mimetype image/*, si prin ambalajele efemer/"vezi o data" —
fara despachetare pareau mesaje fara continut si se aruncau tacut).
- rag/ocr.py: tesseract ron+eng. Modelul de raspuns e strict text, deci OCR
nu e o optiune de calitate, e singura cale.
- cautarea in index merge DOAR pe liniile care arata a eroare; o fereastra
intreaga de meniuri si totaluri dilueaza embedding-ul si scoate chunk-uri
fara legatura. Modelul primeste captura intreaga, marcata ca text OCR.
- capturile se sterg imediat dupa citire (pot contine date de client).
- cand nu se citeste nimic si nu exista legenda, Maria cere textul erorii
in loc sa raspunda in gol.
16 teste noi (42 in total). install.sh verifica tesseract; README documenteaza
ambele metode de asociere si drumul unei capturi.
Separat, in docs/chatboti-si-punti.md: chatul "Eu" e vazut de AMBELE punti de pe
numar. Puntea lui Echo (LXC 110) e asociata ca dispozitiv :11 al aceluiasi cont,
momentan nelegata dar pornita — daca se reasociaza, raspunde in "Eu" langa Maria.
Notat si ca serviciile lui Echo sunt unitati de UTILIZATOR: `systemctl is-active`
ca root raspunde "inactive" desi botul ruleaza.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4uzvgm7AyJch5WH8QHRhY
This commit is contained in:
@@ -60,12 +60,16 @@ embeddings.
|
||||
WhatsApp (self-chat, sau numarul legat)
|
||||
|
|
||||
v
|
||||
whatsapp/index.js (Baileys) -- API HTTP :8099 (/status /send /messages /react /qr)
|
||||
whatsapp/index.js (Baileys) -- API HTTP :8099 (/status /send /messages /react /qr /pair)
|
||||
| descarca imaginile primite in ~/.maria-bridge/media/
|
||||
|
|
||||
v
|
||||
rag/consumer.py -- polling la /messages, RAG stateless (FARA memorie intre mesaje)
|
||||
| vezi docs/maria-whatsapp-rag-prototype.md pentru motiv
|
||||
v
|
||||
rag/ocr.py -- capturile de ecran -> text (tesseract), inainte de RAG
|
||||
|
|
||||
v
|
||||
rag/store.py -- depozit documente (.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
|
||||
@@ -104,15 +108,77 @@ curl -fsSL https://ollama.com/install.sh | sh
|
||||
ollama pull nomic-embed-text # ~274 MB, CPU-only pe acest container
|
||||
```
|
||||
|
||||
Bridge-ul WhatsApp NU porneste automat la instalare — cere scanarea unui cod QR
|
||||
Pentru citirea capturilor de ecran primite (vezi „Imagini cu erori" mai jos):
|
||||
```bash
|
||||
sudo apt-get install -y tesseract-ocr tesseract-ocr-ron
|
||||
```
|
||||
|
||||
Bridge-ul WhatsApp NU porneste automat la instalare — cere asocierea cu telefonul
|
||||
(actiune manuala, o singura data):
|
||||
|
||||
```bash
|
||||
./ops/install.sh --start
|
||||
# apoi deschide dashboard-ul puntii Discord si scaneaza codul QR din
|
||||
# sectiunea "Maria — WhatsApp + RAG" -> cardul "Conectare WhatsApp"
|
||||
# apoi deschide dashboard-ul puntii Discord, sectiunea "Maria — WhatsApp + RAG"
|
||||
# -> cardul "Conectare WhatsApp", si alege una din cele doua metode (mai jos)
|
||||
```
|
||||
|
||||
## Asocierea cu telefonul: QR sau cod
|
||||
|
||||
Ambele duc la acelasi rezultat — puntea devine un *dispozitiv conectat* al contului.
|
||||
Alegerea e practica, nu tehnica:
|
||||
|
||||
| | Cand se foloseste |
|
||||
|---|---|
|
||||
| **Cod QR** | Ai dashboard-ul deschis pe un ecran pe care telefonul il poate fotografia. |
|
||||
| **Cod de asociere** (8 caractere) | Esti pe telefon, sau ecranul cu QR-ul e la distanta: scrii numarul in dashboard, primesti un cod si il tastezi pe telefon. |
|
||||
|
||||
Pentru codul de asociere, in dashboard: scrie numarul **in format international,
|
||||
fara `+` si fara `00`** (ex. `40723197939`), apasa „Cere cod de asociere", apoi pe
|
||||
telefon: WhatsApp -> Dispozitive conectate -> Conecteaza un dispozitiv ->
|
||||
**Conecteaza cu numar de telefon** -> tastezi codul.
|
||||
|
||||
Codul e valabil **~3 minute**; dupa ce expira, dashboard-ul il marcheaza ca expirat
|
||||
si trebuie cerut altul. Dupa introducerea corecta, WhatsApp inchide conexiunea cu
|
||||
codul `restartRequired` (515) — puntea se reconecteaza singura, imediat; nu e o
|
||||
eroare si nu consuma din bugetul de reincercari.
|
||||
|
||||
Din linia de comanda, aceleasi lucruri:
|
||||
```bash
|
||||
curl -s -X POST -H 'Content-Type: application/json' \
|
||||
-d '{"phone":"40723197939"}' http://127.0.0.1:8099/pair
|
||||
curl -s http://127.0.0.1:8099/status | python3 -m json.tool # cod + secunde ramase
|
||||
```
|
||||
|
||||
Codul se poate cere doar cat timp sesiunea NU e inregistrata. Daca puntea raspunde
|
||||
„sesiunea e deja inregistrata", opreste-o, sterge `~/.maria-bridge/whatsapp-auth/`
|
||||
si porneste-o din nou — dar atentie, asta desface asocierea existenta.
|
||||
|
||||
## Imagini cu erori
|
||||
|
||||
Utilizatorii trimit aproape intotdeauna o captura cu fereastra de eroare, nu textul
|
||||
ei. Puntea descarca imaginea in `~/.maria-bridge/media/`, iar consumer-ul o trece
|
||||
prin **tesseract** (`ron+eng`) inainte de RAG. Modelul de raspuns (Qwen3.5-2B pe
|
||||
LXC 104) e strict text, deci OCR-ul e singura cale — nu e o optiune de calitate.
|
||||
|
||||
Doua detalii care nu se vad din cod la prima citire:
|
||||
|
||||
- **Cautarea in index nu foloseste toata captura.** Un ecran intreg de meniuri,
|
||||
coloane si totaluri dilueaza embedding-ul si scoate chunk-uri fara legatura. Se
|
||||
cauta doar dupa liniile care arata a eroare (`ORA-…`, „eroare", „nu exista", …);
|
||||
modelul primeste totusi fereastra intreaga, marcata explicit ca text OCR, ca sa nu
|
||||
trateze greselile de recunoastere ca date exacte. Vezi `rag/ocr.py`.
|
||||
- **Capturile se sterg imediat dupa citire.** Pot contine date de client si nu exista
|
||||
niciun motiv sa ramana pe disc. Ce ramane dupa un restart in mijlocul procesarii se
|
||||
curata la pornirea puntii (dupa 24h).
|
||||
|
||||
Legenda imaginii, daca exista, conteaza: intra si in intrebare si in cautare. Daca
|
||||
OCR-ul nu gaseste nimic lizibil si nu exista legenda, Maria cere textul erorii in
|
||||
loc sa inventeze un raspuns.
|
||||
|
||||
Limite: `MAX_MEDIA_MB` (implicit 8) pentru imaginea bruta, `OCR_MAX_CHARS`
|
||||
(implicit 1500) pentru textul trimis modelului, `OCR_TIMEOUT_S` (60).
|
||||
Videoclipurile, audio si documentele non-imagine sunt in continuare ignorate.
|
||||
|
||||
## Dashboard (comun cu puntea Discord)
|
||||
|
||||
Nu exista un dashboard separat pentru Maria. Controlul se face din dashboard-ul
|
||||
@@ -120,7 +186,7 @@ puntii Discord — vezi `../discord-bridge/README.md` pentru URL si autentificar
|
||||
(`DASHBOARD_TOKEN` din `~/.claude-discord/env`, tunel SSH sau Tailscale la
|
||||
`/claude`). Acolo, sectiunea "Maria — WhatsApp + RAG":
|
||||
- start/stop/restart pentru puntea WhatsApp si consumer-ul RAG
|
||||
- starea conexiunii WhatsApp si codul QR de asociere (cand nu e conectat)
|
||||
- starea conexiunii WhatsApp si asocierea (cod QR sau cod de 8 caractere), cand nu e conectat
|
||||
- listare, adaugare si stergere documente din depozitul RAG
|
||||
- reconstruire index manual, sau sincronizare Drive imediata
|
||||
- ultimele linii din logurile fiecarui serviciu Maria (`whatsapp.log`/`rag.log`)
|
||||
@@ -207,7 +273,8 @@ mtime + marime, vezi `rag/sync.py`), ca sa nu reface embeddings degeaba.
|
||||
|
||||
```bash
|
||||
cd /workspace/romfastsql/proxmox/lxc171-claude-agent/maria-whatsapp-bridge
|
||||
python3 -m pytest # preferinta de format + taierea XML, fara retea si fara Ollama
|
||||
python3 -m pytest # preferinta de format, taierea XML, OCR si mesajele cu imagine
|
||||
# — fara retea, fara Ollama si fara tesseract
|
||||
```
|
||||
|
||||
## Context conversational
|
||||
|
||||
Reference in New Issue
Block a user