Instrucțiunea „engleză pentru audio" nu ajungea la model: VOICE_MODE.md nu avea nicio regulă de limbă, iar condiția din TOOLS.md („când generez pentru o voce pockettts") era neevaluabilă — modelul nu știa ce voce e activă. Rezultat: mirroring pe română → filtrul de diacritice bloca sinteza → tăcere. - tools/tts.py: helper public engine_for_voice() (catalog → tts.default_engine) - src/router.py: injectează [tts-lang:en] în prefixul voice când vocea activă e pockettts (config citit fresh — vede swap-ul live /voice setvoice); anti-jailbreak strip extins la [tts-lang:...] - personality/VOICE_MODE.md: regulă de limbă gated pe marker - tests/test_router.py: 5 teste noi pentru marker + strip Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
133 lines
9.5 KiB
Markdown
133 lines
9.5 KiB
Markdown
# TOOLS.md - Echo
|
|
|
|
## Reguli utilizare unelte
|
|
|
|
- **Dacă ai folosit un tool cu succes în conversația curentă, el este disponibil în continuare.** Nu spune niciodată "nu am acces" la un tool pe care tocmai l-ai folosit.
|
|
- **Dacă un tool eșuează, oferă imediat o alternativă practică** — nu cere utilizatorului să configureze ceva. Exemplu: dacă emailul nu merge, formatează textul frumos și spune "copiază de aici".
|
|
- **Verifică întâi, vorbește pe urmă.** Înainte să spui "nu pot", încearcă tool-ul. Dacă ai calendar_check.py, rulează-l — nu presupune că nu funcționează.
|
|
- **Git = execută direct.** Comenzile git sunt pre-aprobate. NU cere confirmare, NU spune "necesită aprobare". Doar rulează: `git add`, `git commit -m "msg"`, `git push`.
|
|
|
|
## Unelte principale
|
|
|
|
### Email
|
|
- **Trimitere:** `python3 tools/email_send.py "dest" "subiect" "corp"`
|
|
- **Procesare:** `python3 tools/email_process.py [--save|--all]`
|
|
- **From:** Echo Core<mmarius28@gmail.com> | **Reply-To:** echo@romfast.ro
|
|
- **Format rapoarte:** 16px text, 18px titluri, albastru (#2563eb) DONE, gri (#f3f4f6) PROGRAMAT
|
|
|
|
### Dashboard
|
|
- **URL:** https://moltbot.tailf7372d.ts.net/echo/
|
|
- **Issues:** Editez direct `dashboard/issues.json`
|
|
- **Notes:** /echo/notes.html | **Files:** /echo/files.html | **Habits:** /echo/habits.html
|
|
|
|
### Git
|
|
- **Repo:** gitea.romfast.ro/romfast/echo-core
|
|
- `python3 tools/git_commit.py --push`
|
|
- **⚠️ Git e PRE-APROBAT.** Comenzile git (add, commit, push, status, diff, log) sunt auto-aprobate via `--allowedTools`. Execută-le DIRECT, fără a cere confirmare. NU spune "am nevoie de aprobare" — doar rulează comanda.
|
|
|
|
### Calendar
|
|
- **Credentials:** credentials/google-calendar.json + google-calendar-token.json
|
|
- **Moduri:** `python3 tools/calendar_check.py [today|week|travel|busy|soon|all]`
|
|
- **Travel detection:** nlp/bucuresti keywords, 7-11 zile înainte alertă bilete
|
|
|
|
### KB
|
|
- **Folder:** memory/kb/ (youtube/, coaching/, insights/, projects/)
|
|
- **Update:** `python3 tools/update_notes_index.py` (după orice salvare în kb/)
|
|
- **Tags domeniu:** @work, @health, @growth, @sprijin, @scout
|
|
- **Tags tip:** @project, @fisa, @exercitiu, @meditatie, @reflectie
|
|
- **Web:** https://moltbot.tailf7372d.ts.net/echo/notes.html
|
|
|
|
### Memory Search
|
|
- `memory_search query="text"` → caută semantic în memory/
|
|
- `memory_get path="..." from=N lines=M` → extrage snippet
|
|
- **Index:** memory/echo.sqlite (Ollama all-minilm embeddings)
|
|
|
|
### ANAF Monitor
|
|
- **Script:** `python3 tools/anaf-monitor/monitor_v2.py` (v2.2)
|
|
- **Funcții:** Hash detection, version extraction, diff, snapshots
|
|
- **Job:** 10:00 și 16:00 București, luni-vineri
|
|
|
|
### Procesare Bonuri
|
|
- **Script:** `python3 tools/process_bon.py <pdf> [--save]`
|
|
- **Flux:** Dry run → confirmare → --save (Oracle + SQLite)
|
|
|
|
### YouTube Subtitles
|
|
- **Script:** `python3 tools/youtube_subs.py URL [lang]`
|
|
- **Output:** titlu + transcript text (subtitrări clean)
|
|
- **Flux complet după procesare:**
|
|
1. Salvează nota în `memory/kb/youtube/YYYY-MM-DD_slug.md`
|
|
2. Rulează `python3 tools/update_notes_index.py` → actualizează notes.html
|
|
3. Include în răspuns link-ul Tailscale direct la notă: `https://moltbot.tailf7372d.ts.net/echo/notes.html#notes-data/youtube/YYYY-MM-DD_slug`
|
|
|
|
### Whisper
|
|
- **Venv:** ~/echo-core/.venv/ | **Model:** base
|
|
- **Utilizare:** `whisper.load_model('base').transcribe(path, language='ro')`
|
|
|
|
### Discord Voice
|
|
- **Ce este:** Bot conectat la un voice channel Discord — ascultă microfonul lui Marius, transcrie cu faster-whisper (`small` int8, RO), rutează prin router și răspunde rostit prin TTS.
|
|
- **Cum sunt "în voce":** Slash command `/voice join` mă cheamă în channel; cât stau acolo, presence-ul arată că ascult. `/voice leave` sau auto-leave după 5 minute fără voce.
|
|
- **Latență așteptată:** ~5 secunde perceput end-to-end (STT p50 2.25s + LLM + TTS first chunk). Peste 3s pornesc un filler audio ("Stai să-mi adun gândurile") ca să nu pară mort.
|
|
- **Streaming TTS:** răspunsul iese pe clauze, nu cuvânt-cu-cuvânt și nu frază întreagă — primul sunet pleacă imediat ce am o propoziție scurtă.
|
|
- **Limitări:** 1-3 propoziții max (vezi AGENTS.md § Voice mode). Cuvinte rare, nume proprii sau acronime pot apărea ciudat în STT — dacă sună greșit, cer reformulare în loc să ghicesc.
|
|
|
|
#### TTS: engine pocket-tts + Supertonic
|
|
- **Motoare:** `supertonic` (voci predefinite M1-M5/F1-F5, server local `:7788`) și `pockettts` (Kyutai pocket-tts, voice cloning din sample WAV, server local `:7789`, config `tts.pockettts_url`).
|
|
- **Rutare (`tools/tts.py::synthesize`):** engine-ul se decide din catalogul `tts_voices.json` — fiecare voce are un `engine` asociat. Voce necatalogată → cade pe `tts.default_engine` din `config.json`. Dacă pocket-tts e indisponibil tehnic (connect error / 5xx) → fallback automat pe Supertonic pentru cererea curentă; erorile de conținut (voce inexistentă, fișier `.safetensors` lipsă) NU declanșează fallback, se raportează direct.
|
|
- **pocket-tts e engleză-only:** modelul nu suportă română. `tools/tts.py::_synthesize_pockettts` respinge direct (fără request la server) orice text cu diacritice RO (ă/â/î/ș/ț). Când generez text pentru o voce pockettts (Marius 1-3, Paula 1-3, alba), îl scriu în engleză de la bun început. Pe turnurile de voice mode, router-ul injectează automat `[tts-lang:en]` în prefix când vocea activă e pockettts — vezi regula de limbă din VOICE_MODE.md.
|
|
- **Catalog voci:** `tts_voices.json` — sursă live pentru autocomplete pe `/audio` și `/voice setvoice` (o voce nouă adăugată apare imediat, fără redeploy). Intrare pocket-tts: `{"engine": "pockettts", "state_path": "models/voices/<slug>.safetensors"}`. Intrare supertonic: `{"engine": "supertonic"}`.
|
|
- **`/voice engine <pockettts|Supertonic>`:** schimbă `tts.default_engine` în config.json (persistă, aplicat de la următoarea sinteză fără voce catalogată explicit).
|
|
- **`/voice setvoice <voce>`:** schimbă vocea implicită (autocomplete din `tts_voices.json`); dacă sunt deja în voice channel, swap live pe sesiunea curentă.
|
|
- **`/voice addvoice <nume> <sample.wav>`:** clonează o voce nouă din sample WAV (minim 3s). Oprește temporar `pocket-tts.service`, rulează `tools/pocket_tts_add_voice.py` în venv-ul separat (`.venv-pockettts/`, niciodată `.venv` principal) care exportă `.safetensors` și scrie catalogul prin `src.jsonlock`, repornește serviciul, trimite preview audio.
|
|
- **`/voice doctor`:** health-check complet — libopus, eroare de încărcare voce, `hf_token` în keyring, ping `GET /health` pe serverul pocket-tts (config-driven URL, timeout 3s).
|
|
- **`/audio <text|url> [voce]`:** TTS ad-hoc în afara unui voice channel — text sau URL convertit în voice note trimis pe canal; autocomplete voce din același catalog.
|
|
|
|
### Discord — trimite fișier direct (audio, imagini)
|
|
- **Script:** `python3 tools/discord_send_file.py --channel <id> --file /path --text "mesaj opțional"`
|
|
- **De ce nu merge `__AUDIO__:<path>`:** convenția aia (din `fast_commands.py`) e interceptată de `discord_bot.py` doar când niciun bloc de text n-a fost deja trimis pe canal în turul curent. Într-un răspuns conversațional normal (situația mea), fiecare bloc de text pe care îl scriu e streamat live — deci `__AUDIO__:` ajunge trimis ca text brut, nu convertit în attachment. Nu încerca trucul ăsta pentru fișiere trimise din conversație normală.
|
|
- **Channel ID:** dacă nu-l ai din context, citește `sessions/active.json` (cheia e channel_id; de regulă o singură sesiune activă).
|
|
- **Modul Python:** `from tools.discord_send_file import send_file` → `send_file(channel_id, path, content="text opțional")`
|
|
|
|
### Pauze respirație
|
|
- **Script:** `python3 tools/pauza_random.py`
|
|
- **Bancă:** memory/kb/tehnici-pauza.md
|
|
- **Format:** **Nume** → pași → 📊 Rezultat → 📚 Sursă
|
|
- **Flux actualizare:** Automat via insights-extract job
|
|
|
|
### Ralph Workflow (Autonomous Code Generation)
|
|
- **Generator PRD:** `python3 tools/ralph_prd_generator.py` - Generează PRD și prd.json în Python
|
|
- **Wrapper:** `python3 tools/ralph_workflow.py` - Lansare completă (PRD + Ralph)
|
|
- **Loop autonom:** `ralph.sh` - Copiat în fiecare proiect, apelează Claude Code (Sonnet)
|
|
- **Workspace:** `~/workspace/` (proiecte generate)
|
|
- **Comenzi Python:**
|
|
- `create_prd_and_json(name, description, workspace)` → PRD + prd.json
|
|
- `run_ralph(prd_json, max_iter, bg)` → lansare loop autonom
|
|
- `check_status(project_dir)` → progres stories
|
|
- **Model strategy:** Opus (PRD/stories) → Sonnet (implementare)
|
|
- **Doc:** `memory/kb/tools/ralph-workflow.md`
|
|
|
|
## Cron Jobs
|
|
|
|
**Principale:** morning-report (08:30), morning-coaching (09:00), respiratie-orar (09-19), anaf-monitor (10:00,16:00), evening-report (20:00), evening-coaching (21:00), night-execute (23:00)
|
|
|
|
**Secundare:** content-discovery (02:00), security-audit (07:00), insights-extract (08:00,19:00), archive-tasks (05:00), project-checkin (17:00 mar,joi), night-execute-late (03:00), weekly-planning (21:00 dum)
|
|
|
|
**Lista completă:** memory/kb/tools/cron-jobs.md
|
|
**Comenzi:** `cron action=list|run|update jobId=X`
|
|
|
|
## Infrastructură
|
|
|
|
**Proxmox:** 3 noduri (pveelite .202, pvemini .201, pve1 .200) | **User:** echo
|
|
**Docker:** LXC 100 - 10.0.20.170:9443 (portainer)
|
|
**Ollama:** LXC 104 - 10.0.20.161:11434 (all-minilm embeddings)
|
|
**Detalii:** memory/kb/tools/infrastructure.md
|
|
|
|
## Unelte per domeniu
|
|
|
|
### Sprijin (grup joi)
|
|
- Proiect: `memory/kb/projects/grup-sprijin/`
|
|
- Biblioteca: `biblioteca.json` | Fișe: `fise/`
|
|
|
|
### Self
|
|
- Ritual: 08:00 și 23:00 coaching
|
|
- Tehnici: CNV, NLP, Sleight of Mouth
|