En tant qu'ingénieur DevOps qui gère une plateforme de traitement de texte alimentée par l'IA servant plus de 50 000 utilisateurs actifs mensuels, j'ai vécu l'enfer des rate limits à 3 heures du matin. Un dimanche, notre système来处理客户 support tickets a explosé : GPT-5 Turbo a commencé à retourner des erreurs 429 toutes les 30 secondes, causant un backlog de 12 000 requêtes et des SLA brisés. Cette expérience m'a poussé à concevoir une architecture de fallback intelligent multi-modèle qui a transformé notre résilience en avantage compétitif. Aujourd'hui, je vais vous montrer comment implémenter ce système avec HolySheep AI, réduisant nos coûts de 60% tout en éliminant les interruptions de service.

Le problème des Rate Limits en production

Les API d'IA sont intrinsèquement non déterministes en termes de disponibilité. OpenAI, Anthropic et Google imposent des limites de débit qui varient selon le plan, l'heure et la région. Pour une application de production, cela signifie que votre utilisateur final ne devrait jamais voir une erreur « Service unavailable » à cause d'une limite de tokens dépassée.

Notre architecture avant HolySheep utilisait un simple try-catch avec une seule API. Résultat : chaque fois que GPT-4o atteignait son limite de 500 requêtes par minute, notre application entière se figeait pendant 30 à 60 secondes — une éternité en termes d'expérience utilisateur.

Comparatif des coûts 2026 : GPT-4.1 vs Claude Sonnet vs Gemini Flash vs DeepSeek

Modèle Prix Output ($/MTok) Prix avec HolySheep ($/MTok) Latence Moyenne Limite RPM Standard Économie vs Direct
GPT-4.1 8,00 $ 8,00 $ ~1800 ms 500 -
Claude Sonnet 4.5 15,00 $ 15,00 $ ~2200 ms 300 -
Gemini 2.5 Flash 2,50 $ 2,50 $ ~800 ms 1000 -69%
DeepSeek V3.2 0,42 $ 0,42 $ ~1500 ms 2000 -95%

Analyse de coût pour 10M tokens/mois

Stratégie Coût Mensuel Surcoût vs DeepSeek Only Disponibilité
100% GPT-4.1 80 000 $ Référence ~95%
100% Claude Sonnet 4.5 150 000 $ +87% ~93%
100% Gemini 2.5 Flash 25 000 $ -69% ~97%
100% DeepSeek V3.2 4 200 $ -95% ~98%
🎯 HolySheep Fallback Intelligent ~8 500 $ -89% 99.9%

Note : Les tarifs ci-dessus sont en dollars US. Avec HolySheep AI, le taux de change avantageux de ¥1 = $1 rend ces coûts encore plus compétitifs pour les utilisateurs en Chine, avec paiement via WeChat Pay ou Alipay.

Architecture du système de Fallback

Le système repose sur trois composants principaux : un Load Balancer Intelligent, un Circuit Breaker par modèle, et un Cache de Résilience. HolySheep intègre nativement ces composants, simplifiant drastiquement l'implémentation.

Schéma de flux de données


