Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/codex/catalog/model-hints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -582,10 +582,11 @@ function discoveredPricingRate(value: unknown): number | undefined {
/**
* Cost class for one discovered row, read from the provider's own `pricing` object (#3666).
*
* Fail closed. Only a complete pair of non-negative numeric rates classifies at all; a missing,
* one-sided, non-numeric, or negative rate is "unknown" and therefore excluded from a free-only
* filter. Showing a paid model under a Free filter spends the user's money, while hiding a free
* one costs a click.
* Fail closed. Any positive numeric component proves the model is paid. Calling it free requires
* a complete prompt/completion pair and every published pricing component to be a non-negative
* numeric zero; an unsupported component is "unknown" because it may describe another charge.
* Showing a paid model under a Free filter spends the user's money, while hiding a free one costs
* a click.
*
* Two things that look like evidence and are not. A `:free` id suffix is an OpenRouter naming
* convention, not a price — Nous ships `:free` slugs on a provider whose `freeTier` is false on
Expand All @@ -598,10 +599,13 @@ function discoveredPricingRate(value: unknown): number | undefined {
export function discoveredPricingStatus(item: ProviderModelsApiItem): "free" | "paid" | "unknown" {
const pricing = plainRecord(item.pricing) ?? plainRecord(plainRecord(item.metadata)?.pricing);
if (!pricing) return "unknown";
const rates = Object.values(pricing).map(discoveredPricingRate);
if (rates.some(rate => rate !== undefined && rate > 0)) return "paid";
if (rates.some(rate => rate === undefined)) return "unknown";
const prompt = discoveredPricingRate(pricing.prompt ?? pricing.input);
const completion = discoveredPricingRate(pricing.completion ?? pricing.output);
if (prompt === undefined || completion === undefined) return "unknown";
return prompt === 0 && completion === 0 ? "free" : "paid";
return "free";
}

export function catalogHintsFromModelsApiItem(providerName: string, item: ProviderModelsApiItem): Partial<CatalogModel> {
Expand Down
22 changes: 22 additions & 0 deletions tests/codex-integration/catalog-free-pricing-status.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,28 @@ describe("discovered model pricing classification (#3666)", () => {
expect(discoveredPricingStatus({ id: "half2", pricing: { prompt: "1e-6", completion: "0" } })).toBe("paid");
});

test("auxiliary charges prevent a model from classifying free", () => {
expect(discoveredPricingStatus({
id: "request-charge",
pricing: { prompt: "0", completion: "0", request: "0.05" },
})).toBe("paid");
expect(discoveredPricingStatus({
id: "free-all-dimensions",
pricing: { prompt: "0", completion: "0", request: 0, image: "0", web_search: "0.0" },
})).toBe("free");
});

test("unsupported auxiliary pricing stays unknown rather than classifying free", () => {
expect(discoveredPricingStatus({
id: "unsupported-charge",
pricing: { prompt: 0, completion: 0, request: { amount: "0.05" } },
})).toBe("unknown");
expect(discoveredPricingStatus({
id: "invalid-auxiliary",
pricing: { prompt: 0, completion: 0, image: -1 },
})).toBe("unknown");
});

test("a provider that publishes no pricing is unknown, and the hint field is absent", () => {
expect(discoveredPricingStatus({ id: "llama3.2" })).toBe("unknown");
// Absent rather than present-and-"unknown": catalogHintsFromModelsApiItem's contract is that
Expand Down
Loading