Skip to content

[AISAGE-733] fix(ai-gateway): only expect is_byok from upstreams that report it - #8875

Merged
chrarnoldus merged 1 commit into
mainfrom
fix/gateway-byok-check-providers
Oct 26, 2026
Merged

chrarnoldus merged 1 commit into
mainfrom
fix/gateway-byok-check-providers

Conversation

@chrarnoldus

@chrarnoldus chrarnoldus commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

"SUSPICIOUS: openrouters cost accounting doesn't make sense" (KILOCODE-WEB-28E4/-28D1, previously -1R) fires when a response has a cost but no is_byok. With BYOK, OpenRouter's cost is only its 5% fee, so a cost without a BYOK status can't be trusted. But the check ran for every upstream.

I sent small requests to each upstream to see which report is_byok next to usage.cost:

Upstream API cost is_byok cost_details.upstream_inference_cost
OpenRouter chat, Messages, Responses, embeddings yes yes yes
OpenRouter transcriptions yes no no
Vercel chat completions yes yes yes
Vercel Messages, Responses, embeddings no (cost is in provider metadata) no no
Martian chat, Messages, Responses yes no no

Most events came from Martian (stealth models), which never reports is_byok. The check now runs only for upstreams that report it (OpenRouter and Vercel), using providerReportsIsByok. The same gating applies to the is_byok is null exception in parseMicrodollarUsageFromString. Billing is unchanged.

OpenRouter transcriptions keep reporting here because their cost really can't be trusted. #8877 fixes that.

Split out of #8791.

Verification

  • pnpm --filter @kilocode/web-shared typecheck
  • jest packages/web-shared/src/lib/ai-gateway/processUsage packages/web-shared/src/lib/ai-gateway/llm-proxy-helpers.test.ts packages/web-shared/src/lib/ai-gateway/handlers/audio-transcriptions
  • New tests: OpenRouter and Vercel usage with a cost but no is_byok is still reported; Martian usage is billed at its reported cost without a report.

Models: Claude Opus 5.5 (kilo/anthropic/claude-opus-5.5), no subagents.

The "openrouters cost accounting doesn't make sense" check treated a cost
without is_byok as broken accounting for every upstream. Probing showed
which upstreams report is_byok next to cost: OpenRouter (chat completions,
Messages, Responses, embeddings) and Vercel AI Gateway (chat completions).
Martian reports cost but never is_byok, so every stealth-model response
raised the report. Billing is unchanged.
@kilo-code-bot

kilo-code-bot Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The change threads the upstream provider through the usage parsers and scopes the is_byok accounting report to OpenRouter and Vercel; all call sites, imports, and the computeOpenRouterCostFields callers were updated consistently, and the cost path itself is unchanged.

Assumptions: [INFERENCE] Vercel chat-completions responses carry both usage.cost and usage.is_byok (taken from the PR's probing table; not verifiable from the repo). processOpenRouterUsage first tests the gated requireIsByok and only afterwards falls back to extractVercelIsByok(provider_metadata) (packages/web-shared/src/lib/ai-gateway/processUsage.ts:1175), so if a Vercel chat response ever reports cost without usage.is_byok, the warning would still fire even though the metadata resolves BYOK status. Also note providerReportsIsByok has no API-kind parameter, while its doc comment says Vercel reports is_byok only on chat completions; this is currently harmless because Vercel Messages/Responses put cost in provider_metadata and never hit the usage.cost branch. Tests/typecheck were not executed in this read-only review.

Files Reviewed (9 files)
  • packages/web-shared/src/lib/ai-gateway/llm-proxy-helpers.test.ts
  • packages/web-shared/src/lib/ai-gateway/llm-proxy-helpers.ts
  • packages/web-shared/src/lib/ai-gateway/processUsage.messages.test.ts
  • packages/web-shared/src/lib/ai-gateway/processUsage.messages.ts
  • packages/web-shared/src/lib/ai-gateway/processUsage.responses.test.ts
  • packages/web-shared/src/lib/ai-gateway/processUsage.responses.ts
  • packages/web-shared/src/lib/ai-gateway/processUsage.shared.ts
  • packages/web-shared/src/lib/ai-gateway/processUsage.test.ts
  • packages/web-shared/src/lib/ai-gateway/processUsage.ts

Reviewed by deepseek-flash-latest · Input: 72.9K · Output: 15.2K · Cached: 1.6M

Review guidance: REVIEW.md from base branch main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants