Skip to content

fix(pricing): map LiteLLM's opencode_go bucket to the opencode-go provider - #18644

Merged
diegosouzapw merged 6 commits into
cheaper-inference:release/v3.8.53from
yourspraveen:fix/18598-pricing-bucket
Nov 4, 2026
Merged

diegosouzapw merged 6 commits into
cheaper-inference:release/v3.8.53from
yourspraveen:fix/18598-pricing-bucket

Conversation

@yourspraveen

@yourspraveen yourspraveen commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Summary

LiteLLM files OpenCode Go prices under the opencode_go provider. LITELLM_PROVIDER_MAP in src/lib/pricingSync.ts had no entry for that name, so transformToOmniRoute stored the 30 models under opencode_go, a key no cost lookup uses. The registry alias is opencode-go, so every opencode-go request came back unpriced: $0 on the x-omniroute-response-cost header and in usage history, and an unpriced window for the USD quota gate.

This adds opencode_go: ["opencode-go"] to the map.

Existing installs also have a pricing_synced row stored under opencode_go by an earlier sync, which stays unpriced until the next successful sync replaces it (it heals at startup with PRICING_SYNC_ENABLED=true, but not on installs that sync by hand). The map now lives in src/lib/litellmProviderMap.ts, and both synced-pricing readers (getSyncedPricing and the cost layers in getPricingLayers) re-apply it to such historical rows, so they price requests right away. A row already stored under opencode-go wins, model by model. Thanks @trespassmk for spotting this.

Related Issues

Refs #18598 (the OpenCode Go half; the Ollama Cloud and pricing-override parts stay open). Related: draft #18641 by @trespassmk covers the same report with wider surface coverage.

Out of scope:

  • Ollama Cloud is not a mapping bug. LiteLLM has no priced Ollama Cloud models; its ollama bucket holds 29 local models, all at $0. models.dev does price them, and its existing mapping (ollama-cloud) already works once models.dev sync is turned on (Settings > AI; off by default).
  • The PATCH /api/pricing override claim in the issue was not looked at here.

Target Branch

  • Base is the active release/v3.8.x branch (release/v3.8.53), not main

Validation

Reproduced on release/v3.8.53 (b2a6410) against an isolated DATA_DIR, loading today's real LiteLLM and models.dev price files through transformToOmniRoute → saveSyncedPricing → calculateCostDetailed (1M input + 1M output tokens):

