* feat(stt): cadrage + squelette assistant vocal Jarvis Conception validée du projet STT — assistant vocal/HUD du homelab Funk : - HUD web sur-mesure + STT/TTS local (faster-whisper + Piper) - Packaging commande pipx (stt), démarrage auto systemd --user - Cerveau 3 modes + auto-détection LAN : hermes / local-direct / claude-direct - Mémoire 3 tiers : SQLite local + Qdrant s01 + GitHub (distillée, versionnée) Réutilise tools/hermes-voice, LiteLLM, Hermes Agent. Squelette + doc admin/ia/stt.md, implémentation par phases (roadmap dans le doc). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013FmcxGsyXZXogiAHQLjnZT * feat(stt): phase 1-2 — commande, backend vocal, routeur cerveau, HUD MVP - cli.py : commande `stt` (--setup, --mode, --no-tts) - config.py : défauts embarqués + ~/.config/stt/stt.toml - voice/engine.py : refactor de hermes-voice en classe avec callbacks d'état - brain/router.py : 3 modes (hermes SSH / local LiteLLM / claude API) + auto-détection LAN - server/app.py : HTTP statique (HUD) + websocket (états → HUD) - memory/store.py : tier local SQLite (Qdrant + sync GitHub = phase 4) - hud/index.html : HUD MVP (visualiseur d'état + conversation) Vérifié hors-LAN : py_compile, --help, config, routeur (→ claude), mémoire SQLite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013FmcxGsyXZXogiAHQLjnZT * fix(stt): embarquer le HUD dans le package (404 après pipx install) Le HUD était à la racine du projet (stt/hud/) donc absent du package installé par pipx → HTTP 404 sur /. Déplacé dans le package (stt/stt/hud/) + package-data, HUD_DIR ajusté. Vérifié : le wheel contient bien stt/hud/index.html. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013FmcxGsyXZXogiAHQLjnZT * refactor(stt): pivot client-serveur — STT-server in-cluster + client pipx Sépare STT en deux : - stt/client/ : commande `stt` (pipx), voix locale (Whisper/Piper) + HUD ; envoie le texte au serveur via api.py (ServerClient → POST /v1/ask). URL serveur paramétrable, pas de cerveau local (suppression du routeur 3 modes). - stt/server/ : STT-server FastAPI (conteneur), /healthz + /v1/ask → LiteLLM (Qwen3/Claude). Déploiement cluster : - k8s/apps/stt/ : Deployment, Service, IngressRoute (stt.lab.local), litellm-ext (Service + Endpoints → 192.168.10.1:4000 pour joindre LiteLLM hors cluster) - k8s/apps-of-apps/apps/stt.yaml : Application ArgoCD (depuis main) - .github/workflows/build-stt-server.yml : build/push image → ghcr.io/alkatrazz24/funk-stt-server Inférence/chat seulement (outils Hermes 'agir sur Funk' = phase ultérieure, API :8080 à spécifier). Vérifié : py_compile client+serveur, YAML manifests, ServerClient. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013FmcxGsyXZXogiAHQLjnZT --------- Co-authored-by: Claude <noreply@anthropic.com>
8.1 KiB
STT — Assistant vocal "Jarvis" du homelab Funk
STT est l'interface vocale et graphique de Funk : un assistant type Jarvis / Iron Man
qui écoute, parle et affiche un HUD animé. Architecture client-serveur : un client stt
sur le poste (voix + HUD) qui interroge un STT-server in-cluster (orchestration AI).
Objectif ultérieur : « agir sur le homelab » via les outils de Hermes (phase 7).
Nom de code :
STT. À l'origine « Speech-To-Text », mais le projet couvre toute la chaîne voix → cerveau → voix + interface + mémoire. Renommable plus tard sans impact technique (FRIDAY, etc.) — c'est juste un identifiant de répertoire/commande.
⚠️ 2026-06-17 — client (phase 1) + serveur (phase 2) + manifests cluster (phase 3) écrits. Reste : build image (CI), déploiement ArgoCD (après merge sur
main), test audio sur poste.
Principe directeur : réutiliser, ne pas réinventer
~70 % du backend existe déjà dans Funk. STT n'ajoute que le visage (HUD), la personnalisation, la mémoire multi-tiers et le packaging en commande.
| Besoin Jarvis | Brique Funk réutilisée | État |
|---|---|---|
| Modèle local ou Claude | LiteLLM :4000 + hermes-default + hermes-switch qwen|claude |
✅ opérationnel |
| Agir sur le homelab | Hermes Agent (:8080, profils funk-ai/system/monitor/brain) |
✅ opérationnel |
| Voix (STT + TTS + wake word) | tools/hermes-voice/ — faster-whisper + Piper + webrtcvad |
✅ existe (CLI only) |
| Démarrage auto au boot | pattern systemd --user (tools/hermes-voice/install-service.sh) |
✅ éprouvé |
| Mémoire sémantique | Qdrant :6333 + RAG (rag-query/rag-ingest) sur s01 |
⚠️ HS depuis 05/06 |
Maillon réellement manquant : l'interface graphique HUD + le packaging + la mémoire perso.
Décisions d'architecture (verrouillées 2026-06-17)
| Décision | Choix retenu |
|---|---|
| Architecture | Client-serveur : client sur le poste, STT-server in-cluster (révise le tout-local) |
| Interface | HUD web sur-mesure côté client (canvas/WebGL) |
| STT / TTS | Local sur le poste (faster-whisper CPU + Piper) — le serveur ne touche pas à l'audio |
| Packaging | Client : commande stt via pipx (#subdirectory=stt/client). Serveur : conteneur (ghcr) déployé par ArgoCD |
| Cerveau | Côté serveur : route vers LiteLLM :4000 (Qwen3 / Claude). Outils Hermes = phase ultérieure |
| Client → serveur | Client serveur-only (pas de repli Claude). URL serveur paramétrable |
| Mémoire | Côté serveur (futur) : Qdrant s01 + distillée GitHub. Client : cache local SQLite |
Pivot 2026-06-17 (post-test) : on est passé du tout-local à un modèle client-serveur. Le « cerveau » (ex-routeur 3 modes côté client) a migré côté serveur.
Architecture
LAN / *.lab.local
┌─ POSTE — client `stt` (pipx) ─┐ ┌─ CLUSTER k8s (namespace ai) ─────────┐
│ • micro + VAD + wake word │ HTTP │ STT-server (Deployment + Service) │
│ • faster-whisper (STT) │ ─────▶ │ GET /healthz │
│ • Piper (TTS) │ POST │ POST /v1/ask {text} → {reply} │
│ • HUD web (ui/ + hud/) │ /v1/ask│ brain → LiteLLM (httpx) │
│ • api.py → ServerClient │ ◀───── │ IngressRoute : stt.lab.local │
└────────────────────────────────┘ reply │ Service Endpoints : litellm-ext │
└──────────────┬─────────────────────────┘
▼
LiteLLM :4000 (storage-01, hors cluster)
→ Qwen3 (g01) / Claude (hermes-default)
Le cerveau — côté serveur
Le STT-server appelle LiteLLM :4000 (OpenAI-compatible), joint depuis le cluster via
un Service sans sélecteur + Endpoints manuel (litellm-ext → 192.168.10.1:4000). LiteLLM
route lui-même vers Qwen3 (g01) ou Claude selon l'alias hermes-default / hermes-switch.
« Agir sur Funk » (outils de l'agent Hermes via le gateway
:8080) n'est pas dans le MVP : l'API:8080n'est pas spécifiée, et depuis un pod le SSH vers Hermes est impraticable. MVP = inférence/chat. L'intégration Hermes est une étape ultérieure.
La mémoire — côté serveur (futur)
- Client : cache local SQLite (
~/.local/share/stt/, gitignoré) — historique brut. - Serveur (à venir) : Qdrant s01 (sémantique, partagé RAG) + mémoire distillée
versionnée dans
stt/server/memory/distilled/. Sessions multi-clients.
⚠️ Vie privée : seule la mémoire distillée serait committée. Repo privé impératif.
Composants
| Composant | Emplacement | Description |
|---|---|---|
Client stt |
stt/client/ (pipx) |
stt, stt --setup, stt --server <url>, stt --no-tts |
| — voix | stt/client/stt/voice/ |
wake word, STT faster-whisper, TTS Piper |
| — api | stt/client/stt/api.py |
ServerClient → POST /v1/ask |
| — UI/HUD | stt/client/stt/ui/ + hud/ |
HTTP statique + websocket d'états ; HUD embarqué dans le package |
| STT-server | stt/server/ (conteneur) |
FastAPI : /healthz, /v1/ask ; brain.py → LiteLLM |
| Image | ghcr.io/alkatrazz24/funk-stt-server |
construite par .github/workflows/build-stt-server.yml |
| Manifests | k8s/apps/stt/ |
Deployment, Service, IngressRoute (stt.lab.local), litellm-ext |
| Application ArgoCD | k8s/apps-of-apps/apps/stt.yaml |
déploie depuis main |
Personnalisation (« l'image, le design, la voix »)
Côté client, pilotable depuis stt/client/config/ + l'écran de réglages du HUD :
- Avatar / image (
config/avatars/), thème (config/themes/), voix Piper.onnx(config/voices/), wake word, URL serveur.
Prérequis / dépendances
- Poste : micro, Python 3.11+, pipx, navigateur. Piper + voix dans
~/.local/share/piper/,aplay. - Cluster : image poussée sur ghcr ; ArgoCD déploie depuis
main(donc merge requis) ; ghcr privé ⇒ éventuelimagePullSecret. - LiteLLM joignable depuis le cluster (
192.168.10.1:4000).
Roadmap
| Phase | Objectif | État |
|---|---|---|
| 0 — Cadrage | Conception validée | ✅ |
| 1 — Client voix + HUD | stt : voix locale + HUD + websocket |
✅ |
| 2 — STT-server | FastAPI /v1/ask → LiteLLM |
✅ |
| 3 — Déploiement cluster | image ghcr + manifests k8s + ArgoCD + litellm-ext |
✅ (à merger sur main) |
| 4 — HUD avancé | visualiseur arc-reactor + thèmes + écran réglages | ⏳ |
| 5 — Mémoire serveur | Qdrant s01 + distillée GitHub + sessions | ⏳ |
| 6 — Auto-start client | install-service.sh (systemd --user) + kiosk |
⏳ |
| 7 — Outils Hermes | « agir sur Funk » via gateway :8080 (API à spécifier) |
⏳ |
État (testé hors-LAN)
py_compile OK (client + serveur) ; client : stt --help, config, ServerClient vérifiés ;
serveur : import/compile OK. Reste à valider sur cible : build image (CI), déploiement ArgoCD
après merge, et test audio bout-en-bout sur le poste.
Projets de référence (inspiration, non forkés)
Aucun ne se branche proprement sur LiteLLM + Hermes (ils embarquent leur propre LLM/agent), mais bons pour le design et le code à piocher :
- AlexandreSajus/JARVIS — Voice→LLM→Speech, interface web (proche du front visé).
- InterGenJLU/jarvis — AMD ROCm (comme la RX 6700XT), HUD santé, streaming TTS.
- novik133/jarvis — whisper.cpp + Piper (même TTS) + monitoring système.
- rhasspy/wyoming-addons — faster-whisper / Piper conteneurisés (option phase 7).