Funk-lab/docs/stt-presentation.md
alkatrazz c1eaccd7b4 docs(stt): catalogue des demandes possibles à Asa
Ajoute docs/asa-commandes.md : liste complète, classée par capacité, des
demandes que l'on peut faire à Asa (avec exemples de phrases FR), bâtie sur
l'implémentation réelle (intents client + outils serveur + services du portail) :
réveil/veille, santé homelab (host_health/cluster_status), métriques (PromQL),
doc Funk (RAG), recherche web, actions admin (confirmation), ouvrir un service,
portefeuille, mémoire, contextes. Liée depuis README.md et docs/stt-presentation.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 23:33:30 +02:00

6.5 KiB
Raw Blame History

Asa — l'assistant vocal de Funk (STT clientserveur)

Asa est l'interface vocale et graphique du homelab Funk : un assistant type Jarvis qui écoute, parle, affiche un HUD animé, et — surtout — agit comme une véritable agente sur le homelab. Elle sait (doc + état live), cherche (web) et agit (avec confirmation).

Architecture clientserveur : un client stt (pipx) tourne sur le poste (voix + HUD) ; le « cerveau » est un STTserver déployé dans le cluster (namespace ai, exposé stt.lab.local).

Code client stt/client/ · serveur stt/server/
Déploiement client : pipx + service systemd --user · serveur : image GHCR → ArgoCD
Modèle 100 % local — Qwen38B via LiteLLM (function calling natif)
Doc de référence admin/ia/stt.md

Le HUD en images

Conversation (Asa agentique) Veille / réveil vocal
HUD — conversation HUD — veille
Asa sonde l'état live (« gpu01 tourne bien ? » → CPU/RAM/disque/GPU) puis fait une recherche web — chaque réponse taguée asa. État RÉPONSE : anneau arcreactor actif. « Asa, stop » → état SOMMEIL : portrait désaturé, Asa n'écoute plus que le mot de réveil. Dire « Asa » la rallume.

Le portrait affiche le repli « あ » (Asa en hiragana) tant qu'aucun jeu d'avatars n'est déposé dans stt/client/stt/hud/avatars/ (cf. son README). Thème arcreactor, réglable dans le HUD.


Architecture — la chaîne de bout en bout

flowchart LR
    subgraph POSTE["Poste perso — client stt (pipx)"]
        MIC["Micro"] --> VAD["VAD + wake word<br/>« Asa » / « Asa stop »"]
        VAD --> ASR["ASR local<br/>whisper / Parakeet (onnx)"]
        ASR --> API["api.py → ServerClient"]
        REPLY["Réponse"] --> TTS["TTS Piper"]
        REPLY --> HUD["HUD web<br/>bulles, portrait, portail"]
    end

    subgraph CLUSTER["Cluster k8s — namespace ai"]
        SRV["STT-server (FastAPI)<br/>stt.lab.local"]
        SRV --> LOOP["brain.ask_with_tools<br/>function calling (contexte asa)"]
        LOOP --> TOOLS["tools.py"]
    end

    API -->|"POST /v1/ask"| SRV
    SRV -->|"reply + trace"| REPLY

    LOOP -->|"inférence + tool_calls"| LITELLM["LiteLLM :4000<br/>storage-01"]
    LITELLM --> QWEN["Qwen3-8B<br/>gpu-01 :1234"]

    TOOLS -->|"host_health / cluster_status / prometheus_query"| PROM["Prometheus<br/>in-cluster"]
    TOOLS -->|"search_docs"| QDRANT["Qdrant RAG<br/>funk-docs (s01)"]
    TOOLS -->|"web_search"| SEARX["SearXNG<br/>in-cluster, privé"]
    TOOLS -->|"admin_action ⇒ confirmation"| HEXEC["hermes-exec :9096<br/>hermes -z --yolo (s01)"]

    classDef poste fill:#fde,stroke:#c69;
    classDef cluster fill:#def,stroke:#69c;
    class POSTE poste
    class CLUSTER cluster

Principe : le poste ne fait que la voix (STT/TTS) et l'affichage. Toute l'intelligence est côté serveur, qui orchestre LiteLLM et choisit ses outils. Aucune dépendance cloud : modèle, recherche web et données sont tous selfhost.


Le tour d'une question vocale (séquence)

sequenceDiagram
    actor U as Utilisateur
    participant C as Client stt (poste)
    participant S as STT-server (cluster)
    participant L as LiteLLM puis Qwen3-8B
    participant T as Outils (Prom/SearXNG/RAG)

    U->>C: « Asa, est-ce que gpu-01 tourne bien ? »
    Note over C: wake word détecté puis ASR (texte)
    C->>S: POST /v1/ask {text, context:"asa"}
    Note over S: recall mémoire (Qdrant) + assemblage prompt
    S->>L: chat + tools (function calling)
    L-->>S: tool_call host_health(gpu-01)
    S->>T: PromQL (up, CPU, RAM, disque, GPU)
    T-->>S: « en ligne, GPU 61 °C, 99 % »
    S->>L: résultat de l'outil réinjecté
    L-->>S: réponse finale en français
    S-->>C: reply + trace des outils
    C->>U: TTS Piper + bulle dans le HUD

Si Asa veut agir (admin_action), la boucle s'arrête et elle propose ; l'exécution (hermesexec) n'a lieu qu'au tour suivant, après un « confirme » vocal.


Ce qu'Asa sait faire

🗣️ Liste complète des demandes possibles (exemples de phrases) : asa-commandes.md.

Capacité Comment Outils / sources
🔎 Savoir Doc Funk + état live du homelab, l'outil est choisi par le modèle search_docs (RAG), host_health, cluster_status, prometheus_query
🌐 Chercher Recherche Internet privée (métamoteur selfhost) web_search → SearXNG
🤖 Agir Actions d'admin avec confirmation vocale + jeton admin_actionhermesexec
🧠 Se souvenir Mémoire court terme (session) + long terme (Qdrant) stt-memory
🗣️ Veille/réveil « Asa » réveille · « Asa stop » endort machine à états côté client
🧩 Contextes Profils présélectionnables (funk, ghostfolio, grafana, alerting, cluster) contexts.py

Où vivent les choses

stt/
├── client/                 # commande `stt` (pipx) — poste perso
│   └── stt/
│       ├── voice/engine.py # micro, VAD, wake word, ASR, TTS
│       ├── api.py          # client HTTP vers le STTserver
│       └── hud/index.html  # le HUD (portrait, bulles, portail, visualiseur)
└── server/                 # image conteneur — déployée par ArgoCD (ns ai)
    └── stt_server/
        ├── app.py          # API FastAPI (/v1/ask, /v1/contexts…)
        ├── brain.py        # appel LiteLLM + boucle de functioncalling
        ├── tools.py        # outils : doc, état live, web, action
        ├── contexts.py     # profils (dont « asa » = boucle d'outils)
        ├── sources.py      # sondes Prometheus / Alertmanager / Ghostfolio
        ├── knowledge.py    # RAG funkdocs (Qdrant)
        └── longterm.py     # mémoire long terme (Qdrant)

Manifests k8s : k8s/apps/stt/ (STTserver) et k8s/apps/searxng/ (recherche web). Détails et pièges : admin/ia/stt.md.

Capturer ses propres écrans du HUD : déposer un jeu d'avatars dans stt/client/stt/hud/avatars/, lancer le client, et capturer les états (idle, écoute, réponse, portail, visualiseur). Les deux images cidessus ont été rendues depuis le HUD réel.