- 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 le coding-agent charge actuellement les modèles, applique les surcharges, résout les identifiants et choisit les modèles à l’exécution.
Ce qui contrôle le comportement des modèles
Section intitulée « Ce qui contrôle le comportement des modèles »Fichiers d’implémentation principaux :
src/config/model-registry.ts— charge les modèles intégrés + personnalisés, les surcharges de fournisseurs, la découverte à l’exécution, l’intégration de l’authentificationsrc/config/model-resolver.ts— analyse les patterns de modèles et sélectionne les modèles initial/smol/slowsrc/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 des clés 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é
Section intitulée « Emplacement du fichier de configuration et comportement hérité »Chemin de configuration par défaut :
~/.xcsh/agent/models.yml
Comportement hérité toujours présent :
- Si
models.ymlest absent et quemodels.jsonexiste au même emplacement, il est migré versmodels.yml. - Les chemins de configuration explicites en
.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 des fournisseurs :
overridesassocie un sélecteur concret exact (provider/modelId) à un identifiant canonique officiel en amontexcludeexclut 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: Renamed model 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 les fournisseurs/modèles
Section intitulée « Valeurs api autorisées pour les fournisseurs/modèles »openai-completionsopenai-responsesopenai-codex-responsesazure-openai-responsesanthropic-messagesgoogle-generative-aigoogle-vertex
Valeurs autorisées pour auth/discovery
Section intitulée « Valeurs autorisées pour auth/discovery »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 non vide)
Section intitulée « Fournisseur personnalisé complet (models non vide) »Requis :
baseUrlapiKeysauf siauth: noneapiau niveau du fournisseur ou pour chaque modèle
Fournisseur en surcharge uniquement (models absent ou vide)
Section intitulée « Fournisseur en surcharge uniquement (models absent ou vide) »Doit définir au moins l’un des éléments suivants :
baseUrlmodelOverridesdiscovery
Découverte
Section intitulée « Découverte »discoverynécessiteapiau niveau du fournisseur.
Vérifications des valeurs des modèles
Section intitulée « Vérifications des valeurs des modèles »idrequiscontextWindowetmaxTokensdoivent être positifs s’ils sont fournis
Ordre de fusion et de surcharge
Section intitulée « Ordre de fusion et de surcharge »Pipeline de ModelRegistry (lors du rafraîchissement) :
- Charger les fournisseurs/modèles intégrés depuis
@f5-sales-demo/pi-ai. - Charger la configuration personnalisée
models.yml. - Appliquer les surcharges de fournisseurs (
baseUrl,headers) aux modèles intégrés. - Appliquer les
modelOverrides(par fournisseur + identifiant de modèle). - Fusionner les
modelspersonnalisés :- même
provider + idremplace l’existant - sinon, ajouter à la suite
- même
- Appliquer les modèles découverts à l’exécution (actuellement Ollama et LM Studio), puis réappliquer les surcharges de modèles.
Équivalence canonique des modèles et coalescence
Section intitulée « Équivalence canonique des modèles et coalescence »Le registre conserve chaque modèle concret de fournisseur puis construit une couche canonique au-dessus.
Les identifiants canoniques sont uniquement des identifiants officiels en amont, par exemple :
claude-opus-4-6claude-haiku-4-5gpt-5.3-codex
Configuration d’équivalence dans models.yml
Section intitulée « Configuration d’é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 :
- surcharge utilisateur exacte depuis
equivalence.overrides - correspondances d’identifiants officiels groupés depuis les métadonnées des modèles intégrés
- normalisation heuristique conservatrice pour les variantes de passerelle/fournisseur
- repli sur l’identifiant propre du modèle concret
Les heuristiques actuelles sont intentionnellement restrictives :
- les préfixes amont intégrés peuvent être supprimés lorsqu’ils sont présents, par exemple
anthropic/...ouopenai/... - les variantes de version avec points et tirets ne peuvent être normalisées que lorsqu’elles correspondent à un identifiant officiel existant, par exemple
4.6 -> 4-6 - les familles ou versions ambiguës ne sont pas fusionnées sans correspondance groupée ou surcharge 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
modelProviderOrderdansconfig.yml- ordre existant du registre/fournisseur si
modelProviderOrdern’est pas défini
Les fournisseurs désactivés ou non authentifiés sont ignorés.
L’état de session et les transcriptions continuent d’enregistrer le fournisseur/modèle concret qui a réellement exécuté le tour.
Valeurs par défaut du fournisseur vs surcharges par modèle :
- Les
headersdu fournisseur constituent la base. - Les
headersdu modèle surchargent les clés d’en-tête du fournisseur. - Les
modelOverridespeuvent surcharger les métadonnées du modèle (name,reasoning,input,cost,contextWindow,maxTokens,headers,compat,contextPromotionTarget). compatest fusionné en profondeur 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 d’Ollama
Section intitulée « Découverte implicite d’Ollama »Si ollama n’est pas explicitement configuré, le registre ajoute un fournisseur découvrable implicite :
- fournisseur :
ollama - api :
openai-completions - URL de base :
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 des entrées de modèle avec les valeurs par défaut locales.
Découverte implicite de llama.cpp
Section intitulée « Découverte implicite de llama.cpp »Si llama.cpp n’est pas explicitement configuré, le registre ajoute un fournisseur découvrable implicite :
Note : il utilise la nouvelle API anthropic messages au lieu de openai-completions.
- fournisseur :
llama.cpp - api :
openai-responses - URL de base :
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 des entrées de modèle avec les valeurs par défaut locales.
Découverte implicite de LM Studio
Section intitulée « Découverte implicite de LM Studio »Si lm-studio n’est pas explicitement configuré, le registre ajoute un fournisseur découvrable implicite :
- fournisseur :
lm-studio - api :
openai-completions - URL de base :
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 des entrées de modèle avec les valeurs par défaut locales.
Découverte explicite de fournisseur
Section intitulée « Découverte explicite de fournisseur »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(...)), incluant :
- remplacement/ajout de modèle 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 des clés API
Section intitulée « Ordre de résolution de l’authentification et des clés API »Lors de la demande d’une clé pour un fournisseur, l’ordre effectif est :
- Surcharge à l’exécution (CLI
--api-key) - Identifiant de clé API stocké dans
agent.db - Identifiant OAuth stocké dans
agent.db(avec rafraîchissement) - Correspondance de variable d’environnement (
OPENAI_API_KEY,ANTHROPIC_API_KEY, etc.) - Résolveur de repli de ModelRegistry (
apiKeydu fournisseur depuismodels.yml, sémantique nom-d’env-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.
Si authHeader: true et que apiKey du fournisseur est défini, les modèles reçoivent :
- Un en-tête
Authorization: Bearer <clé-résolue>injecté.
Fournisseurs sans clé :
- Les fournisseurs marqués
auth: nonesont considérés comme disponibles sans identifiants. getApiKey*retournekNoAuthpour ceux-ci.
Disponibilité des modèles vs tous les modèles
Section intitulée « Disponibilité des modèles vs tous les modèles »getAll()retourne le registre de modèles chargé (intégrés + personnalisés fusionnés + découverts).getAvailable()filtre pour ne garder que les modèles sans clé ou avec une authentification résolvable.
Ainsi, un modèle peut 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 patterns
Section intitulée « CLI et analyse de patterns »model-resolver.ts prend en charge :
provider/modelIdexact- identifiant canonique de modèle exact
- identifiant de modèle exact (fournisseur déduit)
- correspondance floue/par sous-chaîne
- patterns glob dans
--models(par ex.openai/*,*sonnet*) - suffixe optionnel
:thinkingLevel(off|minimal|low|medium|high|xhigh)
--provider est hérité ; --model est préféré.
Ordre de précédence pour les sélecteurs exacts :
provider/modelIdexact contourne la coalescence- l’identifiant canonique exact est résolu via l’index canonique
- l’identifiant concret nu exact fonctionne toujours
- la correspondance floue et glob s’exécute 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 explicite en CLI
- premier modèle dans la portée (si pas en reprise de session)
- fournisseur/modèle par défaut sauvegardé
- valeurs par défaut de 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èle pris en charge :
default,smol,slow,plan,commit
Les alias de rôle comme pi/smol sont développés via settings.modelRoles. Chaque valeur de rôle peut également ajouter un sélecteur de réflexion tel que :minimal, :low, :medium ou :high.
Si un rôle pointe vers un autre rôle, le modèle cible hérite 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 patterns avec portée)modelProviderOrder(précédence globale fournisseur canonique)providers.kimiApiFormat(format de requêteopenaiouanthropic)providers.openaiWebsockets(préférence websocketauto|off|onpour le transport OpenAI Codex)
modelRoles peut stocker soit :
provider/modelIdpour épingler une variante de fournisseur concrète- un identifiant canonique tel que
gpt-5.3-codexpour permettre la coalescence des fournisseurs
Pour enabledModels et --models en CLI :
- les identifiants canoniques exacts sont développés vers toutes les variantes concrètes de ce groupe canonique
- les entrées explicites
provider/modelIdrestent exactes - les globs et correspondances floues opèrent toujours 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/coalescés :
/modelinclut une vue canonique aux côtés des onglets par fournisseur--list-modelsaffiche une section canonique plus les lignes concrètes par fournisseur
Sélectionner une entrée canonique stocke le sélecteur canonique. Sélectionner une ligne de fournisseur stocke 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 pour les variantes à petit contexte (par exemple *-spark) qui promeut automatiquement vers un modèle frère à plus grand contexte lorsque l’API rejette une requête avec une erreur de longueur de contexte.
Déclenchement et ordre
Section intitulée « Déclenchement et ordre »Lorsqu’un tour échoue avec une erreur de dépassement de contexte (par ex. context_length_exceeded), AgentSession tente la promotion avant de recourir à la compaction :
- Si
contextPromotion.enabledest vrai, résoudre une cible de promotion (voir ci-dessous). - Si une cible est trouvée, basculer vers elle et réessayer la requête — aucune compaction 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, pas par le rôle :
currentModel.contextPromotionTarget(si configuré)- plus petit modèle à plus grand contexte sur le même fournisseur + API
Les candidats sont ignorés à moins que les identifiants ne soient résolus (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 supprime l’état du transport websocket afin que le prochain tour démarre 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 session - ne réécrit pas la correspondance de rôle sauvegardée
Configuration de chaînes de repli explicites
Section intitulée « Configuration de chaînes de repli explicites »Configurez le repli 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é attribue également ceci 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 local compatible OpenAI (sans authentification)
Section intitulée « Point de terminaison 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 une variable d’environnement
Section intitulée « Proxy hébergé avec clé basée sur une variable d’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]Surcharger la route d’un fournisseur intégré + métadonnées du modèle
Section intitulée « Surcharger la route d’un fournisseur intégré + 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 deux variables d’environnement LITELLM_BASE_URL et LITELLM_API_KEY sont définies, xcsh gère automatiquement la configuration de models.yml pour le proxy LiteLLM.
Génération automatique au premier lancement
Section intitulée « Génération automatique au 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 appropriés.
Auto-réparation au démarrage
Section intitulée « Auto-réparation au démarrage »À chaque démarrage, startupHealthCheck() dans le registre des modèles effectue les vérifications suivantes :
| Condition | Action |
|---|---|
models.yml absent | Génération automatique à partir des variables d’environnement |
models.yml corrompu ou non analysable | Sauvegarde en .bak, régénération |
baseUrl ne correspond pas à LITELLM_BASE_URL | Sauvegarde en .bak, régénération avec la nouvelle URL |
configVersion absent ou obsolète | Sauvegarde en .bak, régénération avec la version actuelle |
| Configuration saine | Aucune action |
Toutes les réparations créent des sauvegardes .bak avant l’écrasement. Toutes les opérations sont idempotentes.
Commande CLI
Section intitulée « Commande CLI »xcsh setup litellm # Generate or fix LiteLLM configxcsh setup litellm --check # Validate without writingxcsh setup litellm --check --json # Machine-readable validation outputVariables 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 nom dans la configuration générée, résolue à l’exécution. |
Si l’une des variables n’est pas définie, la configuration automatique est silencieusement ignorée.
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 à jour automatiquement (avec sauvegarde).
Avertissement concernant les consommateurs hérités
Section intitulée « Avertissement concernant les consommateurs hérités »La plupart de la configuration des modèles passe maintenant par models.yml via ModelRegistry.
Un chemin hérité notable subsiste : la résolution d’authentification Anthropic pour la recherche web 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 d’échec
Section intitulée « Mode d’échec »Si models.yml échoue aux vérifications de schéma ou de validation :
- Si
LITELLM_BASE_URLetLITELLM_API_KEYsont définies, la vérification de santé au démarrage tente une auto-réparation (sauvegarde du fichier corrompu, régénération à 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 affichée dans l’interface/les notifications.