Files
claude-agent/TODO.md
2026-08-31 22:13:43 +00:00

171 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# TODO — progresul funcționalităților
Registrul viu al lucrului cerut prin puntea Discord. **Botul îl citește la începutul
oricărei cereri de dezvoltare și îl actualizează la final** — vezi
[docs/flux-dezvoltare.md](docs/flux-dezvoltare.md).
Stări: `🔵 planificat` · `🟡 în lucru` · `⛔ blocat` · `✅ gata` · `❌ abandonat`
---
## 🟡 În lucru
*(nimic în acest moment)*
---
## ⛔ Blocate
*(nimic blocat)*
---
## 🔵 Planificate
### Mesaje vocale din Discord
- **Unde:** `romfastsql/proxmox/lxc171-claude-agent/discord-bridge/bot.py`
- **Ce ar însemna:** atașamentele audio (mesajele vocale Discord) transcrise local
înainte de a intra în prompt. Whisper rulează pe CPU pe LXC 171, deci trebuie
măsurat întâi costul în timp per mesaj.
- **De ce nu acum:** nu a fost cerut; e singura limitare rămasă după atașamente.
- **Actualizat:** 2026-08-31
---
## ✅ Gata
### Maria — rank hibrid, escaladare la suport, dicționar Oracle
- **De unde a pornit:** o captură cu o eroare Oracle a primit un răspuns generic — corect
gramatical, dar despre altă eroare. Nu se putea nici măcar afla ce citise OCR-ul.
- **Ce s-a făcut:** (1) textul OCR se loghează integral, cu interogarea de căutare și
sursele alese cu scoruri; (2) ordonare hibridă embeddings + BM25 cu fuziune RRF, și o
decizie separată „avem acoperire?"; (3) când nu avem, modelul nu mai e întrebat deloc —
întrebarea pleacă la suport pe WhatsApp, cu captura atașată și o referință; (4) dicționar
de 29 de erori Oracle uzuale, scris pentru clienți, nu pentru administratori.
- **De ce hibrid și nu doar embeddings:** măsurat, intervalele se suprapun — întrebările
bune dau 0,600–0,816 și cele străine 0,534–0,685. Codurile (`ORA-01722`, `D406`, `CIF`)
sunt exact ce ratează căutarea semantică. Pragurile sunt măsurate cu
`ops/calibrate-rank.py`, nu alese din burtă: 19/19 pe setul de cazuri.
- **Două lucruri găsite în log pe drum:** fiecare mesaj din self-chat sosea de două ori
(pe `@s.whatsapp.net` și pe `@lid`), deci Maria răspundea dublu — dedup pe `key.id`.
Și reindexarea refăcea toate embeddings-urile (~7 s fiecare): acum refolosește vectorii
chunk-urilor nemodificate — 29 noi în loc de 169.
- **Un bug vechi reparat pe parcurs:** documentele adăugate din dashboard ajungeau în
oglinda Drive și dispăreau la următorul `rclone sync`. Acum există `documents-local/`.
- **Rămas de făcut:** `SUPPORT_JID` e propriul număr, pentru testare — de schimbat cu
numărul sau grupul echipei de suport. Dicționarul Oracle trăiește doar pe container;
locul lui e `document_store` din Drive.
- **Verificat:** 73 de teste (de la 26 la începutul zilei); o escaladare reală cu captură
a plecat pe WhatsApp și apare în dashboard.
- **Terminat:** 2026-08-31
### Maria — asociere prin cod de telefon și citirea capturilor cu erori
- **Ce s-a făcut:** două lucruri cerute în aceeași frază. (1) Asocierea WhatsApp se poate
face acum și cu un cod de 8 caractere, nu doar cu QR — util când nu ai un ecran de dus în
fața telefonului. (2) Maria citește capturile de ecran trimise pe WhatsApp: puntea
descarcă imaginea, `rag/ocr.py` o trece prin tesseract `ron+eng`, restul lanțului rămâne
neschimbat.
- **De ce OCR și nu un model vizual:** modelul de răspuns (Qwen3.5-2B pe LXC 104) e strict
text. Nu e o alegere de calitate, e singura cale fără a schimba modelul.
- **Blocaje găsite pe drum:** endpoint-ul `/pair` exista, dar după introducerea codului
WhatsApp cere un restart (515) care consuma din bugetul de reîncercări și putea opri
puntea la a cincea asociere. Separat, capturile trimise „efemer" ajungeau ca mesaje
fără conținut și se aruncau tăcut — lipsea despachetarea `ephemeralMessage`.
- **O decizie care nu se vede din cod:** căutarea în index merge doar pe liniile care arată
a eroare, nu pe toată captura; un ecran de meniuri și totaluri diluează embedding-ul.
Modelul primește totuși fereastra întreagă, marcată ca text OCR.
- **Verificat:** 16 teste noi (suita Maria: 42 pass), OCR real pe o captură cu
`ORA-01722: invalid number` — extras corect; ambele servicii repornite și conectate.
- **Terminat:** 2026-08-31
### Echo re-legat la WhatsApp după delogare
- **Ce s-a întâmplat:** puntea WhatsApp a lui Echo (LXC 110) fusese delogată de pe telefon
dimineața (401). Utilizatorul a eliberat un slot de dispozitiv; puntea a fost re-legată
prin **cod**, nu prin QR — `auth/` salvat în `auth.bak-2026-08-31`, serviciul repornit,
`POST /pair`. Acum e dispozitivul `:14` al aceluiași cont.
- **Ce s-a lămurit:** de ce nu răspund ambele punți în chatul „Eu". Amândouă primesc
mesajele, dar Echo le aruncă pe toate cu `fromMe && !isGroup`, iar în self-chat tot ce
scrii e `fromMe`. Echo folosește „Eu" doar ca destinație de notificări. Echilibrul e
accidental — scris în `romfastsql/docs/chatboti-si-punti.md`.
- **Terminat:** 2026-08-31
### Maria mutată pe LXC 171, cu tot ce s-a construit
- **Ce s-a făcut:** LXC 171 asociat la WhatsApp (+40723197939, dispozitiv nou al aceluiași
cont); prototipul de pe LXC 104 oprit și dezactivat. `llama-qwen35` rămâne pe 104 și e
folosit de 171 prin rețea (`LLM_URL=http://10.0.20.161:8091`).
- **Rezultat:** Maria a trecut de la 24 de chunk-uri dintr-un singur fișier la 173 din 11
documente, plus sincronizare Drive automată.
- **Un blocaj găsit pe drum:** după asociere nu răspundea nimic. WhatsApp livrează
self-chat-ul cu JID de tip LID (`51947713372214@lid`), iar filtrul compara doar cu
`<număr>@s.whatsapp.net` — arunca tot, fără nicio urmă în log. Reparat în
`whatsapp/index.js`; mesajele respinse se loghează acum cu motivul.
- **Verificat:** „token efactura expirat" → preluat, căutat în RAG, răspuns trimis.
- **Terminat:** 2026-08-31
### Maria — sincronizare Google Drive
- **Unde:** `maria-whatsapp-bridge/ops/setup-drive.sh`, `rag/sync.py`,
`docs/rclone-google-drive-headless.md` (în romfastsql)
- **Ce face:** `rclone` autorizat cu token obținut pe stația Windows (`rclone authorize`,
fără cont de serviciu Google), dosarul fixat pe ID. `maria-sync.timer` trage la 10 min.
- **Rezultat:** depozitul a trecut de la 6 la 11 documente — au intrat SAF-T D406,
e-Factura (`.md` + `.xml`), roaauto și roagest, care lipseau complet.
- **Terminat:** 2026-08-31
### Maria indexează .xml, preferat peste .md
- **Unde:** `maria-whatsapp-bridge/rag/store.py` (`DOC_EXTENSIONS`,
`documents_for_index`), `rag/indexer.py` (`chunk_xml`), `rag/sync.py`,
`discord-bridge/dashboard/api.py` + `index.html`, `tests/`
- **Ce face:** `.xml` intră în depozit și, când același document există și ca `.md`,
doar `.xml` se indexează (`.xml` > `.md` > `.txt`); cel umbrit rămâne pe disc și e
marcat în dashboard. XML-ul se taie câte un chunk per problemă, cu mesajul de eroare
și rezolvarea împreună.
- **De ce:** la `d406_saft_knowledge`, `.xml` e cu 3 luni mai nou și cu 50% mai mare
decât `.md`. Tăierea pe linii goale ar fi separat eroarea de rezolvare.
- **Verificat:** 20 de teste noi (suita Maria, prima ei suită); puntea Discord 426 pass.
- **Terminat:** 2026-08-31
### Atașamente Discord → Claude (imagini + fișiere text)
- **Unde:** `romfastsql/proxmox/lxc171-claude-agent/discord-bridge/bot.py`
(`build_user_content`), `runner.py` (`user_message`), `tests/test_attachments.py`
- **Ce face:** imaginile png/jpeg/gif/webp ajung ca blocuri `image` (max 4, max 3,5 MB),
fișierele text intră în prompt (max 4, trunchiate la 100 KB), restul sunt doar numite.
Merge și mid-tur, ca steering. Un mesaj doar cu poză nu mai e respins ca gol.
- **Verificat:** 31 de teste noi, suita 426 pass; blocurile de imagine testate pe CLI-ul
real (`--input-format stream-json`), Claude descrie corect imaginea.
- **Terminat:** 2026-08-31
### Plan cu Opus, execuție cu Sonnet
- **Unde:** [docs/flux-dezvoltare.md](docs/flux-dezvoltare.md), referit din `CLAUDE.md`
- **Ce face:** orice cerere de dezvoltare trece întâi printr-un subagent `Plan` pe Opus;
planul se postează în fir, apoi execuția merge pe Sonnet, în sesiunea firului.
- **Terminat:** 2026-08-31
### Memorie comună claude-agent ↔ romfastsql
- **Ce face:** `~/.claude/projects/-workspace-claude-agent/memory` e symlink către memoria
proiectului `romfastsql`, deci firele Discord nu mai pornesc fără context.
- **Terminat:** 2026-08-31
### Repo propriu pentru claude-agent + reparare Gitea
- **Ce face:** `/workspace/claude-agent` e repo separat
(`git@gitea.romfast.ro:romfast/claude-agent.git`), scos din `romfast/workspace`.
Gitlink-urile fără `.gitmodules` care dădeau 500 pe pagina repo-ului `workspace` au
fost scoase din index.
- **Terminat:** 2026-08-31
---
## Jurnal
Cea mai recentă intrare prima. O linie per schimbare de stare.
- 2026-08-31 — ✅ Maria: rank hibrid + escaladare la suport + dicționar de erori Oracle
- 2026-08-31 — ✅ Maria: asociere prin cod de telefon + citirea capturilor cu erori (OCR)
- 2026-08-31 — ✅ Echo re-legat la WhatsApp prin cod, ca dispozitiv `:14`
- 2026-08-31 — ✅ Maria mutată pe LXC 171; reparat filtrul care arunca mesajele LID
- 2026-08-31 — ✅ Maria — sincronizare Google Drive, 6 → 11 documente
- 2026-08-31 — ✅ Maria indexează .xml, preferat peste .md
- 2026-08-31 — ✅ Atașamente Discord → Claude (imagini + fișiere text)
- 2026-08-31 — ✅ Plan cu Opus, execuție cu Sonnet
- 2026-08-31 — ✅ Memorie comună claude-agent ↔ romfastsql
- 2026-08-31 — ✅ Repo propriu pentru claude-agent + reparare Gitea