mirror of
https://github.com/Alkatrazz24/Funk-lab.git
synced 2026-07-08 19:54:43 +02:00
Serveur : /v1/ask accepte un model optionnel (validé contre STT_ALLOWED_MODELS), nouvel endpoint GET /v1/models (défaut + alias autorisés). Pas de switch global. Client : 'stt --text' (chat texte simple sans micro/HUD), '--model hermes|claude|qwen|opus' (noms courts → alias LiteLLM), commandes /model et /models en mode texte. Le modèle choisi est envoyé au serveur à chaque requête (voix comme texte). Claude-Session: https://claude.ai/code/session_013FmcxGsyXZXogiAHQLjnZT Co-authored-by: Claude <noreply@anthropic.com>
156 lines
8.6 KiB
Markdown
156 lines
8.6 KiB
Markdown
# 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 │ → LiteLLM s01 192.168.10.1:4000 │
|
|
└──────────────┬─────────────────────────┘
|
|
▼
|
|
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 en
|
|
**IP directe** `192.168.10.1:4000` (même pattern qu'open-webui). 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 `:8080` n'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.
|
|
|
|
**Choix du modèle** : le client envoie un `model` (alias LiteLLM) **par requête** à
|
|
`/v1/ask` ; le serveur le valide contre `STT_ALLOWED_MODELS` et le passe à LiteLLM. Pas de
|
|
switch global type `hermes-switch` (pas de restart, chaque client choisit le sien).
|
|
`GET /v1/models` liste le défaut + les alias autorisés. Noms courts client : `hermes`
|
|
(=hermes-default), `qwen`, `claude` (=claude-sonnet-4-6), `opus`.
|
|
|
|
### 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` (voix+HUD), `stt --text` (chat texte), `stt --setup`, `stt --server <url>`, `stt --model <hermes\|claude\|qwen\|opus>` |
|
|
| — 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`) |
|
|
| 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é ⇒ éventuel `imagePullSecret`.
|
|
- **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 en IP directe) | ✅ déployé |
|
|
| **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](https://github.com/AlexandreSajus/JARVIS) — Voice→LLM→Speech, interface web (proche du front visé).
|
|
- [InterGenJLU/jarvis](https://github.com/InterGenJLU/jarvis) — AMD ROCm (comme la RX 6700XT), HUD santé, streaming TTS.
|
|
- [novik133/jarvis](https://github.com/novik133/jarvis) — whisper.cpp + Piper (même TTS) + monitoring système.
|
|
- [rhasspy/wyoming-addons](https://github.com/rhasspy/wyoming-addons) — faster-whisper / Piper conteneurisés (option phase 7).
|