While looking into Discord reports of inflated usage ("token counts so inflated that it's literally impossible", credit burn far above comparable subscriptions), I traced the SDK's credit calculation and found what looks like a real double-count on every OpenRouter-served request.
The bug
All three cost paths sum usage.cost and usage.cost_details.upstream_inference_cost:
sdk/src/impl/llm.ts:394-396 (reportCost, streaming path)
sdk/src/impl/llm.ts:733-737 (non-stream generateText path)
sdk/src/impl/llm.ts:804-808 (non-stream Responses path)
costOverrideDollars =
(openrouterUsage.cost ?? 0) +
(openrouterUsage.costDetails?.upstreamInferenceCost ?? 0)
That total feeds calculateUsedCredits (sdk/src/impl/llm.ts:62-65) → onCostCalculated, i.e. the credits actually charged/shown to the user.
Per OpenRouter's usage accounting docs, usage.cost is "the total amount charged to your account" and cost_details.upstream_inference_cost is "the actual cost charged by the upstream AI provider" — the upstream component of that total, not an additional amount. On a normal (non-BYOK) OpenRouter route, upstream inference is nearly all of cost, so cost + upstream roughly doubles the true spend before the margin is applied. For a model where upstream is 90% of the total, credits come out ~1.9× too high — which matches the "extreme inflation" reports much better than token counts alone do.
The repo already documents the correct semantics
common/src/constants/freebuff-models.ts:313-320 (the Solar Pro 4 BYOK note): on BYOK routes top-level usage.cost is 0 and the real spend arrives in cost_details.upstream_inference_cost, and "extractUsageAndCost takes the max of the two, so the ledger is right; a naive read of cost is not". So the server-side ledger takes max(cost, upstream) — correct for both shapes — while the SDK's user-facing credit path sums them, which is only correct in the BYOK shape (cost = 0) and double-counts in the common shape.
Suggested fix
Take the max at all three sites, matching the ledger's documented semantics:
costOverrideDollars = Math.max(
openrouterUsage.cost ?? 0,
openrouterUsage.costDetails?.upstreamInferenceCost ?? 0,
)
Happy to open a PR.
Related (not this bug, but likely behind the "millions of input tokens" half of the reports)
- Cumulative per-request
inputTokens includes cache-read tokens at full weight (sdk/src/impl/llm.ts:168-197), and every agent step re-sends the full context (packages/agent-runtime/src/run-agent-step.ts:518), so summed input grows quadratically with steps even when billed credits don't (cache discounts cost, not the reported token figure). "Millions on simple tasks" is what that math produces for any multi-step task with real file context.
- Subagent usage is both rolled into the parent's
creditsUsed (packages/agent-runtime/src/tools/handlers/tool/spawn-agents.ts:218-253) and written as its own run row — any consumer summing rows across the run tree counts each subagent twice. Backend display code is outside this repo, so this may or may not affect what users see.
While looking into Discord reports of inflated usage ("token counts so inflated that it's literally impossible", credit burn far above comparable subscriptions), I traced the SDK's credit calculation and found what looks like a real double-count on every OpenRouter-served request.
The bug
All three cost paths sum
usage.costandusage.cost_details.upstream_inference_cost:sdk/src/impl/llm.ts:394-396(reportCost, streaming path)sdk/src/impl/llm.ts:733-737(non-streamgenerateTextpath)sdk/src/impl/llm.ts:804-808(non-stream Responses path)That total feeds
calculateUsedCredits(sdk/src/impl/llm.ts:62-65) →onCostCalculated, i.e. the credits actually charged/shown to the user.Per OpenRouter's usage accounting docs,
usage.costis "the total amount charged to your account" andcost_details.upstream_inference_costis "the actual cost charged by the upstream AI provider" — the upstream component of that total, not an additional amount. On a normal (non-BYOK) OpenRouter route, upstream inference is nearly all ofcost, socost + upstreamroughly doubles the true spend before the margin is applied. For a model where upstream is 90% of the total, credits come out ~1.9× too high — which matches the "extreme inflation" reports much better than token counts alone do.The repo already documents the correct semantics
common/src/constants/freebuff-models.ts:313-320(the Solar Pro 4 BYOK note): on BYOK routes top-levelusage.costis 0 and the real spend arrives incost_details.upstream_inference_cost, and "extractUsageAndCost takes the max of the two, so the ledger is right; a naive read ofcostis not". So the server-side ledger takes max(cost, upstream) — correct for both shapes — while the SDK's user-facing credit path sums them, which is only correct in the BYOK shape (cost = 0) and double-counts in the common shape.Suggested fix
Take the max at all three sites, matching the ledger's documented semantics:
Happy to open a PR.
Related (not this bug, but likely behind the "millions of input tokens" half of the reports)
inputTokensincludes cache-read tokens at full weight (sdk/src/impl/llm.ts:168-197), and every agent step re-sends the full context (packages/agent-runtime/src/run-agent-step.ts:518), so summed input grows quadratically with steps even when billed credits don't (cache discounts cost, not the reported token figure). "Millions on simple tasks" is what that math produces for any multi-step task with real file context.creditsUsed(packages/agent-runtime/src/tools/handlers/tool/spawn-agents.ts:218-253) and written as its own run row — any consumer summing rows across the run tree counts each subagent twice. Backend display code is outside this repo, so this may or may not affect what users see.