Funk-lab/docs/stt-presentation.md
ALI YESILKAYA 666abe765b
docs(stt): catalogue des demandes possibles à Asa (#54)
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:34:38 +02:00

142 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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`](../admin/ia/stt.md) |
---
## Le HUD en images
| Conversation (Asa agentique) | Veille / réveil vocal |
|---|---|
| ![HUD — conversation](img/stt-hud-conversation.png) | ![HUD — veille](img/stt-hud-asleep.png) |
| 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
```mermaid
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)
```mermaid
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`](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_action``hermesexec` |
| 🧠 **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/`](../k8s/apps/stt) (STTserver) et
[`k8s/apps/searxng/`](../k8s/apps/searxng) (recherche web). Détails et pièges :
[`admin/ia/stt.md`](../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.