Funk-lab/stt
ALI YESILKAYA 9a46f6cbcb
feat(stt): actions cluster via Hermes — contexte « agent » + exécuteur hermes-exec (#42)
Asa peut AGIR sur le homelab (l'autre moitié de la vision), via le vrai agent Hermes,
profil par défaut, tous ses outils — avec confirmation et jeton.

Découverte : Hermes n'a pas d'API HTTP (appli TUI), mais un mode one-shot `hermes -z
"<prompt>" --yolo`. On s'appuie dessus.

storage-01 — exécuteur :
- tools/hermes-exec/server.py : service HTTP qui lance `hermes -z --yolo` en user hermes,
  derrière un jeton Bearer (compare_digest), timeout + audit, une action à la fois.
- rôle Ansible hermes_exec : systemd (User=hermes, env hermes-agent), jeton via
  EnvironmentFile 0640 (Vault vault_hermes_exec_token) ; ajouté au playbook storage-01.

STT-server (0.5.0 → 0.6.0) :
- agent.py : pont vers hermes-exec (jeton) + détection confirme/annule.
- contexts.py : contexte « agent » (court-circuite le LLM).
- app.py : flux dédié — handshake 2 temps par session (pending action) → sur « confirme »,
  appelle hermes-exec ; « annule » annule. /v1/contexts masque « agent » si désactivé.
- config : STT_ACTIONS_ENABLED (opt-in, défaut false) + URL + jeton (secret k8s).
- deployment : env actions + secret stt-server-secrets/hermes-exec-token (optionnel).

Sécurité : opt-in désactivé par défaut ; jeton obligatoire (sinon contexte caché + exécuteur
refuse tout) ; --yolo atteint seulement jeton+confirmation en main ; audit storage-01.
Client : AUCUN changement (le contexte « agent » apparaît tout seul dans le sélecteur).

Validé en local : exécuteur (401 sans/mauvais jeton, exec avec bon jeton via echo),
handshake serveur (TestClient : confirme→exécute, annule→annule, agent masqué si OFF).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 04:00:14 +02:00
..
client refactor(stt): unifie le jeton Ghostfolio — source client unique, appel côté serveur (#41) 2026-06-21 03:28:52 +02:00
server feat(stt): actions cluster via Hermes — contexte « agent » + exécuteur hermes-exec (#42) 2026-06-21 04:00:14 +02:00
README.md feat(stt): lancement & cycle de vie du client — auto-start, app de bureau, auto-update (#18) 2026-06-19 00:05:02 +02:00

STT — Assistant vocal "Jarvis" de Funk

Assistant vocal type Jarvis pour le homelab Funk, en architecture client-serveur :

  • server/ — STT-server : orchestrateur AI dans le cluster k8s. Reçoit les requêtes des clients et route l'inférence vers LiteLLM (Qwen3 / Claude). Mémoire centralisée (futur).
  • client/ — commande stt installable sur le poste : capture micro, STT (Whisper), TTS (Piper), HUD graphique. Envoie le texte au serveur (URL paramétrable).

📐 Conception complète : admin/ia/stt.md.

                 LAN / *.lab.local
   ┌─ POSTE ──────────┐        ┌─ CLUSTER k8s (ns ai) ──────────────┐
   │  client `stt`     │  HTTP  │  STT-server (Deployment)            │
   │  • micro + Whisper│ ─────▶ │  POST /v1/ask → LiteLLM             │
   │  • Piper (TTS)    │ ◀───── │       (→ s01 192.168.10.1:4000)      │
   │  • HUD web        │  reply  │  Ingress: stt.lab.local             │
   └───────────────────┘        └──────────────┬──────────────────────┘
                                                ▼
                                       LiteLLM :4000 (s01)
                                       → Qwen3 (g01) / Claude

Client — installation (poste)

pipx install "git+ssh://git@github.com/Alkatrazz24/Funk-lab.git@<branche>#subdirectory=stt/client"
stt --setup            # génère ~/.config/stt/stt.toml (dont [server] url)
stt --text             # chat texte simple (sans micro ni HUD) — idéal pour tester
stt                    # voix + HUD ; dis "Ok Hermès …"
stt --model claude     # choisir le modèle : hermes (défaut) | claude | qwen | opus
stt --install-service  # auto-start au login (systemd --user, kiosk « écran Jarvis »)
stt --install-desktop  # ajoute STT au menu des applis → fenêtre dédiée (type Discord)
stt --window app       # ouvre le HUD en fenêtre app (sinon : kiosk plein écran)
stt --update           # met à jour depuis git (plus de désinstall/réinstall manuel)

En mode texte : commandes /model <nom>, /models, /quit. Prérequis voix : micro, Piper + voix dans ~/.local/share/piper/, aplay (alsa-utils).

Serveur — déploiement (cluster)

  1. Image : le workflow .github/workflows/build-stt-server.yml (push touchant stt/server/) build l'image taguée sha-<commit> et, sur main, met à jour le manifest avec ce tag (commit ci(stt): image → …). Plus de :latest ni de rollout restart manuel.
  2. ArgoCD : k8s/apps-of-apps/apps/stt.yaml → déploie k8s/apps/stt/ depuis main. Le bump du tag par la CI suffit à déclencher un nouveau pod (déploiement déterministe).
  3. Le serveur joint LiteLLM (s01, hors cluster) en IP directe 192.168.10.1:4000 (même pattern qu'open-webui — pas de Service/Endpoints intermédiaire).
  4. Image privée : le Deployment référence un imagePullSecret ghcr-pull. À créer une fois dans le ns ai (même pratique que ghostfolio-secret, non versionné) :
    kubectl create secret docker-registry ghcr-pull \
      --docker-server=ghcr.io \
      --docker-username=Alkatrazz24 \
      --docker-password=<PAT_ghcr_read:packages> \
      -n ai
    

Structure

stt/
├── client/          # commande `stt` (pipx) — voix + HUD
│   ├── pyproject.toml
│   ├── config/      # stt.example.toml + thèmes/avatars/voix
│   └── stt/         # cli, config, voice/, api.py (→ serveur), ui/ (HUD), hud/
└── server/          # STT-server (conteneur) — API + orchestration AI
    ├── pyproject.toml
    ├── Dockerfile
    ├── memory/      # mémoire distillée GitHub (futur, server-side)
    └── stt_server/  # app.py (FastAPI), brain.py (→ LiteLLM), config.py