Skip to content

refactor: replace resolvePricing positional model args with RoutingInfo and add backward-compat fallback for legacy ExtraFields - #4021

Merged
akshaydeo merged 1 commit into
devfrom
06-03-feat_adds_routing_info_wiring_for_pricing
Jun 9, 2026
Merged

akshaydeo merged 1 commit into
devfrom
06-03-feat_adds_routing_info_wiring_for_pricing

Conversation

@Pratham-Mishra04

@Pratham-Mishra04 Pratham-Mishra04 commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Refactors the pricing resolution path to consume a schemas.RoutingInfo struct directly instead of a loose (provider, originalModelRequested, resolvedModelUsed string) triplet. This aligns pricing lookups with the routing context that core.bifrost already populates at request time, and introduces a structured lookup precedence: AliasModelName → AliasModelID → ModelName.

Changes

  • resolvePricing now accepts a schemas.RoutingInfo instead of three separate string parameters. The lookup order tries ResolvedKeyAlias.ModelName, then ResolvedKeyAlias.ModelID, then RoutingInfo.Model, stopping at the first catalog hit. Override keys are always derived from the wire model (AliasModelID when an alias matched, otherwise Model).
  • calculateBaseCost reads RoutingInfo from ExtraFields directly. A backward-compatibility fallback synthesises a RoutingInfo from the deprecated Provider/OriginalModelRequested/ResolvedModelUsed triplet when RoutingInfo is fully unset — covering LoggerPlugin.RecalculateCosts replaying pre-RoutingInfo logs and third-party plugins on the legacy shape. Partial RoutingInfo population is trusted as-is and does not trigger the fallback.
  • computeCacheEmbeddingCost similarly constructs a RoutingInfo from the cache-debug fields when calling resolvePricing.
  • Container pricing overrides now build a synthetic RoutingInfo that pins the model fields to the container identifier while preserving the provider, replacing the previous dual lookupModel/lookupResolved override.
  • All call sites in tests are updated to pass schemas.RoutingInfo structs. New backward-compat tests cover: legacy-fields-only (no alias), legacy-fields-only (with alias/deployment), RoutingInfo winning over legacy fields when both are set, both empty returning zero cost, and partial RoutingInfo not triggering the fallback.

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

go test ./framework/modelcatalog/...

Key scenarios to verify:

  • Pricing resolves correctly for a non-aliased request via RoutingInfo.Model.
  • Pricing resolves via ResolvedKeyAlias.ModelID when an alias is matched and the deployment ID differs from the caller-facing model name.
  • AliasModelName takes precedence over AliasModelID when both are present.
  • Legacy ExtraFields triplet (no RoutingInfo) still produces correct costs.
  • When both RoutingInfo and the legacy triplet are populated, RoutingInfo wins.
  • Partial RoutingInfo (e.g. Model set but Provider empty) does not fall back to legacy fields.

Breaking changes

  • Yes
  • No

resolvePricing is an internal method, but any code calling it directly with the old (provider, originalModelRequested, resolvedModelUsed string, ...) signature must be updated to pass a schemas.RoutingInfo. External callers populating only the deprecated Provider/OriginalModelRequested/ResolvedModelUsed fields on BifrostResponseExtraFields continue to work via the backward-compat fallback, but should migrate to RoutingInfo.

Related issues

N/A

Security considerations

No auth, secrets, PII, or sandboxing implications. Pricing resolution is internal cost accounting only.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

Summary by CodeRabbit

  • Refactor

    • Cost routing now uses a unified routing-info model with legacy fallbacks, applies container-create model overrides, and ensures semantic-cache embedding billing reflects actual provider/model routing and new lookup precedence.
  • Tests

    • Updated and expanded pricing tests to validate routing-info-based resolution, override precedence, request-type fallbacks, legacy compatibility, and related edge cases.

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Pricing cost resolution is refactored to use schemas.RoutingInfo instead of separate provider/originalModelRequested/resolvedModelUsed parameters. The core resolvePricing function implements new lookup precedence for base catalogs and overrides, while maintaining backward compatibility by synthesizing RoutingInfo from legacy fields when unset.

Changes

RoutingInfo pricing refactoring

Layer / File(s) Summary
Core resolvePricing refactoring
framework/modelcatalog/pricing.go
resolvePricing is refactored to accept schemas.RoutingInfo and implements new base-catalog candidate precedence (ResolvedKeyAlias.ModelNameResolvedKeyAlias.ModelIDRoutingInfo.Model) plus updated override-key selection, removing prior provider/original/resolved deployment fallback flow.
RoutingInfo propagation in cost calculation
framework/modelcatalog/pricing.go
Callers of resolvePricing now construct and use schemas.RoutingInfo: semantic cache embedding derives RoutingInfo from BifrostCacheDebug, base cost computation builds/uses extraFields.RoutingInfo with legacy fallback synthesis, and container creation mutates routingInfo.Model before lookup.
Test fixture setup with RoutingInfo
framework/modelcatalog/pricing_test.go
Introduces routingInfoFor helper and updates response-building fixtures (makeChatResponse, makeEmbeddingResponse, makeRerankResponse, makeImageResponse) to populate ExtraFields.RoutingInfo instead of legacy provider/model fields.
Core resolvePricing unit tests
framework/modelcatalog/pricing_test.go
Direct tests of resolvePricing with new schemas.RoutingInfo signature, covering base-catalog lookups, fallback chains (Gemini/Vertex prefix stripping, Bedrock anthropic prefix, responses/realtime fallbacks), deployment alias matching, and resolved-model priority.
Pricing override precedence tests
framework/modelcatalog/pricing_overrides_test.go
Pricing override tests updated to use schemas.RoutingInfo, covering exact vs wildcard matching, request-type selection, provider-scope fallback, provider-prefixed model handling, override insertion precedence, and deletion behavior.
High-level behavior tests
framework/modelcatalog/pricing_test.go
End-to-end and integration tests updated to use RoutingInfo: semantic cache (direct-hit, semantic-hit, miss), stream/websocket/realtime fallbacks, tiered pricing (priority, non-priority, flex), image generation, and code interpreter.
Container creation cost tests
framework/modelcatalog/pricing_test.go
Container creation pricing tests updated to use RoutingInfo: no-memory-limit, memory-specific-entry, and fallback-to-base-entry scenarios.
Back-compat tests for empty RoutingInfo
framework/modelcatalog/pricing_test.go
New test section for CalculateCost when RoutingInfo is fully unset: verifies legacy triplet-only billing with/without ResolvedModelUsed alias, RoutingInfo precedence over legacy fields, zero cost when both identity sources are empty, and partial RoutingInfo rejection of legacy fallback.

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers:

  • akshaydeo
  • danpiths

"🐰 I hopped through routes of model and name,
I stitched old triplets to RoutingInfo's frame,
Aliases whispered, catalogs took aim,
Lookups now settle with order and claim.
Prices prance neat — the rabbit signs its name."

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main refactoring change: replacing positional model arguments with a RoutingInfo struct and adding backward compatibility fallback.
Description check ✅ Passed The description covers all required sections: Summary, Changes, Type of change (Refactor), Affected areas (Core), How to test, Breaking changes (Yes with explanation), and addresses the key design decisions around lookup precedence and backward compatibility.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 06-03-feat_adds_routing_info_wiring_for_pricing

Comment @coderabbitai help to get the list of available commands and usage tips.

Pratham-Mishra04 commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@greptile-apps

greptile-apps Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

Safe to merge. The refactor is internally contained to the modelcatalog pricing package, the backward-compat fallback is correctly gated on a fully-empty RoutingInfo, and the new test matrix covers the key edge cases.

All three call sites of resolvePricing are updated, the backward-compat condition is precise (all three RoutingInfo fields must be zero/nil to trigger the fallback), the lookup precedence change is tested end-to-end, and the new tests confirm no regression for legacy callers replaying pre-RoutingInfo logs.

No files require special attention.

Important Files Changed

Filename Overview
framework/modelcatalog/pricing.go Core pricing refactor: replaces (provider, origModel, resolvedModel string) triplet with schemas.RoutingInfo in resolvePricing; adds backward-compat fallback for legacy ExtraFields; introduces aliasModelName → aliasModelID → Model lookup precedence. Logic is correct and fallback conditions are sound.
framework/modelcatalog/pricing_overrides_test.go All resolvePricing call sites updated from positional string args to schemas.RoutingInfo structs; no logic changes to the test assertions.
framework/modelcatalog/pricing_test.go Test helpers and response builders migrated from legacy Provider/OriginalModelRequested/ResolvedModelUsed fields to RoutingInfo; five new backward-compat tests cover legacy-only, legacy-with-alias, RoutingInfo-wins, both-empty, and partial-RoutingInfo scenarios.

Reviews (13): Last reviewed commit: "feat: adds routing info wiring for prici..." | Re-trigger Greptile

Comment thread framework/modelcatalog/pricing.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
framework/modelcatalog/pricing_overrides_test.go (1)

65-66: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add skip reasons for disabled pricing override tests

Seven tests in framework/modelcatalog/pricing_overrides_test.go are unconditionally skipped via t.Skip() with no message (lines 66, 104, 205, 234, 268, 303, 381), and there are no nearby TODO/FIXME/issue references explaining why they’re disabled or when to re-enable them.

✨ Suggested improvement

