Ids de modelo não pertencem ao TypeScript
· 6 min de leitura
Um id de modelo é o fato que muda mais rápido em todo este sistema. Os fornecedores os renomeiam, os aposentam, lançam uma variante datada, mudam discretamente para onde aponta o alias sem data e restringem metade deles conforme a conta que está pedindo. Compile isso em um pacote e você garantiu que o pacote estará errado em poucas semanas — não quebrado de um jeito óbvio, o que pelo menos geraria um relato de bug, mas errado justamente do jeito em que um seletor oferece a alguém um modelo que a chave dessa pessoa não consegue chamar.
Por isso o catálogo é um arquivo JSON, e a parte interessante não é ele ser JSON. É o que a separação em camadas por baixo dele admite sobre certeza.
Cinco camadas, as posteriores vencem as anteriores
0. pi-ai's built-in models whatever it knows about the catalogued vendors
1. the bundled catalog.json 27 providers, 6 verified models
2. ~/.oharness/catalog.json your edits, and what discovery found
3. a catalog path in config
4. providers / models in config
5. /models refresh asks the vendor directly
Leia essa coluna de números como um ranking de confiança, e não como uma ordem de carregamento. A camada 0 é o retrato do mundo feito por outra pessoa. A camada 1 é o que estávamos dispostos a afirmar diretamente. A camada 5 é o fornecedor respondendo sobre a sua conta, agora mesmo — e ela vence, porque nada que publicamos três meses atrás sabe mais sobre os seus direitos de acesso do que o endpoint que você está prestes a chamar.
A camada embutida traz vinte e sete provedores e seis modelos verificados, e essa proporção é o design inteiro. Os fatos sobre provedores — o endpoint, a variável de ambiente, o protocolo de transmissão — são estáveis o bastante para serem distribuídos. Ids de modelo não são, então os únicos afirmados diretamente são os que de fato puderam ser verificados, e todo o resto chega pela descoberta, que consulta o próprio /models de cada fornecedor.
Seis é um número desconfortável de publicar. Também é o honesto.
Sobrescritas são por campo
O motivo de isso importar no dia a dia é menor e mais banal: apontar o Kimi para o endpoint da China continental não deveria exigir repetir todo o resto sobre o Kimi.
{ "providers": { "moonshot": { "baseUrl": "https://api.moonshot.cn/v1" } } }
Essa é a edição inteira. Sobrescritas de entradas inteiras são a forma como formatos de configuração apodrecem — uma pessoa copia o bloco distribuído para mudar uma URL e, duas versões depois, a cópia dela é a única coisa entre ela e uma correção que todos os outros já receberam.
Onde a semente para
A camada 0 merece uma observação, porque é a que surpreende as pessoas: um provedor que você nunca conectou já tem modelos para mostrar. Eles vêm do pi-ai, a camada de transmissão, que distribui um catálogo gerado do que conhece. Eles trazem janelas de contexto, preços e níveis de raciocínio, e não sabem absolutamente nada sobre o que a sua conta pode chamar — por isso uma entrada declarada e qualquer coisa que a descoberta retorne vencem ambas sobre eles, e OHARNESS_NO_BUILTIN_MODELS=1 desliga a semente por completo.
Dois limites impedem que essa semente cause estragos.
Um modelo só é semeado em uma entrada cujo protocolo corresponde à API com que o pi-ai o cataloga. Os modelos da Mistral estão listados contra a API de conversations do próprio pi-ai, então ficam a cargo da descoberta, em vez de serem enviados a um endpoint compatível com OpenAI em um formato que ele não fala. Enviar o formato errado é um 400 que você vai ter de depurar, e não uma resposta degradada com a qual dá para conviver.
E, quando os dois catálogos discordam sobre o id de um fornecedor, eles são reconciliados nomeando o outro, e não por adivinhação:
{ "providers": { "moonshot": { "piProvider": "moonshotai" } } }
Um provedor sem semente e ainda sem descoberta — um servidor local, um gateway cujos nomes ninguém embute — continua aparecendo no seletor como uma única linha que abre o painel onde você o conecta. Um estado vazio que se explica é melhor do que um provedor que simplesmente não aparece até que alguma condição invisível seja atendida.
O protocolo é a única coisa que vale nomear
O protocol de uma entrada do catálogo nomeia o formato que o endpoint dela fala:
anthropic-messages openai-chat openai-responses
gemini bedrock vertex
openai-codex
openai-codex é o que justifica manter essa lista explícita, em vez de inferi-la do nome de um fornecedor. É o backend com que a Codex CLI conversa, e é um formato de transmissão genuinamente diferente de openai-responses, e não o mesmo em outro host: store é recusado, max_output_tokens não é enviado e o id da conta viaja em um cabeçalho próprio. Um sistema que chutasse “é OpenAI, use o formato da OpenAI” estaria errado sobre ele de três formas diferentes.
Os SDKs por trás deles são importados sob demanda, então uma sessão que só conversa com a Anthropic nunca carrega os clientes da AWS ou do Google.
O que não mudou
Autenticação. As credenciais são resolvidas a cada requisição pelo próprio AuthManager do harness, porque um token de assinatura válido na inicialização não é válido uma hora depois. Por isso as implementações de API do pi-ai são chamadas diretamente e recebem uma chave e cabeçalhos já resolvidos, em vez de passarem pela autenticação de provedores e pelo armazenamento de credenciais dele.
É por isso que algumas entradas nem são distribuídas. Bedrock e Vertex funcionam como protocolos, mas só com credenciais já presentes no ambiente — a assinatura SigV4 completa e o gcloud ADC ficam exatamente na camada de provedores que este harness se recusa a usar para autenticação. O Azure OpenAI não tem uma URL base fixa para catalogar, porque o endpoint é por implantação. Ambos podem ser declarados por qualquer pessoa cujo ambiente já esteja configurado; nenhum deles vai ser distribuído como um padrão funcional que, discretamente, não funciona.
O padrão por trás de tudo isso: afirme os fatos que ficam parados, pergunte sobre os que não ficam e mantenha a diferença visível no arquivo, em vez de enterrada em uma nota de versão.
O OHarness é um harness de agentes open source, sob licença MIT. A referência de provedores documenta cada camada, sobrescrita e protocolo acima, e o hub de provedores lista o que vem no catálogo embutido hoje.