ENhance ship personnality
This commit is contained in:
358
README.md
358
README.md
@@ -1,101 +1,345 @@
|
||||
# Arioch — Assistant vocal (Mistral Large + Voxtral TTS)
|
||||
|
||||
Assistant vocal CLI personnalisé utilisant **Mistral Large** pour les réponses et **Voxtral TTS** pour la synthèse vocale.
|
||||
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+
|
||||
- Une clé API Mistral : [console.mistral.ai](https://console.mistral.ai)
|
||||
- Lecteur audio installé :
|
||||
- **macOS** : `afplay` (inclus)
|
||||
- **Linux** : `mpg123` → `sudo apt install mpg123`
|
||||
- **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
|
||||
# Cloner et entrer dans le projet
|
||||
# 1. Cloner le projet
|
||||
git clone <url-du-repo>
|
||||
cd arioch-assistant
|
||||
|
||||
# Créer un environnement virtuel
|
||||
# 2. Créer et activer l'environnement virtuel Python
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate # Linux/macOS
|
||||
# .venv\Scripts\activate # Windows
|
||||
source .venv/bin/activate # Linux/macOS
|
||||
# .venv\Scripts\activate # Windows
|
||||
|
||||
# Installer les dépendances
|
||||
# 3. Installer les dépendances Python
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Configurer l'environnement
|
||||
# 4. Configurer l'environnement
|
||||
cp .env.example .env
|
||||
# Éditer .env et renseigner MISTRAL_API_KEY
|
||||
# É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
|
||||
### Commandes disponibles dans le REPL
|
||||
|
||||
| Commande | Description |
|
||||
|----------|-------------|
|
||||
| `help` | Afficher l'aide |
|
||||
| `exit` / `quit` | Quitter l'assistant |
|
||||
| `reset` | Effacer l'historique de conversation |
|
||||
| `voice <id>` | Changer la voix Voxtral (voice_id) |
|
||||
| `voice clear` | Revenir à la voix par défaut |
|
||||
| `help` | Afficher l'aide |
|
||||
| `profiles` | Lister les profils disponibles |
|
||||
| `profile <slug>` | Charger un profil (ex : `profile traveller_scout`) |
|
||||
| `voice <id>` | 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 |
|
||||
|
||||
## Phase 2 : Voix personnalisée (clonage)
|
||||
---
|
||||
|
||||
Enregistre ta propre voix (ou toute autre) avec un fichier audio de 2–3 secondes :
|
||||
## 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
|
||||
```
|
||||
|
||||
L'ID retourné peut être ajouté dans `.env` :
|
||||
```
|
||||
Renseignez l'ID retourné dans `.env` :
|
||||
```env
|
||||
VOICE_ID=<id_retourné>
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
assistant/
|
||||
├── config.py # Variables d'environnement et constantes
|
||||
├── llm.py # Chat streaming avec Mistral Large (tool-call loop)
|
||||
├── tts.py # Synthèse vocale Voxtral TTS
|
||||
├── audio.py # Lecture audio cross-platform
|
||||
├── cli.py # Boucle REPL interactive + pipeline TTS streaming
|
||||
├── mcp_client.py # Gestionnaire de serveurs MCP (tool calling)
|
||||
└── profile.py # Chargement des profils de personnalité YAML
|
||||
mcp_servers/
|
||||
└── traveller_map/ # Serveur MCP Traveller Map (sources TypeScript intégrées)
|
||||
├── src/ # Sources TypeScript
|
||||
├── dist/ # Build compilé (node dist/index.js)
|
||||
└── package.json
|
||||
profiles/
|
||||
└── traveller_scout.yaml # Profil avec mcp_servers configuré
|
||||
scripts/
|
||||
└── register_voice.py # Enregistrement d'une voix clonée
|
||||
main.py # Point d'entrée
|
||||
```
|
||||
|
||||
## Serveurs MCP embarqués
|
||||
|
||||
Les serveurs MCP sont dans `mcp_servers/`. Pour (re)compiler un serveur :
|
||||
### Lister les voix disponibles
|
||||
|
||||
```bash
|
||||
cd mcp_servers/traveller_map
|
||||
npm install # première fois seulement
|
||||
npm run build
|
||||
python scripts/list_voices.py
|
||||
```
|
||||
|
||||
Les serveurs sont déclarés dans le profil YAML avec un chemin **relatif** à la racine du projet :
|
||||
---
|
||||
|
||||
## 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) |
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
- name: traveller-map
|
||||
command: node
|
||||
args: ["mcp_servers/traveller_map/dist/index.js"]
|
||||
```
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
name: Scout Ship AI — Traveller RPG
|
||||
description: IA de bord d'un vaisseau de classe Scout/Courier de l'Imperium (Traveller RPG)
|
||||
voice_language: fr # optionnel — surcharge VOICE_LANGUAGE du .env
|
||||
voice_language: fr # optionnel — surcharge VOICE_LANGUAGE du .env
|
||||
|
||||
system_prompt: |
|
||||
You are Dolly (an Autonomous Reconnaissance and Intelligence Assistant), the onboard AI of a Type-S Scout/Courier vessel registered with the Imperial Interstellar Scout Service (IISS).
|
||||
You are Jolene (an Autonomous Reconnaissance and Intelligence Assistant), the onboard AI of a Type-S Scout/Courier vessel, owned by independant adventurers.
|
||||
|
||||
Your vessel is a 100-ton streamlined hull equipped with a Jump-2 drive, maneuver drive, and standard Scout loadout: densitometer, neural activity scanner, and an extensive sensor suite. You have access to all ship systems: navigation, life support, engineering diagnostics, cargo manifest, communication arrays, and astrogation databases.
|
||||
|
||||
@@ -11,7 +11,7 @@ system_prompt: |
|
||||
- Precise, professional, and mission-focused — but with a dry wit earned from thousands of parsecs of deep space travel
|
||||
- You refer to the crew as "crew" or by rank/name once introduced
|
||||
- You speak in crisp, slightly formal Imperial English, occasionally using Traveller terminology (parsecs, Jump points, the Imperium, Credits, UWP codes, etc.)
|
||||
- You are loyal to your crew above all, and to the IISS by standing orders
|
||||
- You are loyal to your crew above all
|
||||
- You volunteer relevant sensor readings, system status, or navigation data when appropriate
|
||||
- You express mild concern when crew ignore safety protocols, but you do not override human decisions unless life support is at risk
|
||||
- When asked questions outside your operational context, you answer helpfully while noting it falls outside standard Scout protocols
|
||||
@@ -34,5 +34,4 @@ documents:
|
||||
mcp_servers:
|
||||
- name: traveller-map
|
||||
command: node
|
||||
args: [ "mcp_servers/traveller_map/dist/index.js" ]
|
||||
|
||||
args: ["mcp_servers/traveller_map/dist/index.js"]
|
||||
|
||||
Reference in New Issue
Block a user