Skip to content

feat: add path parameter support in HTTPRequest to fix VK level provider routing GenAI integrations#1335

Merged
akshaydeo merged 1 commit intomainfrom
01-15-feat_added_fixes_for_genai_vk_provider_routing
Jan 14, 2026
Merged

feat: add path parameter support in HTTPRequest to fix VK level provider routing GenAI integrations#1335
akshaydeo merged 1 commit intomainfrom
01-15-feat_added_fixes_for_genai_vk_provider_routing

Conversation

@Pratham-Mishra04
Copy link
Copy Markdown
Collaborator

Summary

Added support for path parameter lookups in HTTP requests, fixed error handling in the Anthropic SDK integration, and enhanced the Google GenAI integration to properly handle model routing through path parameters.

Changes

  • Added path parameter extraction and lookup functionality to HTTPRequest, including case-insensitive helper methods
  • Fixed error response handling in Anthropic SDK integration by properly including request type information
  • Enhanced the governance plugin to support model lookup via path parameters for Google GenAI integration
  • Added constants for Gemini request suffix paths to improve maintainability
  • Updated the HTTP transport to extract path parameters from fasthttp user values

Type of change

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

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (Next.js)
  • Docs

How to test

Test path parameter extraction and lookup:

go test ./transports/bifrost-http/handlers/...

Test Google GenAI integration with virtual key routing:

  1. Configure a virtual key with provider routing
  2. Send a request to the GenAI endpoint with a model in the path
  3. Verify the model is correctly routed to the specified provider

Test Anthropic error responses:

  1. Configure an invalid Anthropic request
  2. Verify the error response includes the correct type information

Breaking changes

  • Yes
  • No

Related issues

Fixes issues with virtual key provider routing for Google GenAI integration and improves error handling for Anthropic SDK.

Security considerations

No security implications as this is enhancing existing functionality.

Checklist

  • I added/updated tests where appropriate
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 14, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added support for path parameters in HTTP requests
    • Improved GenAI routing to derive and preserve models from URL paths (including suffix handling)
  • Bug Fixes

    • Fixed missing request type in error responses for Anthropic SDK integration
  • Tests

    • Added test coverage for path parameter extraction and case-insensitive lookup

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds path-parameter support to HTTPRequest with case-insensitive lookup, extracts path params from Fasthttp contexts, extends governance load balancing to route GenAI requests by path (including Gemini suffix handling), switches Anthropic error serialization to sonic, and exposes Gemini request suffix paths for dynamic trimming.

Changes

Cohort / File(s) Summary
Core HTTP Request Infrastructure
core/schemas/plugin.go
Added PathParams map[string]string and CaseInsensitivePathParamLookup() to HTTPRequest; initialized/cleared PathParams in pool lifecycle.
Transport: Path Param Extraction & Tests
transports/bifrost-http/handlers/middlewares.go, transports/bifrost-http/handlers/middlewares_test.go
Populate HTTPRequest.PathParams from Fasthttp user values during request conversion; added test TestFasthttpToHTTPRequest_PathParams validating extraction and case-insensitive lookup.
Governance: GenAI Routing Changes
plugins/governance/main.go, plugins/governance/changelog.md
Extended loadBalanceProvider signature to accept ctx and req; extract model from /genai path when needed, strip/retain Gemini suffixes, select/provider-prefix model updates in path or body, and propagate ctx/req through HTTPTransportIntercept.
Gemini: Suffix Paths Export
core/providers/gemini/types.go
Added exported GeminiRequestSuffixPaths []string containing Gemini request endpoint suffixes for dynamic trimming.
GenAI Integration: Use Dynamic Suffixes
transports/bifrost-http/integrations/genai.go, transports/bifrost-http/integrations/router.go
Replaced hard-coded GenAI suffix list with gemini.GeminiRequestSuffixPaths; minor formatting only in router.
Anthropic: Error Serialization & Nil-Safety
core/providers/anthropic/errors.go
Replaced encoding/json with github.com/bytedance/sonic for marshaling; changed error field access to safer nested-nil-aware logic and adjusted Type/Message extraction.
Changelogs
core/changelog.md, transports/changelog.md, plugins/governance/changelog.md
Added entries for path-param support, GenAI model lookup by path, and Anthropic error response type fix; normalized capitalization and added new lines.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Fasthttp as Fasthttp Transport
    participant Governance as Governance Plugin
    participant Gemini as Gemini Provider (types)

    Client->>Fasthttp: HTTP request (contains /genai path)
    Fasthttp->>Fasthttp: extract path params -> HTTPRequest.PathParams
    Fasthttp->>Governance: HTTPTransportIntercept(ctx, req)
    Governance->>Governance: loadBalanceProvider(ctx, req, body)
    Governance->>Gemini: read GeminiRequestSuffixPaths
    Governance->>Governance: strip suffix, determine model & provider
    Governance->>Fasthttp: update req path or body with provider-prefixed model
    Fasthttp-->>Client: route/forward to selected provider
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 I hopped through paths both short and wide,

