# Arioch — Assistant vocal (Mistral Large + Voxtral TTS) Assistant vocal CLI personnalisé utilisant **Mistral Large** pour les réponses, **Voxtral TTS** pour la synthèse vocale, et **Voxtral Realtime** pour la transcription micro. Supporte le **Model Context Protocol (MCP)** pour appeler des outils externes depuis le LLM. --- ## Table des matières - [Prérequis](#prérequis) - [Installation](#installation) - [Configuration](#configuration) - [Utilisation](#utilisation) - [Mode vocal](#mode-vocal) - [Profils de personnalité](#profils-de-personnalité) - [Serveurs MCP](#serveurs-mcp-model-context-protocol) - [Architecture](#architecture) - [Serveurs MCP embarqués](#serveurs-mcp-embarqués) - [Scripts utilitaires](#scripts-utilitaires) - [Variables d'environnement](#variables-denvironnement) --- ## Prérequis - **Python 3.10+** - **Node.js 18+** (pour les serveurs MCP embarqués TypeScript) - **Une clé API Mistral** : [console.mistral.ai](https://console.mistral.ai) - Lecteur audio système : - **Linux** : `aplay` (inclus dans `alsa-utils` → `sudo apt install alsa-utils`) - **macOS** : `afplay` (inclus avec le système) - **Windows** : PowerShell (inclus) --- ## Installation ```bash # 1. Cloner le projet git clone cd arioch-assistant # 2. Créer et activer l'environnement virtuel Python python -m venv .venv source .venv/bin/activate # Linux/macOS # .venv\Scripts\activate # Windows # 3. Installer les dépendances Python pip install -r requirements.txt # 4. Configurer l'environnement cp .env.example .env # Éditer .env et renseigner au minimum MISTRAL_API_KEY # 5. (Optionnel) Compiler les serveurs MCP embarqués cd mcp_servers/traveller_map npm install npm run build cd ../.. ``` --- ## Configuration Copiez `.env.example` en `.env` et renseignez les variables : ```env # Obligatoire MISTRAL_API_KEY=your-api-key-here # Optionnel — laissez vide pour la voix automatique VOICE_ID= # Optionnel — prompt système par défaut SYSTEM_PROMPT=Tu es Arioch, un assistant vocal intelligent... # Optionnel — langue préférée pour la sélection de voix TTS VOICE_LANGUAGE=fr ``` --- ## Utilisation ```bash # Activer l'environnement et lancer source .venv/bin/activate python main.py ``` ### Commandes disponibles dans le REPL | Commande | Description | |----------|-------------| | `help` | Afficher l'aide | | `exit` / `quit` | Quitter l'assistant | | `reset` | Effacer l'historique de conversation | | `profiles` | Lister les profils disponibles | | `profile ` | Charger un profil (ex : `profile traveller_scout`) | | `voice ` | Définir la voix Voxtral manuellement | | `voice clear` | Revenir à la voix automatique | | `mode vocal` | Passer en mode entrée microphone | | `mode texte` | Revenir en mode saisie clavier | | `mcp` | Lister les serveurs MCP connectés | | `mcp tools` | Lister tous les outils MCP disponibles | --- ## Mode vocal En mode vocal, appuyez sur **Entrée** (sans rien écrire) pour commencer à parler. Le microphone s'active, la transcription s'affiche en temps réel via **Voxtral Realtime**, puis appuyez à nouveau sur **Entrée** pour envoyer. La réponse est lue à voix haute dès que la première phrase est disponible (pipeline streaming — voir [Architecture](#architecture)). --- ## Profils de personnalité Les profils sont des fichiers `.yaml` dans le dossier `profiles/`. Ils permettent de changer la personnalité du LLM, la voix TTS, et les outils MCP disponibles. ```bash # Lister les profils > profiles # Charger un profil > profile traveller_scout ``` ### Structure d'un profil ```yaml name: Mon Assistant Spécialisé description: Courte description affichée dans la liste # Langue préférée pour la sélection de voix (surcharge .env) voice_language: fr # Prompt système du LLM (obligatoire) system_prompt: | Tu es un expert en ... # Documents texte/markdown injectés dans le prompt système (optionnel) documents: - docs/mon_document.md # Serveurs MCP à connecter pour ce profil (optionnel) mcp_servers: - name: mon-serveur command: node args: ["mcp_servers/mon_serveur/dist/index.js"] ``` ### Profils inclus | Slug | Nom | Description | |------|-----|-------------| | `default` | Arioch — Assistant général | Assistant généraliste en français | | `traveller_scout` | Scout Ship AI — Traveller RPG | IA de bord d'un vaisseau Scout/Courier (Traveller RPG), avec accès à la carte de l'univers via MCP | --- ## Serveurs MCP (Model Context Protocol) L'assistant supporte le **Model Context Protocol** pour étendre les capacités du LLM avec des outils externes. Lorsqu'un profil déclare des serveurs MCP, le LLM peut appeler leurs outils automatiquement pour répondre aux questions. ### Comment ça fonctionne 1. Le profil YAML déclare un ou plusieurs serveurs MCP dans `mcp_servers` 2. Au chargement du profil, les serveurs sont lancés en arrière-plan (via stdio ou SSE) 3. Leurs outils sont automatiquement exposés au LLM (Mistral Large) 4. Le LLM appelle les outils si besoin, les résultats sont injectés dans la réponse ### Déclarer un serveur dans un profil **Serveur stdio (processus local, recommandé) :** ```yaml mcp_servers: - name: mon-outil command: node args: ["mcp_servers/mon_outil/dist/index.js"] # env: # variables d'environnement optionnelles # API_KEY: xxx ``` **Serveur SSE (HTTP distant) :** ```yaml mcp_servers: - name: mon-serveur-distant url: "http://localhost:3000/sse" ``` > Les chemins dans `args` peuvent être **relatifs à la racine du projet** — ils sont automatiquement résolus en chemins absolus. ### Inspecter les outils disponibles ```bash > mcp # liste les serveurs connectés > mcp tools # liste tous les outils avec leur description ``` --- ## Architecture ``` main.py ← Point d'entrée assistant/ ├── cli.py ← REPL interactif + pipeline TTS streaming ├── llm.py ← Chat streaming avec Mistral Large (tool-call loop) ├── tts.py ← Synthèse vocale Voxtral TTS ├── audio.py ← Lecture audio cross-platform (aplay / afplay / PowerShell) ├── stt.py ← Transcription micro Voxtral Realtime ├── mcp_client.py ← Gestionnaire serveurs MCP (keeper-task pattern) ├── profile.py ← Chargement/application des profils YAML └── config.py ← Variables d'environnement profiles/ ├── default.yaml ├── traveller_scout.yaml └── docs/ ← Documents de contexte injectés dans les prompts mcp_servers/ └── traveller_map/ ← Serveur MCP Traveller Map (TypeScript, embarqué) ├── src/ ← Sources TypeScript └── dist/ ← Build compilé (versionné) scripts/ ├── register_voice.py ← Enregistrement d'une voix clonée Voxtral └── list_voices.py ← Lister les voix disponibles ``` ### Pipeline TTS en streaming Pour minimiser la latence, la réponse du LLM est traitée en 3 étages parallèles : ``` [Mistral stream] → détection de phrases → sentence_queue ↓ (thread TTS) [Voxtral TTS] → audio_queue ↓ (thread Audio) [aplay / afplay] ``` Dès qu'une phrase complète est détectée dans le flux de tokens, elle part immédiatement en synthèse. L'audio de la phrase 1 est joué pendant que la phrase 2 est synthétisée. ### Tool calling MCP ``` User → LLM (stream) → [tool_calls détectés] → MCPManager.call_tool() ↑ ↓ [rebouclage] résultats injectés dans l'historique ↓ réponse finale (streamée) ``` --- ## Serveurs MCP embarqués ### `mcp_servers/traveller_map` — Carte de l'univers Traveller Serveur MCP pour l'API [travellermap.com](https://travellermap.com). Écrit en TypeScript avec le SDK MCP officiel. #### Outils disponibles | Outil | Description | |-------|-------------| | `search_worlds` | Recherche un monde par nom dans l'univers Traveller | | `find_route` | Calcule une route de saut entre deux mondes | | `get_world_info` | Informations détaillées sur un monde (UWP décodé, atmosphère, etc.) | | `get_worlds_in_jump_range` | Mondes accessibles depuis une position en N sauts | | `get_jump_map` | Carte de la zone autour d'un monde | | `get_subsector_map` | Image d'un sous-secteur | | `render_custom_map` | Rendu de carte personnalisée | | `get_sector_list` | Liste de tous les secteurs de l'univers | | `get_sector_data` | Données d'un secteur (format SEC) | | `get_sector_metadata` | Métadonnées d'un secteur (JSON) | | `get_allegiance_list` | Liste des allégeances politiques | #### (Re)compiler le serveur ```bash cd mcp_servers/traveller_map npm install # première fois seulement npm run build # compile TypeScript → dist/ ``` #### Ajouter un nouveau serveur MCP 1. Créer un dossier `mcp_servers/mon_serveur/` 2. Y placer les sources (TypeScript, Python, ou tout autre langage) 3. Compiler si nécessaire (`npm run build`) 4. Déclarer dans le profil YAML : ```yaml mcp_servers: - name: mon-serveur command: node args: ["mcp_servers/mon_serveur/dist/index.js"] ``` --- ## Scripts utilitaires ### Enregistrer une voix clonée ```bash python scripts/register_voice.py --name "Ma voix" --audio sample.mp3 --language fr ``` Renseignez l'ID retourné dans `.env` : ```env VOICE_ID= ``` ### Lister les voix disponibles ```bash python scripts/list_voices.py ``` --- ## Variables d'environnement | Variable | Obligatoire | Défaut | Description | |----------|-------------|--------|-------------| | `MISTRAL_API_KEY` | ✅ | — | Clé API Mistral AI | | `VOICE_ID` | ❌ | auto | ID voix Voxtral (sélection auto si vide) | | `VOICE_LANGUAGE` | ❌ | `fr` | Langue préférée pour la sélection de voix | | `SYSTEM_PROMPT` | ❌ | prompt Arioch | Prompt système par défaut | | `TTS_PCM_SAMPLE_RATE` | ❌ | `24000` | Fréquence d'échantillonnage audio TTS | --- ## Dépendances Python | Package | Rôle | |---------|------| | `mistralai` | SDK Mistral (LLM, TTS, STT Realtime) | | `python-dotenv` | Chargement des variables `.env` | | `sounddevice` | Capture microphone (mode vocal) | | `numpy` | Traitement PCM audio | | `pyyaml` | Lecture des fichiers de profil | | `mcp` | Client MCP (connexion aux serveurs d'outils) |