Add reported cost support for OpenRouter usage - #449
Open
bozhnyukAlex wants to merge 3 commits into
Open
Conversation
bozhnyukAlex
marked this pull request as ready for review
July 2, 2026 17:00
There was a problem hiding this comment.
1 issue found across 20 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Member
|
Interesting idea @bozhnyukAlex and I agree we should prefer provider cost when we are given that information. I was doing something similar in Pydantic AI for this but I don't mind this. Let me think about it a bit more on how this should look like. Thanks for working on it |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds support for provider-reported total costs and wires it into OpenRouter usage extraction.
For OpenRouter:
usage.costExtractedUsage.calc_price()prefers the reported total cost when presentWhy
OpenRouter can return the actual billed cost in
usage.cost. Recalculating from static model prices can be inaccurate because OpenRouter routing, native token accounting, and billing details may differ from the static price table.Refs #239. Related to #345/#350: this extends OpenRouter usage extraction support to the Responses API flavor as well.
Notes
OpenRouter reports a total cost, not a full input/output price breakdown. When a reported total cost is present,
total_priceis authoritative andprice_sourceis set toreported.The input/output split works as follows:
For example, if static pricing gives
input_price=0.0002,output_price=0.0008,total_price=0.0010, then input is 20% and output is 80%. A reported OpenRouter total of0.0015becomesinput_price=0.0003,output_price=0.0012,total_price=0.0015.output_pricewhen the usage only has output tokens; otherwise it is assigned toinput_price.This makes
total_pricematch OpenRouter's actual billed cost while preserving the existing invariantinput_price + output_price == total_price.The split is intentionally best-effort. OpenRouter's
usage.costis the reliable billing value, but the response does not currently provide an authoritative input/output cost breakdown. Keeping a proportional split avoids breaking existing callers that expect non-null input/output prices and a consistent total, without pretending that the derived breakdown is the source of billing truth.E2E smoke checks
Also verified the public extraction-to-pricing path locally for both packages:
extract_usage(..., provider_id='openrouter', api_flavor='chat').calc_price()usesusage.costas the reportedtotal_price.extract_usage(..., provider_id='openrouter', api_flavor='responses').calc_price()usesusage.costas the reportedtotal_price.findProvider -> extractUsage -> calcPrice(..., { reportedTotalPrice })produces the same reported totals for OpenRouter chat and responses payloads.usage.coststill fall back to calculated static pricing.Validation
make buildmake lintmake typecheckmake testnpm run cinpm run typecheckSKIP=no-commit-to-branch uvx pre-commit run --all-files --verbose