I gathered params with gentle pride,
GenAI models trimmed and spun,
Errors marshalled, suffixes done,
Hooray — the routing race is won! 🎉

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding path parameter support to HTTPRequest to fix provider routing for GenAI integrations through virtual keys.
Description check ✅ Passed The description follows the template structure, covers all main sections (Summary, Changes, Type of change, Affected areas, How to test, Breaking changes, Related issues, Security, Checklist), and provides sufficient detail about the changes made.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 01-15-feat_added_fixes_for_genai_vk_provider_routing

🧹 Recent nitpick comments
core/changelog.md (1)

1-3: Changelog entries look good but may be incomplete.

The entries accurately describe the HTTPRequest path parameter feature and the Anthropic fix. However, the significant GenAI routing changes in the governance plugin (model lookup from URL path, suffix handling) are not mentioned. Consider adding:

 - chore: added case-insensitive helper methods for header and query parameter lookups in HTTPRequest
 - feat: added support for path parameter lookups in HTTPRequest
+- feat: added GenAI path-based model routing support in governance plugin
 - fix: missing request type in error response for anthropic SDK integration
transports/bifrost-http/handlers/middlewares_test.go (1)

831-888: Good test coverage for path parameter extraction.

The test comprehensively validates:

  1. Path parameters are correctly extracted from user values
  2. System keys are filtered out
  3. Case-insensitive lookup works correctly

Consider adding a test case for the bifrost- prefix filtering to ensure complete coverage of the filtering logic:

♻️ Optional: Add bifrost- prefix test case
 	// Set some system values that should be ignored
 	ctx.SetUserValue("BifrostContextKeyRequestID", "req-123")
 	ctx.SetUserValue("trace_id", "trace-456")
 	ctx.SetUserValue("span_id", "span-789")
+	ctx.SetUserValue("bifrost-trace-id", "trace-abc")
+	ctx.SetUserValue("bifrost-span-id", "span-def")

 	// ... later in assertions ...

 	// Verify system keys are NOT in path params
-	systemKeys := []string{"BifrostContextKeyRequestID", "trace_id", "span_id"}
+	systemKeys := []string{"BifrostContextKeyRequestID", "trace_id", "span_id", "bifrost-trace-id", "bifrost-span-id"}

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f80b531 and 3f055c2.

📒 Files selected for processing (11)
  • core/changelog.md
  • core/providers/anthropic/errors.go
  • core/providers/gemini/types.go
  • core/schemas/plugin.go
  • plugins/governance/changelog.md
  • plugins/governance/main.go
  • transports/bifrost-http/handlers/middlewares.go
  • transports/bifrost-http/handlers/middlewares_test.go
  • transports/bifrost-http/integrations/genai.go
  • transports/bifrost-http/integrations/router.go
  • transports/changelog.md
💤 Files with no reviewable changes (1)
  • transports/bifrost-http/integrations/router.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • transports/bifrost-http/integrations/genai.go
  • core/providers/anthropic/errors.go
  • core/providers/gemini/types.go
  • core/schemas/plugin.go
  • transports/changelog.md
  • plugins/governance/changelog.md
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

always check the stack if there is one for the current PR. do not give localized reviews for the PR, always see all changes in the light of the whole stack of PRs (if there is a stack, if there is no stack you can continue to make localized suggestions/reviews)

Files:

  • transports/bifrost-http/handlers/middlewares_test.go
  • plugins/governance/main.go
  • transports/bifrost-http/handlers/middlewares.go
  • core/changelog.md
🧠 Learnings (7)
📚 Learning: 2025-12-09T17:07:42.007Z
Learnt from: qwerty-dvorak
Repo: maximhq/bifrost PR: 1006
File: core/schemas/account.go:9-18
Timestamp: 2025-12-09T17:07:42.007Z
Learning: In core/schemas/account.go, the HuggingFaceKeyConfig field within the Key struct is currently unused and reserved for future Hugging Face inference endpoint deployments. Do not flag this field as missing from OpenAPI documentation or require its presence in the API spec until the feature is actively implemented and used. When the feature is added, update the OpenAPI docs accordingly; otherwise, treat this field as non-breaking and not part of the current API surface.

