- Home
- Documentation
- Provider
- Configurazione di modelli e provider (`models.yml`)
Configurazione di modelli e provider (`models.yml`)
Questo documento descrive come il coding-agent carica attualmente i modelli, applica le sostituzioni, risolve le credenziali e sceglie i modelli in fase di esecuzione.
Cosa controlla il comportamento dei modelli
Sezione intitolata “Cosa controlla il comportamento dei modelli”File di implementazione principali:
src/config/model-registry.ts— carica i modelli integrati e personalizzati, le sostituzioni del provider, il rilevamento in fase di esecuzione, l’integrazione con l’autenticazionesrc/config/model-resolver.ts— analizza i pattern dei modelli e seleziona i modelli iniziali/smol/slowsrc/config/settings-schema.ts— impostazioni relative ai modelli (modelRoles, preferenze di trasporto del provider)src/session/auth-storage.ts— ordine di risoluzione per chiavi API e OAuthpackages/ai/src/models.tsepackages/ai/src/types.ts— provider/modelli integrati e tipiModel/compat
Posizione del file di configurazione e comportamento legacy
Sezione intitolata “Posizione del file di configurazione e comportamento legacy”Percorso di configurazione predefinito:
~/.xcsh/agent/models.yml
Comportamento legacy ancora presente:
- Se
models.ymlnon è presente emodels.jsonesiste nella stessa posizione, viene migrato inmodels.yml. - I percorsi di configurazione
.json/.jsoncespliciti sono ancora supportati quando passati programmaticamente aModelRegistry.
Struttura di models.yml
Sezione intitolata “Struttura di 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 è un intero opzionale scritto dal sistema di configurazione automatica. Quando presente, xcsh lo utilizza per rilevare configurazioni obsolete e aggiornarle automaticamente.
provider-id è la chiave canonica del provider utilizzata per la selezione e la ricerca dell’autenticazione.
equivalence è opzionale e configura il raggruppamento canonico dei modelli al di sopra dei modelli concreti del provider:
overridesmappa un selettore concreto esatto (provider/modelId) a un id canonico ufficiale upstreamexcludeesclude un selettore concreto dal raggruppamento canonico
Campi a livello di provider
Sezione intitolata “Campi a livello di provider”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: mlxValori api consentiti per provider/modello
Sezione intitolata “Valori api consentiti per provider/modello”openai-completionsopenai-responsesopenai-codex-responsesazure-openai-responsesanthropic-messagesgoogle-generative-aigoogle-vertex
Valori consentiti per auth/discovery
Sezione intitolata “Valori consentiti per auth/discovery”auth:apiKey(predefinito) ononediscovery.type:ollama
Regole di validazione (attuali)
Sezione intitolata “Regole di validazione (attuali)”Provider personalizzato completo (models non vuoto)
Sezione intitolata “Provider personalizzato completo (models non vuoto)”Obbligatori:
baseUrlapiKeya meno che non sia impostatoauth: noneapia livello di provider o per ciascun modello
Provider solo per sostituzione (models assente o vuoto)
Sezione intitolata “Provider solo per sostituzione (models assente o vuoto)”Deve definire almeno uno dei seguenti:
baseUrlmodelOverridesdiscovery
Discovery
Sezione intitolata “Discovery”discoveryrichiedeapia livello di provider.
Controlli sui valori del modello
Sezione intitolata “Controlli sui valori del modello”idobbligatoriocontextWindowemaxTokensdevono essere positivi se forniti
Ordine di unione e sostituzione
Sezione intitolata “Ordine di unione e sostituzione”Pipeline di ModelRegistry (durante l’aggiornamento):
- Carica provider/modelli integrati da
@f5-sales-demo/pi-ai. - Carica la configurazione personalizzata da
models.yml. - Applica le sostituzioni del provider (
baseUrl,headers) ai modelli integrati. - Applica
modelOverrides(per provider + id modello). - Unisce i
modelspersonalizzati:- lo stesso
provider + idsostituisce quello esistente - altrimenti viene aggiunto in coda
- lo stesso
- Applica i modelli scoperti in fase di esecuzione (attualmente Ollama e LM Studio), quindi riapplica le sostituzioni del modello.
Equivalenza canonica dei modelli e coalescenza
Sezione intitolata “Equivalenza canonica dei modelli e coalescenza”Il registro mantiene ogni modello concreto del provider e poi costruisce un livello canonico al di sopra di essi.
Gli id canonici sono id ufficiali upstream, ad esempio:
claude-opus-4-6claude-haiku-4-5gpt-5.3-codex
Configurazione dell’equivalenza in models.yml
Sezione intitolata “Configurazione dell’equivalenza in models.yml”Esempio:
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-previewOrdine di costruzione per il raggruppamento canonico:
- sostituzione utente esatta da
equivalence.overrides - corrispondenze di id ufficiali incluse nei metadati del modello integrato
- normalizzazione euristica conservativa per varianti gateway/provider
- fallback all’id proprio del modello concreto
Le euristiche attuali sono intenzionalmente limitate:
- i prefissi upstream incorporati possono essere rimossi quando presenti, ad esempio
anthropic/...oopenai/... - le varianti di versione con punti e trattini possono essere normalizzate solo quando mappano a un id ufficiale esistente, ad esempio
4.6 -> 4-6 - le famiglie o versioni ambigue non vengono unite senza una corrispondenza inclusa o una sostituzione esplicita
Comportamento della risoluzione canonica
Sezione intitolata “Comportamento della risoluzione canonica”Quando più varianti concrete condividono un id canonico, la risoluzione utilizza:
- disponibilità e autenticazione
modelProviderOrderinconfig.yml- ordine del registro/provider esistente se
modelProviderOrdernon è impostato
I provider disabilitati o non autenticati vengono ignorati.
Lo stato della sessione e le trascrizioni continuano a registrare il provider/modello concreto che ha effettivamente eseguito il turno.
Valori predefiniti del provider rispetto alle sostituzioni per modello:
- Gli
headersdel provider costituiscono la base. - Gli
headersdel modello sovrascrivono le chiavi degli header del provider. modelOverridespuò sovrascrivere i metadati del modello (name,reasoning,input,cost,contextWindow,maxTokens,headers,compat,contextPromotionTarget).compatviene unito in profondità per i blocchi di routing annidati (openRouterRouting,vercelGatewayRouting,extraBody).
Integrazione con il rilevamento in fase di esecuzione
Sezione intitolata “Integrazione con il rilevamento in fase di esecuzione”Rilevamento implicito di Ollama
Sezione intitolata “Rilevamento implicito di Ollama”Se ollama non è configurato esplicitamente, il registro aggiunge un provider rilevabile in modo implicito:
- provider:
ollama - api:
openai-completions - URL base:
OLLAMA_BASE_URLohttp://127.0.0.1:11434 - modalità di autenticazione: senza chiave (comportamento
auth: none)
Il rilevamento in fase di esecuzione chiama GET /api/tags su Ollama e sintetizza le voci del modello con valori predefiniti locali.
Rilevamento implicito di llama.cpp
Sezione intitolata “Rilevamento implicito di llama.cpp”Se llama.cpp non è configurato esplicitamente, il registro aggiunge un provider rilevabile in modo implicito:
Nota: utilizza la nuova API anthropic messages invece di openai-completions.
- provider:
llama.cpp - api:
openai-responses - URL base:
LLAMA_CPP_BASE_URLohttp://127.0.0.1:8080 - modalità di autenticazione: senza chiave (comportamento
auth: none)
Il rilevamento in fase di esecuzione chiama GET models su llama.cpp e sintetizza le voci del modello con valori predefiniti locali.
Rilevamento implicito di LM Studio
Sezione intitolata “Rilevamento implicito di LM Studio”Se lm-studio non è configurato esplicitamente, il registro aggiunge un provider rilevabile in modo implicito:
- provider:
lm-studio - api:
openai-completions - URL base:
LM_STUDIO_BASE_URLohttp://127.0.0.1:1234/v1 - modalità di autenticazione: senza chiave (comportamento
auth: none)
Il rilevamento in fase di esecuzione recupera i modelli (GET /models) e sintetizza le voci del modello con valori predefiniti locali.
Rilevamento esplicito del provider
Sezione intitolata “Rilevamento esplicito del provider”È possibile configurare il rilevamento manualmente:
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.cppRegistrazione di provider tramite estensioni
Sezione intitolata “Registrazione di provider tramite estensioni”Le estensioni possono registrare provider in fase di esecuzione (pi.registerProvider(...)), inclusi:
- sostituzione/aggiunta di modelli per un provider
- registrazione di gestori di stream personalizzati per nuovi ID API
- registrazione di provider OAuth personalizzati
Ordine di risoluzione per autenticazione e chiavi API
Sezione intitolata “Ordine di risoluzione per autenticazione e chiavi API”Quando si richiede una chiave per un provider, l’ordine effettivo è:
- Sostituzione in fase di esecuzione (CLI
--api-key) - Credenziale chiave API memorizzata in
agent.db - Credenziale OAuth memorizzata in
agent.db(con aggiornamento) - Mappatura tramite variabile d’ambiente (
OPENAI_API_KEY,ANTHROPIC_API_KEY, ecc.) - Resolver di fallback di ModelRegistry (provider
apiKeydamodels.yml, semantica nome-env-o-letterale)
Comportamento di apiKey in models.yml:
- Il valore viene prima trattato come nome di variabile d’ambiente.
- Se non esiste alcuna variabile d’ambiente, la stringa letterale viene utilizzata come token.
Se authHeader: true e il provider apiKey è impostato, i modelli ricevono:
- header
Authorization: Bearer <chiave-risolta>iniettato.
Provider senza chiave:
- I provider contrassegnati con
auth: nonevengono considerati disponibili senza credenziali. getApiKey*restituiscekNoAuthper essi.
Disponibilità dei modelli vs tutti i modelli
Sezione intitolata “Disponibilità dei modelli vs tutti i modelli”getAll()restituisce il registro dei modelli caricati (integrati + personalizzati uniti + scoperti).getAvailable()filtra i modelli che sono senza chiave o hanno un’autenticazione risolvibile.
Pertanto un modello può esistere nel registro ma non essere selezionabile finché non è disponibile l’autenticazione.
Risoluzione dei modelli in fase di esecuzione
Sezione intitolata “Risoluzione dei modelli in fase di esecuzione”Analisi di CLI e pattern
Sezione intitolata “Analisi di CLI e pattern”model-resolver.ts supporta:
provider/modelIdesatto- id di modello canonico esatto
- id di modello esatto (provider dedotto)
- corrispondenza fuzzy/per sottostringa
- pattern glob nell’ambito di
--models(ad es.openai/*,*sonnet*) - suffisso opzionale
:thinkingLevel(off|minimal|low|medium|high|xhigh)
--provider è legacy; è preferibile usare --model.
Precedenza della risoluzione per selettori esatti:
provider/modelIdesatto bypassa la coalescenza- id canonico esatto risolve tramite l’indice canonico
- id concreto semplice esatto funziona comunque
- la corrispondenza fuzzy e glob viene eseguita dopo i percorsi esatti
Priorità di selezione del modello iniziale
Sezione intitolata “Priorità di selezione del modello iniziale”findInitialModel(...) utilizza questo ordine:
- provider+modello esplicito da CLI
- primo modello nell’ambito (se non si riprende una sessione)
- provider/modello predefinito salvato
- valori predefiniti di provider noti (ad es. OpenAI/Anthropic/ecc.) tra i modelli disponibili
- primo modello disponibile
Alias di ruolo e impostazioni
Sezione intitolata “Alias di ruolo e impostazioni”Ruoli dei modelli supportati:
default,smol,slow,plan,commit
Gli alias di ruolo come pi/smol si espandono tramite settings.modelRoles. Ogni valore di ruolo può anche aggiungere un selettore di pensiero come :minimal, :low, :medium o :high.
Se un ruolo punta a un altro ruolo, il modello di destinazione eredita normalmente e qualsiasi suffisso esplicito sul ruolo di riferimento prevale per quell’uso specifico del ruolo.
Impostazioni correlate:
modelRoles(record)enabledModels(elenco di pattern nell’ambito)modelProviderOrder(precedenza globale del provider canonico)providers.kimiApiFormat(formato della richiestaopenaioanthropic)providers.openaiWebsockets(preferenza websocketauto|off|onper il trasporto OpenAI Codex)
modelRoles può memorizzare:
provider/modelIdper fissare una variante concreta del provider- un id canonico come
gpt-5.3-codexper consentire la coalescenza del provider
Per enabledModels e CLI --models:
- gli id canonici esatti si espandono a tutte le varianti concrete in quel gruppo canonico
- le voci esplicite
provider/modelIdrimangono esatte - i glob e le corrispondenze fuzzy operano comunque sui modelli concreti
/model e --list-models
Sezione intitolata “/model e --list-models”Entrambe le superfici mantengono visibili e selezionabili i modelli con prefisso del provider.
Ora espongono anche i modelli canonici/coalescenti:
/modelinclude una vista canonica insieme alle schede del provider--list-modelsstampa una sezione canonica più le righe concrete del provider
La selezione di una voce canonica memorizza il selettore canonico. La selezione di una riga del provider memorizza l’provider/modelId esplicito.
Promozione del contesto (catene di fallback a livello di modello)
Sezione intitolata “Promozione del contesto (catene di fallback a livello di modello)”La promozione del contesto è un meccanismo di recupero da overflow per varianti con contesto ridotto (ad esempio *-spark) che promuove automaticamente a un elemento gemello con contesto più ampio quando l’API rifiuta una richiesta con un errore di lunghezza del contesto.
Attivazione e ordine
Sezione intitolata “Attivazione e ordine”Quando un turno fallisce con un errore di overflow del contesto (ad es. context_length_exceeded), AgentSession tenta la promozione prima di ricorrere alla compattazione:
- Se
contextPromotion.enabledè true, risolve un target di promozione (vedere di seguito). - Se viene trovato un target, lo sostituisce e riprova la richiesta — senza necessità di compattazione.
- Se non è disponibile alcun target, prosegue con la compattazione automatica sul modello corrente.
Selezione del target
Sezione intitolata “Selezione del target”La selezione è guidata dal modello, non dal ruolo:
currentModel.contextPromotionTarget(se configurato)- modello con contesto più ampio più piccolo sullo stesso provider + API
I candidati vengono ignorati a meno che le credenziali non si risolvano (ModelRegistry.getApiKey(...)).
Handoff del websocket OpenAI Codex
Sezione intitolata “Handoff del websocket OpenAI Codex”In caso di passaggio da/a openai-codex-responses, la chiave di stato del provider di sessione openai-codex-responses viene chiusa prima del cambio di modello. Questo elimina lo stato del trasporto websocket in modo che il turno successivo parta pulito sul modello promosso.
Comportamento della persistenza
Sezione intitolata “Comportamento della persistenza”La promozione utilizza il cambio temporaneo (setModelTemporary):
- registrata come
model_changetemporaneo nella cronologia della sessione - non riscrive la mappatura dei ruoli salvata
Configurazione di catene di fallback esplicite
Sezione intitolata “Configurazione di catene di fallback esplicite”Configurare il fallback direttamente nei metadati del modello tramite contextPromotionTarget.
contextPromotionTarget accetta:
provider/model-id(esplicito)model-id(risolto nel provider corrente)
Esempio (models.yml) per Spark -> non-Spark sullo stesso provider:
providers: openai-codex: modelOverrides: gpt-5.3-codex-spark: contextPromotionTarget: openai-codex/gpt-5.3-codexIl generatore di modelli integrato assegna anche questo automaticamente per i modelli *-spark quando esiste un modello base sullo stesso provider.
Campi di compatibilità e routing
Sezione intitolata “Campi di compatibilità e routing”models.yml supporta questo sottoinsieme di compat:
supportsStoresupportsDeveloperRolesupportsReasoningEffortmaxTokensField(max_completion_tokensomax_tokens)openRouterRouting.only/openRouterRouting.ordervercelGatewayRouting.only/vercelGatewayRouting.order
Questi vengono utilizzati dalla logica di trasporto OpenAI-completions e combinati con il rilevamento automatico basato su URL.
Esempi pratici
Sezione intitolata “Esempi pratici”Endpoint compatibile con OpenAI locale (senza autenticazione)
Sezione intitolata “Endpoint compatibile con OpenAI locale (senza autenticazione)”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 ospitato con chiave basata su variabile d’ambiente
Sezione intitolata “Proxy ospitato con chiave basata su variabile d’ambiente”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]Sostituzione del routing del provider integrato e metadati del modello
Sezione intitolata “Sostituzione del routing del provider integrato e metadati del modello”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]Configurazione automatica del proxy LiteLLM
Sezione intitolata “Configurazione automatica del proxy LiteLLM”Quando le variabili d’ambiente LITELLM_BASE_URL e LITELLM_API_KEY sono entrambe impostate, xcsh gestisce automaticamente la configurazione di models.yml per il proxy LiteLLM.
Generazione automatica al primo avvio
Sezione intitolata “Generazione automatica al primo avvio”Se models.yml non esiste e vengono rilevate le variabili d’ambiente LiteLLM, xcsh lo genera automaticamente:
# 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_KEYViene generato anche un config.yml predefinito con impostazioni sensate per il provider di immagini.
Autoripristino all’avvio
Sezione intitolata “Autoripristino all’avvio”Ad ogni avvio, startupHealthCheck() nel registro dei modelli esegue i seguenti controlli:
| Condizione | Azione |
|---|---|
models.yml mancante | Genera automaticamente dalle variabili d’ambiente |
models.yml corrotto o non analizzabile | Backup in .bak, rigenera |
baseUrl non corrisponde a LITELLM_BASE_URL | Backup in .bak, rigenera con nuovo URL |
configVersion mancante o obsoleto | Backup in .bak, rigenera con versione corrente |
| Configurazione integra | Nessuna azione |
Tutte le riparazioni creano backup .bak prima di sovrascrivere. Tutte le operazioni sono idempotenti.
Comando CLI
Sezione intitolata “Comando CLI”xcsh setup litellm # Generate or fix LiteLLM configxcsh setup litellm --check # Validate without writingxcsh setup litellm --check --json # Machine-readable validation outputVariabili d’ambiente richieste
Sezione intitolata “Variabili d’ambiente richieste”| Variabile | Scopo |
|---|---|
LITELLM_BASE_URL | URL del proxy LiteLLM (ad es. https://your-proxy.example.com). Deve iniziare con http:// o https://. |
LITELLM_API_KEY | Chiave API per il proxy. Referenziata per nome nella configurazione generata, risolta in fase di esecuzione. |
Se una delle variabili non è impostata, la configurazione automatica viene ignorata silenziosamente.
Versioning della configurazione
Sezione intitolata “Versioning della configurazione”Le configurazioni generate includono un campo configVersion. Quando il formato generato cambia nelle versioni future, xcsh rileva le configurazioni obsolete e le aggiorna automaticamente (con backup).
Avvertenza per i consumer legacy
Sezione intitolata “Avvertenza per i consumer legacy”La maggior parte della configurazione dei modelli ora fluisce tramite models.yml attraverso ModelRegistry.
Rimane un percorso legacy degno di nota: la risoluzione dell’autenticazione Anthropic per la ricerca web legge ancora direttamente ~/.xcsh/agent/models.json in src/web/search/auth.ts.
Se si fa affidamento su quel percorso specifico, tenere presente la compatibilità JSON finché tale modulo non viene migrato.
Modalità di errore
Sezione intitolata “Modalità di errore”Se models.yml non supera i controlli di schema o validazione:
- Se
LITELLM_BASE_URLeLITELLM_API_KEYsono impostati, il controllo di integrità all’avvio tenta la riparazione automatica (backup del file corrotto, rigenerazione dalle variabili d’ambiente). Se la riparazione ha esito positivo, il registro ricarica la configurazione corretta. - Se la riparazione automatica non è possibile (variabili d’ambiente non impostate, errore di scrittura), il registro continua a operare con i modelli integrati.
- L’errore viene esposto tramite
ModelRegistry.getError()e visualizzato nell’interfaccia utente/notifiche.