- Início
- Documentation
- Provedores
- Configuração de Modelos e Provedores (`models.yml`)
Configuração de Modelos e Provedores (`models.yml`)
Este documento descreve como o coding-agent atualmente carrega modelos, aplica substituições, resolve credenciais e escolhe modelos em tempo de execução.
O que controla o comportamento dos modelos
Seção intitulada “O que controla o comportamento dos modelos”Arquivos de implementação principais:
src/config/model-registry.ts— carrega modelos integrados + customizados, substituições de provedores, descoberta em tempo de execução, integração de autenticaçãosrc/config/model-resolver.ts— analisa padrões de modelo e seleciona modelos initial/smol/slowsrc/config/settings-schema.ts— configurações relacionadas a modelos (modelRoles, preferências de transporte do provedor)src/session/auth-storage.ts— ordem de resolução de chave de API + OAuthpackages/ai/src/models.tsepackages/ai/src/types.ts— provedores/modelos integrados e tiposModel/compat
Localização do arquivo de configuração e comportamento legado
Seção intitulada “Localização do arquivo de configuração e comportamento legado”Caminho de configuração padrão:
~/.xcsh/agent/models.yml
Comportamento legado ainda presente:
- Se
models.ymlestiver ausente emodels.jsonexistir no mesmo local, ele é migrado paramodels.yml. - Caminhos de configuração explícitos
.json/.jsoncainda são suportados quando passados programaticamente paraModelRegistry.
Estrutura do models.yml
Seção intitulada “Estrutura do 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 é um inteiro opcional escrito pelo sistema de auto-configuração. Quando presente, o xcsh o utiliza para detectar configurações desatualizadas e atualizá-las automaticamente.
provider-id é a chave canônica do provedor usada em seleção e busca de autenticação.
equivalence é opcional e configura o agrupamento de modelos canônicos sobre os modelos concretos do provedor:
overridesmapeia um seletor concreto exato (provider/modelId) para um id canônico oficial upstreamexcluderetira um seletor concreto do agrupamento canônico
Campos em nível de provedor
Seção intitulada “Campos em nível de provedor”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: mlxValores permitidos de api para provedor/modelo
Seção intitulada “Valores permitidos de api para provedor/modelo”openai-completionsopenai-responsesopenai-codex-responsesazure-openai-responsesanthropic-messagesgoogle-generative-aigoogle-vertex
Valores permitidos de auth/discovery
Seção intitulada “Valores permitidos de auth/discovery”auth:apiKey(padrão) ounonediscovery.type:ollama
Regras de validação (atuais)
Seção intitulada “Regras de validação (atuais)”Provedor customizado completo (models não vazio)
Seção intitulada “Provedor customizado completo (models não vazio)”Obrigatório:
baseUrlapiKeya menos queauth: noneapino nível do provedor ou em cada modelo
Provedor apenas com substituições (models ausente ou vazio)
Seção intitulada “Provedor apenas com substituições (models ausente ou vazio)”Deve definir pelo menos um dos seguintes:
baseUrlmodelOverridesdiscovery
Discovery
Seção intitulada “Discovery”discoveryrequerapino nível do provedor.
Verificações de valores do modelo
Seção intitulada “Verificações de valores do modelo”idobrigatóriocontextWindowemaxTokensdevem ser positivos se fornecidos
Ordem de mesclagem e substituição
Seção intitulada “Ordem de mesclagem e substituição”Pipeline do ModelRegistry (ao atualizar):
- Carregar provedores/modelos integrados de
@f5-sales-demo/pi-ai. - Carregar configuração customizada de
models.yml. - Aplicar substituições de provedor (
baseUrl,headers) aos modelos integrados. - Aplicar
modelOverrides(por provedor + id do modelo). - Mesclar
modelscustomizados:- mesmo
provider + idsubstitui o existente - caso contrário, adiciona ao final
- mesmo
- Aplicar modelos descobertos em tempo de execução (atualmente Ollama e LM Studio), depois reaplicar substituições de modelo.
Equivalência canônica de modelos e coalescência
Seção intitulada “Equivalência canônica de modelos e coalescência”O registro mantém cada modelo concreto do provedor e então constrói uma camada canônica acima deles.
Ids canônicos são apenas ids oficiais upstream, por exemplo:
claude-opus-4-6claude-haiku-4-5gpt-5.3-codex
Configuração de equivalência no models.yml
Seção intitulada “Configuração de equivalência no models.yml”Exemplo:
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-previewOrdem de construção para agrupamento canônico:
- substituição exata do usuário de
equivalence.overrides - correspondências de id oficial integradas dos metadados do modelo built-in
- normalização heurística conservadora para variantes de gateway/provedor
- fallback para o próprio id do modelo concreto
As heurísticas atuais são intencionalmente restritas:
- prefixos upstream incorporados podem ser removidos quando presentes, por exemplo
anthropic/...ouopenai/... - variantes de versão com pontos e hífens podem normalizar apenas quando mapeiam para um id oficial existente, por exemplo
4.6 -> 4-6 - famílias ou versões ambíguas não são mescladas sem uma correspondência integrada ou substituição explícita
Comportamento de resolução canônica
Seção intitulada “Comportamento de resolução canônica”Quando múltiplas variantes concretas compartilham um id canônico, a resolução usa:
- disponibilidade e autenticação
modelProviderOrderdoconfig.yml- ordem existente no registro/provedor se
modelProviderOrdernão estiver definido
Provedores desabilitados ou não autenticados são ignorados.
O estado da sessão e as transcrições continuam registrando o provedor/modelo concreto que realmente executou o turno.
Padrões do provedor vs substituições por modelo:
headersdo provedor são a base.headersdo modelo substituem as chaves de header do provedor.modelOverridespode substituir metadados do modelo (name,reasoning,input,cost,contextWindow,maxTokens,headers,compat,contextPromotionTarget).compaté mesclado profundamente para blocos de roteamento aninhados (openRouterRouting,vercelGatewayRouting,extraBody).
Integração de descoberta em tempo de execução
Seção intitulada “Integração de descoberta em tempo de execução”Descoberta implícita do Ollama
Seção intitulada “Descoberta implícita do Ollama”Se ollama não estiver explicitamente configurado, o registro adiciona um provedor descobrível implícito:
- provedor:
ollama - api:
openai-completions - URL base:
OLLAMA_BASE_URLouhttp://127.0.0.1:11434 - modo de autenticação: sem chave (comportamento
auth: none)
A descoberta em tempo de execução chama GET /api/tags no Ollama e sintetiza entradas de modelo com padrões locais.
Descoberta implícita do llama.cpp
Seção intitulada “Descoberta implícita do llama.cpp”Se llama.cpp não estiver explicitamente configurado, o registro adiciona um provedor descobrível implícito:
Nota: está usando a API de mensagens antropic mais recente em vez de openai-completions.
- provedor:
llama.cpp - api:
openai-responses - URL base:
LLAMA_CPP_BASE_URLouhttp://127.0.0.1:8080 - modo de autenticação: sem chave (comportamento
auth: none)
A descoberta em tempo de execução chama GET models no llama.cpp e sintetiza entradas de modelo com padrões locais.
Descoberta implícita do LM Studio
Seção intitulada “Descoberta implícita do LM Studio”Se lm-studio não estiver explicitamente configurado, o registro adiciona um provedor descobrível implícito:
- provedor:
lm-studio - api:
openai-completions - URL base:
LM_STUDIO_BASE_URLouhttp://127.0.0.1:1234/v1 - modo de autenticação: sem chave (comportamento
auth: none)
A descoberta em tempo de execução busca modelos (GET /models) e sintetiza entradas de modelo com padrões locais.
Descoberta explícita de provedor
Seção intitulada “Descoberta explícita de provedor”Você pode configurar a descoberta 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.cppRegistro de provedor por extensão
Seção intitulada “Registro de provedor por extensão”Extensões podem registrar provedores em tempo de execução (pi.registerProvider(...)), incluindo:
- substituição/adição de modelos para um provedor
- registro de handler de stream customizado para novos IDs de API
- registro de provedor OAuth customizado
Ordem de resolução de autenticação e chave de API
Seção intitulada “Ordem de resolução de autenticação e chave de API”Ao solicitar uma chave para um provedor, a ordem efetiva é:
- Substituição em tempo de execução (CLI
--api-key) - Credencial de chave de API armazenada em
agent.db - Credencial OAuth armazenada em
agent.db(com refresh) - Mapeamento de variável de ambiente (
OPENAI_API_KEY,ANTHROPIC_API_KEY, etc.) - Resolver de fallback do ModelRegistry (
apiKeydo provedor emmodels.yml, semântica de nome-de-env-ou-literal)
Comportamento de apiKey no models.yml:
- O valor é primeiro tratado como um nome de variável de ambiente.
- Se nenhuma variável de ambiente existir, a string literal é usada como token.
Se authHeader: true e apiKey do provedor estiver definido, os modelos recebem:
- Header
Authorization: Bearer <chave-resolvida>injetado.
Provedores sem chave:
- Provedores marcados com
auth: nonesão tratados como disponíveis sem credenciais. getApiKey*retornakNoAuthpara eles.
Disponibilidade de modelos vs todos os modelos
Seção intitulada “Disponibilidade de modelos vs todos os modelos”getAll()retorna o registro de modelos carregado (integrados + customizados mesclados + descobertos).getAvailable()filtra para modelos que são sem chave ou possuem autenticação resolvível.
Portanto, um modelo pode existir no registro, mas não ser selecionável até que a autenticação esteja disponível.
Resolução de modelo em tempo de execução
Seção intitulada “Resolução de modelo em tempo de execução”CLI e análise de padrões
Seção intitulada “CLI e análise de padrões”model-resolver.ts suporta:
provider/modelIdexato- id canônico de modelo exato
- id de modelo exato (provedor inferido)
- correspondência fuzzy/substring
- padrões glob de escopo em
--models(ex.:openai/*,*sonnet*) - sufixo opcional
:thinkingLevel(off|minimal|low|medium|high|xhigh)
--provider é legado; --model é preferido.
Precedência de resolução para seletores exatos:
provider/modelIdexato ignora coalescência- id canônico exato resolve através do índice canônico
- id concreto bare exato ainda funciona
- correspondência fuzzy e glob executa após os caminhos exatos
Prioridade de seleção do modelo inicial
Seção intitulada “Prioridade de seleção do modelo inicial”findInitialModel(...) usa esta ordem:
- provedor+modelo explícito via CLI
- primeiro modelo com escopo (se não estiver retomando)
- provedor/modelo padrão salvo
- padrões conhecidos de provedores (ex.: OpenAI/Anthropic/etc.) entre modelos disponíveis
- primeiro modelo disponível
Aliases de papel e configurações
Seção intitulada “Aliases de papel e configurações”Papéis de modelo suportados:
default,smol,slow,plan,commit
Aliases de papel como pi/smol expandem através de settings.modelRoles. Cada valor de papel também pode adicionar um seletor de thinking como :minimal, :low, :medium ou :high.
Se um papel aponta para outro papel, o modelo alvo ainda herda normalmente e qualquer sufixo explícito no papel referente prevalece para aquele uso específico do papel.
Configurações relacionadas:
modelRoles(registro)enabledModels(lista de padrões com escopo)modelProviderOrder(precedência global canônica-provedor)providers.kimiApiFormat(formato de requisiçãoopenaiouanthropic)providers.openaiWebsockets(preferência de websocketauto|off|onpara transporte OpenAI Codex)
modelRoles pode armazenar tanto:
provider/modelIdpara fixar uma variante concreta de provedor- um id canônico como
gpt-5.3-codexpara permitir coalescência de provedor
Para enabledModels e CLI --models:
- ids canônicos exatos expandem para todas as variantes concretas naquele grupo canônico
- entradas explícitas
provider/modelIdpermanecem exatas - globs e correspondências fuzzy ainda operam sobre modelos concretos
/model e --list-models
Seção intitulada “/model e --list-models”Ambas as interfaces mantêm modelos com prefixo de provedor visíveis e selecionáveis.
Agora também expõem modelos canônicos/coalescidos:
/modelinclui uma visualização canônica junto com as abas de provedor--list-modelsimprime uma seção canônica mais as linhas concretas por provedor
Selecionar uma entrada canônica armazena o seletor canônico. Selecionar uma linha de provedor armazena o provider/modelId explícito.
Promoção de contexto (cadeias de fallback em nível de modelo)
Seção intitulada “Promoção de contexto (cadeias de fallback em nível de modelo)”A promoção de contexto é um mecanismo de recuperação de overflow para variantes de contexto pequeno (por exemplo *-spark) que automaticamente promove para um modelo irmão de contexto maior quando a API rejeita uma requisição com erro de comprimento de contexto.
Gatilho e ordem
Seção intitulada “Gatilho e ordem”Quando um turno falha com erro de overflow de contexto (ex.: context_length_exceeded), AgentSession tenta a promoção antes de recorrer à compactação:
- Se
contextPromotion.enabledfor true, resolver um alvo de promoção (veja abaixo). - Se um alvo for encontrado, trocar para ele e retentar a requisição — sem necessidade de compactação.
- Se nenhum alvo estiver disponível, prosseguir para auto-compactação no modelo atual.
Seleção do alvo
Seção intitulada “Seleção do alvo”A seleção é orientada por modelo, não por papel:
currentModel.contextPromotionTarget(se configurado)- menor modelo de contexto maior no mesmo provedor + API
Candidatos são ignorados a menos que as credenciais sejam resolvidas (ModelRegistry.getApiKey(...)).
Handoff de websocket do OpenAI Codex
Seção intitulada “Handoff de websocket do OpenAI Codex”Se trocar de/para openai-codex-responses, a chave de estado do provedor da sessão openai-codex-responses é fechada antes da troca de modelo. Isso descarta o estado de transporte websocket para que o próximo turno inicie limpo no modelo promovido.
Comportamento de persistência
Seção intitulada “Comportamento de persistência”A promoção usa troca temporária (setModelTemporary):
- registrada como uma
model_changetemporária no histórico da sessão - não reescreve o mapeamento de papel salvo
Configurando cadeias de fallback explícitas
Seção intitulada “Configurando cadeias de fallback explícitas”Configure o fallback diretamente nos metadados do modelo via contextPromotionTarget.
contextPromotionTarget aceita tanto:
provider/model-id(explícito)model-id(resolvido dentro do provedor atual)
Exemplo (models.yml) para Spark -> não-Spark no mesmo provedor:
providers: openai-codex: modelOverrides: gpt-5.3-codex-spark: contextPromotionTarget: openai-codex/gpt-5.3-codexO gerador de modelos integrado também atribui isso automaticamente para modelos *-spark quando um modelo base do mesmo provedor existe.
Campos de compatibilidade e roteamento
Seção intitulada “Campos de compatibilidade e roteamento”models.yml suporta este subconjunto de compat:
supportsStoresupportsDeveloperRolesupportsReasoningEffortmaxTokensField(max_completion_tokensoumax_tokens)openRouterRouting.only/openRouterRouting.ordervercelGatewayRouting.only/vercelGatewayRouting.order
Estes são consumidos pela lógica de transporte OpenAI-completions e combinados com auto-detecção baseada em URL.
Exemplos práticos
Seção intitulada “Exemplos práticos”Endpoint local compatível com OpenAI (sem autenticação)
Seção intitulada “Endpoint local compatível com OpenAI (sem autenticação)”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 hospedado com chave baseada em variável de ambiente
Seção intitulada “Proxy hospedado com chave baseada em variável de 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]Substituir rota de provedor integrado + metadados do modelo
Seção intitulada “Substituir rota de provedor integrado + metadados do modelo”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]Auto-configuração do proxy LiteLLM
Seção intitulada “Auto-configuração do proxy LiteLLM”Quando ambas as variáveis de ambiente LITELLM_BASE_URL e LITELLM_API_KEY estão definidas, o xcsh gerencia automaticamente a configuração de models.yml para o proxy LiteLLM.
Auto-geração na primeira execução
Seção intitulada “Auto-geração na primeira execução”Se models.yml não existir e as variáveis de ambiente do LiteLLM forem detectadas, o xcsh o gera 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_KEYUm config.yml padrão também é gerado com configurações sensatas de provedor de imagens.
Auto-reparo na inicialização
Seção intitulada “Auto-reparo na inicialização”A cada inicialização, startupHealthCheck() no registro de modelos executa as seguintes verificações:
| Condição | Ação |
|---|---|
models.yml ausente | Auto-gerar a partir das variáveis de ambiente |
models.yml corrompido ou não analisável | Backup para .bak, regenerar |
baseUrl não corresponde ao LITELLM_BASE_URL | Backup para .bak, regenerar com nova URL |
configVersion ausente ou desatualizado | Backup para .bak, regenerar com versão atual |
| Configuração saudável | Nenhuma ação |
Todos os reparos criam backups .bak antes de sobrescrever. Todas as operações são idempotentes.
Comando CLI
Seção intitulada “Comando CLI”xcsh setup litellm # Generate or fix LiteLLM configxcsh setup litellm --check # Validate without writingxcsh setup litellm --check --json # Machine-readable validation outputVariáveis de ambiente obrigatórias
Seção intitulada “Variáveis de ambiente obrigatórias”| Variável | Propósito |
|---|---|
LITELLM_BASE_URL | URL do proxy LiteLLM (ex.: https://your-proxy.example.com). Deve começar com http:// ou https://. |
LITELLM_API_KEY | Chave de API para o proxy. Referenciada por nome na configuração gerada, resolvida em tempo de execução. |
Se qualquer variável não estiver definida, a auto-configuração é silenciosamente ignorada.
Versionamento de configuração
Seção intitulada “Versionamento de configuração”Configurações geradas incluem um campo configVersion. Quando o formato gerado muda em versões futuras, o xcsh detecta configurações desatualizadas e as atualiza automaticamente (com backup).
Ressalva sobre consumidor legado
Seção intitulada “Ressalva sobre consumidor legado”A maioria das configurações de modelo agora flui através de models.yml via ModelRegistry.
Um caminho legado notável permanece: a resolução de autenticação Anthropic para busca web ainda lê ~/.xcsh/agent/models.json diretamente em src/web/search/auth.ts.
Se você depende desse caminho específico, mantenha a compatibilidade com JSON em mente até que esse módulo seja migrado.
Modo de falha
Seção intitulada “Modo de falha”Se models.yml falhar nas verificações de schema ou validação:
- Se
LITELLM_BASE_URLeLITELLM_API_KEYestiverem definidos, a verificação de saúde na inicialização tenta auto-reparo (backup do arquivo corrompido, regeneração a partir das variáveis de ambiente). Se o reparo for bem-sucedido, o registro recarrega a configuração corrigida. - Se o auto-reparo não for possível (variáveis de ambiente não definidas, falha de escrita), o registro continua operando com modelos integrados.
- O erro é exposto via
ModelRegistry.getError()e exibido na UI/notificações.