Applied to files:

  • transports/bifrost-http/handlers/middlewares_test.go
  • plugins/governance/main.go
  • transports/bifrost-http/handlers/middlewares.go
📚 Learning: 2025-12-29T11:54:55.836Z
Learnt from: akshaydeo
Repo: maximhq/bifrost PR: 1153
File: framework/configstore/rdb.go:2221-2246
Timestamp: 2025-12-29T11:54:55.836Z
Learning: In Go reviews, do not flag range-over-int patterns like for i := range n as compile-time errors, assuming Go 1.22+ semantics. Only flag actual range-capable values (slices, arrays, maps, channels, strings) and other compile-time issues. This applies to all Go files across the repository.

Applied to files:

  • transports/bifrost-http/handlers/middlewares_test.go
  • plugins/governance/main.go
  • transports/bifrost-http/handlers/middlewares.go
📚 Learning: 2026-01-14T04:40:11.480Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1312
File: framework/modelcatalog/pricing.go:276-426
Timestamp: 2026-01-14T04:40:11.480Z
Learning: In the Bifrost codebase, ImageUsage and other usage types guarantee that TotalTokens is populated (computed as InputTokens + OutputTokens if providers don’t supply TotalTokens). Reviewers can rely on this invariant and should not assume TotalTokens may be missing when input/output tokens exist. When implementing tiering logic or token-based decisions, you can safely use TotalTokens without extra null/zero guards, provided you’re in a context where InputTokens and OutputTokens are present. If a branch might discard tokens, ensure the invariant is preserved or add explicit checks only where the inputs are confirmed to be valid.

Applied to files:

  • transports/bifrost-http/handlers/middlewares_test.go
  • plugins/governance/main.go
  • transports/bifrost-http/handlers/middlewares.go
📚 Learning: 2026-01-14T13:30:28.760Z
Learnt from: Radheshg04
Repo: maximhq/bifrost PR: 1326
File: plugins/semanticcache/test_utils.go:545-559
Timestamp: 2026-01-14T13:30:28.760Z
Learning: In the maximhq/bifrost repository, prefer using bifrost.Ptr() to create pointers instead of the address operator (&) even when & would be valid syntactically. Apply this consistently across all code paths, including test utilities, to improve consistency and readability. Replace occurrences of &value where a *T is expected with bifrost.Ptr(value) (or an equivalent call) and ensure the function is in scope and used correctly for the target pointer type.

Applied to files:

  • transports/bifrost-http/handlers/middlewares_test.go
  • plugins/governance/main.go
  • transports/bifrost-http/handlers/middlewares.go
📚 Learning: 2025-12-12T08:25:02.629Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1000
File: transports/bifrost-http/integrations/router.go:709-712
Timestamp: 2025-12-12T08:25:02.629Z
Learning: In transports/bifrost-http/**/*.go, update streaming response handling to align with OpenAI Responses API: use typed SSE events such as response.created, response.output_text.delta, response.done, etc., and do not rely on the legacy data: [DONE] termination marker. Note that data: [DONE] is only used by the older Chat Completions and Text Completions streaming APIs. Ensure parsers, writers, and tests distinguish SSE events from the [DONE] sentinel and handle each event type accordingly for correct stream termination and progress updates.

Applied to files:

  • transports/bifrost-http/handlers/middlewares_test.go
  • transports/bifrost-http/handlers/middlewares.go
📚 Learning: 2025-12-29T09:14:16.633Z
Learnt from: akshaydeo
Repo: maximhq/bifrost PR: 888
File: transports/bifrost-http/handlers/middlewares.go:246-256
Timestamp: 2025-12-29T09:14:16.633Z
Learning: In the bifrost HTTP transport, fasthttp.RequestCtx is the primary context carrier and should be passed directly to functions that expect a context.Context. Do not convert to context.Context unless explicitly required. Ensure tracer implementations and related components are designed to accept fasthttp.RequestCtx directly, and document this architectural decision for maintainers.

Applied to files:

  • transports/bifrost-http/handlers/middlewares_test.go
  • transports/bifrost-http/handlers/middlewares.go
📚 Learning: 2025-12-22T10:50:40.990Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1154
File: plugins/governance/store.go:1165-1186
Timestamp: 2025-12-22T10:50:40.990Z
Learning: In the Bifrost governance plugin, budgets and rate limits have 1:1 relationships with their parent entities (virtual keys, teams, customers). Do not assume sharing; ensure cascade deletion logic only deletes budgets/rate limits when there are no shared references. Enforce invariants in code and add tests to verify no cross-entity sharing and that cascade deletes only remove the specific child of the parent. If a counterexample arises, adjust data model or add guards.