Setup openrouter/openai/gpt-oss-120b (control) opencode-go/glm-5.2 ollama-cloud/deepseek-v4.1-flash
LiteLLM sync only (the reporter's setup), before $0.75, priced $0, unpriced $0, unpriced
LiteLLM sync only, after $0.75, priced $5.80, priced $0, unpriced (no LiteLLM price)
LiteLLM + models.dev sync $0.75, priced $5.80, priced $0.75, priced

$5.80 matches LiteLLM's price for glm-5.2 ($1.40 input / $4.40 output per million tokens).

  • Change type: pricing sync / cost attribution
  • Focused tests: the new test file fails before each fix and passes after (2/2 for the map entry, 2/2 for historical rows). 1,690 of 1,691 tests across the *pric*, *cost*, *usage-limit* and *catalog* unit suites pass; the remaining one (model-select-field-catalog-vision-10809) fails locally only because this worktree's node_modules predates @radix-ui/react-select.
  • typecheck:core clean; ESLint --max-warnings 0 clean on the changed files
  • quality.yml gates run locally against the merge-base: all pass except provider-asset-provenance (the base's config/quality/provider-assets-provenance.jsonl names audited commit ca7fc3f5ff, which is on no upstream branch), mutation-test-coverage (5 unrelated tests missing from stryker.conf.json), dashboard-typecheck (errors in ui-kit, logs/page.tsx, ProxyRegistryManager.tsx and shared components, none touched here), agent-skills-sync (4 unrelated generated skills) and workflows (actionlint/zizmor not installed locally; no workflow changes). All are inherited from the base.
  • Production-code changes include a new automated test

Tests Added Or Updated

  • tests/unit/pricing-sync-opencode-go-18598.test.ts: the transform stores opencode_go entries under opencode-go; calculateCostDetailed("opencode-go", "glm-5.2", …) prices a request from LiteLLM-synced pricing on a real DB; a DB holding only a historical opencode_go row still prices it; and an existing opencode-go row wins over a historical one.

Coverage Notes

Both the new map entry and remapHistoricalLitellmRows are covered by the four tests.

…vider

LiteLLM files OpenCode Go prices under opencode_go, which had no
LITELLM_PROVIDER_MAP entry, so the sync stored them under a key no cost
lookup reads and every opencode-go request was booked as unpriced $0.

Fixes cheaper-inference#18598
@trespassmk

Copy link
Copy Markdown
Contributor

Thanks for working on this. I independently opened #18641 for the same report and am keeping it draft while we coordinate.

This PR fixes the fresh LiteLLM transform path. One existing-install edge remains: the regression test transforms and then saves canonical data, but does not seed a historical pricing_synced/opencode_go row. Databases that already contain that row remain unpriced until another successful LiteLLM sync. Could we either normalize that verified alias on read or explicitly require and test a resync after upgrade? #18641 includes a historical-row reproduction plus cost/header, catalog, source-map, quota, override/reset, and cache-identity coverage that may be useful.

Two scope notes before merge:

  • Fixes #18598 would auto-close the entire issue, although Ollama Cloud and the reported override behavior are out of scope here. Refs #18598 would preserve that remainder.
  • The models.dev API exposes the Ollama Cloud base/off-peak values but omits its source tariff's weekday 12:00–18:00 UTC 2× multiplier. OmniRoute currently ingests only static rates, so the $0.75 row demonstrates a lookup but not schedule-correct automatic Ollama Cloud billing.

I am happy to leave #18641 draft and reconcile the unique historical-data coverage whichever way maintainers prefer.

…ed as opencode_go

A sync that ran before the opencode_go map entry left its bucket under the
raw LiteLLM name, so existing installs stayed unpriced until the next sync.
The provider map moves to its own module, and both synced-pricing readers
re-apply it to such historical rows; rows under the mapped alias still win.

Refs cheaper-inference#18598
@yourspraveen

Copy link
Copy Markdown
Contributor Author

@trespassmk thanks, good catch on the historical row. I reproduced it on this branch: with only a pricing_synced/opencode_go row in the DB, opencode-go/glm-5.2 came back unpriced ($0), and one fresh sync fixed it ($5.80 for 1M in + 1M out). Since each sync replaces the whole namespace, PRICING_SYNC_ENABLED=true installs heal at startup, but installs that sync by hand from the dashboard stay unpriced until someone clicks Sync Now.

a8e778e normalizes on read instead of requiring a resync: the provider map moved to src/lib/litellmProviderMap.ts, and both synced-pricing readers (getSyncedPricing and the cost layers in getPricingLayers) re-apply it to rows stored under a raw LiteLLM name. A row already under opencode-go wins, model by model. Two new tests cover a historical-only DB and the precedence case.

On scope:

  • Agreed, the body now says Refs #18598, so the Ollama Cloud and override parts stay open.
  • On Ollama Cloud: fair point. I only checked that the models.dev path finds a price (the base rate). I haven't verified the weekday 12:00–18:00 UTC multiplier, but if it applies, models.dev sync gives base-rate costs during those hours rather than schedule-correct billing. I'll add that note on the issue.

This PR stays the minimal fix for the OpenCode Go lookup; #18641 has the wider surface coverage (header, catalog, source map, quota, override/reset). Happy for the maintainers to pick either one or combine them.

@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Summary

Summary by CodeRabbit

  • Bug Fixes
    • OpenCode Go requests are now priced using LiteLLM-synced rates rather than being recorded as unpriced at $0.
    • Pricing for historical LiteLLM entries is now recognized across supported provider aliases. Existing alias-specific prices continue to take precedence for matching models, while historical entries can provide prices for other models.

LiteLLM provider aliases are now shared across pricing code. Historical LiteLLM rows are remapped to their aliases when pricing is loaded. Added tests cover OpenCode Go pricing and alias precedence.

Changes: LiteLLM pricing aliases

Layer / File(s) Summary
Shared provider aliases and remapping
src/lib/litellmProviderMap.ts, src/lib/pricingSync.ts
A shared provider map and remapping helper replace the local map in pricingSync. Historical rows are copied to aliases, while existing alias values take precedence for matching models.
Pricing load integration and regression tests
src/lib/db/settings/pricing.ts, src/lib/pricingSync.ts, tests/unit/pricing-sync-opencode-go-18598.test.ts, changelog.d/fixes/18644-opencode-go-litellm-bucket.md
Both pricing load paths remap historical rows. Tests cover OpenCode Go alias transformation, per-million-token pricing, and precedence when both aliases contain data. The changelog describes the reported $0 pricing behavior and its restoration.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: Minimal · up to 0cc52

Historical LiteLLM prices are available through provider aliases. No merge-blocking risk was identified.

Security architecture risk: Low · up to 0cc52

The change restores pricing while preserving existing overrides and storage transactions. No new external endpoint or permission expansion was identified. Limited uncertainty remains about precedence when multiple historical sources contain conflicting prices for the same model.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — Within a deployment sharing the pricing database, affected alias/model prices can influence cost calculations for every API key using those models. Spending aggregation remains scoped by API-key identity; no identity or authorization change was identified in this path.

Trust Boundaries and Controls

  • observed — The newly interpreted input is persisted sync-owned pricing, not a newly accepted request payload. Alias destinations come from the predefined map, and normalization does not overwrite existing alias entries or bypass higher-priority user pricing.

Resilience and Maintainability Implications

  • observed — Dry runs skip saving, fetch or transformation failures occur before replacement, and delete-plus-insert replacement remains transactional. Post-commit backup and invalidation ordering is unchanged; the remapper adds no new durable recovery state.

Hardening Proposals

  • proposed — Define the intended precedence when multiple historical buckets map to the same alias and model, including whether it should match fresh-sync overwrite semantics. This would reduce future spending-control drift; conflicting deployed prices were not established.
Pre-merge checks: Passed 6 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
No Ai Attribution Inconclusive All six commits and the PR title pass the repository AI-attribution scan. The supplied PR body is explicitly truncated, and no full PR event payload or body file is available in the checkout. The omit… Provide the complete PR body or GitHub pull_request event payload, then scan it for AI/bot Co-Authored-By trailers and AI-generation footers.
Passed Passed checks: 6 passed
Check name Status Explanation
Title check Passed The title follows Conventional Commits with type fix and scope pricing. It names the main change: mapping LiteLLM's opencode_go bucket to the opencode-go provider, which the changeset does through the…
Description check Passed The description covers the core of the template. It has a Summary that explains the root cause and fix, a Related Issues section (Refs #18598), a Target Branch checklist, a Validation section with rep…
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Tests For Production Code Passed PASS: The PR changes production code under src/ in three files and adds tests/unit/pricing-sync-opencode-go-18598.test.ts. The added tests cover the new opencode_go mapping, pricing from synced …
Full details: Title check

Explanation

The title follows Conventional Commits with type fix and scope pricing. It names the main change: mapping LiteLLM's opencode_go bucket to the opencode-go provider, which the changeset does through the new LITELLM_PROVIDER_MAP entry and historical-row remapping.

Full details: Description check

Explanation

The description covers the core of the template. It has a Summary that explains the root cause and fix, a Related Issues section (Refs #18598), a Target Branch checklist, a Validation section with reproduction tables and checks, a Tests Added Or Updated section, and a Coverage Notes section. The Reviewer Notes section is missing. The Coverage Notes section does not explain coverage of the full pricing paths, and the Target Branch checklist omits the v4-feature note, which is not required for a fix.

Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 2 functions across 4 files. (1 skipped: 1 unsupported.)

Full details: Tests For Production Code

Explanation

PASS: The PR changes production code under src/ in three files and adds tests/unit/pricing-sync-opencode-go-18598.test.ts. The added tests cover the new opencode_go mapping, pricing from synced data, historical rows, and precedence behavior.

Full details: No Ai Attribution

Explanation

All six commits and the PR title pass the repository AI-attribution scan. The supplied PR body is explicitly truncated, and no full PR event payload or body file is available in the checkout. The omitted body could contain a forbidden AI footer, so the complete check cannot be decided.

Resolution

Provide the complete PR body or GitHub pull_request event payload, then scan it for AI/bot Co-Authored-By trailers and AI-generation footers.

Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Usage-based review receipt

  • Mode: Continue automatically
  • Reviewed files: 5
  • Waived: $1.25 (charged $0.00)
  • View usage details

Note

This review exceeded your plan’s limits and used usage-based reviews—free during trial, billed after paid activation unless disabled. Manage usage-based reviews.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between f000c11 and 0cc528f.

Files selected for processing: 5
  • changelog.d/fixes/18644-opencode-go-litellm-bucket.md
  • src/lib/db/settings/pricing.ts
  • src/lib/litellmProviderMap.ts
  • src/lib/pricingSync.ts
  • tests/unit/pricing-sync-opencode-go-18598.test.ts

Limit details: You’ve used all 10 included reviews currently available.

@diegosouzapw
diegosouzapw merged commit 4b9528e into cheaper-inference:release/v3.8.53 Nov 4, 2026
13 of 34 checks passed
@yourspraveen
yourspraveen deleted the fix/18598-pricing-bucket branch November 5, 2026 01:12
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.

3 participants