-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Show cache read and write prices for OpenRouter inference providers #7176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your contribution! I've reviewed the changes and they look good overall. The implementation correctly addresses the cache support detection issues and improves provider identification. I have a few minor suggestions for improvement.
@@ -188,7 +189,7 @@ export const parseOpenRouterModel = ({ | |||
|
|||
const cacheReadsPrice = model.pricing?.input_cache_read ? parseApiPrice(model.pricing?.input_cache_read) : undefined | |||
|
|||
const supportsPromptCache = typeof cacheWritesPrice !== "undefined" && typeof cacheReadsPrice !== "undefined" | |||
const supportsPromptCache = typeof cacheReadsPrice !== "undefined" // some models support caching but don't charge a cacheWritesPrice, e.g. GPT-5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we make this comment more descriptive? Consider:
const supportsPromptCache = typeof cacheReadsPrice !== "undefined" // some models support caching but don't charge a cacheWritesPrice, e.g. GPT-5 | |
const supportsPromptCache = typeof cacheReadsPrice !== "undefined" // OpenRouter reports cache support based on read price only, as some models support caching without charging for cache writes (e.g. GPT-5) |
@@ -24,6 +24,7 @@ describe("OpenRouter API", () => { | |||
const models = await getOpenRouterModels() | |||
|
|||
const openRouterSupportedCaching = Object.entries(models) | |||
.filter(([id, _]) => id.startsWith("anthropic/claude") || id.startsWith("google/gemini")) // only these support cache_control breakpoints (https://openrouter.ai/docs/features/prompt-caching) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be helpful to expand this comment to explain the cache_control limitation more clearly? Something like:
.filter(([id, _]) => id.startsWith("anthropic/claude") || id.startsWith("google/gemini")) // only these support cache_control breakpoints (https://openrouter.ai/docs/features/prompt-caching) | |
.filter(([id, _]) => id.startsWith("anthropic/claude") || id.startsWith("google/gemini")) // Only Anthropic Claude and Google Gemini models support cache_control breakpoints for explicit cache management (https://openrouter.ai/docs/features/prompt-caching) |
|
||
for (const endpoint of endpoints) { | ||
const providerName = endpoint.name.split("|")[0].trim() | ||
const providerName = endpoint.tag ?? endpoint.name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency with the backend implementation, consider adding a comment explaining the fallback logic:
const providerName = endpoint.tag ?? endpoint.name | |
const providerName = endpoint.tag ?? endpoint.name // Use unique tag when available, fallback to name for backward compatibility |
@@ -149,7 +150,7 @@ export async function getOpenRouterModelEndpoints( | |||
const { id, architecture, endpoints } = data | |||
|
|||
for (const endpoint of endpoints) { | |||
models[endpoint.provider_name] = parseOpenRouterModel({ | |||
models[endpoint.tag ?? endpoint.provider_name] = parseOpenRouterModel({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this fallback to endpoint.provider_name
intentional for backward compatibility? If the OpenRouter API doesn't always provide tags, this is a good defensive approach.
Related GitHub Issue
Upstreaming some changes from Kilo Code: Kilo-Org/kilocode#1893, Kilo-Org/kilocode#1940
Description
Fixes OpenRouters models that don't list a cache write price, but do support caching showing as "Does not support prompt caching" (e.g. GPT-5).
Fixes all models showing as "Supports prompt caching" when a specific inference provider is selected, even when they don't support prompt caching.
For specific inference providers, show the cache read and write prices from the OpenRouter metadata.
Use the unique tag for inference providers, rather than the non-unique provider_name.
Test Procedure
Go into the API Providers settings, select OpenRouter and verify all displayed info is correct:
Pre-Submission Checklist
Screenshots / Videos
Before
GPT-5 shown as not supporting prompt caching even though it does:
Qwen3 Coder with DeepInfra inference provider showing it does support prompt caching even though it doesn't:
Inference provider list for Sonnet 4 being incomplete, because the names are not unique:
After
GPT-5 shown as supporting prompt caching:
Qwen3 Coder with DeepInfra inference provider shown as not supporting prompt caching:
GLM 4.5 metadata without specific inference provider selected:
GLM 4.5 metadata with Z.AI selected as inference provider, which supports prompt caching:
Entire list of Sonnet 4 providers shown with unique tags:
Additional Notes
Some of the fields in the OpenRouter metadata are not documented. I have pinged our OpenRouter reps to update the docs.
Get in Touch
Christiaan in shared Slack
Important
Fixes cache support and pricing display for OpenRouter models, using unique tags for provider identification.
openrouter.ts
.useOpenRouterModelProviders.ts
.useOpenRouterModelProviders.ts
.tag
field toopenRouterModelEndpointSchema
inopenrouter.ts
anduseOpenRouterModelProviders.ts
.parseOpenRouterModel
to usetag
for provider identification inopenrouter.ts
.openrouter.spec.ts
to reflect changes in cache support and provider identification.This description was created by
for 4733f15. You can customize this summary. It will automatically update as commits are pushed.