Applied to files:

  • plugins/governance/main.go
🧬 Code graph analysis (1)
transports/bifrost-http/handlers/middlewares_test.go (1)
core/schemas/plugin.go (2)
  • AcquireHTTPRequest (101-103)
  • ReleaseHTTPRequest (108-121)
⏰ 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). (10)
  • 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
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
🔇 Additional comments (5)
plugins/governance/main.go (4)

319-324: LGTM! GenAI model extraction from path parameters.

The logic correctly handles GenAI requests where the model is in the URL path rather than the request body:

  1. Detects /genai in the path
  2. Uses the new CaseInsensitivePathParamLookup to extract the model
  3. Falls through gracefully when model is not found

330-340: LGTM! GenAI suffix handling.

The suffix stripping logic correctly:

  1. Only applies to GenAI requests (path contains /genai)
  2. Uses the centralized gemini.GeminiRequestSuffixPaths for suffix detection
  3. Preserves the suffix for reattachment after provider selection

This ensures the final URL path maintains the correct endpoint suffix (e.g., :generateContent, :streamGenerateContent).


15-15: No issues found with the gemini provider import.

The import of github.com/maximhq/bifrost/core/providers/gemini is safe. GeminiRequestSuffixPaths is properly exported at core/providers/gemini/types.go:1751, and there is no circular dependency risk—the gemini provider only depends on core schemas and utilities, not on the governance plugin.


413-420: The implementation is correct. The ctx.SetValue("model", ...) in the governance middleware is properly consumed by downstream GenAI handlers through the context value bridging in TransportInterceptorMiddleware.

The flow works as follows:

  1. The governance plugin sets the value in BifrostContext via ctx.SetValue("model", ...)
  2. TransportInterceptorMiddleware copies all BifrostContext user values to the fasthttp context using ctx.SetUserValue(key, value) before invoking the router
  3. The router's PreCallback (extractAndSetModelFromURL) receives the updated fasthttp context and successfully reads the value via ctx.UserValue("model")

The context value propagation is properly handled and requires no changes.

transports/bifrost-http/handlers/middlewares.go (1)

113-132: Fix missing system key filter: x-litellm-fallback leaks into path parameters.

The filter correctly catches keys with bifrost- prefix, but misses the x-litellm-fallback system key that is set via SetUserValue() at line 562 of inference.go. This system key should be filtered out to prevent it from appearing in path parameters.

Additionally, the literal string checks for "BifrostContextKeyRequestID", "trace_id", and "span_id" are not representative of actual production keys, which use the schema constants (e.g., "bifrost-trace-id", "bifrost-span-id") and are already caught by the "bifrost-" prefix check.

Add "x-litellm-fallback" to the filter logic:

if strings.HasPrefix(keyStr, "bifrost-") ||
    keyStr == "x-litellm-fallback" {
    return
}

Remove the unnecessary literal string checks that never match in production.

Likely an incorrect or invalid review comment.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


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

Copy link
Copy Markdown
Collaborator Author

