routeur_ia_api / README.md
Cyril Dupland
Refactoring gestion Agent
c392583
metadata
title: Routeur Ia Api
emoji: 📊
colorFrom: pink
colorTo: purple
sdk: docker
pinned: false

Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference

CAPL Routeur IA API

API sécurisée pour l'interaction avec des agents IA basés sur LangGraph, avec support multi-modèles (OpenAI et Mistral AI).

🚀 Fonctionnalités

  • Authentification JWT pour sécuriser l'accès
  • Completion texte avec support du streaming (Server-Sent Events)
  • Multi-modèles: OpenAI (GPT-4, GPT-3.5) et Mistral AI (Large, Medium, Small, Tiny)
  • Multi-agents: Architecture extensible pour différents types d'agents LangGraph
  • Transcription audio: Conversion audio vers texte avec OpenAI Whisper
  • WebSocket: Communication temps réel bidirectionnelle
  • Architecture Clean: Séparation domain/services/api selon les principes SOLID

📋 Prérequis

  • Python 3.12+
  • Clés API OpenAI et Mistral AI

🛠️ Installation

  1. Cloner le repository
git clone <repository-url>
cd routeur_ia_api
  1. Créer un environnement virtuel
python -m venv venv
source venv/bin/activate  # Linux/Mac
# ou
venv\Scripts\activate  # Windows
  1. Installer les dépendances
pip install -r requirements.txt
  1. Configurer les variables d'environnement

Créez un fichier .env à la racine du projet (voir .env.example pour référence):

# API Keys
OPENAI_API_KEY=sk-your-openai-key-here
MISTRALAI_API_KEY=your-mistral-key-here

# JWT Security
JWT_SECRET_KEY=your-secret-key-here-change-in-production
JWT_ALGORITHM=HS256
JWT_EXPIRATION_MINUTES=60

# API Config
API_TITLE=CAPL Routeur IA API
API_VERSION=1.0.0
ENVIRONMENT=development

⚠️ IMPORTANT: Changez JWT_SECRET_KEY en production avec une valeur sécurisée!

🚀 Lancement

Mode développement

python app.py

ou avec uvicorn directement:

uvicorn app:app --reload --port 7860

Mode production

uvicorn app:app --host 0.0.0.0 --port 7860 --workers 4

Avec Docker

docker build -t routeur-ia-api .
docker run -p 7860:7860 --env-file .env routeur-ia-api

📚 Documentation API

Une fois l'API lancée, accédez à:

🔐 Authentification

1. Obtenir un token JWT

curl -X POST "http://localhost:7860/auth/token" \
  -H "Content-Type: application/json"

Réponse:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 3600
}

2. Utiliser le token

Incluez le token dans le header Authorization de toutes vos requêtes:

curl -X GET "http://localhost:7860/models" \
  -H "Authorization: Bearer <votre-token>"

📖 Utilisation

Liste des modèles disponibles

curl -X GET "http://localhost:7860/models" \
  -H "Authorization: Bearer <token>"

Liste des agents disponibles

curl -X GET "http://localhost:7860/agents" \
  -H "Authorization: Bearer <token>"

Completion simple (non-streaming)

curl -X POST "http://localhost:7860/completion" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Bonjour, comment vas-tu?",
    "model": "gpt-4o",
    "agent": "V2",
    "stream": false,
    "temperature": 0.7
  }'

Completion avec streaming (SSE)

curl -X POST "http://localhost:7860/completion" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -N \
  -d '{
    "message": "Raconte-moi une histoire",
    "model": "gpt-4o",
    "stream": true
  }'

Transcription audio

curl -X POST "http://localhost:7860/transcription" \
  -H "Authorization: Bearer <token>" \
  -F "file=@audio.mp3" \
  -F "language=fr"

Transcription asynchrone

L’API expose également des endpoints de transcription asynchrones permettant d’uploader un fichier audio, de recevoir immédiatement un job_id, puis de poller l’état du job jusqu’à obtenir la transcription complète.

Endpoints

  • Synchrone (existants)

    • POST /transcription
    • POST /transcription/meeting
  • Asynchrone (nouveaux)

    • POST /transcription/jobs
      Crée un job de transcription audio (job_type = "transcription_audio") et retourne un job_id.
    • POST /transcription/meeting/jobs
      Crée un job de transcription de réunion (job_type = "transcription_meeting") et retourne un job_id.
    • GET /transcription/jobs/{job_id}
      Retourne l’état du job et, une fois terminé, la transcription.

Tous ces endpoints nécessitent un JWT (Authorization: Bearer <token>).

Gestion des fichiers audio

  • Formats supportés : mp3, mp4, mpeg, mpga, m4a, wav, webm.
  • Taille maximale d’upload : settings.max_upload_mb_audio (par défaut 500 Mo).
  • Limite OpenAI (25 Mo) : le backend découpe automatiquement les fichiers audio de grande taille en plusieurs segments (ré-encodés en MP3 128 kbps) et enchaîne les appels à l’API OpenAI, en concaténant les résultats. Un prompt glissant (fin du chunk précédent) est utilisé pour conserver le contexte.

