lyra-assistant 1.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lyra_assistant-1.3.1/.gitignore +67 -0
- lyra_assistant-1.3.1/CHANGELOG.md +422 -0
- lyra_assistant-1.3.1/CLA.md +7 -0
- lyra_assistant-1.3.1/COMMERCIAL-LICENSE.md +13 -0
- lyra_assistant-1.3.1/LICENSE +668 -0
- lyra_assistant-1.3.1/PKG-INFO +324 -0
- lyra_assistant-1.3.1/README.md +279 -0
- lyra_assistant-1.3.1/benchmarks/README.md +266 -0
- lyra_assistant-1.3.1/config.yaml.example +317 -0
- lyra_assistant-1.3.1/docs/README.md +7 -0
- lyra_assistant-1.3.1/docs/dev/rag_enhanced/CHANGELOG.md +530 -0
- lyra_assistant-1.3.1/installer/README.md +100 -0
- lyra_assistant-1.3.1/installer/__init__.py +0 -0
- lyra_assistant-1.3.1/installer/app/__init__.py +1 -0
- lyra_assistant-1.3.1/installer/app/__main__.py +9 -0
- lyra_assistant-1.3.1/installer/app/backend/__init__.py +1 -0
- lyra_assistant-1.3.1/installer/app/backend/bridge.py +128 -0
- lyra_assistant-1.3.1/installer/app/backend/server.py +315 -0
- lyra_assistant-1.3.1/installer/app/backend/static/assets/index-BFcnm2OU.css +1 -0
- lyra_assistant-1.3.1/installer/app/backend/static/assets/index-DZRIdwlA.js +13 -0
- lyra_assistant-1.3.1/installer/app/backend/static/fonts/cantarell-Bold.woff2 +0 -0
- lyra_assistant-1.3.1/installer/app/backend/static/fonts/cantarell-Regular.woff2 +0 -0
- lyra_assistant-1.3.1/installer/app/backend/static/fonts/jbm-ExtraBold.woff2 +0 -0
- lyra_assistant-1.3.1/installer/app/backend/static/fonts/jbm-Light.woff2 +0 -0
- lyra_assistant-1.3.1/installer/app/backend/static/fonts/jbm-Regular.woff2 +0 -0
- lyra_assistant-1.3.1/installer/app/backend/static/fonts/jbm-SemiBold.woff2 +0 -0
- lyra_assistant-1.3.1/installer/app/backend/static/index.html +15 -0
- lyra_assistant-1.3.1/installer/app/frontend/.gitignore +2 -0
- lyra_assistant-1.3.1/installer/app/frontend/index.html +14 -0
- lyra_assistant-1.3.1/installer/app/frontend/package-lock.json +1841 -0
- lyra_assistant-1.3.1/installer/app/frontend/package.json +22 -0
- lyra_assistant-1.3.1/installer/app/frontend/public/fonts/cantarell-Bold.woff2 +0 -0
- lyra_assistant-1.3.1/installer/app/frontend/public/fonts/cantarell-Regular.woff2 +0 -0
- lyra_assistant-1.3.1/installer/app/frontend/public/fonts/jbm-ExtraBold.woff2 +0 -0
- lyra_assistant-1.3.1/installer/app/frontend/public/fonts/jbm-Light.woff2 +0 -0
- lyra_assistant-1.3.1/installer/app/frontend/public/fonts/jbm-Regular.woff2 +0 -0
- lyra_assistant-1.3.1/installer/app/frontend/public/fonts/jbm-SemiBold.woff2 +0 -0
- lyra_assistant-1.3.1/installer/app/frontend/src/App.tsx +110 -0
- lyra_assistant-1.3.1/installer/app/frontend/src/components/BootSplash.tsx +121 -0
- lyra_assistant-1.3.1/installer/app/frontend/src/components/Mascot.tsx +60 -0
- lyra_assistant-1.3.1/installer/app/frontend/src/components/Reactor.tsx +128 -0
- lyra_assistant-1.3.1/installer/app/frontend/src/components/ui.tsx +76 -0
- lyra_assistant-1.3.1/installer/app/frontend/src/main.tsx +5 -0
- lyra_assistant-1.3.1/installer/app/frontend/src/screens/Configure.tsx +113 -0
- lyra_assistant-1.3.1/installer/app/frontend/src/screens/Done.tsx +70 -0
- lyra_assistant-1.3.1/installer/app/frontend/src/screens/Install.tsx +188 -0
- lyra_assistant-1.3.1/installer/app/frontend/src/screens/SelectMcps.tsx +94 -0
- lyra_assistant-1.3.1/installer/app/frontend/src/screens/Welcome.tsx +79 -0
- lyra_assistant-1.3.1/installer/app/frontend/src/styles.css +620 -0
- lyra_assistant-1.3.1/installer/app/frontend/tsconfig.json +18 -0
- lyra_assistant-1.3.1/installer/app/frontend/vite.config.ts +26 -0
- lyra_assistant-1.3.1/installer/assets/mascots.json +1 -0
- lyra_assistant-1.3.1/installer/core/__init__.py +0 -0
- lyra_assistant-1.3.1/installer/core/catalog.py +133 -0
- lyra_assistant-1.3.1/installer/core/catalog.yaml +274 -0
- lyra_assistant-1.3.1/installer/core/configpatch.py +127 -0
- lyra_assistant-1.3.1/installer/core/events.py +104 -0
- lyra_assistant-1.3.1/installer/core/gitauth.py +68 -0
- lyra_assistant-1.3.1/installer/core/osdetect.py +101 -0
- lyra_assistant-1.3.1/installer/core/pipeline.py +129 -0
- lyra_assistant-1.3.1/installer/core/runner.py +72 -0
- lyra_assistant-1.3.1/installer/core/state.py +38 -0
- lyra_assistant-1.3.1/installer/core/steps/__init__.py +0 -0
- lyra_assistant-1.3.1/installer/core/steps/clone.py +33 -0
- lyra_assistant-1.3.1/installer/core/steps/config.py +50 -0
- lyra_assistant-1.3.1/installer/core/steps/mcps.py +256 -0
- lyra_assistant-1.3.1/installer/core/steps/ollama.py +66 -0
- lyra_assistant-1.3.1/installer/core/steps/packages.py +22 -0
- lyra_assistant-1.3.1/installer/core/steps/piper.py +59 -0
- lyra_assistant-1.3.1/installer/core/steps/post.py +63 -0
- lyra_assistant-1.3.1/installer/core/steps/systemd.py +91 -0
- lyra_assistant-1.3.1/installer/core/steps/venv.py +54 -0
- lyra_assistant-1.3.1/installer/core/sudoprime.py +27 -0
- lyra_assistant-1.3.1/installer/install.sh +50 -0
- lyra_assistant-1.3.1/installer/tui/__init__.py +0 -0
- lyra_assistant-1.3.1/installer/tui/__main__.py +9 -0
- lyra_assistant-1.3.1/installer/tui/boot.py +98 -0
- lyra_assistant-1.3.1/installer/tui/forms.py +87 -0
- lyra_assistant-1.3.1/installer/tui/keys.py +58 -0
- lyra_assistant-1.3.1/installer/tui/main.py +252 -0
- lyra_assistant-1.3.1/installer/tui/mascot.py +64 -0
- lyra_assistant-1.3.1/installer/tui/menu.py +154 -0
- lyra_assistant-1.3.1/installer/tui/mode_select.py +106 -0
- lyra_assistant-1.3.1/installer/tui/model.py +115 -0
- lyra_assistant-1.3.1/installer/tui/popup.py +66 -0
- lyra_assistant-1.3.1/installer/tui/render.py +211 -0
- lyra_assistant-1.3.1/installer/tui/theme.py +62 -0
- lyra_assistant-1.3.1/intro/README.md +1 -0
- lyra_assistant-1.3.1/lyra/__init__.py +11 -0
- lyra_assistant-1.3.1/lyra/client/__init__.py +1 -0
- lyra_assistant-1.3.1/lyra/client/__main__.py +183 -0
- lyra_assistant-1.3.1/lyra/client/launcher.py +121 -0
- lyra_assistant-1.3.1/lyra/client/reminders.py +26 -0
- lyra_assistant-1.3.1/lyra/client/render.py +102 -0
- lyra_assistant-1.3.1/lyra/client/repl.py +237 -0
- lyra_assistant-1.3.1/lyra/core/__init__.py +16 -0
- lyra_assistant-1.3.1/lyra/core/config.py +211 -0
- lyra_assistant-1.3.1/lyra/core/constants.py +94 -0
- lyra_assistant-1.3.1/lyra/core/fastpath.py +51 -0
- lyra_assistant-1.3.1/lyra/core/formatters.py +306 -0
- lyra_assistant-1.3.1/lyra/core/menus.py +214 -0
- lyra_assistant-1.3.1/lyra/core/paths.py +72 -0
- lyra_assistant-1.3.1/lyra/core/pipeline.py +1383 -0
- lyra_assistant-1.3.1/lyra/core/retrieval.py +396 -0
- lyra_assistant-1.3.1/lyra/core/settings.py +184 -0
- lyra_assistant-1.3.1/lyra/core/settings_menu.py +280 -0
- lyra_assistant-1.3.1/lyra/core/settings_tui.py +213 -0
- lyra_assistant-1.3.1/lyra/core/types.py +123 -0
- lyra_assistant-1.3.1/lyra/core/validation.py +212 -0
- lyra_assistant-1.3.1/lyra/core/workflows/__init__.py +6 -0
- lyra_assistant-1.3.1/lyra/core/workflows/context.py +73 -0
- lyra_assistant-1.3.1/lyra/core/workflows/vm_clone.py +427 -0
- lyra_assistant-1.3.1/lyra/core/workflows/vm_clone_exec.py +191 -0
- lyra_assistant-1.3.1/lyra/core/workflows/vm_export.py +256 -0
- lyra_assistant-1.3.1/lyra/core/workflows/vm_snapshot.py +175 -0
- lyra_assistant-1.3.1/lyra/core/workflows/vm_snapshot_exec.py +291 -0
- lyra_assistant-1.3.1/lyra/core/workflows/vm_start.py +95 -0
- lyra_assistant-1.3.1/lyra/core/workflows/vm_stop.py +78 -0
- lyra_assistant-1.3.1/lyra/daemon/__init__.py +1 -0
- lyra_assistant-1.3.1/lyra/daemon/__main__.py +33 -0
- lyra_assistant-1.3.1/lyra/daemon/actions.py +230 -0
- lyra_assistant-1.3.1/lyra/daemon/protocol.py +105 -0
- lyra_assistant-1.3.1/lyra/daemon/remote_ui.py +142 -0
- lyra_assistant-1.3.1/lyra/daemon/server.py +386 -0
- lyra_assistant-1.3.1/lyra/daemon/state.py +145 -0
- lyra_assistant-1.3.1/lyra/hestia/__init__.py +18 -0
- lyra_assistant-1.3.1/lyra/hestia/background_tasks.py +563 -0
- lyra_assistant-1.3.1/lyra/hestia/executor.py +479 -0
- lyra_assistant-1.3.1/lyra/hestia/metrics.py +157 -0
- lyra_assistant-1.3.1/lyra/hestia/notion_logger.py +142 -0
- lyra_assistant-1.3.1/lyra/hestia/tracking_client.py +194 -0
- lyra_assistant-1.3.1/lyra/models/__init__.py +28 -0
- lyra_assistant-1.3.1/lyra/models/_analysis.py +33 -0
- lyra_assistant-1.3.1/lyra/models/cartes.py +370 -0
- lyra_assistant-1.3.1/lyra/models/ephaistos.py +958 -0
- lyra_assistant-1.3.1/lyra/models/ephaistos_exp.py +862 -0
- lyra_assistant-1.3.1/lyra/models/intent_classifier.py +255 -0
- lyra_assistant-1.3.1/lyra/models/lyra_voice.py +839 -0
- lyra_assistant-1.3.1/lyra/models/model_manager.py +291 -0
- lyra_assistant-1.3.1/lyra/rag/__init__.py +24 -0
- lyra_assistant-1.3.1/lyra/rag/fusion.py +141 -0
- lyra_assistant-1.3.1/lyra/rag/indexer.py +327 -0
- lyra_assistant-1.3.1/lyra/rag/keyword_retriever.py +146 -0
- lyra_assistant-1.3.1/lyra/rag/semantic_retriever.py +275 -0
- lyra_assistant-1.3.1/lyra/rag/session_memory.py +265 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/README.md +236 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/__init__.py +140 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/confidence_cascader.py +193 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/config.py +262 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/constants.py +64 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/context_db.py +237 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/context_injector.py +225 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/feedback_loop.py +468 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/pipeline_enhanced.py +667 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/rag_3tier.py +631 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/slang_normalizer.py +234 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/synonym_expander.py +247 -0
- lyra_assistant-1.3.1/lyra/rag_enhanced/types.py +71 -0
- lyra_assistant-1.3.1/lyra/rules/__init__.py +43 -0
- lyra_assistant-1.3.1/lyra/rules/backup.py +56 -0
- lyra_assistant-1.3.1/lyra/rules/base.py +23 -0
- lyra_assistant-1.3.1/lyra/rules/catt.py +85 -0
- lyra_assistant-1.3.1/lyra/rules/denon.py +87 -0
- lyra_assistant-1.3.1/lyra/rules/hue.py +128 -0
- lyra_assistant-1.3.1/lyra/rules/ironman.py +35 -0
- lyra_assistant-1.3.1/lyra/rules/screen_manager.py +198 -0
- lyra_assistant-1.3.1/lyra/rules/tracking.py +76 -0
- lyra_assistant-1.3.1/lyra/rules/tv.py +137 -0
- lyra_assistant-1.3.1/lyra/rules/vm.py +388 -0
- lyra_assistant-1.3.1/lyra/utils/__init__.py +0 -0
- lyra_assistant-1.3.1/lyra/utils/error_log.py +93 -0
- lyra_assistant-1.3.1/lyra/utils/mermaid_viewer.py +196 -0
- lyra_assistant-1.3.1/lyra/utils/toon.py +193 -0
- lyra_assistant-1.3.1/mcp-servers/mermaid-mcp/README.md +602 -0
- lyra_assistant-1.3.1/modules/__init__.py +16 -0
- lyra_assistant-1.3.1/modules/audio.py +463 -0
- lyra_assistant-1.3.1/modules/llm.py +233 -0
- lyra_assistant-1.3.1/modules/mcp.py +1104 -0
- lyra_assistant-1.3.1/modules/n8n.py +443 -0
- lyra_assistant-1.3.1/modules/ui.py +812 -0
- lyra_assistant-1.3.1/prompts/system_prompt.txt +274 -0
- lyra_assistant-1.3.1/pyproject.toml +70 -0
- lyra_assistant-1.3.1/scenes/README.md +1 -0
- lyra_assistant-1.3.1/scenes/ironman/phases/README.md +274 -0
- lyra_assistant-1.3.1/scenes/ironman/tests/README.md +70 -0
- lyra_assistant-1.3.1/scenes/ironman/tests/__init__.py +1 -0
- lyra_assistant-1.3.1/scenes/ironman/tests/e2e/__init__.py +0 -0
- lyra_assistant-1.3.1/scenes/ironman/tests/e2e/test_ironman_e2e.sh +19 -0
- lyra_assistant-1.3.1/scenes/ironman/tests/test_edge_cases.py +193 -0
- lyra_assistant-1.3.1/scenes/ironman/tests/test_integration.py +228 -0
- lyra_assistant-1.3.1/scenes/ironman/tests/test_performance.py +141 -0
- lyra_assistant-1.3.1/scenes/ironman/tests/test_stress.py +138 -0
- lyra_assistant-1.3.1/scripts/async_mcp_wrapper.py +580 -0
- lyra_assistant-1.3.1/scripts/bench_boucle.py +156 -0
- lyra_assistant-1.3.1/scripts/bench_common.py +107 -0
- lyra_assistant-1.3.1/scripts/bench_daemon.py +171 -0
- lyra_assistant-1.3.1/scripts/bench_recall.py +135 -0
- lyra_assistant-1.3.1/scripts/bench_tts.py +223 -0
- lyra_assistant-1.3.1/scripts/cast-clipboard.sh +105 -0
- lyra_assistant-1.3.1/scripts/controle_hors_regles.py +75 -0
- lyra_assistant-1.3.1/scripts/gen_benchmarks_md.py +330 -0
- lyra_assistant-1.3.1/scripts/gen_figures_boucle.py +185 -0
- lyra_assistant-1.3.1/scripts/gen_mcp_tools_md.py +126 -0
- lyra_assistant-1.3.1/scripts/index_mcp_specs.py +428 -0
- lyra_assistant-1.3.1/scripts/index_rag_3tier.py +351 -0
- lyra_assistant-1.3.1/scripts/mermaid_render.py +99 -0
- lyra_assistant-1.3.1/scripts/reindex_mcp_rag_optimized.py +1037 -0
- lyra_assistant-1.3.1/scripts/smoke_mcps.py +191 -0
- lyra_assistant-1.3.1/secrets.yaml.example +22 -0
- lyra_assistant-1.3.1/tests/__init__.py +1 -0
- lyra_assistant-1.3.1/tests/cases_hors_regles.py +70 -0
- lyra_assistant-1.3.1/tests/cases_hors_regles_2.py +124 -0
- lyra_assistant-1.3.1/tests/cases_hors_regles_3.py +75 -0
- lyra_assistant-1.3.1/tests/cases_hors_regles_4.py +68 -0
- lyra_assistant-1.3.1/tests/cases_hors_regles_5.py +67 -0
- lyra_assistant-1.3.1/tests/conftest.py +10 -0
- lyra_assistant-1.3.1/tests/e2e/rag_enhanced/__init__.py +9 -0
- lyra_assistant-1.3.1/tests/e2e/rag_enhanced/conftest.py +151 -0
- lyra_assistant-1.3.1/tests/e2e/rag_enhanced/test_e2e_advanced.py +236 -0
- lyra_assistant-1.3.1/tests/e2e/rag_enhanced/test_e2e_basic_scenarios.py +254 -0
- lyra_assistant-1.3.1/tests/e2e/rag_enhanced/test_e2e_context_cascade.py +176 -0
- lyra_assistant-1.3.1/tests/generate_pdf_report.py +667 -0
- lyra_assistant-1.3.1/tests/installer/__init__.py +0 -0
- lyra_assistant-1.3.1/tests/installer/test_catalog.py +71 -0
- lyra_assistant-1.3.1/tests/installer/test_configpatch.py +93 -0
- lyra_assistant-1.3.1/tests/installer/test_gitauth.py +111 -0
- lyra_assistant-1.3.1/tests/installer/test_mcps_sudoers.py +191 -0
- lyra_assistant-1.3.1/tests/installer/test_ollama_step.py +79 -0
- lyra_assistant-1.3.1/tests/installer/test_osdetect.py +40 -0
- lyra_assistant-1.3.1/tests/installer/test_pipeline.py +130 -0
- lyra_assistant-1.3.1/tests/installer/test_sudoprime.py +39 -0
- lyra_assistant-1.3.1/tests/installer/test_systemd_client_shim.py +60 -0
- lyra_assistant-1.3.1/tests/installer/test_systemd_render.py +28 -0
- lyra_assistant-1.3.1/tests/integration/__init__.py +1 -0
- lyra_assistant-1.3.1/tests/integration/rag_enhanced/__init__.py +1 -0
- lyra_assistant-1.3.1/tests/integration/rag_enhanced/test_pipeline_integration.py +258 -0
- lyra_assistant-1.3.1/tests/integration/rag_enhanced/test_pipeline_integration_simple.py +117 -0
- lyra_assistant-1.3.1/tests/integration/test_pipeline.py +585 -0
- lyra_assistant-1.3.1/tests/integration/test_vm_clone_running.py +306 -0
- lyra_assistant-1.3.1/tests/test_campaign_llm.py +549 -0
- lyra_assistant-1.3.1/tests/test_campaign_mcp.py +1024 -0
- lyra_assistant-1.3.1/tests/test_campaign_oneshot.py +614 -0
- lyra_assistant-1.3.1/tests/test_campaign_opts.py +485 -0
- lyra_assistant-1.3.1/tests/unit/__init__.py +1 -0
- lyra_assistant-1.3.1/tests/unit/rag_enhanced/__init__.py +1 -0
- lyra_assistant-1.3.1/tests/unit/rag_enhanced/conftest.py +73 -0
- lyra_assistant-1.3.1/tests/unit/rag_enhanced/test_confidence_cascader.py +242 -0
- lyra_assistant-1.3.1/tests/unit/rag_enhanced/test_config.py +265 -0
- lyra_assistant-1.3.1/tests/unit/rag_enhanced/test_context_db.py +240 -0
- lyra_assistant-1.3.1/tests/unit/rag_enhanced/test_context_injector.py +299 -0
- lyra_assistant-1.3.1/tests/unit/rag_enhanced/test_feedback_loop.py +309 -0
- lyra_assistant-1.3.1/tests/unit/rag_enhanced/test_m1_rag_step_messages.py +228 -0
- lyra_assistant-1.3.1/tests/unit/rag_enhanced/test_rag_3tier.py +222 -0
- lyra_assistant-1.3.1/tests/unit/rag_enhanced/test_slang_normalizer.py +217 -0
- lyra_assistant-1.3.1/tests/unit/rag_enhanced/test_specs_pour_ephaistos.py +15 -0
- lyra_assistant-1.3.1/tests/unit/rag_enhanced/test_synonym_expander.py +318 -0
- lyra_assistant-1.3.1/tests/unit/rules/__init__.py +0 -0
- lyra_assistant-1.3.1/tests/unit/rules/test_backup.py +181 -0
- lyra_assistant-1.3.1/tests/unit/rules/test_catt.py +218 -0
- lyra_assistant-1.3.1/tests/unit/rules/test_denon.py +211 -0
- lyra_assistant-1.3.1/tests/unit/rules/test_hue.py +227 -0
- lyra_assistant-1.3.1/tests/unit/rules/test_ironman.py +103 -0
- lyra_assistant-1.3.1/tests/unit/rules/test_registry_order.py +128 -0
- lyra_assistant-1.3.1/tests/unit/rules/test_screen_manager.py +256 -0
- lyra_assistant-1.3.1/tests/unit/rules/test_tracking.py +151 -0
- lyra_assistant-1.3.1/tests/unit/rules/test_tv.py +301 -0
- lyra_assistant-1.3.1/tests/unit/rules/test_vm.py +342 -0
- lyra_assistant-1.3.1/tests/unit/test_async_wrapper_cmd.py +42 -0
- lyra_assistant-1.3.1/tests/unit/test_async_wrapper_validation.py +92 -0
- lyra_assistant-1.3.1/tests/unit/test_bench_boucle.py +28 -0
- lyra_assistant-1.3.1/tests/unit/test_bench_recall.py +26 -0
- lyra_assistant-1.3.1/tests/unit/test_campaign_equivalences.py +29 -0
- lyra_assistant-1.3.1/tests/unit/test_campaign_eval.py +22 -0
- lyra_assistant-1.3.1/tests/unit/test_cartes.py +34 -0
- lyra_assistant-1.3.1/tests/unit/test_client_reminders.py +28 -0
- lyra_assistant-1.3.1/tests/unit/test_client_version.py +42 -0
- lyra_assistant-1.3.1/tests/unit/test_clone_system_pending.py +43 -0
- lyra_assistant-1.3.1/tests/unit/test_confirm_prompt.py +73 -0
- lyra_assistant-1.3.1/tests/unit/test_constants.py +47 -0
- lyra_assistant-1.3.1/tests/unit/test_daemon_core.py +288 -0
- lyra_assistant-1.3.1/tests/unit/test_disambiguation.py +139 -0
- lyra_assistant-1.3.1/tests/unit/test_ephaistos.py +416 -0
- lyra_assistant-1.3.1/tests/unit/test_ephaistos_exp.py +834 -0
- lyra_assistant-1.3.1/tests/unit/test_fusion.py +265 -0
- lyra_assistant-1.3.1/tests/unit/test_gen_mcp_tools_md.py +29 -0
- lyra_assistant-1.3.1/tests/unit/test_hestia_executor.py +397 -0
- lyra_assistant-1.3.1/tests/unit/test_hestia_metrics.py +319 -0
- lyra_assistant-1.3.1/tests/unit/test_hestia_notion.py +377 -0
- lyra_assistant-1.3.1/tests/unit/test_index_rag_3tier.py +44 -0
- lyra_assistant-1.3.1/tests/unit/test_intent_classifier.py +52 -0
- lyra_assistant-1.3.1/tests/unit/test_intent_overrides.py +95 -0
- lyra_assistant-1.3.1/tests/unit/test_keyword_retriever.py +225 -0
- lyra_assistant-1.3.1/tests/unit/test_lyra_voice.py +334 -0
- lyra_assistant-1.3.1/tests/unit/test_model_manager.py +210 -0
- lyra_assistant-1.3.1/tests/unit/test_normalized_forms.py +74 -0
- lyra_assistant-1.3.1/tests/unit/test_oneshot_incomplete_reminder.py +29 -0
- lyra_assistant-1.3.1/tests/unit/test_paths.py +69 -0
- lyra_assistant-1.3.1/tests/unit/test_rag_3tier_document.py +22 -0
- lyra_assistant-1.3.1/tests/unit/test_resolution_outil.py +167 -0
- lyra_assistant-1.3.1/tests/unit/test_rules_hue_couleur.py +26 -0
- lyra_assistant-1.3.1/tests/unit/test_semantic_retriever.py +220 -0
- lyra_assistant-1.3.1/tests/unit/test_session_store.py +88 -0
- lyra_assistant-1.3.1/tests/unit/test_settings.py +256 -0
- lyra_assistant-1.3.1/tests/unit/test_settings_tui.py +169 -0
- lyra_assistant-1.3.1/tests/unit/test_toon.py +347 -0
- lyra_assistant-1.3.1/tests/unit/test_tracking_client.py +47 -0
- lyra_assistant-1.3.1/tests/unit/test_ui_raw_error.py +43 -0
- lyra_assistant-1.3.1/tests/unit/test_workflow_vm_clone_args.py +52 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# ---------- Python ----------
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.so
|
|
5
|
+
*.egg-info/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.eggs/
|
|
9
|
+
.venv/
|
|
10
|
+
.venv-installer/
|
|
11
|
+
venv/
|
|
12
|
+
.mypy_cache/
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
.pytest_cache/
|
|
15
|
+
htmlcov/
|
|
16
|
+
.coverage
|
|
17
|
+
.coverage.*
|
|
18
|
+
|
|
19
|
+
# ---------- Configuration et secrets (jamais versionnes) ----------
|
|
20
|
+
config.yaml
|
|
21
|
+
secrets.yaml
|
|
22
|
+
secrets.yaml.bak*
|
|
23
|
+
.env
|
|
24
|
+
|
|
25
|
+
# ---------- Donnees et modeles generes a l'execution ----------
|
|
26
|
+
data/chromadb/
|
|
27
|
+
data/chroma_db/
|
|
28
|
+
/.chromadb/
|
|
29
|
+
data/session_history.db
|
|
30
|
+
data/feedback.json
|
|
31
|
+
*.sqlite3
|
|
32
|
+
# Ancre a la racine : sans le slash initial, la regle masquait aussi
|
|
33
|
+
# le paquet de code lyra/models/ (ephaistos, model_manager...).
|
|
34
|
+
/models/
|
|
35
|
+
/voices/
|
|
36
|
+
*.onnx
|
|
37
|
+
*.onnx.json
|
|
38
|
+
|
|
39
|
+
# ---------- Rapports et sorties de tests (regenerables) ----------
|
|
40
|
+
tests/*_report.txt
|
|
41
|
+
tests/*_report.pdf
|
|
42
|
+
tests/debug/
|
|
43
|
+
*.log
|
|
44
|
+
|
|
45
|
+
# ---------- Caches des animations (intro Manim) ----------
|
|
46
|
+
intro/media/**/partial_movie_files/
|
|
47
|
+
intro/media/**/Tex/
|
|
48
|
+
intro/media/**/texts/
|
|
49
|
+
|
|
50
|
+
# ---------- Serveurs MCP developpes dans leurs propres depots ----------
|
|
51
|
+
mcp-servers/pylips-mcp/
|
|
52
|
+
mcp-servers/denon-mcp/
|
|
53
|
+
mcp-servers/catt-mcp/
|
|
54
|
+
mcp-servers/fedora-agents/
|
|
55
|
+
mcp-servers/hue-mcp/
|
|
56
|
+
|
|
57
|
+
# ---------- Interface d'installation ----------
|
|
58
|
+
installer/app/frontend/node_modules/
|
|
59
|
+
|
|
60
|
+
# ---------- Notes de travail et outils locaux ----------
|
|
61
|
+
.claude-sync/
|
|
62
|
+
.playwright-mcp/
|
|
63
|
+
to-synthese/
|
|
64
|
+
demandes/
|
|
65
|
+
lyra-v1-CDC
|
|
66
|
+
readme
|
|
67
|
+
.venv-licenses/
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
# Changelog - Lyra
|
|
2
|
+
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
## [1.3.1] - 2026-09-24
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Daemon: `tool` message on the socket for clients that only need one MCP call (name, arguments, `confirmed` option). The daemon checks the HESTIA catalogue, asks for confirmation when the tool is dangerous and not confirmed, runs it under the busy lock and streams `tool_result` then `result`. No model in the loop; used by neutroncore (roadmap issue 73).
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- MCP_TOOLS.md regenerated: `tv.get_state` now reports volume, mute and ambilight; `denon.get_status` reports mute, source and reachability (pylips-mcp 0.2.0, denon-mcp 0.2.0).
|
|
12
|
+
- First release built and published by the shared release workflow (PyPI Trusted Publishing); 1.3.0 was tagged before the workflow existed.
|
|
13
|
+
|
|
14
|
+
## [1.3.0] - 2026-09-24
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- `lyra --version` prints the installed `lyra-assistant` version, or the pyproject version when run from sources (#15).
|
|
18
|
+
- `scripts/gen_mcp_tools_md.py` regenerates docs/user/MCP_TOOLS.md from the live MCP servers, with a confirmation column derived from `lyra/core/constants.py`.
|
|
19
|
+
- EPHAISTOS variants `inventaire_vm` (real VM names from vm_status or `LYRA_VMS`), `lexique_courant` and `verbes_courants` (everyday French synonyms and verbs, written outside any test set).
|
|
20
|
+
- Fourth held-out set `tests/cases_hors_regles_3.py` (50 phrasings, real machine names, ten tools never measured before); fifth set `tests/cases_hors_regles_4.py`, sealed before iteration 16.
|
|
21
|
+
- `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.
|
|
22
|
+
- EPHAISTOS variants `outil_par_machine`, `mots_courants_2`, `nombres_tri`, `mots_courants_3` (iterations 15-16); `net_assoupli` measured and refuted.
|
|
23
|
+
- 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.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- 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_EXP` for ablation. Word tables and lexicons move to `lyra/models/cartes.py` (data only). Mechanical recall and the benches are identical before and after (21/21, 51/51, 100/100).
|
|
27
|
+
- `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 from `benchmarks/results/` by `scripts/gen_figures_boucle.py`.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- **The daemon did not run the path the bench measured.** `EnhancedPipeline` sent EPHAISTOS a single spec, without the `tool_name:` prefix, then let a session-context injection and the intent classifier override the result: "reveille fedora-base" gave `tv.power_on`, "archive test-vm" gave `tv.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 --reel` measures 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.
|
|
31
|
+
- 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.
|
|
32
|
+
- Argument names invented by the 0.5b in `missing_args` ("chromecast") no longer trigger a clarification; only real parameters of the tool count.
|
|
33
|
+
- Hue: a `group_id` that does not exist on the bridge is replaced by the default group (real groups read at startup).
|
|
34
|
+
- Performance mode (`-p`) and `-y`: LYRA printed "Tu confirmes ?" then executed without waiting; it now says what it does.
|
|
35
|
+
- Slang normalizer: URLs are no longer lowercased (a YouTube id is case-sensitive).
|
|
36
|
+
- 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.
|
|
37
|
+
- 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.
|
|
38
|
+
- Security: `main_rag.py` compared a prefixed tool name (`fedora.vm_destroy`) to the short names of `DANGEROUS_TOOLS`, so `-y` skipped the confirmation of destructive tools; it now uses `is_dangerous_tool()`.
|
|
39
|
+
- Security: an empty answer (Enter) no longer confirms a sensitive or destructive action in the daemon UI and the terminal UI; `o`/`oui` is required, as in `actions.py`.
|
|
40
|
+
- Security: `vm_snapshot` (revert/delete), `vm_import` and `vm_copy` are now in `DANGEROUS_TOOLS`; `PERFORMANCE_TOOLS` entries are prefixed (the eight `cast_*` never matched), Denon and read-only tools added; `main.py` (legacy) no longer keeps its own diverging lists.
|
|
41
|
+
- Rules: `tv.sound_only` and `tv.ambilight_color` do not exist in pylips-mcp; "son seul / mode musique" now maps to `tv.screen_off`, a colour request to `ambilight_mode(manual)` (pylips-mcp#7); `tv.youtube_video` sends `video` (schema name) instead of `video_id`.
|
|
42
|
+
- 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).
|
|
43
|
+
- `scripts/index_rag_3tier.py` ignores documents without `server_name` (a local `ironman.run_scene` would have created an UNKNOWN server); `config.yaml.example` declares the catt server.
|
|
44
|
+
- 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.
|
|
45
|
+
- Rules: "eteins les leds de la tele" was a power_off (sixth set control).
|
|
46
|
+
- Config: the dead `security.destructive_tools` list (never read, listed a non-existent `vm_delete`) is removed from config.yaml.example; `lyra/core/constants.py` is the only source. `docs/dev/INDEX_RAG.md` documents the v2 -> v3 regeneration order.
|
|
47
|
+
- 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.delete` and `tracking.kill_task` require an explicit confirmation.
|
|
48
|
+
|
|
49
|
+
## [1.2.0] - 2026-09-10
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
- docs/user/DATA_FLOWS.md: what Lyra captures, keeps, and the optional network outputs with their switches.
|
|
53
|
+
- VOICES.md and docs/licenses/: Piper voice licences, Llama 3.2 Community License and use policy ("Built with Llama").
|
|
54
|
+
- THIRD_PARTY_LICENSES.md generated by `make licenses` and checked in CI.
|
|
55
|
+
- README: English summary, prerequisites table, security guarantees mapped to code and tests, clickable metrics, ecosystem block.
|
|
56
|
+
- ROADMAP.md.
|
|
57
|
+
|
|
58
|
+
### Changed
|
|
59
|
+
- Packaging: hatchling, distribution name `lyra-assistant`, dependencies in pyproject with `gpu`/`dev` extras and a uv lockfile; CUDA libraries are no longer imposed.
|
|
60
|
+
- CI: reusable workflow (unit + installer tests on 3.11/3.12, ruff, personal-path guard), Dependabot.
|
|
61
|
+
- systemd units shipped with `@LYRA_DIR@` / `@HOME@` placeholders; no personal path left in code, scripts or tests.
|
|
62
|
+
- Tracking client defaults come from `TRACKING_SERVER_SCRIPT` / `TRACKING_VENV_PYTHON`; RAG spec sources from `LYRA_MCP_SPECS_DIR`.
|
|
63
|
+
|
|
64
|
+
## [1.1.0] - 2026-09-09
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
- License: AGPL-3.0-or-later with a commercial license option and a CLA (versions up to 1.0.0 remain MIT).
|
|
68
|
+
- README: HTTPS clone URL, status badges, dated claims, no more reference to a web domain.
|
|
69
|
+
- CLAUDE.md condensed to what an agent needs.
|
|
70
|
+
|
|
71
|
+
### Removed
|
|
72
|
+
- Generated artifacts (empty ChromaDB databases, test reports, Manim caches), the self-referencing `lyra/run.sh` symlink that broke CI, and workshop files (Claude Code prompts, session notes, n8n exports, divergent documentation copy), now archived privately.
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
- CI: the pip cache step no longer fails on a symlink loop.
|
|
76
|
+
|
|
77
|
+
## [v1.1.0 - Pipeline modulaire complet] - 2026-03-10
|
|
78
|
+
|
|
79
|
+
### Refactoring - Decomposition de pipeline.py en modules separes (7 missions)
|
|
80
|
+
|
|
81
|
+
`pipeline.py` passe de 2899 lignes a 919 lignes (~68% de reduction).
|
|
82
|
+
164/164 tests MCP conserves a 100% apres chaque mission.
|
|
83
|
+
|
|
84
|
+
**Mission 1 - Types et constantes (`core/types.py`, `core/config.py`)**
|
|
85
|
+
- Extraction de `QueryType`, `PipelineResult`, constantes MCP (`CATEGORY_KEYWORDS`, `TOOL_TYPE_KEYWORDS`, etc.)
|
|
86
|
+
|
|
87
|
+
**Mission 2 - Retrievers (`core/retrieval.py`)**
|
|
88
|
+
- Classe `Retriever` : encapsule SemanticRetriever + KeywordRetriever + RRFFusion
|
|
89
|
+
- API : `initialize()`, `retrieve(query)`, `detect_query_type(query)`
|
|
90
|
+
- Pipeline utilise `self._retriever` au lieu de 3 composants separes
|
|
91
|
+
|
|
92
|
+
**Mission 3 - Menus outils (`core/menus.py`)**
|
|
93
|
+
- `is_list_tools_query()`, `process_tools_query_step1()`, `handle_server_selection()`
|
|
94
|
+
- Constantes `LIST_VERBS`, `LIST_SUBJECTS`
|
|
95
|
+
|
|
96
|
+
**Mission 4 - Workflows base (`core/workflows/`)**
|
|
97
|
+
- `context.py` : `WorkflowContext` avec callables injectes (`prepare_execution`, `route_query`)
|
|
98
|
+
- `vm_start.py` : `handle_vm_start_confirm()` (4 cas oui/non/clarification/autre)
|
|
99
|
+
- `vm_stop.py` : `handle_vm_stop_choice()` (choix 1/2/3 arret VM avant clone)
|
|
100
|
+
- `vm_snapshot.py` : `handle_vm_snapshot_create_workflow()`, `handle_vm_snapshot_list_workflow()`, `handle_vm_snapshot_pending()`
|
|
101
|
+
|
|
102
|
+
**Mission 5 - Workflows clone/export (`core/workflows/vm_clone.py`, `vm_export.py`)**
|
|
103
|
+
- `vm_clone.py` : `suggest_vm_name()`, `handle_cow_choice()`, `handle_vm_clone_workflow()` (6 cas validation)
|
|
104
|
+
- `vm_export.py` : `CUSTOM_EXPORT_GROUPS`, workflow multi-tours (6 groupes virt-sysprep + firstboot)
|
|
105
|
+
|
|
106
|
+
**Mission 6 - Formatters et validation (`core/formatters.py`, `core/validation.py`)**
|
|
107
|
+
- `formatters.py` : `enrich_description()`, `enrich_optional_args()`, `format_listing_result()`
|
|
108
|
+
- `validation.py` : `validate_vm_existence()`, helpers VM state, constantes outils VM
|
|
109
|
+
|
|
110
|
+
**Mission 7 - Cleanup final**
|
|
111
|
+
- Suppression imports inutilises (`re`, `sys`, `unicodedata`) dans pipeline.py
|
|
112
|
+
- Mise a jour CLAUDE.md section "Project Structure"
|
|
113
|
+
- 164/164 PASS confirme (100%)
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## [v0.7 - 53/54 Tests MCP] - 2026-02-25
|
|
118
|
+
|
|
119
|
+
### Campagne de tests complete - 54 tests MCP one-shot
|
|
120
|
+
|
|
121
|
+
Passage de 38/54 (70%) a 53/54 (98%). Un seul FAIL attendu (T10: vm_clone, source VM inexistante).
|
|
122
|
+
|
|
123
|
+
**Fixes FEDORA:**
|
|
124
|
+
- T1: vm_status({}) pour listing global (etait vm_name='' -> EXEC_ERROR)
|
|
125
|
+
- T6: vm_exec(vm_name, cmd) "execute CMD sur VM" (etait ls() mauvais outil)
|
|
126
|
+
- T7: vm_copy(source, vm_name, dest) "copie FILE vers VM" (etait FAIL)
|
|
127
|
+
- T11: vm_clone_system(name) "clone systeme VM en NEWVM" (etait FAIL)
|
|
128
|
+
- T12: vm_verify(vm_name) "verifie la VM NAME" (etait FAIL)
|
|
129
|
+
- T14: backup_status({}) sans watch=True (etait TIMEOUT boucle infinie)
|
|
130
|
+
- T15: backup_create(vm_name) args corrects (etait sans vm_name)
|
|
131
|
+
- T16: backup_verify(vm_name) argument correct (etait type= au lieu de vm_name=)
|
|
132
|
+
|
|
133
|
+
**Fixes TV:**
|
|
134
|
+
- T30: tv.volume_up (etait tv.power_on)
|
|
135
|
+
- T31: tv.volume_down (etait FAIL)
|
|
136
|
+
- T33: tv.mute (etait tv.power_off)
|
|
137
|
+
|
|
138
|
+
**Fixes DENON:**
|
|
139
|
+
- T39: denon.power_off (etait eteins() mauvais outil)
|
|
140
|
+
- T42: denon.volume_set(level=50) (etait hue.set_brightness mauvais outil!)
|
|
141
|
+
- T44: denon.mute_off (etait denon(status=off))
|
|
142
|
+
|
|
143
|
+
**Fixes HUE:**
|
|
144
|
+
- T19: hue.turn_on_group(group_id=81) (etait allume() via embedding ChromaDB confus)
|
|
145
|
+
- T27: hue.turn_off_light (etait turn_on_light!)
|
|
146
|
+
|
|
147
|
+
**Fixes CATT:**
|
|
148
|
+
- T46: catt.cast_scan (etait catt.cast_dual_stop)
|
|
149
|
+
- T51: catt.cast_volume (etait denon.volume_up + intent=knowledge)
|
|
150
|
+
|
|
151
|
+
**Changements techniques:**
|
|
152
|
+
|
|
153
|
+
1. **BM25 accent normalization** (`keyword_retriever.py`):
|
|
154
|
+
- `_tokenize()` normalise les accents (NFD) avant BM25
|
|
155
|
+
- "Demarre" dans docs ChromaDB = "demarre" dans query sans accent
|
|
156
|
+
|
|
157
|
+
2. **`_rule_based_detect()` etendue** (`pipeline.py`):
|
|
158
|
+
- BACKUP (6 regles): backup_status/list/verify/create/restore/clean
|
|
159
|
+
- FEDORA VM (9 regles): vm_start/stop/destroy/exec/snapshot/status/verify/copy/clone_system
|
|
160
|
+
- CATT (2 regles): cast_scan, cast_volume (avec support "diffuse" = SlangNorm("cast"))
|
|
161
|
+
- HUE (2 regles): turn_on_group, turn_off_light
|
|
162
|
+
- vm_start: exclusion TV context ("lance Netflix sur la TV" -> PAS vm_start)
|
|
163
|
+
|
|
164
|
+
3. **`_DEMANDE_VERBS_RE` etendu** (`intent_classifier.py`):
|
|
165
|
+
- Ajoute: status|statut|nettoie|restaure|allume|eteins|mute|scan|caste|lance|demarre|arrete|supprime
|
|
166
|
+
|
|
167
|
+
4. **FRENCH_ENRICHMENTS** (`pipeline.py`):
|
|
168
|
+
- turn_on_group/turn_off_group: retire verbes dupliques (deja fournis par "turn_on"/"turn_off")
|
|
169
|
+
- Distingue singular ("lumiere") vs pluriel ("lumieres") pour light vs group
|
|
170
|
+
|
|
171
|
+
5. **Normalisation accents dans `_rule_based_detect()`**:
|
|
172
|
+
- NFD normalization au debut (SlangNorm ajoute des accents: "execute"->"exécute")
|
|
173
|
+
|
|
174
|
+
**Fichiers modifies:**
|
|
175
|
+
- `lyra/rag/keyword_retriever.py`: `_tokenize()` accent normalization
|
|
176
|
+
- `lyra/models/intent_classifier.py`: `_DEMANDE_VERBS_RE` etendu
|
|
177
|
+
- `lyra/core/pipeline.py`: `_rule_based_detect()`, FRENCH_ENRICHMENTS, vm_start TV exclusion
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## [v0.6.1 - Fixes RAG TV/DENON/CATT] - 2026-02-25
|
|
182
|
+
|
|
183
|
+
### Fixes RAG TV/DENON/CATT (pipeline.py)
|
|
184
|
+
|
|
185
|
+
**Cause racine:** EPHAISTOS 0.5b echoue sur les outils domotique (volume TV, mute, Denon).
|
|
186
|
+
BM25 retourne de mauvais outils ("volume denon a 50" → catt.cast_volume, "demute le denon" → denon.power_off).
|
|
187
|
+
SlangNormalizer transforme "cast" → "diffuse" ce qui casse la detection cast_scan.
|
|
188
|
+
|
|
189
|
+
**Fix: regles TV/DENON/CATT dans `_rule_based_detect()`** (`pipeline.py`):
|
|
190
|
+
- TV: `tv.volume_up/down/set/mute` detectes par presence de "tv/tele" + verbe/chiffre/sourdine
|
|
191
|
+
- DENON: `denon.power_on/off/mute_on/off/volume_up/down/set` detectes par presence de "denon"
|
|
192
|
+
- Couvre formes original ("eteins", "demute") et normalisees ("sourdine")
|
|
193
|
+
- Ordre: power_off/on → mute_off/on → volume_set → volume_up/down
|
|
194
|
+
- CATT scan: "scan + cast/diffuse/appareils" → `catt.cast_scan`
|
|
195
|
+
(gere les deux formes: original "cast" et SlangNorm "diffuse")
|
|
196
|
+
|
|
197
|
+
**Resultats:**
|
|
198
|
+
|
|
199
|
+
| Query | Avant | Apres |
|
|
200
|
+
|-------|-------|-------|
|
|
201
|
+
| "monte le volume de la TV" | EPHAISTOS 0.5b echec | tv.volume_up OK |
|
|
202
|
+
| "coupe le son de la TV" | EPHAISTOS 0.5b echec | tv.mute OK |
|
|
203
|
+
| "volume denon a 50" | BM25 → catt.cast_volume | denon.volume_set {level:50} OK |
|
|
204
|
+
| "demute le denon" | BM25 → denon.power_off | denon.mute_off OK |
|
|
205
|
+
| "eteins le denon" | BM25 score trop bas | denon.power_off OK |
|
|
206
|
+
| "scan les appareils cast" | SlangNorm → cast_youtube | catt.cast_scan OK |
|
|
207
|
+
|
|
208
|
+
**Fichiers modifies:**
|
|
209
|
+
- `lyra/core/pipeline.py` : `_rule_based_detect()` etendu avec regles TV/DENON/CATT
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## [v0.6 - One-Shot + Fixes RAG] - 2026-02-25
|
|
214
|
+
|
|
215
|
+
### Mode One-Shot CLI
|
|
216
|
+
|
|
217
|
+
Ajout du mode one-shot: `lyra "[requete]" [-v] [-y]`
|
|
218
|
+
|
|
219
|
+
- `lyra "demarre preprod-01"` - execution directe sans UI interactive
|
|
220
|
+
- `-v / --verbose` : affiche les etapes RAG en temps reel (`[rag]`, `[intent]`, `[action]`)
|
|
221
|
+
- `-y / --yes` : auto-confirme les actions (mode non interactif)
|
|
222
|
+
- Codes de sortie: 0=OK, 1=EXEC_ERROR, 2=CANCEL, 3=PIPELINE_FAIL, 124=TIMEOUT
|
|
223
|
+
|
|
224
|
+
**Fichiers modifies:**
|
|
225
|
+
- `main_rag.py` : fonction `run_one_shot()`, argparse mis a jour
|
|
226
|
+
- `run.sh` : documentation one-shot dans les commentaires
|
|
227
|
+
|
|
228
|
+
### Tests MCP one-shot (54 tests)
|
|
229
|
+
|
|
230
|
+
Resultats: 38/54 = 70% (voir `test_mcp_results.md`)
|
|
231
|
+
|
|
232
|
+
| Serveur | Total | OK | Problemes |
|
|
233
|
+
|---------|-------|----|-----------|
|
|
234
|
+
| FEDORA | 18 | 11 | 7 |
|
|
235
|
+
| HUE | 9 | 8 | 1 |
|
|
236
|
+
| TV | 9 | 5 | 4 |
|
|
237
|
+
| DENON | 9 | 6 | 3 |
|
|
238
|
+
| CATT | 8 | 7 | 1 |
|
|
239
|
+
| MERMAID | 1 | 1 | 0 |
|
|
240
|
+
|
|
241
|
+
### Fixes RAG FEDORA (vm_clone_system, vm_clone, vm_copy, vm_verify)
|
|
242
|
+
|
|
243
|
+
**Cause racine identifiee:** EPHAISTOS 0.5b trop petit pour extraire les arguments, enrichissements BM25 confondent "copie" avec vm_clone, IntentClassifier classe "verifie" comme "info".
|
|
244
|
+
|
|
245
|
+
**Fix 1 - vm_clone_system** (`pipeline.py`):
|
|
246
|
+
- Bug substring: `"vm_clone" in "fedora.vm_clone_system"` = True
|
|
247
|
+
- Fix: `analysis.tool in ("vm_clone", "fedora.vm_clone")`
|
|
248
|
+
|
|
249
|
+
**Fix 2 - vm_clone** (`pipeline.py`):
|
|
250
|
+
- EPHAISTOS detecte l'outil mais `arguments={}` + `missing_args=[]` → NullPointerError ligne 1290
|
|
251
|
+
- Fix: regex fallback dans `_handle_vm_clone_workflow` extrait "clone X en Y"
|
|
252
|
+
- Fix: null-check `if source_vm and vm.replace(...)`
|
|
253
|
+
- Fix: `_rule_based_detect()` intercepte "clone X en Y" avant EPHAISTOS
|
|
254
|
+
|
|
255
|
+
**Fix 3 - vm_copy** (`pipeline.py`):
|
|
256
|
+
- BM25 retourne vm_clone au lieu de vm_copy ("copie" present dans enrichissement "clone")
|
|
257
|
+
- Fix: `_rule_based_detect()` intercepte "copie/transfere FILE vers/sur VM"
|
|
258
|
+
|
|
259
|
+
**Fix 4 - vm_verify** (`intent_classifier.py`, `pipeline.py`):
|
|
260
|
+
- IntentClassifier (Llama 1b) classe "verifie la VM" comme "info" → pipeline ignorait l'outil
|
|
261
|
+
- Fix: regex override `_DEMANDE_VERBS_RE` dans `classify()` force "demande" pour verbes d'action
|
|
262
|
+
- Fix: `_rule_based_detect()` intercepte "verifie/verif [la VM] NAME"
|
|
263
|
+
|
|
264
|
+
**Nouveaux examples EPHAISTOS** (`ephaistos.py`):
|
|
265
|
+
- vm_clone avec source_vm + new_vm_name
|
|
266
|
+
- vm_copy avec source + vm_name + dest
|
|
267
|
+
- vm_verify avec vm_name optionnel
|
|
268
|
+
- vm_clone_system avec name
|
|
269
|
+
|
|
270
|
+
**Fichiers modifies:**
|
|
271
|
+
- `lyra/core/pipeline.py` : `import re`, `_rule_based_detect()`, fixes `_handle_vm_clone_workflow`
|
|
272
|
+
- `lyra/models/intent_classifier.py` : `_DEMANDE_VERBS_RE`, exemples prompt
|
|
273
|
+
- `lyra/models/ephaistos.py` : 4 nouveaux exemples FEDORA
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## [Phase 4] - 2026-01-23
|
|
278
|
+
|
|
279
|
+
### Operations Async via n8n + Fallback Subprocess
|
|
280
|
+
|
|
281
|
+
**Ajouts:**
|
|
282
|
+
- Module `modules/n8n.py` : Client n8n + executeur async fallback
|
|
283
|
+
- 3 workflows n8n crees avec noeud `code` (JS)
|
|
284
|
+
- Detection automatique des operations longues (vm_clone, backup_create, backup_restore)
|
|
285
|
+
- **Fallback subprocess** : Si n8n non disponible, execute en arriere-plan via threading
|
|
286
|
+
- Notification dans le terminal quand operation terminee (mode fallback)
|
|
287
|
+
|
|
288
|
+
**Workflows n8n:**
|
|
289
|
+
| Workflow | Webhook | Description |
|
|
290
|
+
|----------|---------|-------------|
|
|
291
|
+
| Lyra - Clone VM v2 | `/webhook/lyra-clone-vm-v2` | Clone VM via kvm-clone.sh |
|
|
292
|
+
| Lyra - Backup Create | `/webhook/lyra-backup-create` | Cree backup timeshift/borg |
|
|
293
|
+
| Lyra - Backup Restore | `/webhook/lyra-backup-restore` | Restaure backup |
|
|
294
|
+
|
|
295
|
+
**Note:** Les workflows utilisent le noeud `n8n-nodes-base.code` au lieu de `executeCommand`
|
|
296
|
+
(ce dernier n'etait pas reconnu par l'API).
|
|
297
|
+
|
|
298
|
+
**Fichiers modifies:**
|
|
299
|
+
- `main.py` : Integration n8n avec fallback subprocess
|
|
300
|
+
- `modules/n8n.py` : Client n8n + AsyncExecutor pour fallback
|
|
301
|
+
- `config.yaml` : n8n.enabled = true, webhook path mis a jour
|
|
302
|
+
- `prompts/system_prompt.txt` : Section operations async
|
|
303
|
+
|
|
304
|
+
**Mode fallback (subprocess):**
|
|
305
|
+
Quand n8n n'est pas disponible ou les webhooks ne sont pas actifs:
|
|
306
|
+
1. Lyra detecte l'echec du webhook
|
|
307
|
+
2. Lance la commande en arriere-plan via subprocess.Popen
|
|
308
|
+
3. Notifie dans le terminal quand c'est termine
|
|
309
|
+
|
|
310
|
+
**Configuration requise:**
|
|
311
|
+
```yaml
|
|
312
|
+
n8n:
|
|
313
|
+
enabled: true
|
|
314
|
+
base_url: http://localhost:5678
|
|
315
|
+
api_key: <votre-cle-api> # Optionnel
|
|
316
|
+
webhooks:
|
|
317
|
+
clone-vm: /webhook/lyra-clone-vm-v2
|
|
318
|
+
backup-create: /webhook/lyra-backup-create
|
|
319
|
+
backup-restore: /webhook/lyra-backup-restore
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**Pour activer les webhooks n8n:**
|
|
323
|
+
1. Aller sur http://localhost:5678
|
|
324
|
+
2. Ouvrir chaque workflow Lyra
|
|
325
|
+
3. Cliquer sur le toggle "Active" en haut a droite
|
|
326
|
+
4. Les webhooks seront alors operationnels
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## [Phase 3] - 2026-01-23
|
|
331
|
+
|
|
332
|
+
### Actions + Securite
|
|
333
|
+
|
|
334
|
+
**Ajouts:**
|
|
335
|
+
- Principe **Read-First** : verification automatique de l'etat VM avant toute action
|
|
336
|
+
- System prompt externe (`prompts/system_prompt.txt`) au lieu de hardcode
|
|
337
|
+
- Confirmation vocale avec mots-cles ("oui"/"non"/"oui je confirme")
|
|
338
|
+
- Affichage de l'etat VM dans la confirmation (status, IP)
|
|
339
|
+
- Description vocale naturelle des actions proposees
|
|
340
|
+
|
|
341
|
+
**Regles de securite:**
|
|
342
|
+
- `READ_FIRST_TOOLS` : vm_start, vm_stop, vm_destroy, vm_snapshot, vm_clone
|
|
343
|
+
- `READ_ONLY_TOOLS` : vm_status, backup_status, backup_list, backup_verify
|
|
344
|
+
- Actions dangereuses : confirmation explicite "oui je confirme" en vocal
|
|
345
|
+
|
|
346
|
+
**Fichiers modifies:**
|
|
347
|
+
- `main.py` : Chargement prompt externe, Read-First, descriptions vocales
|
|
348
|
+
- `modules/ui.py` : Confirmation vocale, affichage etat VM
|
|
349
|
+
- `prompts/system_prompt.txt` : Regles de securite detaillees
|
|
350
|
+
|
|
351
|
+
**Confirmation vocale:**
|
|
352
|
+
- Option `[v]` pour passer en mode vocal
|
|
353
|
+
- Mots-cles acceptes : oui, yes, ok, d'accord, confirme, vas-y
|
|
354
|
+
- Mots-cles annulation : non, no, annule, stop, arrete
|
|
355
|
+
- Actions destructives : exigent "oui je confirme"
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## [Phase 2] - 2026-01-22
|
|
360
|
+
|
|
361
|
+
### Mode Vocal (STT/TTS)
|
|
362
|
+
|
|
363
|
+
**Ajouts:**
|
|
364
|
+
- Mode `--vocal` pour interaction vocale complete
|
|
365
|
+
- Module `modules/audio.py` : STT, TTS, AudioRecorder, VoiceInterface
|
|
366
|
+
- Script `run.sh` : Lancement avec configuration CUDA automatique
|
|
367
|
+
- Alias bash `lyra` et `lyra --vocal`
|
|
368
|
+
- Bip sonore avant l'ecoute
|
|
369
|
+
- Indicateur visuel de niveau audio en temps reel
|
|
370
|
+
- Detection de silence pour fin d'enregistrement automatique
|
|
371
|
+
|
|
372
|
+
**Stack vocale:**
|
|
373
|
+
- STT : faster-whisper (modele base, CUDA float16)
|
|
374
|
+
- TTS : Piper (voix fr_FR-upmc-medium)
|
|
375
|
+
- Audio : sounddevice avec resampling 48kHz
|
|
376
|
+
|
|
377
|
+
**Configuration (`config.yaml`):**
|
|
378
|
+
```yaml
|
|
379
|
+
audio:
|
|
380
|
+
sample_rate: 48000 # Compatible PipeWire/ALSA
|
|
381
|
+
silence_threshold: 0.005
|
|
382
|
+
silence_duration: 1.0
|
|
383
|
+
stt:
|
|
384
|
+
model: base
|
|
385
|
+
device: cuda
|
|
386
|
+
compute_type: float16
|
|
387
|
+
tts:
|
|
388
|
+
model: fr_FR-upmc-medium
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
**Dependances ajoutees:**
|
|
392
|
+
- faster-whisper
|
|
393
|
+
- piper-tts
|
|
394
|
+
- sounddevice
|
|
395
|
+
- nvidia-cublas-cu12
|
|
396
|
+
- nvidia-cudnn-cu12
|
|
397
|
+
|
|
398
|
+
**Fixes techniques:**
|
|
399
|
+
- Resampling audio : 48kHz (PipeWire) <-> 16kHz (Whisper) <-> 22050Hz (Piper)
|
|
400
|
+
- `suppress_stderr()` : Masque les warnings cffi de sounddevice
|
|
401
|
+
- Configuration CUDA via `LD_LIBRARY_PATH` dans run.sh
|
|
402
|
+
|
|
403
|
+
**Issue connue:**
|
|
404
|
+
- Elgato Wave 3 non fonctionnel (necessite Wave Link sur Windows/Mac)
|
|
405
|
+
- Workaround : Utiliser G522 LIGHTSPEED comme micro par defaut
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## [Phase 1] - 2024
|
|
410
|
+
|
|
411
|
+
### Wrapper Python + MCP (mode texte)
|
|
412
|
+
|
|
413
|
+
**Fonctionnalites:**
|
|
414
|
+
- Client Ollama avec parsing JSON des tool calls
|
|
415
|
+
- Client MCP pour fedora-agents
|
|
416
|
+
- Human-in-the-Loop : confirmation avant execution
|
|
417
|
+
- Interface CLI en francais
|
|
418
|
+
- Raccourcis clavier (Ctrl+L, double Ctrl+C)
|
|
419
|
+
|
|
420
|
+
**Outils MCP disponibles:**
|
|
421
|
+
- VM : vm_status, vm_start, vm_stop, vm_snapshot, vm_exec, vm_clone
|
|
422
|
+
- Backup : backup_status, backup_list, backup_create, backup_verify
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Accord de contribution / Contributor License Agreement
|
|
2
|
+
|
|
3
|
+
**FR.** En soumettant une contribution (pull request, patch, suggestion de code) à Lyra, vous confirmez que vous en êtes l'auteur ou que vous avez le droit de la soumettre, et vous accordez à amineutron une licence perpétuelle, mondiale, non exclusive et gratuite pour l'utiliser, la modifier et la distribuer sous la licence AGPL-3.0 **et** sous la licence commerciale de Lyra. Vous conservez tous vos droits sur votre contribution. Cet accord existe pour que la double licence reste possible.
|
|
4
|
+
|
|
5
|
+
**EN.** By submitting a contribution (pull request, patch, code suggestion) to Lyra, you confirm that you authored it or have the right to submit it, and you grant amineutron a perpetual, worldwide, non-exclusive, royalty-free license to use, modify and distribute it under the AGPL-3.0 **and** under Lyra's commercial license. You keep all rights to your contribution. This agreement exists so that the dual-licensing model remains possible.
|
|
6
|
+
|
|
7
|
+
To accept, add this line to your pull request description: `I have read and accept CLA.md`.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Licence commerciale / Commercial license
|
|
2
|
+
|
|
3
|
+
**FR.** Lyra est publiée sous licence **AGPL-3.0** : vous pouvez l'utiliser, l'étudier, la modifier et la redistribuer librement, à condition de publier vos modifications sous la même licence, y compris quand Lyra est utilisée à travers un réseau. C'est gratuit et sans limite pour un usage personnel, associatif, académique, et pour toute organisation qui accepte ces conditions.
|
|
4
|
+
|
|
5
|
+
Les entreprises qui souhaitent intégrer Lyra dans un produit ou un service **sans publier leurs modifications**, ou qui ont besoin d'un support contractuel, peuvent obtenir une **licence commerciale**. Écrivez à amine.neutroncore@gmail.com (objet : « Licence commerciale Lyra ») ; la grille tarifaire est communiquée sur demande.
|
|
6
|
+
|
|
7
|
+
Les versions jusqu'à v1.0.0 incluse restent sous licence MIT.
|
|
8
|
+
|
|
9
|
+
**EN.** Lyra is released under the **AGPL-3.0**: use, study, modify and redistribute it freely, provided you publish your changes under the same license, including when Lyra is used over a network. This is free for personal, non-profit and academic use, and for any organisation accepting these terms.
|
|
10
|
+
|
|
11
|
+
Companies that want to embed Lyra in a product or service **without publishing their changes**, or that need contractual support, can obtain a **commercial license**. Contact amine.neutroncore@gmail.com (subject: "Lyra commercial license"); pricing is available on request.
|
|
12
|
+
|
|
13
|
+
Releases up to and including v1.0.0 remain under the MIT License.
|