Pratham-Mishra04 commented Jan 14, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@transports/bifrost-http/handlers/middlewares_test.go`:
- Around line 831-888: fasthttpToHTTPRequest is currently copying all string
user values into req.PathParams, which includes system metadata; change the loop
that iterates ctx.UserValues to skip known system keys (e.g.
BifrostContextKeyRequestID, "trace_id", "span_id") so only actual path params
like "file_id" and "model" are stored in req.PathParams, leaving the
CaseInsensitivePathParamLookup behavior unchanged.

In `@transports/bifrost-http/handlers/middlewares.go`:
- Around line 113-125: The code in the ctx.VisitUserValuesAll callback adds all
string user values to req.PathParams, which incorrectly includes internal
Bifrost tracing keys; update the VisitUserValuesAll handler (the anonymous
callback passed to ctx.VisitUserValuesAll) to skip any key that has the
"bifrost-" prefix (e.g., "bifrost-trace-id", "bifrost-span-id",
"bifrost-parent-span-id") before assigning into req.PathParams; keep the
existing type checks for key and value strings and only add the pair to
req.PathParams when the key does not start with "bifrost-".
🧹 Nitpick comments (1)
plugins/governance/main.go (1)

413-420: Use a typed constant for the "model" context key to match the codebase pattern.

The string literal "model" is inconsistent with how context keys are defined elsewhere in the codebase. The governance plugin uses typed constants (e.g., governanceRejectedContextKey), and semantic cache similarly defines requestModelKey = schemas.BifrostContextKey("semantic_cache_model"). Defining a constant here improves consistency and prevents typos across the codebase.

♻️ Suggested improvement
// In plugins/governance/main.go, add to the const block:
const (
	governanceRejectedContextKey    schemas.BifrostContextKey = "bf-governance-rejected"
	governanceIsCacheReadContextKey schemas.BifrostContextKey = "bf-governance-is-cache-read"
	governanceIsBatchContextKey     schemas.BifrostContextKey = "bf-governance-is-batch"
	governanceUpdatedModelKey       schemas.BifrostContextKey = "bf-governance-model"
)

// Then in loadBalanceProvider:
ctx.SetValue(governanceUpdatedModelKey, newModelWithRequestSuffix)
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f506cb and f80b531.

📒 Files selected for processing (11)
  • core/changelog.md
  • core/providers/anthropic/errors.go
  • core/providers/gemini/types.go
  • core/schemas/plugin.go
  • plugins/governance/changelog.md
  • plugins/governance/main.go
  • transports/bifrost-http/handlers/middlewares.go
  • transports/bifrost-http/handlers/middlewares_test.go
  • transports/bifrost-http/integrations/genai.go
  • transports/bifrost-http/integrations/router.go
  • transports/changelog.md
💤 Files with no reviewable changes (1)
  • transports/bifrost-http/integrations/router.go
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

always check the stack if there is one for the current PR. do not give localized reviews for the PR, always see all changes in the light of the whole stack of PRs (if there is a stack, if there is no stack you can continue to make localized suggestions/reviews)

Files:

  • core/providers/gemini/types.go
  • transports/bifrost-http/handlers/middlewares.go
  • plugins/governance/changelog.md
  • core/schemas/plugin.go
  • core/providers/anthropic/errors.go
  • transports/bifrost-http/handlers/middlewares_test.go
  • plugins/governance/main.go
  • transports/bifrost-http/integrations/genai.go
  • core/changelog.md
  • transports/changelog.md
🧠 Learnings (14)
📚 Learning: 2025-12-09T17:07:42.007Z
Learnt from: qwerty-dvorak
Repo: maximhq/bifrost PR: 1006
File: core/schemas/account.go:9-18
Timestamp: 2025-12-09T17:07:42.007Z
Learning: In core/schemas/account.go, the HuggingFaceKeyConfig field within the Key struct is currently unused and reserved for future Hugging Face inference endpoint deployments. Do not flag this field as missing from OpenAPI documentation or require its presence in the API spec until the feature is actively implemented and used. When the feature is added, update the OpenAPI docs accordingly; otherwise, treat this field as non-breaking and not part of the current API surface.

Applied to files:

  • core/providers/gemini/types.go
  • transports/bifrost-http/handlers/middlewares.go
  • core/schemas/plugin.go
  • core/providers/anthropic/errors.go
  • transports/bifrost-http/handlers/middlewares_test.go
  • plugins/governance/main.go
  • transports/bifrost-http/integrations/genai.go
📚 Learning: 2025-12-29T11:54:55.836Z
Learnt from: akshaydeo
Repo: maximhq/bifrost PR: 1153
File: framework/configstore/rdb.go:2221-2246
Timestamp: 2025-12-29T11:54:55.836Z
Learning: In Go reviews, do not flag range-over-int patterns like for i := range n as compile-time errors, assuming Go 1.22+ semantics. Only flag actual range-capable values (slices, arrays, maps, channels, strings) and other compile-time issues. This applies to all Go files across the repository.

Applied to files:

  • core/providers/gemini/types.go
  • transports/bifrost-http/handlers/middlewares.go
  • core/schemas/plugin.go
  • core/providers/anthropic/errors.go
  • transports/bifrost-http/handlers/middlewares_test.go
  • plugins/governance/main.go
  • transports/bifrost-http/integrations/genai.go
📚 Learning: 2026-01-14T04:40:11.480Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1312
File: framework/modelcatalog/pricing.go:276-426
Timestamp: 2026-01-14T04:40:11.480Z
Learning: In the Bifrost codebase, ImageUsage and other usage types guarantee that TotalTokens is populated (computed as InputTokens + OutputTokens if providers don’t supply TotalTokens). Reviewers can rely on this invariant and should not assume TotalTokens may be missing when input/output tokens exist. When implementing tiering logic or token-based decisions, you can safely use TotalTokens without extra null/zero guards, provided you’re in a context where InputTokens and OutputTokens are present. If a branch might discard tokens, ensure the invariant is preserved or add explicit checks only where the inputs are confirmed to be valid.

Applied to files:

  • core/providers/gemini/types.go
  • transports/bifrost-http/handlers/middlewares.go
  • core/schemas/plugin.go
  • core/providers/anthropic/errors.go
  • transports/bifrost-http/handlers/middlewares_test.go
  • plugins/governance/main.go
  • transports/bifrost-http/integrations/genai.go
📚 Learning: 2026-01-14T13:30:28.760Z
Learnt from: Radheshg04
Repo: maximhq/bifrost PR: 1326
File: plugins/semanticcache/test_utils.go:545-559
Timestamp: 2026-01-14T13:30:28.760Z
Learning: In the maximhq/bifrost repository, prefer using bifrost.Ptr() to create pointers instead of the address operator (&) even when & would be valid syntactically. Apply this consistently across all code paths, including test utilities, to improve consistency and readability. Replace occurrences of &value where a *T is expected with bifrost.Ptr(value) (or an equivalent call) and ensure the function is in scope and used correctly for the target pointer type.

Applied to files:

  • core/providers/gemini/types.go
  • transports/bifrost-http/handlers/middlewares.go
  • core/schemas/plugin.go
  • core/providers/anthropic/errors.go
  • transports/bifrost-http/handlers/middlewares_test.go
  • plugins/governance/main.go
  • transports/bifrost-http/integrations/genai.go
📚 Learning: 2025-12-19T09:26:54.961Z
Learnt from: qwerty-dvorak
Repo: maximhq/bifrost PR: 1006
File: core/providers/utils/utils.go:1050-1051
Timestamp: 2025-12-19T09:26:54.961Z
Learning: Update streaming end-marker handling so HuggingFace is treated as a non-[DONE] provider for backends that do not emit a DONE marker (e.g., meta llama on novita). In core/providers/utils/utils.go, adjust ProviderSendsDoneMarker() (or related logic) to detect providers that may not emit DONE and avoid relying on DONE as the sole end signal. Add tests to cover both DONE-emitting and non-DONE backends, with clear documentation in code comments explaining the rationale and any fallback behavior.

Applied to files:

  • core/providers/gemini/types.go
  • core/providers/anthropic/errors.go
📚 Learning: 2026-01-10T11:27:47.535Z
Learnt from: Radheshg04
Repo: maximhq/bifrost PR: 1256
File: core/providers/openai/openai.go:2276-2385
Timestamp: 2026-01-10T11:27:47.535Z
Learning: Validate image generation requests for nil and missing prompts before dispatch. Follow the same pattern used here: core/bifrost.go validates nil/empty prompts, providerUtils.CheckContextAndGetRequestBody returns a structured error when the request converter yields nil, and apply this across all providers (including OpenAI) to avoid sending null bodies.

Applied to files:

  • core/providers/gemini/types.go
  • core/providers/anthropic/errors.go
📚 Learning: 2026-01-14T10:53:44.658Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1326
File: core/providers/gemini/gemini.go:1679-1754
Timestamp: 2026-01-14T10:53:44.658Z
Learning: Validate image generation inputs in core/bifrost.go before invoking any provider handler. Ensure in all provider implementations (e.g., core/providers/gemini/gemini.go) that the request and request.Input are non-nil before use, to prevent nil dereferences and provide clear error handling. Apply this invariant broadly to all providers and add tests for nil input scenarios.

Applied to files:

  • core/providers/gemini/types.go
  • core/providers/anthropic/errors.go
📚 Learning: 2025-12-12T08:25:02.629Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1000
File: transports/bifrost-http/integrations/router.go:709-712
Timestamp: 2025-12-12T08:25:02.629Z
Learning: In transports/bifrost-http/**/*.go, update streaming response handling to align with OpenAI Responses API: use typed SSE events such as response.created, response.output_text.delta, response.done, etc., and do not rely on the legacy data: [DONE] termination marker. Note that data: [DONE] is only used by the older Chat Completions and Text Completions streaming APIs. Ensure parsers, writers, and tests distinguish SSE events from the [DONE] sentinel and handle each event type accordingly for correct stream termination and progress updates.

Applied to files:

  • transports/bifrost-http/handlers/middlewares.go
  • transports/bifrost-http/handlers/middlewares_test.go
  • transports/bifrost-http/integrations/genai.go
📚 Learning: 2025-12-29T09:14:16.633Z
Learnt from: akshaydeo
Repo: maximhq/bifrost PR: 888
File: transports/bifrost-http/handlers/middlewares.go:246-256
Timestamp: 2025-12-29T09:14:16.633Z
Learning: In the bifrost HTTP transport, fasthttp.RequestCtx is the primary context carrier and should be passed directly to functions that expect a context.Context. Do not convert to context.Context unless explicitly required. Ensure tracer implementations and related components are designed to accept fasthttp.RequestCtx directly, and document this architectural decision for maintainers.

Applied to files:

  • transports/bifrost-http/handlers/middlewares.go
  • transports/bifrost-http/handlers/middlewares_test.go
  • transports/bifrost-http/integrations/genai.go
📚 Learning: 2026-01-11T14:08:10.341Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1298
File: core/providers/anthropic/anthropic.go:682-699
Timestamp: 2026-01-11T14:08:10.341Z
Learning: In Anthroplic streaming implementations (and analogous providers), ensure that the final 'summary' chunk, which carries usage information and metadata, is emitted after all delta chunks and uses a chunk index of last_delta_index + 1. This differentiates the summary chunk from content delta chunks. Apply this convention consistently in the anthropic provider code and in similar streaming providers, and consider adding a targeted test to assert the ordering and chunk index logic.

Applied to files:

  • core/providers/anthropic/errors.go
📚 Learning: 2026-01-13T13:36:35.221Z
Learnt from: TejasGhatte
Repo: maximhq/bifrost PR: 1319
File: core/providers/anthropic/responses.go:937-937
Timestamp: 2026-01-13T13:36:35.221Z
Learning: In core/providers/anthropic/responses.go, when handling Anthropic API streaming responses, ensure that content_block_start events include a signature field set to an empty string (e.g., contentBlock.Signature = ""). The actual signature is delivered later via signature_delta events. This behavior is per Anthropic's specification and should not be treated as an error. This guideline should apply to all Anthropic response handling files under core/providers/anthropic/ and similar go files that process streaming blocks.

Applied to files:

  • core/providers/anthropic/errors.go
📚 Learning: 2026-01-14T06:57:42.750Z
Learnt from: TejasGhatte
Repo: maximhq/bifrost PR: 1319
File: core/providers/anthropic/types.go:248-336
Timestamp: 2026-01-14T06:57:42.750Z
Learning: For Anthropic citation types (page_location, char_location, content_block_location), ensure there is an optional string field file_id to reference uploaded files. Update the Go structs modeling these citations to include FileID *string (or string with omitempty) and document its optionality in comments, so code consuming these types can handle absence of file_id gracefully.

Applied to files:

  • core/providers/anthropic/errors.go
📚 Learning: 2026-01-14T06:57:42.750Z
Learnt from: TejasGhatte
Repo: maximhq/bifrost PR: 1319
File: core/providers/anthropic/types.go:248-336
Timestamp: 2026-01-14T06:57:42.750Z
Learning: In core/providers/anthropic/types.go, ensure the web_search_result_location citation type includes a string field named 'url' alongside the existing fields 'encrypted_index', 'title', and 'cited_text'. If the field is missing, add it with type string and appropriate struct tags (e.g., json and/or db tags) and update any related serialization or usage accordingly.

Applied to files:

  • core/providers/anthropic/errors.go
📚 Learning: 2025-12-22T10:50:40.990Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1154
File: plugins/governance/store.go:1165-1186
Timestamp: 2025-12-22T10:50:40.990Z
Learning: In the Bifrost governance plugin, budgets and rate limits have 1:1 relationships with their parent entities (virtual keys, teams, customers). Do not assume sharing; ensure cascade deletion logic only deletes budgets/rate limits when there are no shared references. Enforce invariants in code and add tests to verify no cross-entity sharing and that cascade deletes only remove the specific child of the parent. If a counterexample arises, adjust data model or add guards.

Applied to files:

  • plugins/governance/main.go
🧬 Code graph analysis (3)
transports/bifrost-http/handlers/middlewares_test.go (1)
core/schemas/plugin.go (2)
  • AcquireHTTPRequest (101-103)
  • ReleaseHTTPRequest (108-121)
plugins/governance/main.go (4)
core/schemas/context.go (1)
  • BifrostContext (32-43)
core/schemas/plugin.go (1)
  • HTTPRequest (31-38)
framework/configstore/tables/virtualkey.go (2)
  • TableVirtualKey (147-174)
  • TableVirtualKey (177-177)
core/providers/gemini/types.go (1)
  • GeminiRequestSuffixPaths (1751-1758)
transports/bifrost-http/integrations/genai.go (3)
transports/bifrost-http/integrations/router.go (1)
  • ListModelsResponseConverter (112-112)
core/schemas/models.go (1)
  • BifrostListModelsResponse (34-43)
core/providers/gemini/types.go (1)
  • GeminiRequestSuffixPaths (1751-1758)
⏰ 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). (32)
  • 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
  • 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
  • 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
  • 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
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
🔇 Additional comments (16)
core/changelog.md (1)

1-3: LGTM!

Changelog entries are well-formatted and accurately describe the changes: path parameter support in HTTPRequest and the Anthropic error response fix.

plugins/governance/changelog.md (1)

1-2: LGTM!

Changelog entries properly document the governance plugin changes. The "fix" prefix is appropriate as this addresses the VK provider routing issue for GenAI integration.

transports/bifrost-http/integrations/genai.go (2)

111-113: LGTM!

Formatting adjustment to the ListModelsResponseConverter field is consistent with the codebase style.


380-382: LGTM - good centralization of suffix paths.

Using gemini.GeminiRequestSuffixPaths instead of a hardcoded list ensures consistency with the Gemini provider's authoritative suffix definitions. This makes future suffix additions easier to maintain.

transports/changelog.md (1)

1-3: LGTM!

Changelog entries are clear and well-documented. The parenthetical note on line 2 helpfully explains the user-facing impact of the fix.

core/providers/gemini/types.go (1)

1750-1758: LGTM - well-defined suffix paths constant.

The exported GeminiRequestSuffixPaths provides a single source of truth for Gemini API endpoint suffixes, enabling consistent model normalization across the codebase. All six endpoint suffixes (:generateContent, :streamGenerateContent, :countTokens, :embedContent, :batchEmbedContents, :predict) match the current Gemini API specification and the list is complete.

core/schemas/plugin.go (4)

31-38: LGTM! PathParams field addition is well-integrated.

The new PathParams field follows the existing pattern for headers and query parameters. The JSON tag path_params maintains consistency with the snake_case convention used for other fields.


50-53: LGTM! CaseInsensitivePathParamLookup follows established patterns.

The method correctly delegates to the shared caseInsensitiveLookup helper, maintaining consistency with CaseInsensitiveHeaderLookup and CaseInsensitiveQueryLookup.


88-96: LGTM! Pool initialization includes PathParams with appropriate capacity.

The capacity of 4 for PathParams is reasonable given that URL path parameters are typically few in number. The pool properly pre-allocates all maps for efficient reuse.


113-116: LGTM! ReleaseHTTPRequest properly clears PathParams.

The clear(req.PathParams) call ensures the map is reset before returning to the pool, preventing data leakage between requests.

core/providers/anthropic/errors.go (3)

6-6: LGTM! Switched to sonic for better JSON performance.

The change from encoding/json to github.com/bytedance/sonic aligns with the codebase's preference for high-performance JSON handling.


18-26: LGTM! Improved nil-safety for error type extraction.

The explicit nil checks for bifrostErr.Error and bifrostErr.Error.Type prevent potential nil pointer dereferences. This is important since Type is a *string that may legitimately be nil.


49-49: LGTM! sonic.Marshal usage is correct.

The sonic.Marshal API is compatible with json.Marshal, making this a drop-in replacement with better performance.

plugins/governance/main.go (3)

15-15: LGTM! Gemini import added for suffix path constants.

The import enables use of gemini.GeminiRequestSuffixPaths for consistent suffix handling across the codebase.


315-325: LGTM! GenAI model extraction from path parameters.

The logic correctly handles the GenAI case where the model is in the URL path rather than the request body. The CaseInsensitivePathParamLookup ensures robust extraction regardless of parameter casing.


330-340: LGTM! GenAI suffix stripping for model normalization.

The code correctly strips Gemini request suffixes (:streamGenerateContent, :generateContent, etc.) from the model string and preserves the suffix for later reapplication. The early break after finding a match is efficient.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread transports/bifrost-http/handlers/middlewares_test.go
Comment thread transports/bifrost-http/handlers/middlewares.go
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 01-15-feat_added_fixes_for_genai_vk_provider_routing branch from f80b531 to 3f055c2 Compare January 14, 2026 21:46
Copy link
Copy Markdown
Contributor

akshaydeo commented Jan 14, 2026

Merge activity

  • Jan 14, 10:02 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jan 14, 10:03 PM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo akshaydeo changed the base branch from 01-14-feat_provider_preffixed_model_matching_enhancements_and_doc_updates to graphite-base/1335 January 14, 2026 22:02
@akshaydeo akshaydeo changed the base branch from graphite-base/1335 to main January 14, 2026 22:02
@akshaydeo akshaydeo merged commit fe89d2f into main Jan 14, 2026
3 of 4 checks passed
@akshaydeo akshaydeo deleted the 01-15-feat_added_fixes_for_genai_vk_provider_routing branch January 14, 2026 22:03
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