Exemple – création d’un job asynchrone

curl -X POST "http://localhost:7860/transcription/jobs" \
  -H "Authorization: Bearer <token>" \
  -F "file=@audio.mp3" \
  -F "language=fr" \
  -F "prompt=Contexte de la réunion"

Réponse (UploadJobResponse) :

{
  "job_id": "uuid-...",
  "status": "queued",
  "created_at": "2026-03-09T12:34:56Z"
}

Exemple – polling de l’état d’un job

curl -X GET "http://localhost:7860/transcription/jobs/<job_id>" \
  -H "Authorization: Bearer <token>"

Réponse (JobStatusResponse) – extrait :

{
  "job_id": "uuid-...",
  "status": "succeeded",
  "job_type": "transcription_audio",
  "progress_percent": 100,
  "transcript_text": "Texte complet de la transcription...",
  "transcript_language": "fr",
  "transcript_duration": 123.45,
  "transcript_model": "whisper-1"
}

Stratégie côté client

  1. Appeler POST /transcription/jobs ou /transcription/meeting/jobs et récupérer job_id.
  2. Poller régulièrement GET /transcription/jobs/{job_id} (toutes les 2–5 secondes).
  3. Arrêter le polling lorsque :
    • status = "succeeded" → utiliser transcript_text,
    • status = "failed" → afficher/traiter error.
  4. Prévoir un timeout global et éventuellement une barre de progression basée sur progress_percent.

WebSocket temps réel

const ws = new WebSocket('ws://localhost:7860/realtime/ws');

ws.onopen = () => {
  console.log('Connected');
  
  // Envoyer un message
  ws.send(JSON.stringify({
    type: 'message',
    payload: { text: 'Hello!' }
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Received:', data);
};

🏗️ Architecture

routeur_ia_api/
├── config/           # Configuration et settings
├── core/             # Sécurité JWT et dépendances
├── domain/           # Modèles et enums du domaine
├── services/         # Services métier (LLM, Agent, Transcription)
├── graphs/           # Graphes LangGraph
├── api/
│   ├── routes/       # Routes API
│   └── middleware.py # Middleware personnalisé
├── app.py            # Point d'entrée FastAPI
└── requirements.txt  # Dépendances Python

Principes SOLID appliqués

  • Single Responsibility: Chaque service a une responsabilité unique
  • Open/Closed: Agents extensibles via le registre sans modifier l'API
  • Liskov Substitution: Tous les LLM respectent l'interface BaseChatModel
  • Interface Segregation: Interfaces minimales et spécifiques
  • Dependency Inversion: Dépendances abstraites via injection

🤖 Ajouter un nouvel agent

  1. Créez un nouveau graphe dans graphs/:
# graphs/custom_graph.py
from langgraph.graph import StateGraph, END

def create_custom_graph(llm):
    # Votre logique
    workflow = StateGraph(CustomState)
    workflow.add_node("custom", custom_node)
    workflow.set_entry_point("custom")
    workflow.add_edge("custom", END)
    return workflow.compile()
  1. Enregistrez-le dans le registre:
# services/agent_registry.py
from graphs.custom_graph import create_custom_graph

agent_registry.register_agent(
    "my_agent",
    create_custom_graph,
    "Description de votre agent"
)
  1. Utilisez-le via l'API avec "agent": "my_agent" dans la requête POST /completion.

🧪 Tests

# À implémenter
pytest tests/

📊 Monitoring avec LangSmith

Activez LangSmith dans .env:

LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=your-langsmith-key
LANGCHAIN_PROJECT=routeur-ia

🔒 Sécurité

  • ✅ Authentification JWT obligatoire
  • ✅ Validation Pydantic stricte
  • ✅ Headers de sécurité (CORS, CSP, etc.)
  • ✅ Gestion des erreurs sécurisée
  • ⚠️ En production: Utilisez HTTPS uniquement
  • ⚠️ En production: Restreignez CORS aux origines autorisées
  • ⚠️ En production: Utilisez un secret JWT robuste

📝 TODO / Roadmap

  • Harmoniser la nomenclature du pipeline voix: le champ agent_type est encore utilisé dans services/voice/voice_pipeline.py pour des événements internes et devra être renommé en agent lors d'un prochain refactoring.
  • Tests unitaires et d'intégration
  • Implémentation complète WebRTC avec aiortc
  • Agent RAG avec base vectorielle
  • Agent avec outils (recherche web, calculatrice)
  • Rate limiting
  • Cache des réponses
  • Métriques Prometheus
  • CI/CD pipeline

🤝 Contribution

Les contributions sont les bienvenues! Veuillez suivre les principes SOLID et Clean Architecture.

📄 Licence

[À définir]

👥 Auteurs

CAPL - Routeur IA Team


Note: Cette API est en développement actif. Certaines fonctionnalités (notamment WebRTC complet) sont des placeholders et nécessitent une implémentation complète pour la production.