ADR 0225 — O OpenRouter recebe um teto de preço por chamada (provider.max_price = catálogo × 1,5)
Status
Accepted. 2026-10-28 (AT-606, EP-026, decisões do dono de 27/10). Tema: llm.
Estende o 0166 (que só
mandava provider.sort e deixava max_price como decisão de produto própria)
e convive com o 0221 (session_id), sem
editar nenhum dos dois. Segue o
0041: a
capability só vira true com prova contra a API real.
Contexto
Na 18ª rodada do TP-01, o deepseek/deepseek-v4.1-flash passou por 17
upstreams e o custo real foi 1,85× o de catálogo; o custo por milhão de entrada
variou de US$ 0,044 a 0,268. O session_id do 0221 prende o agente ao upstream
que o atendeu, mas pode prendê-lo a um upstream CARO (o Together, onde o smoke
da AT-580 grudou, custa 2,1× a entrada e 2,9× a saída do catálogo). O
provider.max_price do OpenRouter é um FILTRO por preço (US$ por milhão,
entrada e saída) que se combina com o sort, que é uma ORDEM.
Decisão
- O Brabo manda
provider.max_price = { prompt, completion }= preço de catálogo do modelo × 1,5, por chamada, nas chamadas ao OpenRouter (StreamLlmTurnUseCase,RunLlmTurnUseCase,SendChatMessageUseCase). O fator (FATOR_DO_TETO_DE_PRECO) é fixo no código e ligado por padrão em todo modelo com preço de catálogo > 0 nas duas pontas; preço 0 (desconhecido) não manda teto. Com 1,5 passam cerca de 11 dos 41 endpoints do deepseek, e ficam de fora o Together e os de US$ 0,30+. Mudar o fator é ADR novo. - Capability nova
priceCeilingemLLMProviderCapabilities,falsenos nove outros providers etrueno OpenRouter depois do smokeopenrouter-provider.teto.smoke.spec.ts. Declará-la sem o hookcampoDeTetoDePrecofalha na construção. O objetoproviderdo teto é MESCLADO com o dosort(espalhá-los lado a lado apagaria osort). - 404 por nenhum upstream no teto: o 404 de uma chamada que levava teto vira
o erro NOMEADO
LLMPriceCeilingError(code: price_ceiling), distinto deLLMModelNotFoundError. Os três casos de uso repetem UMA vez sem teto (no mesmo laço da RN-916), gravamtoken_usage.price_ceiling_factornulo nessa linha e avisam no log; o turno não falha por política de custo. - Metering:
token_usage.price_ceiling_factor(real, nulável) congela o fator que FOI AO FIO, no molde dorouting_preference(RN-583).null= nada enviado. - Fora: filtro de quantização (a qualidade por upstream não foi medida e
seria um segundo critério),
provider.only/ignore(lista curada por modelo fica velha sozinha e pede mapa nome→slug) eorder(desliga o sticky). O Jev (ADR 0179) não recebe o teto.
Consequências
- O
sortescolhe a ordem entre os baratos; osession_idmantém o upstream; o teto tira os caros do sorteio quando o grude cai. - Preço de catálogo velho ou manual (
manual_pricing) dá teto errado; sem upstream no teto, a repetição sem teto mede o excesso (linha com fator nulo). - O DTO de
GET /llm/provider-capabilitiesganhapriceCeiling.