Skip to content

feat: add model pricing data to Bifrost and model responses - #745

Merged
Pratham-Mishra04 merged 1 commit into
mainfrom
11-04-feat_model_pricing_added_to_list_models_endpoint
Nov 14, 2025
Merged

feat: add model pricing data to Bifrost and model responses#745
Pratham-Mishra04 merged 1 commit into
mainfrom
11-04-feat_model_pricing_added_to_list_models_endpoint

Conversation

@Pratham-Mishra04

Copy link
Copy Markdown
Collaborator

Summary

Added model pricing data support to the Bifrost core, enabling automatic pricing information in model listings and providing a mechanism to sync pricing data from external sources.

Changes

  • Added a pricingData field to the Bifrost struct to store pricing information for models
  • Created new methods to set and retrieve pricing data for models
  • Added a DataSheetPricingEntry struct to represent detailed pricing information
  • Enhanced BifrostListModelsResponse with an AddPricing method to include pricing in model listings
  • Integrated pricing data with the model catalog framework
  • Added a callback mechanism to update pricing data when synced from external sources
  • Added DeploymentName field to the Model struct

Type of change

  • Feature
  • Refactor

Affected areas

  • Core (Go)
  • Transports (HTTP)

How to test

# Core/Transports
go version
go test ./...

# Test model listing with pricing data
curl -X GET "http://localhost:8000/v1/models" -H "Authorization: Bearer $BIFROST_API_KEY"

Breaking changes

  • No

Related issues

Enhances model listing capabilities with pricing information

Security considerations

No security implications as this only adds informational data to model responses.

Checklist

  • I added/updated tests where appropriate
  • I verified builds succeed (Go and UI)

Pratham-Mishra04 commented Nov 4, 2025

Copy link
Copy Markdown
Collaborator Author

@coderabbitai

coderabbitai Bot commented Nov 4, 2025

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@Pratham-Mishra04 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 9 minutes and 37 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 7e6b09b and 0a199a8.

📒 Files selected for processing (10)
  • core/bifrost.go (1 hunks)
  • core/schemas/models.go (1 hunks)
  • docs/quickstart/gateway/cli-agents.mdx (1 hunks)
  • framework/changelog.md (1 hunks)
  • framework/modelcatalog/main.go (1 hunks)
  • framework/modelcatalog/sync.go (2 hunks)
  • framework/modelcatalog/utils.go (1 hunks)
  • transports/bifrost-http/handlers/inference.go (2 hunks)
  • transports/bifrost-http/server/server.go (2 hunks)
  • transports/changelog.md (1 hunks)
📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added ability to retrieve list of configured providers.
    • Pricing information now included in model list responses.
  • Bug Fixes

    • Improved pagination logic with enhanced token validation.
    • Corrected speech endpoint input validation.
  • Documentation

    • Clarified MCP tool execution behavior and limitations in gateway mode.

Walkthrough

Adds a public method to read configured model providers, implements pagination for model listings, refactors pricing data shape and loading, adds a ModelCatalog accessor to fetch pricing per model, enriches listModels responses with pricing, tightens speech input validation, and updates docs/changelogs.

Changes

Cohort / File(s) Summary
Core — provider discovery
core/bifrost.go
Added GetConfiguredProviders() ([]schemas.ModelProvider, error) to return configured providers or error when none present.
Core — model listing pagination
core/schemas/models.go
Added ApplyPagination(pageSize int, pageToken string) *BifrostListModelsResponse implementing offset-based pagination with LastID validation and NextPageToken handling (removed duplicate implementation).
Framework — pricing model & accessor
framework/modelcatalog/main.go
Removed PricingData alias and several legacy pricing fields from PricingEntry; added GetPricingEntryForModel(model string, provider schemas.ModelProvider) *PricingEntry which searches pricing entries across request modes under read-lock.
Framework — pricing loading
framework/modelcatalog/sync.go
Updated loadPricingFromURL to return map[string]PricingEntry and adjusted unmarshalling accordingly.
Framework — pricing conversion util
framework/modelcatalog/utils.go
Added convertTableModelPricingToPricingData(pricing *configstoreTables.TableModelPricing) *PricingEntry to map table pricing rows into PricingEntry.
Transport — listModels enrichment & validation
transports/bifrost-http/handlers/inference.go
Enriched listModels responses by attaching Pricing objects when available (Prompt/Completion and optional Image/InputCacheRead); tightened speech input validation to require SpeechInput non-nil and non-empty.
Transport — server comment
transports/bifrost-http/server/server.go
Inserted a no-op comment after AddModelDataToPool(modelData) in Bootstrap (no functional change).
Docs & changelogs
docs/quickstart/gateway/cli-agents.mdx, framework/changelog.md, transports/changelog.md
Clarified MCP gateway tool behavior / approval flow; added changelog entry describing pricing exposure and related responses API note.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant HTTPHandler as listModels Handler
    participant Bifrost
    participant ModelCatalog

    Client->>HTTPHandler: GET /v1/models
    HTTPHandler->>Bifrost: GetConfiguredProviders()
    Bifrost-->>HTTPHandler: []ModelProvider
    HTTPHandler->>Bifrost: ListModels(providers)
    Bifrost-->>HTTPHandler: BifrostListModelsResponse

    alt Pricing manager configured
        loop per model
            HTTPHandler->>ModelCatalog: GetPricingEntryForModel(modelID, provider)
            ModelCatalog-->>HTTPHandler: *PricingEntry / nil
            HTTPHandler->>HTTPHandler: attach Pricing to response item (if present)
        end
    end

    HTTPHandler-->>Client: ListModelsResponse (with optional Pricing)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review focus:
    • Call sites still referencing removed PricingData or removed PricingEntry fields.
    • Thread-safety and correctness of GetPricingEntryForModel.
    • Pagination token parsing and NextPageToken semantics in ApplyPagination.
    • Null-safety when attaching Pricing in listModels and the stricter speech validation.

Possibly related PRs

Suggested reviewers

  • akshaydeo
  • danpiths

Poem

🐇
I hopped through code and found the rows,
Providers peeking where the wild log grows.
Pages skip lightly, pricing carrots gleam—
A tiny rabbit cheers the new data stream. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The description covers all required template sections: Summary, Changes, Type of change, Affected areas, How to test, Breaking changes, Related issues, Security considerations, and Checklist. All required information is present and complete.
Title check ✅ Passed The title clearly and concisely summarizes the main objective: adding model pricing data to Bifrost and model responses, which is directly supported by the changes across multiple files.

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

@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: 5

🧹 Nitpick comments (1)
core/bifrost.go (1)

376-378: Avoid duplicate AddPricing calls.

AddPricing already runs in ListModelsRequest; calling it again in ListAllModels is redundant.

Apply this diff:

- // Add pricing data to the response
- response.AddPricing(bifrost.GetPricingDataForModel)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ba5078f and 951ed2f.

📒 Files selected for processing (7)
  • core/bifrost.go (5 hunks)
  • core/schemas/models.go (4 hunks)
  • framework/modelcatalog/main.go (4 hunks)
  • framework/modelcatalog/sync.go (3 hunks)
  • framework/modelcatalog/utils.go (3 hunks)
  • transports/bifrost-http/lib/config.go (2 hunks)
  • transports/bifrost-http/server.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (7)
transports/bifrost-http/server.go (2)
framework/modelcatalog/main.go (1)
  • Config (26-30)
transports/bifrost-http/lib/config.go (1)
  • Config (139-169)
transports/bifrost-http/lib/config.go (1)
core/schemas/models.go (1)
  • DataSheetPricingEntry (200-229)
core/bifrost.go (2)
core/schemas/models.go (1)
  • DataSheetPricingEntry (200-229)
core/schemas/bifrost.go (1)
  • ModelProvider (32-32)
framework/modelcatalog/utils.go (1)
core/schemas/models.go (1)
  • DataSheetPricingEntry (200-229)
core/schemas/models.go (2)
core/schemas/bifrost.go (1)
  • ModelProvider (32-32)
core/schemas/provider.go (1)
  • Provider (199-226)
framework/modelcatalog/sync.go (2)
framework/modelcatalog/main.go (1)
  • ModelCatalog (32-56)
core/schemas/models.go (1)
  • DataSheetPricingEntry (200-229)
framework/modelcatalog/main.go (1)
core/schemas/models.go (1)
  • DataSheetPricingEntry (200-229)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
🔇 Additional comments (3)
transports/bifrost-http/server.go (1)

732-734: Bootstrap pricing propagation looks good.

This correctly seeds the client with pricing after catalog load.

core/schemas/models.go (1)

118-131: Pricing attachment logic looks solid.

Sets DataSheetPricingEntry irrespective of preexisting Pricing object.

transports/bifrost-http/lib/config.go (1)

920-924: Review comment references non-existent method GetBifrostClient()

The data race concern is valid—both callbacks at lines 467–468 and 921–922 use unsynchronized direct reads of config.client while SetBifrostClient (line 1523) writes with muMCP lock protection. However, the suggested diff cannot be applied as written because GetBifrostClient() does not exist in the codebase.

To properly fix the data race, either:

  1. Create a thread-safe GetBifrostClient() getter method that acquires the muMCP lock before returning the client, then apply the suggested diff, OR
  2. Modify both callbacks to acquire the mutex directly, similar to how AddMCPClient uses c.muMCP.Lock() for client field access.

Comment thread core/bifrost.go Outdated
Comment thread framework/modelcatalog/main.go
Comment thread framework/modelcatalog/sync.go Outdated
Comment thread framework/modelcatalog/utils.go Outdated
Comment thread transports/bifrost-http/lib/config.go Outdated
@Pratham-Mishra04 Pratham-Mishra04 changed the title feat: add model pricing data to Bifrost and model responses DO NOT MERGE feat: add model pricing data to Bifrost and model responses Nov 4, 2025
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 11-04-feat_model_pricing_added_to_list_models_endpoint branch from 951ed2f to 49db44b Compare November 4, 2025 10:01
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 10-31-feat_modelcatelog_enhancements branch from ba5078f to 9782009 Compare November 4, 2025 10:01
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 11-04-feat_model_pricing_added_to_list_models_endpoint branch from 49db44b to b31416f Compare November 4, 2025 10:35
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 10-31-feat_modelcatelog_enhancements branch from 9782009 to f34e7ee Compare November 4, 2025 10:35
@akshaydeo
akshaydeo changed the base branch from 10-31-feat_modelcatelog_enhancements to graphite-base/745 November 4, 2025 10:36
@akshaydeo
akshaydeo force-pushed the 11-04-feat_model_pricing_added_to_list_models_endpoint branch from b31416f to 8fc37ed Compare November 4, 2025 10:36
@graphite-app
graphite-app Bot changed the base branch from graphite-base/745 to main November 4, 2025 10:37
@akshaydeo
akshaydeo force-pushed the 11-04-feat_model_pricing_added_to_list_models_endpoint branch from 8fc37ed to 7e6b09b Compare November 4, 2025 10:37

@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: 3

♻️ Duplicate comments (3)
framework/modelcatalog/sync.go (1)

131-134: Invoke the pricing callback with normalized data.

Passing the raw map from the download keeps provider-prefixed keys, so downstream consumers (e.g. Bifrost.SetPricingData) see inconsistent identifiers and produce incorrect keys. Call the accessor that already returns our canonicalized map instead.

Apply this diff:

-	if mc.pricingSyncCallback != nil {
-		mc.pricingSyncCallback(pricingData)
+	if mc.pricingSyncCallback != nil {
+		mc.pricingSyncCallback(mc.GetPricingData())
core/bifrost.go (1)

838-840: Normalize incoming pricing keys before storing.

Once the catalog starts returning provider-qualified keys, this loop will emit provider/provider/model, corrupting lookups. Strip the provider prefix from the incoming key before composing the final storage key.

Apply this diff:

 func (bifrost *Bifrost) SetPricingData(pricingData map[string]schemas.DataSheetPricingEntry) {
-	for model, pricing := range pricingData {
-		bifrost.pricingData.Store(pricing.Provider+"/"+model, pricing)
+	for model, pricing := range pricingData {
+		normalized := model
+		prefix := pricing.Provider + "/"
+		if strings.HasPrefix(normalized, prefix) {
+			normalized = strings.TrimPrefix(normalized, prefix)
+		}
+		bifrost.pricingData.Store(pricing.Provider+"/"+normalized, pricing)
 	}
 }
framework/modelcatalog/main.go (1)

169-171: Fix pricing map key collisions across providers.

Keying the export map by model alone overwrites entries whenever two providers expose the same model name (e.g. OpenAI vs Azure wrappers), so callers receive whichever entry happened to be processed last. Use a provider-qualified key (matching what the client expects) to preserve every variant.

Apply this diff:

-		model, _, _ := splitKey(key)
-		pricingData[model] = convertTableModelPricingToPricingData(pricing)
+		model, provider, _ := splitKey(key)
+		composite := provider + "/" + model
+		pricingData[composite] = convertTableModelPricingToPricingData(pricing)
🧹 Nitpick comments (1)
framework/modelcatalog/utils.go (1)

14-17: Defend against malformed pricing keys.

splitKey panics on any key that lacks two delimiters (e.g. legacy rows, manual config edits). Add a length check and fall back safely to avoid taking down the pricing sync.

Apply this diff:

 func splitKey(key string) (string, string, string) {
 	parts := strings.Split(key, "|")
-	return parts[0], parts[1], parts[2]
+	if len(parts) < 3 {
+		return key, "", ""
+	}
+	return parts[0], parts[1], parts[2]
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 49db44b and 7e6b09b.

📒 Files selected for processing (7)
  • core/bifrost.go (5 hunks)
  • core/schemas/models.go (4 hunks)
  • framework/modelcatalog/main.go (4 hunks)
  • framework/modelcatalog/sync.go (3 hunks)
  • framework/modelcatalog/utils.go (3 hunks)
  • transports/bifrost-http/lib/config.go (2 hunks)
  • transports/bifrost-http/server/server.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • transports/bifrost-http/lib/config.go
🧰 Additional context used
🧬 Code graph analysis (6)
transports/bifrost-http/server/server.go (2)
framework/modelcatalog/main.go (1)
  • Config (26-30)
transports/bifrost-http/lib/config.go (1)
  • Config (139-169)
framework/modelcatalog/sync.go (2)
framework/modelcatalog/main.go (1)
  • ModelCatalog (32-56)
core/schemas/models.go (1)
  • DataSheetPricingEntry (200-229)
framework/modelcatalog/utils.go (1)
core/schemas/models.go (1)
  • DataSheetPricingEntry (200-229)
core/schemas/models.go (2)
core/schemas/bifrost.go (1)
  • ModelProvider (32-32)
core/schemas/provider.go (1)
  • Provider (199-226)
framework/modelcatalog/main.go (1)
core/schemas/models.go (1)
  • DataSheetPricingEntry (200-229)
core/bifrost.go (2)
core/schemas/models.go (1)
  • DataSheetPricingEntry (200-229)
core/schemas/bifrost.go (1)
  • ModelProvider (32-32)
🔇 Additional comments (4)
core/schemas/models.go (4)

48-108: LGTM! Well-implemented pagination with cursor validation.

The pagination logic correctly handles edge cases including nil responses, invalid cursors, empty pages, and boundary conditions. The use of opaque tokens with LastID validation ensures cursor integrity.


110-110: LGTM! Clean function type definition.

The type signature appropriately uses a pointer return to allow for optional pricing data.


136-136: LGTM! Field addition follows established patterns.

The new DeploymentName field is appropriately optional with a pointer type and correct JSON tags, consistent with other fields in the struct.


199-229: LGTM! Comprehensive and well-structured pricing data model.

The DataSheetPricingEntry struct appropriately distinguishes required fields (basic token pricing, provider, mode) from optional fields (media, character-based, 128k+, cache/batch pricing). The naming is consistent and descriptive, and the use of pointers for optional fields is correct.

Comment thread core/schemas/models.go Outdated
Comment thread core/schemas/models.go Outdated
Comment thread core/schemas/models.go Outdated
@Pratham-Mishra04 Pratham-Mishra04 linked an issue Nov 4, 2025 that may be closed by this pull request
2 tasks
@Pratham-Mishra04 Pratham-Mishra04 changed the title DO NOT MERGE feat: add model pricing data to Bifrost and model responses feat: add model pricing data to Bifrost and model responses Nov 14, 2025
@Pratham-Mishra04
Pratham-Mishra04 changed the base branch from main to graphite-base/745 November 14, 2025 09:59
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 11-04-feat_model_pricing_added_to_list_models_endpoint branch from 7e6b09b to d990c56 Compare November 14, 2025 09:59
@Pratham-Mishra04
Pratham-Mishra04 changed the base branch from graphite-base/745 to 11-11-fix_responses_streaming_accumulation_fixes November 14, 2025 09:59
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 11-04-feat_model_pricing_added_to_list_models_endpoint branch from d990c56 to d2152f4 Compare November 14, 2025 10:02
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 11-04-feat_model_pricing_added_to_list_models_endpoint branch 2 times, most recently from b0c0f3c to 05c00fe Compare November 14, 2025 10:28

Pratham-Mishra04 commented Nov 14, 2025

Copy link
Copy Markdown
Collaborator Author

Merge activity

  • Nov 14, 10:29 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Nov 14, 10:31 AM UTC: Graphite rebased this pull request as part of a merge.
  • Nov 14, 10:32 AM UTC: @Pratham-Mishra04 merged this pull request with Graphite.

@Pratham-Mishra04
Pratham-Mishra04 changed the base branch from 11-11-fix_responses_streaming_accumulation_fixes to graphite-base/745 November 14, 2025 10:29
@Pratham-Mishra04
Pratham-Mishra04 changed the base branch from graphite-base/745 to main November 14, 2025 10:29
@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 11-04-feat_model_pricing_added_to_list_models_endpoint branch from 05c00fe to 0a199a8 Compare November 14, 2025 10:30
@Pratham-Mishra04
Pratham-Mishra04 merged commit a24cd44 into main Nov 14, 2025
4 checks passed
@Pratham-Mishra04
Pratham-Mishra04 deleted the 11-04-feat_model_pricing_added_to_list_models_endpoint branch November 14, 2025 10:32
@codecov

codecov Bot commented Nov 14, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 71 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
core/schemas/models.go 0.00% 32 Missing ⚠️
framework/modelcatalog/utils.go 0.00% 21 Missing ⚠️
framework/modelcatalog/main.go 0.00% 16 Missing ⚠️
framework/modelcatalog/sync.go 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

akshaydeo pushed a commit that referenced this pull request Nov 17, 2025
## Summary

Added model pricing data support to the Bifrost core, enabling automatic pricing information in model listings and providing a mechanism to sync pricing data from external sources.

## Changes

- Added a `pricingData` field to the Bifrost struct to store pricing information for models
- Created new methods to set and retrieve pricing data for models
- Added a `DataSheetPricingEntry` struct to represent detailed pricing information
- Enhanced `BifrostListModelsResponse` with an `AddPricing` method to include pricing in model listings
- Integrated pricing data with the model catalog framework
- Added a callback mechanism to update pricing data when synced from external sources
- Added `DeploymentName` field to the Model struct

## Type of change

- [x] Feature
- [x] Refactor

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)

## How to test

```sh
# Core/Transports
go version
go test ./...

# Test model listing with pricing data
curl -X GET "http://localhost:8000/v1/models" -H "Authorization: Bearer $BIFROST_API_KEY"
```

## Breaking changes

- [x] No

## Related issues

Enhances model listing capabilities with pricing information

## Security considerations

No security implications as this only adds informational data to model responses.

## Checklist

- [x] I added/updated tests where appropriate
- [x] I verified builds succeed (Go and UI)
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.

[Bug]: /v1/models endpoint not returning pricing

1 participant