- Accueil
- Documentation
- Fournisseurs
- Configuration des modèles et des fournisseurs (`models.yml`)
Configuration des modèles et des fournisseurs (`models.yml`)
Ce document décrit comment l’agent de codage (coding-agent) charge actuellement les modèles, applique les remplacements (overrides), résout les informations d’identification (credentials) et choisit les modèles lors de l’exécution (runtime).
Ce qui contrôle le comportement du modèle
Section intitulée « Ce qui contrôle le comportement du modèle »Fichiers d’implémentation principaux :
src/config/model-registry.ts— charge les modèles intégrés + personnalisés, les remplacements de fournisseurs, la découverte à l’exécution, l’intégration de l’authentificationsrc/config/model-resolver.ts— analyse les modèles de recherche (patterns) et sélectionne les modèles initiaux/smol/lents (slow)src/config/settings-schema.ts— paramètres liés aux modèles (modelRoles, préférences de transport des fournisseurs)src/session/auth-storage.ts— ordre de résolution de la clé API + OAuthpackages/ai/src/models.tsetpackages/ai/src/types.ts— fournisseurs/modèles intégrés et typesModel/compat
Emplacement du fichier de configuration et comportement hérité (legacy)
Section intitulée « Emplacement du fichier de configuration et comportement hérité (legacy) »Chemin de configuration par défaut :
~/.xcsh/agent/models.yml
Comportement hérité toujours présent :
- Si
models.ymlest manquant et quemodels.jsonexiste au même emplacement, il est migré versmodels.yml. - Les chemins de configuration explicites
.json/.jsoncsont toujours pris en charge lorsqu’ils sont passés programmatiquement àModelRegistry.
Structure de models.yml
Section intitulée « Structure de models.yml »configVersion: 1 # optional — written by auto-config, used for migration detectionproviders: <provider-id>: # provider-level configequivalence: overrides: <provider-id>/<model-id>: <canonical-model-id> exclude: - <provider-id>/<model-id>configVersion est un entier optionnel écrit par le système de configuration automatique. Lorsqu’il est présent, xcsh l’utilise pour détecter les configurations obsolètes et les mettre à jour automatiquement.
provider-id est la clé canonique du fournisseur utilisée pour la sélection et la recherche d’authentification.
equivalence est optionnel et configure le regroupement canonique des modèles au-dessus des modèles concrets du fournisseur :
overridesmappe un sélecteur concret exact (provider/modelId) vers un identifiant canonique officiel en amont (upstream)excludeexclut un sélecteur concret du regroupement canonique
Champs au niveau du fournisseur
Section intitulée « Champs au niveau du fournisseur »providers: my-provider: baseUrl: https://api.example.com/v1 apiKey: MY_PROVIDER_API_KEY api: openai-completions headers: X-Team: platform authHeader: true auth: apiKey discovery: type: ollama modelOverrides: some-model-id: name: Modèle renommé models: - id: some-model-id name: Some Model api: openai-completions reasoning: false input: [text] cost: input: 0 output: 0 cacheRead: 0 cacheWrite: 0 contextWindow: 128000 maxTokens: 16384 headers: X-Model: value compat: supportsStore: true supportsDeveloperRole: true supportsReasoningEffort: true maxTokensField: max_completion_tokens openRouterRouting: only: [anthropic] vercelGatewayRouting: order: [anthropic, openai] extraBody: gateway: m1-01 controller: mlxValeurs api autorisées pour le fournisseur/modèle
Section intitulée « Valeurs api autorisées pour le fournisseur/modèle »openai-completionsopenai-responsesopenai-codex-responsesazure-openai-responsesanthropic-messagesgoogle-generative-aigoogle-vertex
Valeurs auth/discovery autorisées
Section intitulée « Valeurs auth/discovery autorisées »auth:apiKey(par défaut) ounonediscovery.type:ollama
Règles de validation (actuelles)
Section intitulée « Règles de validation (actuelles) »Fournisseur personnalisé complet (models n’est pas vide)
Section intitulée « Fournisseur personnalisé complet (models n’est pas vide) »Requis :
baseUrlapiKeysauf siauth: noneapiau niveau du fournisseur ou de chaque modèle
Fournisseur avec remplacements uniquement (models manquant ou vide)
Section intitulée « Fournisseur avec remplacements uniquement (models manquant ou vide) »Doit définir au moins l’un des éléments suivants :
baseUrlmodelOverridesdiscovery
Découverte (Discovery)
Section intitulée « Découverte (Discovery) »discoverynécessiteapiau niveau du fournisseur.
Vérifications des valeurs du modèle
Section intitulée « Vérifications des valeurs du modèle »idrequiscontextWindowetmaxTokensdoivent être positifs s’ils sont fournis
Ordre de fusion et de remplacement
Section intitulée « Ordre de fusion et de remplacement »Pipeline ModelRegistry (lors de l’actualisation) :
- Charger les fournisseurs/modèles intégrés à partir de
@f5-sales-demo/pi-ai. - Charger la configuration personnalisée
models.yml. - Appliquer les remplacements de fournisseur (
baseUrl,headers) aux modèles intégrés. - Appliquer
modelOverrides(par fournisseur + identifiant de modèle). - Fusionner les
modelspersonnalisés :- même
provider + idremplace l’existant - sinon, ajouter
- même
- Appliquer les modèles découverts à l’exécution (actuellement Ollama et LM Studio), puis réappliquer les remplacements de modèles.
Équivalence canonique des modèles et regroupement
Section intitulée « Équivalence canonique des modèles et regroupement »Le registre conserve chaque modèle de fournisseur concret, puis construit une couche canonique au-dessus d’eux.
Les identifiants canoniques sont uniquement des identifiants officiels en amont, par exemple :
claude-opus-4-6claude-haiku-4-5gpt-5.3-codex
Configuration de l’équivalence dans models.yml
Section intitulée « Configuration de l’équivalence dans models.yml »Exemple :
providers: zenmux: baseUrl: https://api.zenmux.example/v1 apiKey: ZENMUX_API_KEY api: openai-codex-responses models: - id: codex name: Zenmux Codex reasoning: true input: [text] cost: input: 0 output: 0 cacheRead: 0 cacheWrite: 0 contextWindow: 200000 maxTokens: 32768
equivalence: overrides: zenmux/codex: gpt-5.3-codex p-codex/codex: gpt-5.3-codex exclude: - demo/codex-previewOrdre de construction pour le regroupement canonique :
- remplacement utilisateur exact à partir de
equivalence.overrides - correspondances d’identifiants officiels intégrés à partir des métadonnées du modèle
- normalisation heuristique conservatrice pour les variantes de passerelle/fournisseur
- repli sur le propre identifiant du modèle concret
Les heuristiques actuelles sont intentionnellement limitées :
- les préfixes amont intégrés peuvent être supprimés s’ils sont présents, par exemple
anthropic/...ouopenai/... - les variantes de version avec des points et des tirets ne peuvent être normalisées que si elles correspondent à un identifiant officiel existant, par exemple
4.6 -> 4-6 - les familles ou versions ambiguës ne sont pas fusionnées sans une correspondance intégrée ou un remplacement explicite
Comportement de la résolution canonique
Section intitulée « Comportement de la résolution canonique »Lorsque plusieurs variantes concrètes partagent un identifiant canonique, la résolution utilise :
- disponibilité et authentification
config.ymlmodelProviderOrder- ordre du registre/fournisseur existant si
modelProviderOrdern’est pas défini
Les fournisseurs désactivés ou non authentifiés sont ignorés.
L’état de la session et les transcriptions continuent d’enregistrer le fournisseur/modèle concret qui a réellement exécuté le tour (turn).
Valeurs par défaut du fournisseur vs remplacements par modèle :
- Les
headersdu fournisseur sont la base. - Les
headersdu modèle remplacent les clés d’en-tête du fournisseur. modelOverridespeut remplacer les métadonnées du modèle (name,reasoning,input,cost,contextWindow,maxTokens,headers,compat,contextPromotionTarget).compatest fusionné en profondeur (deep-merged) pour les blocs de routage imbriqués (openRouterRouting,vercelGatewayRouting,extraBody).
Intégration de la découverte à l’exécution
Section intitulée « Intégration de la découverte à l’exécution »Découverte implicite Ollama
Section intitulée « Découverte implicite Ollama »Si ollama n’est pas explicitement configuré, le registre ajoute un fournisseur découvrable implicite :
- provider :
ollama - api :
openai-completions - base URL :
OLLAMA_BASE_URLouhttp://127.0.0.1:11434 - mode d’authentification : sans clé (comportement
auth: none)
La découverte à l’exécution appelle GET /api/tags sur Ollama et synthétise les entrées de modèles avec les valeurs par défaut locales.
Découverte implicite llama.cpp
Section intitulée « Découverte implicite llama.cpp »Si llama.cpp n’est pas explicitement configuré, le registre ajoute un fournisseur découvrable implicite :
Remarque : il utilise la nouvelle api anthropic messages au lieu de openai-completions.
- provider :
llama.cpp - api :
openai-responses - base URL :
LLAMA_CPP_BASE_URLouhttp://127.0.0.1:8080 - mode d’authentification : sans clé (comportement
auth: none)
La découverte à l’exécution appelle GET models sur llama.cpp et synthétise les entrées de modèles avec les valeurs par défaut locales.
Découverte implicite LM Studio
Section intitulée « Découverte implicite LM Studio »Si lm-studio n’est pas explicitement configuré, le registre ajoute un fournisseur découvrable implicite :
- provider :
lm-studio - api :
openai-completions - base URL :
LM_STUDIO_BASE_URLouhttp://127.0.0.1:1234/v1 - mode d’authentification : sans clé (comportement
auth: none)
La découverte à l’exécution récupère les modèles (GET /models) et synthétise les entrées de modèles avec les valeurs par défaut locales.
Découverte de fournisseur explicite
Section intitulée « Découverte de fournisseur explicite »Vous pouvez configurer la découverte vous-même :
providers: ollama: baseUrl: http://127.0.0.1:11434 api: openai-completions auth: none discovery: type: ollama
llama.cpp: baseUrl: http://127.0.0.1:8080 api: openai-responses auth: none discovery: type: llama.cppEnregistrement de fournisseur par extension
Section intitulée « Enregistrement de fournisseur par extension »Les extensions peuvent enregistrer des fournisseurs à l’exécution (pi.registerProvider(...)), notamment :
- remplacement/ajout de modèles pour un fournisseur
- enregistrement de gestionnaire de flux personnalisé pour de nouveaux identifiants d’API
- enregistrement de fournisseur OAuth personnalisé
Ordre de résolution de l’authentification et de la clé API
Section intitulée « Ordre de résolution de l’authentification et de la clé API »Lors de la demande d’une clé pour un fournisseur, l’ordre effectif est le suivant :
- Remplacement à l’exécution (CLI
--api-key) - Informations d’identification de clé API stockées dans
agent.db - Informations d’identification OAuth stockées dans
agent.db(avec actualisation) - Mappage des variables d’environnement (
OPENAI_API_KEY,ANTHROPIC_API_KEY, etc.) - Résolveur de secours (fallback) ModelRegistry (
apiKeydu fournisseur à partir demodels.yml, sémantique nom d’environnement ou littéral)
Comportement de apiKey dans models.yml :
- La valeur est d’abord traitée comme un nom de variable d’environnement.
- Si aucune variable d’environnement n’existe, la chaîne littérale est utilisée comme jeton (token).
Si authHeader: true et que le apiKey du fournisseur est défini, les modèles obtiennent :
- En-tête
Authorization: Bearer <resolved-key>injecté.
Fournisseurs sans clé :
- Les fournisseurs marqués
auth: nonesont traités comme disponibles sans informations d’identification. getApiKey*renvoiekNoAuthpour eux.
Disponibilité des modèles vs tous les modèles
Section intitulée « Disponibilité des modèles vs tous les modèles »getAll()renvoie le registre des modèles chargés (intégrés + personnalisés fusionnés + découverts).getAvailable()filtre les modèles pour ne conserver que ceux qui sont sans clé ou qui ont une authentification résolvable.
Un modèle peut donc exister dans le registre mais ne pas être sélectionnable tant que l’authentification n’est pas disponible.
Résolution des modèles à l’exécution
Section intitulée « Résolution des modèles à l’exécution »CLI et analyse de modèles (patterns)
Section intitulée « CLI et analyse de modèles (patterns) »model-resolver.ts prend en charge :
provider/modelIdexact- identifiant de modèle canonique exact
- identifiant de modèle exact (fournisseur déduit)
- correspondance floue (fuzzy)/de sous-chaîne
- modèles de portée (glob patterns) dans
--models(par ex.openai/*,*sonnet*) - suffixe
:thinkingLeveloptionnel (off|minimal|low|medium|high|xhigh)
--provider est hérité (legacy) ; --model est préféré.
Priorité de résolution pour les sélecteurs exacts :
provider/modelIdexact contourne le regroupement (coalescing)- l’identifiant canonique exact est résolu via l’index canonique
- l’identifiant concret nu exact fonctionne toujours
- la correspondance floue et les modèles globaux (glob patterns) s’exécutent après les chemins exacts
Priorité de sélection du modèle initial
Section intitulée « Priorité de sélection du modèle initial »findInitialModel(...) utilise cet ordre :
- fournisseur+modèle CLI explicite
- premier modèle de portée (si ce n’est pas une reprise)
- fournisseur/modèle par défaut enregistré
- valeurs par défaut des fournisseurs connus (par ex. OpenAI/Anthropic/etc.) parmi les modèles disponibles
- premier modèle disponible
Alias de rôles et paramètres
Section intitulée « Alias de rôles et paramètres »Rôles de modèles pris en charge :
default,smol,slow,plan,commit
Les alias de rôle comme pi/smol se développent via settings.modelRoles. Chaque valeur de rôle peut également ajouter un sélecteur de réflexion (thinking) tel que :minimal, :low, :medium ou :high.
Si un rôle pointe vers un autre rôle, le modèle cible hérite toujours normalement et tout suffixe explicite sur le rôle référent l’emporte pour cette utilisation spécifique au rôle.
Paramètres associés :
modelRoles(enregistrement)enabledModels(liste de modèles à portée)modelProviderOrder(priorité canonique-fournisseur globale)providers.kimiApiFormat(format de requêteopenaiouanthropic)providers.openaiWebsockets(préférence de transport websocketauto|off|onpour OpenAI Codex)
modelRoles peut stocker soit :
provider/modelIdpour épingler une variante concrète d’un fournisseur- un identifiant canonique tel que
gpt-5.3-codexpour permettre le regroupement de fournisseurs
Pour enabledModels et le CLI --models :
- les identifiants canoniques exacts se développent vers toutes les variantes concrètes de ce groupe canonique
- les entrées
provider/modelIdexplicites restent exactes - les correspondances globales (globs) et floues (fuzzy) continuent d’opérer sur les modèles concrets
/model et --list-models
Section intitulée « /model et --list-models »Les deux interfaces gardent les modèles préfixés par le fournisseur visibles et sélectionnables.
Elles exposent désormais également les modèles canoniques/regroupés :
/modelinclut une vue canonique aux côtés des onglets des fournisseurs--list-modelsaffiche une section canonique en plus des lignes concrètes des fournisseurs
La sélection d’une entrée canonique enregistre le sélecteur canonique. La sélection d’une ligne de fournisseur enregistre le provider/modelId explicite.
Promotion de contexte (chaînes de repli au niveau du modèle)
Section intitulée « Promotion de contexte (chaînes de repli au niveau du modèle) »La promotion de contexte est un mécanisme de récupération de dépassement (overflow) pour les variantes à petit contexte (par exemple *-spark) qui promeut automatiquement vers un modèle frère (sibling) à contexte plus grand lorsque l’API rejette une requête avec une erreur de longueur de contexte.
Déclencheur et ordre
Section intitulée « Déclencheur et ordre »Lorsqu’un tour échoue avec une erreur de dépassement de contexte (par exemple context_length_exceeded), AgentSession tente une promotion avant de se replier sur la compaction :
- Si
contextPromotion.enabledest vrai (true), résoudre une cible de promotion (voir ci-dessous). - Si une cible est trouvée, basculer vers elle et relancer la requête — aucune compaction n’est nécessaire.
- Si aucune cible n’est disponible, passer à la compaction automatique sur le modèle actuel.
Sélection de la cible
Section intitulée « Sélection de la cible »La sélection est pilotée par le modèle, et non par le rôle :
currentModel.contextPromotionTarget(si configuré)- le plus petit modèle à contexte plus grand sur le même fournisseur + API
Les candidats sont ignorés à moins que les informations d’identification ne soient résolues (ModelRegistry.getApiKey(...)).
Transfert websocket OpenAI Codex
Section intitulée « Transfert websocket OpenAI Codex »Si le basculement se fait depuis/vers openai-codex-responses, la clé d’état du fournisseur de session openai-codex-responses est fermée avant le changement de modèle. Cela abandonne l’état du transport websocket afin que le tour suivant commence proprement sur le modèle promu.
Comportement de persistance
Section intitulée « Comportement de persistance »La promotion utilise un basculement temporaire (setModelTemporary) :
- enregistré comme un
model_changetemporaire dans l’historique de la session - ne réécrit pas le mappage de rôle enregistré
Configuration de chaînes de repli explicites
Section intitulée « Configuration de chaînes de repli explicites »Configurez le repli (fallback) directement dans les métadonnées du modèle via contextPromotionTarget.
contextPromotionTarget accepte soit :
provider/model-id(explicite)model-id(résolu au sein du fournisseur actuel)
Exemple (models.yml) pour Spark -> non-Spark sur le même fournisseur :
providers: openai-codex: modelOverrides: gpt-5.3-codex-spark: contextPromotionTarget: openai-codex/gpt-5.3-codexLe générateur de modèles intégré l’attribue également automatiquement pour les modèles *-spark lorsqu’un modèle de base du même fournisseur existe.
Champs de compatibilité et de routage
Section intitulée « Champs de compatibilité et de routage »models.yml prend en charge ce sous-ensemble compat :
supportsStoresupportsDeveloperRolesupportsReasoningEffortmaxTokensField(max_completion_tokensoumax_tokens)openRouterRouting.only/openRouterRouting.ordervercelGatewayRouting.only/vercelGatewayRouting.order
Ceux-ci sont consommés par la logique de transport OpenAI-completions et combinés avec la détection automatique basée sur l’URL.
Exemples pratiques
Section intitulée « Exemples pratiques »Point de terminaison (endpoint) local compatible OpenAI (sans authentification)
Section intitulée « Point de terminaison (endpoint) local compatible OpenAI (sans authentification) »providers: local-openai: baseUrl: http://127.0.0.1:8000/v1 auth: none api: openai-completions models: - id: Qwen/Qwen2.5-Coder-32B-Instruct name: Qwen 2.5 Coder 32B (local)Proxy hébergé avec clé basée sur l’environnement
Section intitulée « Proxy hébergé avec clé basée sur l’environnement »providers: anthropic-proxy: baseUrl: https://proxy.example.com/anthropic apiKey: ANTHROPIC_PROXY_API_KEY api: anthropic-messages authHeader: true models: - id: claude-sonnet-4-20250514 name: Claude Sonnet 4 (Proxy) reasoning: true input: [text, image]Remplacer la route du fournisseur intégré + les métadonnées du modèle
Section intitulée « Remplacer la route du fournisseur intégré + les métadonnées du modèle »providers: openrouter: baseUrl: https://my-proxy.example.com/v1 headers: X-Team: platform modelOverrides: anthropic/claude-sonnet-4: name: Sonnet 4 (Corp) compat: openRouterRouting: only: [anthropic]Configuration automatique du proxy LiteLLM
Section intitulée « Configuration automatique du proxy LiteLLM »Lorsque les variables d’environnement LITELLM_BASE_URL et LITELLM_API_KEY sont toutes deux définies, xcsh gère automatiquement la configuration de models.yml pour le proxy LiteLLM.
Génération automatique lors du premier lancement
Section intitulée « Génération automatique lors du premier lancement »Si models.yml n’existe pas et que les variables d’environnement LiteLLM sont détectées, xcsh le génère automatiquement :
# Auto-generated by xcsh for LiteLLM proxy# API key resolved from LITELLM_API_KEY env var at runtimeconfigVersion: 1providers: anthropic: baseUrl: "https://your-litellm-proxy.example.com/anthropic" apiKey: LITELLM_API_KEYUn config.yml par défaut est également généré avec des paramètres de fournisseur d’images judicieux.
Auto-réparation au démarrage
Section intitulée « Auto-réparation au démarrage »À chaque démarrage, startupHealthCheck() dans le registre de modèles exécute les vérifications suivantes :
| Condition | Action |
|---|---|
models.yml manquant | Auto-générer à partir des variables d’environnement |
models.yml corrompu ou impossible à analyser | Sauvegarder dans .bak, régénérer |
baseUrl ne correspond pas à LITELLM_BASE_URL | Sauvegarder dans .bak, régénérer avec la nouvelle URL |
configVersion manquant ou obsolète | Sauvegarder dans .bak, régénérer avec la version actuelle |
| La configuration est saine | Aucune action |
Toutes les réparations créent des sauvegardes .bak avant d’écraser. Toutes les opérations sont idempotentes.
Commande CLI
Section intitulée « Commande CLI »xcsh setup litellm # Générer ou réparer la configuration LiteLLMxcsh setup litellm --check # Valider sans écrirexcsh setup litellm --check --json # Sortie de validation lisible par machineVariables d’environnement requises
Section intitulée « Variables d’environnement requises »| Variable | Objectif |
|---|---|
LITELLM_BASE_URL | URL du proxy LiteLLM (par ex. https://your-proxy.example.com). Doit commencer par http:// ou https://. |
LITELLM_API_KEY | Clé API pour le proxy. Référencée par son nom dans la configuration générée, résolue à l’exécution. |
Si l’une de ces variables n’est pas définie, la configuration automatique est ignorée silencieusement.
Versionnement de la configuration
Section intitulée « Versionnement de la configuration »Les configurations générées incluent un champ configVersion. Lorsque le format généré change dans les versions futures, xcsh détecte les configurations obsolètes et les met à niveau automatiquement (avec sauvegarde).
Mise en garde concernant les consommateurs hérités (Legacy consumer)
Section intitulée « Mise en garde concernant les consommateurs hérités (Legacy consumer) »La plupart des configurations de modèles transitent désormais par models.yml via ModelRegistry.
Un chemin hérité notable demeure : la résolution de l’authentification Anthropic pour la recherche sur le Web (web-search) lit toujours ~/.xcsh/agent/models.json directement dans src/web/search/auth.ts.
Si vous dépendez de ce chemin spécifique, gardez la compatibilité JSON à l’esprit jusqu’à ce que ce module soit migré.
Mode de défaillance (Failure mode)
Section intitulée « Mode de défaillance (Failure mode) »Si models.yml échoue aux vérifications de schéma ou de validation :
- Si
LITELLM_BASE_URLetLITELLM_API_KEYsont définis, la vérification de santé (health check) au démarrage tente une auto-réparation (sauvegarder le fichier corrompu, régénérer à partir des variables d’environnement). Si la réparation réussit, le registre recharge la configuration corrigée. - Si l’auto-réparation n’est pas possible (variables d’environnement non définies, échec d’écriture), le registre continue de fonctionner avec les modèles intégrés.
- L’erreur est exposée via
ModelRegistry.getError()et remontée dans l’interface utilisateur/les notifications.