Changelog - Lyra¶
[Unreleased]¶
[1.4.0] - 2026-11-06¶
Breaking¶
scripts/async_mcp_wrapper.pyno longer falls back to~/dev/fedora-setup/scripts: background MCP scripts are resolved only from the root-owned copy (/usr/local/lib/lyra/scripts,LYRA_SCRIPTS_DIRorpaths.scripts). The old path was user-writable and covered by no sudoers rule; run the installer (or setLYRA_SCRIPTS_DIR) if you relied on it.
Added¶
- Releases:
sbom.json(CycloneDX inventory of the base andgpudependencies, exact versions fromuv.lock) attached to each GitHub release; wheel and sdist carry a SLSA provenance attestation and an SBOM attestation, both verifiable withgh attestation verify. The release refuses to build whenuv.lockis stale. Procedure indocs/dev/release-process.md.
Security¶
- Background tasks: their
.log,.pid,.progressand.donefiles move from/tmp(predictable names, readable by every account) to a private 0700 directory,$XDG_RUNTIME_DIR/lyra/tasks(LYRA_TASK_DIRto override). The Discord webhook reaches the task wrapper through the environment, no longer as a command-line argument visible to every account in the process list. - Daemon socket: created with mode 0600 directly (umask around
bind) instead of being chmod-ed right after, and~/.lyrais created 0700. - The MCP
destructiveHintannotation now requires a strict confirmation in the daemon and in standalone mode, likeDANGEROUS_TOOLS. A third-party server that marked a tool destructive only got the soft[O/n]prompt (Enter = yes), and-yran it without asking: the annotation was read byPipeline.is_dangerous_action, which nothing called. Bundled servers are unaffected (fedora-agents annotates exactly the tools already listed). - Graphical installer (
install.sh --app, 127.0.0.1:9877): a web page open in the browser could start the install and answer its confirmations (no Host, Origin or Content-Type check; atext/plainPOST needs no CORS preflight; question ids wereask-1,ask-2...), andoptions.ollama_hostwas written unquoted into~/.bashrc, so a crafted value ran shell code at the next login. The backend now refuses a non-local Host (DNS rebinding), a foreign Origin and any non-JSON POST; question ids are random;ollama_hostmust be a host name or an IP (all frontends: app, TUI, headless) and is quoted in.bashrc.
Changed¶
- CI: ruff lint is now blocking (240 findings cleared: 139 were the documented
from manim import *of the intro animations, now a per-file ignore;main.pykeeps its CUDA-before-imports order under a justified E402 ignore). The test job also runsscenes/ironman.
Fixed¶
- Discord notifications: the webhook is read from
config.yaml, then from the neighbouringsecrets.yamlwhereconfig.yaml.exampleand the data-flow doc put it; onlyconfig.yamlwas read, so a webhook stored as documented sent nothing (daemon and standalone mode). scripts/async_mcp_wrapper.pyransudo -non scripts under~/dev/fedora-setup/scripts: no sudoers rule covers that user-writable path, so system clone, backup creation and backup restore failed when run in the background. It now uses the root-owned copy resolved bylyra.core.paths(/usr/local/lib/lyra/scripts,LYRA_SCRIPTS_DIR,paths.scripts).main_rag.py: the module docstring sat afterfrom __future__ import annotations, so it was not the docstring (and flagged every import); it is first again.- Bare
except:in ephaistos and the MCP client no longer swallow Ctrl+C. - Tests: the Iron Man red-flash test now checks the colour sent to the lamp (it computed it without asserting); the phase 0 timing test mocks the parallel state reads added with the refactor (it made real requests and measured their 2 s timeout).
- Dead code removed: an unused Zod pattern in the indexer, an unused score colour in the step display.
[1.3.1] - 2026-09-24¶
Added¶
- Daemon:
toolmessage on the socket for clients that only need one MCP call (name, arguments,confirmedoption). The daemon checks the HESTIA catalogue, asks for confirmation when the tool is dangerous and not confirmed, runs it under the busy lock and streamstool_resultthenresult. No model in the loop; used by neutroncore (roadmap issue 73).
Changed¶
- MCP_TOOLS.md regenerated:
tv.get_statenow reports volume, mute and ambilight;denon.get_statusreports mute, source and reachability (pylips-mcp 0.2.0, denon-mcp 0.2.0). - First release built and published by the shared release workflow (PyPI Trusted Publishing); 1.3.0 was tagged before the workflow existed.
[1.3.0] - 2026-09-24¶
Added¶
lyra --versionprints the installedlyra-assistantversion, or the pyproject version when run from sources (#15).scripts/gen_mcp_tools_md.pyregenerates docs/user/MCP_TOOLS.md from the live MCP servers, with a confirmation column derived fromlyra/core/constants.py.- EPHAISTOS variants
inventaire_vm(real VM names from vm_status orLYRA_VMS),lexique_courantandverbes_courants(everyday French synonyms and verbs, written outside any test set). - Fourth held-out set
tests/cases_hors_regles_3.py(50 phrasings, real machine names, ten tools never measured before); fifth settests/cases_hors_regles_4.py, sealed before iteration 16. scripts/bench_recall.py: mechanical recall of a set (rank of the expected tool, precision of the "net" criterion) without calling the model, the measurement to run before any bench.- EPHAISTOS variants
outil_par_machine,mots_courants_2,nombres_tri,mots_courants_3(iterations 15-16);net_assouplimeasured and refuted. - Iterations 17-21 ("99 % on every set"): variants
cartes_17,lumiere_sans_verbe,nom_de_vm(replayed),force_definitif; the five development sets reach 21/21, 51/51, 100/100, 50/50, 50/50 with qwen2.5-coder:0.5b; a sixth set (tests/cases_hors_regles_5.py) sealed first and measured once.
Changed¶
- EPHAISTOS: the 17 refuted or neutral variants are removed from the code (module 1581 -> ~810 lines); the 42 retained ones are the default configuration, still switchable one by one through
LYRA_EXPfor ablation. Word tables and lexicons move tolyra/models/cartes.py(data only). Mechanical recall and the benches are identical before and after (21/21, 51/51, 100/100). docs/articles/2026-09-boucle-ephaistos.fr.md: the improvement loop written up as a research report (abstract, method, results, limits, reproduction), with five SVG figures generated frombenchmarks/results/byscripts/gen_figures_boucle.py.
Fixed¶
- The daemon did not run the path the bench measured.
EnhancedPipelinesent EPHAISTOS a single spec, without thetool_name:prefix, then let a session-context injection and the intent classifier override the result: "reveille fedora-base" gavetv.power_on, "archive test-vm" gavetv.mute, "de la lumiere dans le salon" was answered as small talk (manual acceptance test, 2026-09-23). The pipeline now builds the specs exactly like the bench (specs_pour_ephaistos, shared), passes all of them, skips the context injection when the variants are active, and treats a query as a command when the spec sort is unambiguous (Ephaistos.est_net).tests/test_campaign_llm.py --reelmeasures this real path (one session per case, correct refusals of unknown VMs counted apart): 21/21, 43/43 and 91/92 on the three development sets. - One-shot calls: a pending clarification or choice left in the shared session polluted the next call ("mets staging-03 au repos" was read as an answer about preprod-10). It is cleared when nobody can answer.
- Argument names invented by the 0.5b in
missing_args("chromecast") no longer trigger a clarification; only real parameters of the tool count. - Hue: a
group_idthat does not exist on the bridge is replaced by the default group (real groups read at startup). - Performance mode (
-p) and-y: LYRA printed "Tu confirmes ?" then executed without waiting; it now says what it does. - Slang normalizer: URLs are no longer lowercased (a YouTube id is case-sensitive).
- A matching rule, or a spec sort that recognises a tool word, is a command whatever the intent classifier says ("silence sur l'ampli" and "les leds de la tele, tu me les enleves" got no action); a tool imposed by a net sort no longer triggers the disambiguation question.
- Rules: "affiche les taches" lists the running tasks; the Denon rule also answers to "ampli", "AVR" and "home cinema" ("l'ampli sur game"), a state question gives
get_status, "bascule ... sur le bluray" is a source change. - Security:
main_rag.pycompared a prefixed tool name (fedora.vm_destroy) to the short names ofDANGEROUS_TOOLS, so-yskipped the confirmation of destructive tools; it now usesis_dangerous_tool(). - Security: an empty answer (Enter) no longer confirms a sensitive or destructive action in the daemon UI and the terminal UI;
o/ouiis required, as inactions.py. - Security:
vm_snapshot(revert/delete),vm_importandvm_copyare now inDANGEROUS_TOOLS;PERFORMANCE_TOOLSentries are prefixed (the eightcast_*never matched), Denon and read-only tools added;main.py(legacy) no longer keeps its own diverging lists. - Rules:
tv.sound_onlyandtv.ambilight_colordo not exist in pylips-mcp; "son seul / mode musique" now maps totv.screen_off, a colour request toambilight_mode(manual)(pylips-mcp#7);tv.youtube_videosendsvideo(schema name) instead ofvideo_id. - Rules: "lance CMD sur VM" is an exec, "l'etat de la lampe" is not a VM status, "il est tard" is not a state question (found by the fourth set control).
scripts/index_rag_3tier.pyignores documents withoutserver_name(a localironman.run_scenewould have created an UNKNOWN server);config.yaml.exampledeclares the catt server.- EPHAISTOS: a tool imposed by a net sort was overridden by the second pass (
double_passe) and applied after the argument completion; the net criterion ignored the machine bonus. Three fixes with unit tests. - Rules: "eteins les leds de la tele" was a power_off (sixth set control).
- Config: the dead
security.destructive_toolslist (never read, listed a non-existentvm_delete) is removed from config.yaml.example;lyra/core/constants.pyis the only source.docs/dev/INDEX_RAG.mddocuments the v2 -> v3 regeneration order. - Rules: the screen-manager module is out of the registry (server absent from disk and config, lyra#24); a room name is not a VM; "arrete la synchro des lampes" is not a task kill; a question about the chromecast is
cast_status; "l'ambilight qui suit la musique" sets the mode.tracking.deleteandtracking.kill_taskrequire an explicit confirmation.
[1.2.0] - 2026-09-10¶
Added¶
- docs/user/DATA_FLOWS.md: what Lyra captures, keeps, and the optional network outputs with their switches.
- VOICES.md and docs/licenses/: Piper voice licences, Llama 3.2 Community License and use policy ("Built with Llama").
- THIRD_PARTY_LICENSES.md generated by
make licensesand checked in CI. - README: English summary, prerequisites table, security guarantees mapped to code and tests, clickable metrics, ecosystem block.
- ROADMAP.md.
Changed¶
- Packaging: hatchling, distribution name
lyra-assistant, dependencies in pyproject withgpu/devextras and a uv lockfile; CUDA libraries are no longer imposed. - CI: reusable workflow (unit + installer tests on 3.11/3.12, ruff, personal-path guard), Dependabot.
- systemd units shipped with
@LYRA_DIR@/@HOME@placeholders; no personal path left in code, scripts or tests. - Tracking client defaults come from
TRACKING_SERVER_SCRIPT/TRACKING_VENV_PYTHON; RAG spec sources fromLYRA_MCP_SPECS_DIR.
[1.1.0] - 2026-09-09¶
Changed¶
- License: AGPL-3.0-or-later with a commercial license option and a CLA (versions up to 1.0.0 remain MIT).
- README: HTTPS clone URL, status badges, dated claims, no more reference to a web domain.
- CLAUDE.md condensed to what an agent needs.
Removed¶
- Generated artifacts (empty ChromaDB databases, test reports, Manim caches), the self-referencing
lyra/run.shsymlink that broke CI, and workshop files (Claude Code prompts, session notes, n8n exports, divergent documentation copy), now archived privately.
Fixed¶
- CI: the pip cache step no longer fails on a symlink loop.
[v1.1.0 - Pipeline modulaire complet] - 2026-03-10¶
Refactoring - Decomposition de pipeline.py en modules separes (7 missions)¶
pipeline.py passe de 2899 lignes a 919 lignes (~68% de reduction).
164/164 tests MCP conserves a 100% apres chaque mission.
Mission 1 - Types et constantes (core/types.py, core/config.py)
- Extraction de QueryType, PipelineResult, constantes MCP (CATEGORY_KEYWORDS, TOOL_TYPE_KEYWORDS, etc.)
Mission 2 - Retrievers (core/retrieval.py)
- Classe Retriever : encapsule SemanticRetriever + KeywordRetriever + RRFFusion
- API : initialize(), retrieve(query), detect_query_type(query)
- Pipeline utilise self._retriever au lieu de 3 composants separes
Mission 3 - Menus outils (core/menus.py)
- is_list_tools_query(), process_tools_query_step1(), handle_server_selection()
- Constantes LIST_VERBS, LIST_SUBJECTS
Mission 4 - Workflows base (core/workflows/)
- context.py : WorkflowContext avec callables injectes (prepare_execution, route_query)
- vm_start.py : handle_vm_start_confirm() (4 cas oui/non/clarification/autre)
- vm_stop.py : handle_vm_stop_choice() (choix 1/2/3 arret VM avant clone)
- vm_snapshot.py : handle_vm_snapshot_create_workflow(), handle_vm_snapshot_list_workflow(), handle_vm_snapshot_pending()
Mission 5 - Workflows clone/export (core/workflows/vm_clone.py, vm_export.py)
- vm_clone.py : suggest_vm_name(), handle_cow_choice(), handle_vm_clone_workflow() (6 cas validation)
- vm_export.py : CUSTOM_EXPORT_GROUPS, workflow multi-tours (6 groupes virt-sysprep + firstboot)
Mission 6 - Formatters et validation (core/formatters.py, core/validation.py)
- formatters.py : enrich_description(), enrich_optional_args(), format_listing_result()
- validation.py : validate_vm_existence(), helpers VM state, constantes outils VM
Mission 7 - Cleanup final
- Suppression imports inutilises (re, sys, unicodedata) dans pipeline.py
- Mise a jour CLAUDE.md section "Project Structure"
- 164/164 PASS confirme (100%)
[v0.7 - 53/54 Tests MCP] - 2026-02-25¶
Campagne de tests complete - 54 tests MCP one-shot¶
Passage de 38/54 (70%) a 53/54 (98%). Un seul FAIL attendu (T10: vm_clone, source VM inexistante).
Fixes FEDORA: - T1: vm_status({}) pour listing global (etait vm_name='' -> EXEC_ERROR) - T6: vm_exec(vm_name, cmd) "execute CMD sur VM" (etait ls() mauvais outil) - T7: vm_copy(source, vm_name, dest) "copie FILE vers VM" (etait FAIL) - T11: vm_clone_system(name) "clone systeme VM en NEWVM" (etait FAIL) - T12: vm_verify(vm_name) "verifie la VM NAME" (etait FAIL) - T14: backup_status({}) sans watch=True (etait TIMEOUT boucle infinie) - T15: backup_create(vm_name) args corrects (etait sans vm_name) - T16: backup_verify(vm_name) argument correct (etait type= au lieu de vm_name=)
Fixes TV: - T30: tv.volume_up (etait tv.power_on) - T31: tv.volume_down (etait FAIL) - T33: tv.mute (etait tv.power_off)
Fixes DENON: - T39: denon.power_off (etait eteins() mauvais outil) - T42: denon.volume_set(level=50) (etait hue.set_brightness mauvais outil!) - T44: denon.mute_off (etait denon(status=off))
Fixes HUE: - T19: hue.turn_on_group(group_id=81) (etait allume() via embedding ChromaDB confus) - T27: hue.turn_off_light (etait turn_on_light!)
Fixes CATT: - T46: catt.cast_scan (etait catt.cast_dual_stop) - T51: catt.cast_volume (etait denon.volume_up + intent=knowledge)
Changements techniques:
- BM25 accent normalization (
keyword_retriever.py): _tokenize()normalise les accents (NFD) avant BM25-
"Demarre" dans docs ChromaDB = "demarre" dans query sans accent
-
_rule_based_detect()etendue (pipeline.py): - BACKUP (6 regles): backup_status/list/verify/create/restore/clean
- FEDORA VM (9 regles): vm_start/stop/destroy/exec/snapshot/status/verify/copy/clone_system
- CATT (2 regles): cast_scan, cast_volume (avec support "diffuse" = SlangNorm("cast"))
- HUE (2 regles): turn_on_group, turn_off_light
-
vm_start: exclusion TV context ("lance Netflix sur la TV" -> PAS vm_start)
-
_DEMANDE_VERBS_REetendu (intent_classifier.py): -
Ajoute: status|statut|nettoie|restaure|allume|eteins|mute|scan|caste|lance|demarre|arrete|supprime
-
FRENCH_ENRICHMENTS (
pipeline.py): - turn_on_group/turn_off_group: retire verbes dupliques (deja fournis par "turn_on"/"turn_off")
-
Distingue singular ("lumiere") vs pluriel ("lumieres") pour light vs group
-
Normalisation accents dans
_rule_based_detect(): - NFD normalization au debut (SlangNorm ajoute des accents: "execute"->"exécute")
Fichiers modifies:
- lyra/rag/keyword_retriever.py: _tokenize() accent normalization
- lyra/models/intent_classifier.py: _DEMANDE_VERBS_RE etendu
- lyra/core/pipeline.py: _rule_based_detect(), FRENCH_ENRICHMENTS, vm_start TV exclusion
[v0.6.1 - Fixes RAG TV/DENON/CATT] - 2026-02-25¶
Fixes RAG TV/DENON/CATT (pipeline.py)¶
Cause racine: EPHAISTOS 0.5b echoue sur les outils domotique (volume TV, mute, Denon). BM25 retourne de mauvais outils ("volume denon a 50" → catt.cast_volume, "demute le denon" → denon.power_off). SlangNormalizer transforme "cast" → "diffuse" ce qui casse la detection cast_scan.
Fix: regles TV/DENON/CATT dans _rule_based_detect() (pipeline.py):
- TV: tv.volume_up/down/set/mute detectes par presence de "tv/tele" + verbe/chiffre/sourdine
- DENON: denon.power_on/off/mute_on/off/volume_up/down/set detectes par presence de "denon"
- Couvre formes original ("eteins", "demute") et normalisees ("sourdine")
- Ordre: power_off/on → mute_off/on → volume_set → volume_up/down
- CATT scan: "scan + cast/diffuse/appareils" → catt.cast_scan
(gere les deux formes: original "cast" et SlangNorm "diffuse")
Resultats:
| Query | Avant | Apres |
|---|---|---|
| "monte le volume de la TV" | EPHAISTOS 0.5b echec | tv.volume_up OK |
| "coupe le son de la TV" | EPHAISTOS 0.5b echec | tv.mute OK |
| "volume denon a 50" | BM25 → catt.cast_volume | denon.volume_set {level:50} OK |
| "demute le denon" | BM25 → denon.power_off | denon.mute_off OK |
| "eteins le denon" | BM25 score trop bas | denon.power_off OK |
| "scan les appareils cast" | SlangNorm → cast_youtube | catt.cast_scan OK |
Fichiers modifies:
- lyra/core/pipeline.py : _rule_based_detect() etendu avec regles TV/DENON/CATT
[v0.6 - One-Shot + Fixes RAG] - 2026-02-25¶
Mode One-Shot CLI¶
Ajout du mode one-shot: lyra "[requete]" [-v] [-y]
lyra "demarre preprod-01"- execution directe sans UI interactive-v / --verbose: affiche les etapes RAG en temps reel ([rag],[intent],[action])-y / --yes: auto-confirme les actions (mode non interactif)- Codes de sortie: 0=OK, 1=EXEC_ERROR, 2=CANCEL, 3=PIPELINE_FAIL, 124=TIMEOUT
Fichiers modifies:
- main_rag.py : fonction run_one_shot(), argparse mis a jour
- run.sh : documentation one-shot dans les commentaires
Tests MCP one-shot (54 tests)¶
Resultats: 38/54 = 70% (voir test_mcp_results.md)
| Serveur | Total | OK | Problemes |
|---|---|---|---|
| FEDORA | 18 | 11 | 7 |
| HUE | 9 | 8 | 1 |
| TV | 9 | 5 | 4 |
| DENON | 9 | 6 | 3 |
| CATT | 8 | 7 | 1 |
| MERMAID | 1 | 1 | 0 |
Fixes RAG FEDORA (vm_clone_system, vm_clone, vm_copy, vm_verify)¶
Cause racine identifiee: EPHAISTOS 0.5b trop petit pour extraire les arguments, enrichissements BM25 confondent "copie" avec vm_clone, IntentClassifier classe "verifie" comme "info".
Fix 1 - vm_clone_system (pipeline.py):
- Bug substring: "vm_clone" in "fedora.vm_clone_system" = True
- Fix: analysis.tool in ("vm_clone", "fedora.vm_clone")
Fix 2 - vm_clone (pipeline.py):
- EPHAISTOS detecte l'outil mais arguments={} + missing_args=[] → NullPointerError ligne 1290
- Fix: regex fallback dans _handle_vm_clone_workflow extrait "clone X en Y"
- Fix: null-check if source_vm and vm.replace(...)
- Fix: _rule_based_detect() intercepte "clone X en Y" avant EPHAISTOS
Fix 3 - vm_copy (pipeline.py):
- BM25 retourne vm_clone au lieu de vm_copy ("copie" present dans enrichissement "clone")
- Fix: _rule_based_detect() intercepte "copie/transfere FILE vers/sur VM"
Fix 4 - vm_verify (intent_classifier.py, pipeline.py):
- IntentClassifier (Llama 1b) classe "verifie la VM" comme "info" → pipeline ignorait l'outil
- Fix: regex override _DEMANDE_VERBS_RE dans classify() force "demande" pour verbes d'action
- Fix: _rule_based_detect() intercepte "verifie/verif [la VM] NAME"
Nouveaux examples EPHAISTOS (ephaistos.py):
- vm_clone avec source_vm + new_vm_name
- vm_copy avec source + vm_name + dest
- vm_verify avec vm_name optionnel
- vm_clone_system avec name
Fichiers modifies:
- lyra/core/pipeline.py : import re, _rule_based_detect(), fixes _handle_vm_clone_workflow
- lyra/models/intent_classifier.py : _DEMANDE_VERBS_RE, exemples prompt
- lyra/models/ephaistos.py : 4 nouveaux exemples FEDORA
[Phase 4] - 2026-01-23¶
Operations Async via n8n + Fallback Subprocess¶
Ajouts:
- Module modules/n8n.py : Client n8n + executeur async fallback
- 3 workflows n8n crees avec noeud code (JS)
- Detection automatique des operations longues (vm_clone, backup_create, backup_restore)
- Fallback subprocess : Si n8n non disponible, execute en arriere-plan via threading
- Notification dans le terminal quand operation terminee (mode fallback)
Workflows n8n:
| Workflow | Webhook | Description |
|----------|---------|-------------|
| Lyra - Clone VM v2 | /webhook/lyra-clone-vm-v2 | Clone VM via kvm-clone.sh |
| Lyra - Backup Create | /webhook/lyra-backup-create | Cree backup timeshift/borg |
| Lyra - Backup Restore | /webhook/lyra-backup-restore | Restaure backup |
Note: Les workflows utilisent le noeud n8n-nodes-base.code au lieu de executeCommand
(ce dernier n'etait pas reconnu par l'API).
Fichiers modifies:
- main.py : Integration n8n avec fallback subprocess
- modules/n8n.py : Client n8n + AsyncExecutor pour fallback
- config.yaml : n8n.enabled = true, webhook path mis a jour
- prompts/system_prompt.txt : Section operations async
Mode fallback (subprocess): Quand n8n n'est pas disponible ou les webhooks ne sont pas actifs: 1. Lyra detecte l'echec du webhook 2. Lance la commande en arriere-plan via subprocess.Popen 3. Notifie dans le terminal quand c'est termine
Configuration requise:
n8n:
enabled: true
base_url: http://localhost:5678
api_key: <votre-cle-api> # Optionnel
webhooks:
clone-vm: /webhook/lyra-clone-vm-v2
backup-create: /webhook/lyra-backup-create
backup-restore: /webhook/lyra-backup-restore
Pour activer les webhooks n8n: 1. Aller sur http://localhost:5678 2. Ouvrir chaque workflow Lyra 3. Cliquer sur le toggle "Active" en haut a droite 4. Les webhooks seront alors operationnels
[Phase 3] - 2026-01-23¶
Actions + Securite¶
Ajouts:
- Principe Read-First : verification automatique de l'etat VM avant toute action
- System prompt externe (prompts/system_prompt.txt) au lieu de hardcode
- Confirmation vocale avec mots-cles ("oui"/"non"/"oui je confirme")
- Affichage de l'etat VM dans la confirmation (status, IP)
- Description vocale naturelle des actions proposees
Regles de securite:
- READ_FIRST_TOOLS : vm_start, vm_stop, vm_destroy, vm_snapshot, vm_clone
- READ_ONLY_TOOLS : vm_status, backup_status, backup_list, backup_verify
- Actions dangereuses : confirmation explicite "oui je confirme" en vocal
Fichiers modifies:
- main.py : Chargement prompt externe, Read-First, descriptions vocales
- modules/ui.py : Confirmation vocale, affichage etat VM
- prompts/system_prompt.txt : Regles de securite detaillees
Confirmation vocale:
- Option [v] pour passer en mode vocal
- Mots-cles acceptes : oui, yes, ok, d'accord, confirme, vas-y
- Mots-cles annulation : non, no, annule, stop, arrete
- Actions destructives : exigent "oui je confirme"
[Phase 2] - 2026-01-22¶
Mode Vocal (STT/TTS)¶
Ajouts:
- Mode --vocal pour interaction vocale complete
- Module modules/audio.py : STT, TTS, AudioRecorder, VoiceInterface
- Script run.sh : Lancement avec configuration CUDA automatique
- Alias bash lyra et lyra --vocal
- Bip sonore avant l'ecoute
- Indicateur visuel de niveau audio en temps reel
- Detection de silence pour fin d'enregistrement automatique
Stack vocale: - STT : faster-whisper (modele base, CUDA float16) - TTS : Piper (voix fr_FR-upmc-medium) - Audio : sounddevice avec resampling 48kHz
Configuration (config.yaml):
audio:
sample_rate: 48000 # Compatible PipeWire/ALSA
silence_threshold: 0.005
silence_duration: 1.0
stt:
model: base
device: cuda
compute_type: float16
tts:
model: fr_FR-upmc-medium
Dependances ajoutees: - faster-whisper - piper-tts - sounddevice - nvidia-cublas-cu12 - nvidia-cudnn-cu12
Fixes techniques:
- Resampling audio : 48kHz (PipeWire) <-> 16kHz (Whisper) <-> 22050Hz (Piper)
- suppress_stderr() : Masque les warnings cffi de sounddevice
- Configuration CUDA via LD_LIBRARY_PATH dans run.sh
Issue connue: - Elgato Wave 3 non fonctionnel (necessite Wave Link sur Windows/Mac) - Workaround : Utiliser G522 LIGHTSPEED comme micro par defaut
[Phase 1] - 2024¶
Wrapper Python + MCP (mode texte)¶
Fonctionnalites: - Client Ollama avec parsing JSON des tool calls - Client MCP pour fedora-agents - Human-in-the-Loop : confirmation avant execution - Interface CLI en francais - Raccourcis clavier (Ctrl+L, double Ctrl+C)
Outils MCP disponibles: - VM : vm_status, vm_start, vm_stop, vm_snapshot, vm_exec, vm_clone - Backup : backup_status, backup_list, backup_create, backup_verify