Add an explanatory message to each t.Skip():

 func TestGetPricing_RequestTypeSpecificOverrideBeatsGeneric(t *testing.T) {
-	t.Skip()
+	t.Skip("TODO: re-enable after request-type matching is fully wired (PR `#XXXX`)")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@framework/modelcatalog/pricing_overrides_test.go` around lines 65 - 66,
Several tests in pricing_overrides_test.go are unconditionally skipped with bare
t.Skip() which lacks context; update each t.Skip() call (e.g., in
TestGetPricing_RequestTypeSpecificOverrideBeatsGeneric and the other tests in
framework/modelcatalog/pricing_overrides_test.go that call t.Skip()) to include
a concise skip reason string (briefly stating why the test is disabled) and, if
applicable, a TODO or issue reference and the condition required to re-enable
the test; ensure the message is short and actionable so future maintainers can
understand and track when to re-enable the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@framework/modelcatalog/pricing.go`:
- Around line 275-280: Two consecutive comment blocks redundantly state that
cache-debug pricing has a single model identifier; remove the duplicate and
replace with a single concise comment describing the behavior (e.g.,
"Cache-debug pricing has a single model identifier recorded by the cache; it
maps to aliasKey and RoutingInfo.Model with no alias resolution context, so
modelName/modelID remain empty"). Edit the comment adjacent to the cache-debug
pricing logic in pricing.go (the block referencing aliasKey and
RoutingInfo.Model) to keep only this single, clear sentence and delete the
repeated lines.

---

Outside diff comments:
In `@framework/modelcatalog/pricing_overrides_test.go`:
- Around line 65-66: Several tests in pricing_overrides_test.go are
unconditionally skipped with bare t.Skip() which lacks context; update each
t.Skip() call (e.g., in TestGetPricing_RequestTypeSpecificOverrideBeatsGeneric
and the other tests in framework/modelcatalog/pricing_overrides_test.go that
call t.Skip()) to include a concise skip reason string (briefly stating why the
test is disabled) and, if applicable, a TODO or issue reference and the
condition required to re-enable the test; ensure the message is short and
actionable so future maintainers can understand and track when to re-enable the
test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 67dded0a-2c9a-44a2-a9cf-996d09a37630

📥 Commits

Reviewing files that changed from the base of the PR and between 7795c41 and afd8acd.

📒 Files selected for processing (3)
  • framework/modelcatalog/pricing.go
  • framework/modelcatalog/pricing_overrides_test.go
  • framework/modelcatalog/pricing_test.go

Comment thread framework/modelcatalog/pricing.go Outdated
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routing_info_wiring_for_pricing branch from afd8acd to 86ffbe6 Compare June 4, 2026 20:49
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routinginfo_in_respose_error_extra_fields branch from 7795c41 to 53ed5e5 Compare June 4, 2026 20:49
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routinginfo_in_respose_error_extra_fields branch from 53ed5e5 to 6fe1303 Compare June 5, 2026 09:48
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routing_info_wiring_for_pricing branch 2 times, most recently from 53745d2 to 61f1e36 Compare June 5, 2026 10:43
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routinginfo_in_respose_error_extra_fields branch from 6fe1303 to 3d70a3f Compare June 5, 2026 10:43
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routing_info_wiring_for_pricing branch from 61f1e36 to 1d1469c Compare June 7, 2026 07:25
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routinginfo_in_respose_error_extra_fields branch 2 times, most recently from 139c90d to decab23 Compare June 8, 2026 06:54
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routing_info_wiring_for_pricing branch 2 times, most recently from 5f44a42 to ff3bf4c Compare June 8, 2026 07:18
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routinginfo_in_respose_error_extra_fields branch from 0f1ec91 to dd0fa43 Compare June 8, 2026 11:55
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routing_info_wiring_for_pricing branch 2 times, most recently from 69e5dd3 to cf9c97e Compare June 8, 2026 12:24
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routinginfo_in_respose_error_extra_fields branch from 48605b5 to d355ea9 Compare June 8, 2026 12:28
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routing_info_wiring_for_pricing branch from cf9c97e to b90517b Compare June 8, 2026 12:28
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routinginfo_in_respose_error_extra_fields branch from d355ea9 to bdb85c8 Compare June 8, 2026 21:20
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 06-03-feat_adds_routing_info_wiring_for_pricing branch from b90517b to 8011af6 Compare June 8, 2026 21:20

akshaydeo commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Merge activity

  • Jun 9, 5:17 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 9, 5:29 AM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo
akshaydeo changed the base branch from 06-03-feat_adds_routinginfo_in_respose_error_extra_fields to graphite-base/4021 June 9, 2026 05:28
@akshaydeo
akshaydeo changed the base branch from graphite-base/4021 to dev June 9, 2026 05:28
@akshaydeo
akshaydeo merged commit 99092bb into dev Jun 9, 2026
10 of 11 checks passed
@akshaydeo
akshaydeo deleted the 06-03-feat_adds_routing_info_wiring_for_pricing branch June 9, 2026 05:29
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