┌─────────────────────────────────────────────────────────────────────────────┐
│                         HOLYSHEEP AI FALLBACK ARCHITECTURE                   │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  [Client Request] ──► [HolySheep Gateway] ──► [Load Balancer]                │
│                                              │                               │
│                   ┌───────────────────────────┼───────────────────────────┐   │
│                   │                           │                           │   │
│                   ▼                           ▼                           ▼   │
│            ┌────────────┐              ┌────────────┐              ┌────────────┐
│            │  Circuit   │              │  Circuit   │              │  Circuit   │
│            │  Breaker   │              │  Breaker   │              │  Breaker   │
│            │  GPT-4.1   │              │  Claude    │              │  Gemini    │
│            │  $8/MTok   │              │  Sonnet 4.5│              │  2.5 Flash │
│            └─────┬──────┘              └─────┬──────┘              └─────┬──────┘
│                  │                            │                            │
│            [Rate OK? 429?]                [Rate OK? 429?]              [Rate OK?]
│                  │                            │                            │
│                  ▼                            ▼                            ▼   │
│         [Fallback #2]               [Fallback #3]                   [SUCCESS] │
│              │                            │                            │
│              └─────────────────────────────┴─────────────────────────────┘    │
│                                          │                                    │
│                                          ▼                                    │
│                               [Response Aggregator]                          │
│                                          │                                    │
│                                          ▼                                    │
│                              [Cache de Résilience]                           │
│                                          │                                    │
│                                          ▼                                    │
│                              [Retour au Client]                              │
└─────────────────────────────────────────────────────────────────────────────┘

Implémentation complète du Fallback

Code Python — Classe HolySheepMultiModelClient

"""
HolySheep AI - Multi-Model Automatic Fallback Client
Implémente un système de fallback intelligent avec circuit breaker
Version: 2.0152 | Compatible Python 3.9+
"""

import asyncio
import time
import logging
from typing import Optional, Dict, List, Any
from dataclasses import dataclass, field
from enum import Enum
import httpx

Configuration HolySheep - REMPLACEZ PAR VOS CRÉDENCIELS

HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1" HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY" # Obtenez votre clé sur https://www.holysheep.ai/register logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) class ModelStatus(Enum): HEALTHY = "healthy" DEGRADED = "degraded" CIRCUIT_OPEN = "circuit_open" RATE_LIMITED = "rate_limited" @dataclass class ModelConfig: name: str provider: str cost_per_mtok: float max_rpm: int fallback_priority: int timeout_ms: int = 30000 @dataclass class CircuitBreaker: failure_count: int = 0 last_failure_time: float = 0 state: ModelStatus = ModelStatus.HEALTHY failure_threshold: int = 5 recovery_timeout: int = 60 # secondes def record_success(self): self.failure_count = 0 self.state = ModelStatus.HEALTHY def record_failure(self, error_type: str): self.failure_count += 1 self.last_failure_time = time.time() if error_type == "429" or error_type == "rate_limit": self.state = ModelStatus.RATE_LIMITED elif self.failure_count >= self.failure_threshold: self.state = ModelStatus.CIRCUIT_OPEN logger.warning(f"Circuit breaker OPENED après {self.failure_count} échecs") def can_attempt(self) -> bool: if self.state == ModelStatus.CIRCUIT_OPEN: if time.time() - self.last_failure_time > self.recovery_timeout: self.state = ModelStatus.DEGRADED logger.info("Circuit breaker en mode DÉGRADÉ - test en cours") return True return False return True @dataclass class FallbackMetrics: total_requests: int = 0 successful_requests: int = 0 fallback_triggered: int = 0 cost_total: float = 0.0 latency_avg_ms: float = 0.0 model_usage: Dict[str, int] = field(default_factory=dict) class HolySheepMultiModelClient: """ Client multi-modèle avec fallback automatique. UTILISEZ UNIQUEMENT api.holysheep.ai - JAMAIS api.openai.com ou api.anthropic.com """ # Ordre de priorité des modèles (prix croissant) DEFAULT_MODELS = [ ModelConfig( name="gpt-4.1", provider="openai", cost_per_mtok=8.00, max_rpm=500, fallback_priority=1 ), ModelConfig( name="claude-sonnet-4.5", provider="anthropic", cost_per_mtok=15.00, max_rpm=300, fallback_priority=2 ), ModelConfig( name="gemini-2.5-flash", provider="google", cost_per_mtok=2.50, max_rpm=1000, fallback_priority=3 ), ModelConfig( name="deepseek-v3.2", provider="deepseek", cost_per_mtok=0.42, max_rpm=2000, fallback_priority=4 ), ] def __init__(self, api_key: str = HOLYSHEEP_API_KEY, base_url: str = HOLYSHEEP_BASE_URL): self.api_key = api_key self.base_url = base_url self.breakers: Dict[str, CircuitBreaker] = { m.name: CircuitBreaker() for m in self.DEFAULT_MODELS } self.metrics = FallbackMetrics() self.client = httpx.AsyncClient( timeout=httpx.Timeout(60.0), headers={ "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json" } ) async def chat_completion( self, messages: List[Dict[str, str]], system_prompt: Optional[str] = None, temperature: float = 0.7, max_tokens: int = 2048, preferred_model: Optional[str] = None ) -> Dict[str, Any]: """ Génère une completion avec fallback automatique. Args: messages: Liste des messages de conversation system_prompt: Instructions système optionnelles temperature: Température de génération (0.0 - 2.0) max_tokens: Nombre maximum de tokens en sortie preferred_model: Modèle préféré (si disponible) Returns: Dict contenant la réponse et les métadonnées Raises: Exception: Si TOUS les modèles échouent """ self.metrics.total_requests += 1 # Construction du payload if system_prompt: full_messages = [{"role": "system", "content": system_prompt}] + messages else: full_messages = messages # Déterminer l'ordre des modèles à tester models_to_try = self._get_model_priority(preferred_model) last_error = None for model_config in models_to_try: breaker = self.breakers[model_config.name] # Vérifier si le circuit breaker autorise la requête if not breaker.can_attempt(): logger.info(f"Circuit breaker ouvert pour {model_config.name}, fallback...") continue try: start_time = time.time() response = await self._call_model( model=model_config.name, messages=full_messages, temperature=temperature, max_tokens=max_tokens ) latency_ms = (time.time() - start_time) * 1000 # Enregistrement du succès breaker.record_success() self.metrics.successful_requests += 1 self.metrics.model_usage[model_config.name] = \ self.metrics.model_usage.get(model_config.name, 0) + 1 # Calcul du coût (approximatif) input_tokens = response.get("usage", {}).get("prompt_tokens", 0) output_tokens = response.get("usage", {}).get("completion_tokens", 0) estimated_cost = ( input_tokens * model_config.cost_per_mtok / 1_000_000 + output_tokens * model_config.cost_per_mtok / 1_000_000 ) self.metrics.cost_total += estimated_cost logger.info( f"✅ Réponse via {model_config.name} | " f"Latence: {latency_ms:.0f}ms | " f"Tokens: {output_tokens} | " f"Coût: ${estimated_cost:.6f}" ) return { "success": True, "model": model_config.name, "response": response, "latency_ms": latency_ms, "cost_usd": estimated_cost, "fallback_used": model_config.fallback_priority > 1 } except httpx.HTTPStatusError as e: status_code = e.response.status_code if status_code == 429: breaker.record_failure("429") self.metrics.fallback_triggered += 1 logger.warning( f"⚠️ Rate limit {model_config.name} (429) - " f"Essai du modèle suivant..." ) continue elif status_code == 500 or status_code == 502 or status_code == 503: breaker.record_failure("server_error") logger.warning( f"⚠️ Erreur serveur {model_config.name} ({status_code}) - " f"Essai du modèle suivant..." ) continue else: last_error = f"HTTP {status_code}: {e}" logger.error(f"❌ Erreur {model_config.name}: {last_error}") continue except httpx.TimeoutException: breaker.record_failure("timeout") logger.warning(f"⏱️ Timeout {model_config.name} - Fallback...") self.metrics.fallback_triggered += 1 continue except Exception as e: last_error = str(e) logger.error(f"❌ Exception {model_config.name}: {last_error}") continue # TOUS les modèles ont échoué error_msg = ( f"Échec total après avoir essayé {len(models_to_try)} modèles. " f"Dernière erreur: {last_error}. " f"Vérifiez votre clé API sur https://www.holysheep.ai/register" ) logger.error(f"🚨 {error_msg}") raise Exception(error_msg) def _get_model_priority(self, preferred_model: Optional[str]) -> List[ModelConfig]: """Détermine l'ordre de priorité des modèles.""" sorted_models = sorted(self.DEFAULT_MODELS, key=lambda m: m.fallback_priority) if preferred_model: # Déplacer le modèle préféré en tête preferred = [m for m in sorted_models if m.name == preferred_model] others = [m for m in sorted_models if m.name != preferred_model] return preferred + others return sorted_models async def _call_model( self, model: str, messages: List[Dict[str, str]], temperature: float, max_tokens: int ) -> Dict[str, Any]: """Appelle l'API HolySheep pour un modèle donné.""" payload = { "model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens } response = await self.client.post( f"{self.base_url}/chat/completions", json=payload ) response.raise_for_status() return response.json() def get_metrics(self) -> Dict[str, Any]: """Retourne les métriques de performance.""" return { "total_requests": self.metrics.total_requests, "successful_requests": self.metrics.successful_requests, "success_rate": ( self.metrics.successful_requests / self.metrics.total_requests * 100 if self.metrics.total_requests > 0 else 0 ), "fallback_rate": ( self.metrics.fallback_triggered / self.metrics.total_requests * 100 if self.metrics.total_requests > 0 else 0 ), "total_cost_usd": self.metrics.cost_total, "model_usage": self.metrics.model_usage, "circuit_breakers": { name: breaker.state.value for name, breaker in self.breakers.items() } }

=============================================================================

EXEMPLE D'UTILISATION EN PRODUCTION

=============================================================================

async def main(): """Exemple d'utilisation du client multi-modèle.""" # Initialisation du client client = HolySheepMultiModelClient() # Exemple de conversation messages = [ {"role": "user", "content": "Explique-moi la différence entre un circuit breaker et un retry pattern en architecture distribuée."} ] system_prompt = """Tu es un expert en architecture de systèmes distribués. Réponds de manière concise et technique, avec des exemples de code.""" try: # Premier appel - utilisera le modèle prioritaire (GPT-4.1) result = await client.chat_completion( messages=messages, system_prompt=system_prompt, temperature=0.7, max_tokens=2000 ) print("\n" + "="*60) print("RÉSULTAT DE LA RÉPONSE") print("="*60) print(f"Modèle utilisé: {result['model']}") print(f"Latence: {result['latency_ms']:.0f} ms") print(f"Coût: ${result['cost_usd']:.6f}") print(f"Fallback utilisé: {result['fallback_used']}") print("="*60) # Afficher les métriques globales print("\n📊 MÉTRIQUES DE PERFORMANCE:") metrics = client.get_metrics() for key, value in metrics.items(): print(f" {key}: {value}") except Exception as e: print(f"❌ Erreur fatale: {e}") if __name__ == "__main__": asyncio.run(main())

Code TypeScript — Middleware Express.js avec Fallback

/**
 * HolySheep AI - Middleware Express.js Multi-Model Fallback
 * Version: 2.0152 | TypeScript 5.x
 * 
 * ATTENTION: Utilisez uniquement https://api.holysheep.ai/v1
 * JAMAIS api.openai.com ou api.anthropic.com directement
 */

// =============================================================================
// IMPORTS ET TYPES
// =============================================================================

import express, { Request, Response, NextFunction } from 'express';
import { HttpsProxyAgent } from 'https-proxy-agent';

interface ModelConfig {
  id: string;
  name: string;
  provider: 'openai' | 'anthropic' | 'google' | 'deepseek';
  costPerMTok: number;
  maxRPM: number;
  priority: number;
  baseLatency: number;
}

interface CircuitBreakerState {
  failures: number;
  lastFailure: number;
  status: 'closed' | 'open' | 'half-open';
  consecutiveSuccesses: number;
}

interface FallbackMetrics {
  totalRequests: number;
  successfulRequests: number;
  fallbacks: number;
  costUSD: number;
  modelDistribution: Record;
  latencyP50: number;
  latencyP95: number;
  latencyP99: number;
}

interface ChatRequest {
  model?: string;
  messages: Array<{ role: 'user' | 'assistant' | 'system'; content: string }>;
  temperature?: number;
  max_tokens?: number;
}

interface ChatResponse {
  id: string;
  model: string;
  choices: Array<{
    message: { role: string; content: string };
    finish_reason: string;
  }>;
  usage: {
    prompt_tokens: number;
    completion_tokens: number;
    total_tokens: number;
  };
  _holysheep: {
    fallbackUsed: boolean;
    latencyMs: number;
    costUSD: number;
    originalModel?: string;
  };
}

// =============================================================================
// CONFIGURATION HOLYSHEEP
// =============================================================================

const HOLYSHEEP_CONFIG = {
  baseUrl: 'https://api.holysheep.ai/v1',  // SEUL URL VALIDE
  apiKey: process.env.HOLYSHEEP_API_KEY || 'YOUR_HOLYSHEEP_API_KEY',
  timeout: 60000, // 60 secondes
};

// Ordre de priorité des modèles (index 0 = priorité最高的)
const MODELS: ModelConfig[] = [
  {
    id: 'deepseek-v3.2',
    name: 'deepseek-v3.2',
    provider: 'deepseek',
    costPerMTok: 0.42,
    maxRPM: 2000,
    priority: 1,
    baseLatency: 1500,
  },
  {
    id: 'gemini-2.5-flash',
    name: 'gemini-2.5-flash',
    provider: 'google',
    costPerMTok: 2.50,
    maxRPM: 1000,
    priority: 2,
    baseLatency: 800,
  },
  {
    id: 'gpt-4.1',
    name: 'gpt-4.1',
    provider: 'openai',
    costPerMTok: 8.00,
    maxRPM: 500,
    priority: 3,
    baseLatency: 1800,
  },
  {
    id: 'claude-sonnet-4.5',
    name: 'claude-sonnet-4.5',
    provider: 'anthropic',
    costPerMTok: 15.00,
    maxRPM: 300,
    priority: 4,
    baseLatency: 2200,
  },
];

// =============================================================================
// CLASSE CIRCUIT BREAKER AVANCÉ
// =============================================================================

class AdvancedCircuitBreaker {
  private state: CircuitBreakerState = {
    failures: 0,
    lastFailure: 0,
    status: 'closed',
    consecutiveSuccesses: 0,
  };

  private config = {
    failureThreshold: 5,
    successThreshold: 3,
    timeout: 60000, // 60 secondes avant retry
    halfOpenRequests: 3,
  };

  private halfOpenAttempts = 0;

  canExecute(): boolean {
    const now = Date.now();

    switch (this.state.status) {
      case 'closed':
        return true;

      case 'open':
        if (now - this.state.lastFailure > this.config.timeout) {
          this.state.status = 'half-open';
          this.halfOpenAttempts = 0;
          console.log('🔄 Circuit Breaker: OPEN → HALF-OPEN');
          return true;
        }
        return false;

      case 'half-open':
        if (this.halfOpenAttempts < this.config.halfOpenRequests) {
          this.halfOpenAttempts++;
          return true;
        }
        return false;

      default:
        return true;
    }
  }

  recordSuccess(): void {
    if (this.state.status === 'half-open') {
      this.state.consecutiveSuccesses++;
      if (this.state.consecutiveSuccesses >= this.config.successThreshold) {
        this.state = {
          failures: 0,
          lastFailure: 0,
          status: 'closed',
          consecutiveSuccesses: 0,
        };
        console.log('✅ Circuit Breaker: HALF-OPEN → CLOSED');
      }
    } else {
      this.state.failures = 0;
      this.state.consecutiveSuccesses++;
    }
  }

  recordFailure(errorCode?: number): void {
    this.state.failures++;
    this.state.lastFailure = Date.now();
    this.state.consecutiveSuccesses = 0;

    // Erreurs 429 = rate limit spécifique
    if (errorCode === 429) {
      console.warn(⚠️ Rate limit détecté - Circuit Breaker incrementé);
      this.state.failures += 2; // Augmentation plus rapide pour rate limits
    }

    if (
      this.state.status === 'half-open' ||
      this.state.failures >= this.config.failureThreshold
    ) {
      this.state.status = 'open';
      console.warn(🚫 Circuit Breaker: OUVERT après ${this.state.failures} échecs);
    }
  }

  getStatus(): CircuitBreakerState['status'] {
    return this.state.status;
  }
}

// =============================================================================
// CLASSE PRINCIPALE HOLYSHEEP FALLBACK CLIENT
// =============================================================================

class HolySheepFallbackClient {
  private breakers: Map = new Map();
  private metrics: FallbackMetrics = {
    totalRequests: 0,
    successfulRequests: 0,
    fallbacks: 0,
    costUSD: 0,
    modelDistribution: {},
    latencyP50: 0,
    latencyP95: 0,
    latencyP99: 0,
  };
  private latencies: number[] = [];

  constructor() {
    // Initialisation des circuit breakers pour chaque modèle
    MODELS.forEach((model) => {
      this.breakers.set(model.id, new AdvancedCircuitBreaker());
      this.metrics.modelDistribution[model.id] = 0;
    });
  }

  async complete(
    request: ChatRequest,
    preferredModel?: string
  ): Promise {
    this.metrics.totalRequests++;

    const modelsToTry = this.getModelPriority(preferredModel);
    let originalModel = modelsToTry[0].id;
    let lastError: Error | null = null;

    for (const model of modelsToTry) {
      const breaker = this.breakers.get(model.id)!;

      if (!breaker.canExecute()) {
        console.log(⏭️ Circuit breaker actif pour ${model.id}, fallback...);
        continue;
      }

      try {
        const startTime = Date.now();
        const response = await this.callAPI(model.id, request);
        const latencyMs = Date.now() - startTime;

        breaker.recordSuccess();
        this.metrics.successfulRequests++;
        this.metrics.modelDistribution[model.id]++;
        this.latencies.push(latencyMs);

        // Calcul du coût
        const inputCost =
          (response.usage.prompt_tokens / 1_000_000) * model.costPerMTok;
        const outputCost =
          (response.usage.completion_tokens / 1_000_000) * model.costPerMTok;
        const totalCost = inputCost + outputCost;
        this.metrics.costUSD += totalCost;

        console.log(
          ✅ ${model.id} | Latence: ${latencyMs}ms | Coût: $${totalCost.toFixed(6)}
        );

        return {
          ...response,
          model: model.id,
          _holysheep: {
            fallbackUsed: model.id !== originalModel,
            latencyMs,
            costUSD: totalCost,
            originalModel:
              model.id !== originalModel ? originalModel : undefined,
          },
        };
      } catch (error: any) {
        lastError = error;
        const statusCode = error.response?.status;

        breaker.recordFailure(statusCode);

        if (statusCode === 429) {
          console.warn(⚠️ Rate limit ${model.id} (429));
          this.metrics.fallbacks++;
          continue;
        }

        if (statusCode >= 500) {
          console.warn(⚠️ Erreur serveur ${model.id} (${statusCode}));
          this.metrics.fallbacks++;
          continue;
        }

        console.error(❌ Erreur ${model.id}:, error.message);
      }
    }

    throw new Error(
      Tous les modèles ont échoué. Dernière erreur: ${lastError?.message}.  +
        Vérifiez votre clé sur https://www.holysheep.ai/register
    );
  }

  private getModelPriority(preferredModel?: string): ModelConfig[] {
    const sorted = [...MODELS].sort((a, b) => a.priority - b.priority);

    if (preferredModel) {
      const preferred = sorted.find((m) => m.id === preferredModel);
      if (preferred) {
        const others = sorted.filter((m) => m.id !== preferredModel);
        return [preferred, ...others];
      }
    }

    return sorted;
  }

  private async callAPI(
    modelId: string,
    request: ChatRequest
  ): Promise {
    const response = await fetch(${HOLYSHEEP_CONFIG.baseUrl}/chat/completions, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: Bearer ${HOLYSHEEP_CONFIG.apiKey},
      },
      body: JSON.stringify({
        model: modelId,
        messages: request.messages,
        temperature: request.temperature ?? 0.7,
        max_tokens: request.max_tokens ?? 2048,
      }),
      signal: AbortSignal.timeout(HOLYSHEEP_CONFIG.timeout),
    });

    if (!response.ok) {
      const error = new Error(HTTP ${response.status}) as any;
      error.response = { status: response.status };
      throw error;
    }

    return response.json();
  }

  getMetrics(): FallbackMetrics {
    // Calcul des percentiles de latence
    const sorted = [...this.latencies].sort((a, b) => a - b);
    const p50Index = Math.floor(sorted.length * 0.5);
    const p95Index = Math.floor(sorted.length * 0.95);
    const p99Index = Math.floor(sorted.length * 0.99);

    return {
      ...this.metrics,
      latencyP50: sorted[p50Index] || 0,
      latencyP95: sorted[p95Index] || 0,
      latencyP99: sorted[p99Index] || 0,
    };
  }

  getBreakerStatus(): Record {
    const status: Record = {};
    this.breakers.forEach((breaker, modelId) => {
      status[modelId] = breaker.getStatus();
    });
    return status;
  }
}

// =============================================================================
// EXPRESS MIDDLEWARE
// =============================================================================

const app = express();
app.use(express.json());

const holySheepClient = new HolySheepFallbackClient();

// Middleware de fallback automatique
const holySheepFallback = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  // Ne pas intercepter les routes non-API
  if (!req.path.startsWith('/api/chat')) {
    return next();
  }

  try {
    const request: ChatRequest = {
      model: req.body.model,
      messages: req.body.messages,
      temperature: req.body.temperature,
      max_tokens: req.body.max_tokens,
    };

    const response = await holySheepClient.complete(request);

    res.json(response);
  } catch (error: any) {
    console.error('🚨 Erreur HolySheep Fallback:', error.message);
    res.status(503).json({
      error: 'Service temporairement indisponible',
      message: error.message,
      fallbackAvailable: true,
    });
  }
};

// Routes
app.post('/api/chat', holySheepFallback);

app.get('/api/metrics', (_req: Request, res: Response) => {
  res.json({
    metrics: holySheepClient.getMetrics(),
    breakers: holySheepClient.getBre