Skip to content

Conversation

Pratham-Mishra04
Copy link
Collaborator

Add OpenAI API compatibility layer to Bifrost HTTP transport

This PR adds an OpenAI-compatible API interface to the Bifrost HTTP transport, allowing applications designed for OpenAI's API to work with Bifrost without modification.

Key features:

  • Implements the /openai/v1/chat/completions endpoint
  • Supports both text-only and multimodal (vision) requests
  • Handles modern tool calls and legacy function calls
  • Provides bidirectional conversion between OpenAI and Bifrost request/response formats
  • Preserves all OpenAI parameters including temperature, max_tokens, etc.

The implementation includes:

  • A router for handling OpenAI API requests
  • Comprehensive type definitions for OpenAI request/response formats
  • Conversion logic between OpenAI and Bifrost data structures
  • Registration of the OpenAI router in the main HTTP transport

This enables seamless integration with existing OpenAI-compatible clients and tools while leveraging Bifrost's capabilities.

Copy link
Contributor

coderabbitai bot commented Jun 9, 2025

Summary by CodeRabbit

  • New Features
    • Added native OpenAI-compatible HTTP endpoint, allowing users to send OpenAI-style chat requests and receive responses in the OpenAI format.
    • Expanded support for multiple AI providers through dedicated endpoints, including both OpenAI and GenAI integrations.
  • Improvements
    • Enhanced routing infrastructure for integrations, providing more robust and flexible request handling.
    • Improved model selection and compatibility for GenAI requests via explicit model specification.
  • Documentation
    • Updated documentation to clarify provider-specific endpoint patterns and integration capabilities.

Summary by CodeRabbit

  • New Features
    • Added native support for OpenAI-compatible chat completion requests via a dedicated HTTP endpoint, enabling seamless integration with OpenAI's API format including vision capabilities with mixed text and image content.
    • Enhanced provider integration framework to support multiple AI providers (including OpenAI and GenAI) with flexible, provider-specific HTTP endpoints.
    • Improved request routing and conversion, allowing requests and responses to be automatically translated between provider-native and internal formats using a new generic routing infrastructure.
  • Documentation
    • Added detailed documentation on multi-provider integration endpoints and usage examples for OpenAI, GenAI, and Anthropic.
  • Chores
    • Refactored GenAI integration to embed the generic router and use route configs with pre-callbacks.
    • Integrated OpenAI extension routes into the HTTP server setup for expanded compatibility.
    • Introduced a comprehensive generic routing framework with interfaces, route configuration, and callback-driven request handling.

Walkthrough

The changes introduce a new OpenAI-compatible HTTP integration for the Bifrost system, including route registration, request/response conversion logic, and support for OpenAI's chat completion API with vision features. The GenAI integration was refactored to use the new generic routing framework. The main server now initializes and registers the OpenAI router alongside existing integrations, leveraging the new extensible routing infrastructure.

Changes

Files/Paths Change Summary
transports/bifrost-http/integrations/openai/router.go New file: Implements OpenAIRouter struct embedding GenericRouter, registers OpenAI chat completion route.
transports/bifrost-http/integrations/openai/types.go New file: Defines OpenAI chat request/response types and conversion logic to/from Bifrost formats.
transports/bifrost-http/main.go Imports OpenAI integration and adds OpenAI router to the HTTP server's extension routers slice.
transports/bifrost-http/integrations/genai/router.go Refactored GenAIRouter to embed GenericRouter, use route configs, and add pre-callback for model extraction. Removed explicit route registration and handlers.
transports/bifrost-http/integrations/genai/types.go Added Model field to GeminiChatRequest and updated ConvertToBifrostRequest to use it internally.
transports/bifrost-http/integrations/utils.go Added generic routing framework: ExtensionRouter interface, GenericRouter struct, route config, request/response converters, pre/post callbacks, and handler creation logic.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant OpenAIRouter
    participant BifrostClient

    Client->>OpenAIRouter: POST /openai/v1/chat/completions (OpenAI request)
    OpenAIRouter->>OpenAIRouter: Parse & validate request
    OpenAIRouter->>OpenAIRouter: Convert to BifrostRequest
    OpenAIRouter->>BifrostClient: ChatCompletionRequest(BifrostRequest)
    BifrostClient-->>OpenAIRouter: BifrostResponse
    OpenAIRouter->>OpenAIRouter: Convert to OpenAIChatResponse
    OpenAIRouter-->>Client: HTTP 200 + JSON (OpenAIChatResponse)
Loading

Possibly related PRs

Suggested reviewers

  • akshaydeo
  • danpiths

Poem

A router hops in, OpenAI in tow,
With chat and vision, watch it go!
Converts and connects, with types so neat,
Bifrost and OpenAI now meet.
The server grows, new routes appear—
More magic for all, the future is here!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Collaborator Author

Pratham-Mishra04 commented Jun 9, 2025

Copy link
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: 7

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac54c86 and b015950.

📒 Files selected for processing (3)
  • transports/bifrost-http/integrations/openai/router.go (1 hunks)
  • transports/bifrost-http/integrations/openai/types.go (1 hunks)
  • transports/bifrost-http/main.go (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
transports/bifrost-http/main.go (3)
transports/bifrost-http/integrations/utils.go (1)
  • ExtensionRouter (5-7)
transports/bifrost-http/integrations/genai/router.go (1)
  • NewGenAIRouter (18-20)
transports/bifrost-http/integrations/openai/router.go (1)
  • NewOpenAIRouter (35-37)
🔇 Additional comments (1)
transports/bifrost-http/main.go (1)

180-183: OpenAI router successfully wired in – nothing blocking
Nice, the new router is appended in the same extensions slice as the existing GenAI router, so registration order stays deterministic and no paths collide with the legacy /v1/* routes.

@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 06-09-feat_openai_integration_added_to_http_transport branch from b015950 to 111399d Compare June 9, 2025 11:42
Copy link
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

♻️ Duplicate comments (3)
transports/bifrost-http/integrations/openai/router.go (3)

46-58: ⚠️ Potential issue

Missing validation for empty messages array

OpenAI requires at least one message; forwarding an empty slice will explode deeper in the stack. Add the gate here, similar to what exists in main.go.

+	if len(req.Messages) == 0 {
+		ctx.SetStatusCode(fasthttp.StatusBadRequest)
+		ctx.SetContentType("application/json")
+		ctx.SetBodyString(`{"error":"messages array is required"}`)
+		return
+	}

47-52: 🧹 Nitpick (assertive)

Content-Type header missing on 400 replies

Clients expecting JSON will choke unless the header is set.

-		ctx.SetStatusCode(fasthttp.StatusBadRequest)
+		ctx.SetStatusCode(fasthttp.StatusBadRequest)
+		ctx.SetContentType("application/json")

64-70: 🛠️ Refactor suggestion

Return correct HTTP status & set Content-Type on errors

Every error is currently surfaced as 500. Use the same 4xx/5xx branching adopted in main.go and mark the body as JSON.

-	if err != nil {
-		ctx.SetStatusCode(fasthttp.StatusInternalServerError)
+	if err != nil {
+		if err.IsBifrostError {
+			ctx.SetStatusCode(fasthttp.StatusInternalServerError)
+		} else {
+			ctx.SetStatusCode(fasthttp.StatusBadRequest)
+		}
+		ctx.SetContentType("application/json")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b015950 and 111399d.

📒 Files selected for processing (3)
  • transports/bifrost-http/integrations/openai/router.go (1 hunks)
  • transports/bifrost-http/integrations/openai/types.go (1 hunks)
  • transports/bifrost-http/main.go (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
transports/bifrost-http/integrations/openai/router.go (2)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.907Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and handles the conversion internally, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.907Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and always returns a pointer to a valid context. It starts with context.Background() and only adds values to it, so nil checks are not needed when calling this function.
🧬 Code Graph Analysis (2)
transports/bifrost-http/main.go (3)
transports/bifrost-http/integrations/utils.go (1)
  • ExtensionRouter (5-7)
transports/bifrost-http/integrations/genai/router.go (1)
  • NewGenAIRouter (18-20)
transports/bifrost-http/integrations/openai/router.go (1)
  • NewOpenAIRouter (35-37)
transports/bifrost-http/integrations/openai/types.go (3)
core/utils.go (1)
  • Ptr (3-5)
core/schemas/bifrost.go (25)
  • ToolChoiceTypeFunction (126-126)
  • ToolCall (266-270)
  • FunctionCall (260-263)
  • Function (101-105)
  • Tool (108-112)
  • ToolChoice (137-140)
  • LLMUsage (197-203)
  • ImageContent (174-179)
  • BifrostRequest (54-64)
  • OpenAI (34-34)
  • RequestInput (46-49)
  • BifrostMessage (143-152)
  • ModelParameters (75-89)
  • ModelChatMessageRole (20-20)
  • ModelChatMessageRoleUser (24-24)
  • UserMessage (155-157)
  • ModelChatMessageRoleTool (27-27)
  • ToolMessage (160-163)
  • AssistantMessage (166-171)
  • ToolChoiceType (116-116)
  • ToolChoiceTypeNone (120-120)
  • ToolChoiceTypeAuto (122-122)
  • ToolChoiceTypeRequired (128-128)
  • ToolChoiceFunction (132-134)
  • BifrostResponse (184-194)
core/schemas/provider.go (1)
  • Provider (142-149)

@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 06-09-feat_openai_integration_added_to_http_transport branch from 111399d to 7ee161c Compare June 9, 2025 13:50
Copy link
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: 3

♻️ Duplicate comments (2)
transports/bifrost-http/main.go (1)

180-183: LGTM: Proper router registration.

The OpenAI router is correctly registered alongside the GenAI router using the extensions framework.

The package-level documentation (lines 4-6) needs to be updated to include the newly exposed /openai/v1/chat/completions route alongside the existing routes, as mentioned in previous reviews.

transports/bifrost-http/integrations/openai/types.go (1)

185-190: ⚠️ Potential issue

Compilation failure – cannot range over an int

requestVal.NumField() returns an int, not a slice.
for i := range requestVal.NumField() will not compile.

-for i := range requestVal.NumField() {
+for i := 0; i < requestVal.NumField(); i++ {

Without this fix go vet, go test, and go build all fail.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 111399d and 7ee161c.

📒 Files selected for processing (6)
  • transports/bifrost-http/integrations/genai/router.go (1 hunks)
  • transports/bifrost-http/integrations/genai/types.go (2 hunks)
  • transports/bifrost-http/integrations/openai/router.go (1 hunks)
  • transports/bifrost-http/integrations/openai/types.go (1 hunks)
  • transports/bifrost-http/integrations/utils.go (1 hunks)
  • transports/bifrost-http/main.go (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
transports/bifrost-http/integrations/openai/router.go (2)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.907Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and handles the conversion internally, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.907Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and always returns a pointer to a valid context. It starts with context.Background() and only adds values to it, so nil checks are not needed when calling this function.
🧬 Code Graph Analysis (3)
transports/bifrost-http/main.go (3)
transports/bifrost-http/integrations/utils.go (1)
  • ExtensionRouter (15-17)
transports/bifrost-http/integrations/genai/router.go (1)
  • NewGenAIRouter (19-41)
transports/bifrost-http/integrations/openai/router.go (1)
  • NewOpenAIRouter (16-37)
transports/bifrost-http/integrations/openai/router.go (3)
transports/bifrost-http/integrations/utils.go (4)
  • GenericRouter (52-55)
  • RouteConfig (39-47)
  • RequestConverter (21-21)
  • NewGenericRouter (59-64)
core/bifrost.go (2)
  • Bifrost (39-51)
  • RequestType (20-20)
core/schemas/bifrost.go (2)
  • BifrostRequest (54-64)
  • BifrostResponse (184-194)
transports/bifrost-http/integrations/utils.go (3)
core/schemas/bifrost.go (2)
  • BifrostRequest (54-64)
  • BifrostResponse (184-194)
core/bifrost.go (3)
  • RequestType (20-20)
  • Bifrost (39-51)
  • ChatCompletionRequest (24-24)
transports/bifrost-http/lib/ctx.go (1)
  • ConvertToBifrostContext (43-73)
🔇 Additional comments (7)
transports/bifrost-http/main.go (1)

33-33: LGTM: Clean import addition.

The import for the OpenAI integration package is properly added.

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

15-15: LGTM: Model field addition supports the new routing pattern.

The explicit Model field allows the router's pre-callback to set the model from the URL path parameter, which is cleaner than passing it as a separate parameter.


24-27: LGTM: Method signature simplified correctly.

The removal of the modelStr parameter and use of r.Model field aligns with the new generic router framework where the model is set via the extractAndSetModelFromURL pre-callback.

transports/bifrost-http/integrations/openai/router.go (1)

9-13: LGTM: Clean router struct definition.

The OpenAIRouter properly embeds the GenericRouter following the same pattern as the GenAI integration.

transports/bifrost-http/integrations/genai/router.go (3)

14-16: LGTM: Successful refactoring to generic router framework.

The GenAIRouter now properly embeds the GenericRouter, eliminating code duplication and leveraging the shared routing infrastructure.

Also applies to: 38-41


20-36: LGTM: Clean declarative route configuration.

The route configuration clearly defines:

  • Path with model parameter: /genai/v1beta/models/{model}
  • Request/response conversion functions
  • Pre-callback for model extraction

This approach is much cleaner than the previous imperative handler method.


43-68: LGTM: Robust model extraction logic.

The extractAndSetModelFromURL function properly:

  • Validates the model parameter exists
  • Cleans the model string (removes :generateContent suffix and trailing colons)
  • Adds the required google/ prefix
  • Type-checks the request before setting the model field
  • Returns appropriate error messages

@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 06-09-feat_openai_integration_added_to_http_transport branch from 7ee161c to 4ad600d Compare June 9, 2025 14:20
Copy link
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

♻️ Duplicate comments (2)
transports/bifrost-http/integrations/utils.go (1)

96-103: Re-use of a single request object – identical to previous review feedback

The same concurrency bug described above was flagged in an earlier review and is still present.
Please address it to avoid panics / corrupted requests.

transports/bifrost-http/integrations/openai/types.go (1)

185-190: ⚠️ Potential issue

Compilation fails – cannot range over an int

reflect.Value.NumField() returns an int, not a slice.
The current loop does not compile.

-	for i := range requestVal.NumField() {
+	for i := 0; i < requestVal.NumField(); i++ {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ee161c and 4ad600d.

📒 Files selected for processing (6)
  • transports/bifrost-http/integrations/genai/router.go (1 hunks)
  • transports/bifrost-http/integrations/genai/types.go (2 hunks)
  • transports/bifrost-http/integrations/openai/router.go (1 hunks)
  • transports/bifrost-http/integrations/openai/types.go (1 hunks)
  • transports/bifrost-http/integrations/utils.go (1 hunks)
  • transports/bifrost-http/main.go (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
transports/bifrost-http/integrations/openai/router.go (3)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.907Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and handles the conversion internally, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.907Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and always returns a pointer to a valid context. It starts with context.Background() and only adds values to it, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:0-0
Timestamp: 2025-06-09T14:03:34.187Z
Learning: In the Bifrost HTTP transport layer (transports/bifrost-http/integrations/), request validation like checking for empty messages should be handled by the provider rather than at the transport layer. The transport layer should forward requests to Bifrost core/providers for validation.
🧬 Code Graph Analysis (1)
transports/bifrost-http/integrations/genai/types.go (2)
core/schemas/bifrost.go (2)
  • BifrostRequest (54-64)
  • Vertex (39-39)
core/schemas/provider.go (1)
  • Provider (142-149)
🔇 Additional comments (7)
transports/bifrost-http/main.go (2)

16-29: Excellent documentation enhancement!

The comprehensive documentation clearly explains the integration support pattern and provides concrete examples for OpenAI, GenAI, and Anthropic endpoints. This addresses the previous feedback about updating package documentation to reflect the full API surface area.


194-197: Clean integration following established patterns.

The OpenAI router registration alongside GenAI demonstrates consistent use of the generic router framework. Both integrations follow the same ExtensionRouter interface pattern.

transports/bifrost-http/integrations/openai/router.go (1)

16-37: Well-structured router following established patterns.

The OpenAI router implementation effectively leverages the generic router framework with:

  • Correct endpoint path /openai/v1/chat/completions
  • Proper request type and conversion logic
  • Response transformation function

This design avoids code duplication and maintains consistency with the GenAI integration approach.

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

15-15: Good addition of model field for cleaner architecture.

Adding the Model field directly to the request struct simplifies the conversion interface and aligns well with the router's URL-based model extraction pattern.


24-27: Clean refactoring of conversion method.

The removal of the modelStr parameter and use of the embedded r.Model field creates a more cohesive API where the request object contains all necessary data for conversion.

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

20-41: Excellent refactoring to generic router framework.

The migration to use RouteConfig with defined converters and callbacks demonstrates good architectural consistency. The PreCallback for model extraction ensures the model is properly set before request conversion.


43-68: Robust model extraction with proper error handling.

The extractAndSetModelFromURL function correctly:

  • Validates model parameter presence
  • Handles GenAI-specific URL suffixes (:generateContent)
  • Adds required google/ prefix for Bifrost compatibility
  • Provides appropriate error messages for invalid cases

@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 06-09-feat_openai_integration_added_to_http_transport branch 2 times, most recently from fbd3a73 to e0e01b8 Compare June 9, 2025 14:32
Copy link
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: 9

♻️ Duplicate comments (2)
transports/bifrost-http/integrations/utils.go (2)

40-46: Shared RequestType instance -> data-race persists
The field is still interface{} and a single value is re-used for every request. This reproduces the request-bleed / data-race problem already reported in earlier reviews.


98-110: req := config.RequestType mutates the same object for all calls
Because the previous issue is unresolved, json.Unmarshal will mutate the shared struct concurrently, corrupting state under load. A per-request factory (NewRequest func() interface{}) is still required.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ad600d and 4cf3b95.

📒 Files selected for processing (6)
  • transports/bifrost-http/integrations/genai/router.go (1 hunks)
  • transports/bifrost-http/integrations/genai/types.go (2 hunks)
  • transports/bifrost-http/integrations/openai/router.go (1 hunks)
  • transports/bifrost-http/integrations/openai/types.go (1 hunks)
  • transports/bifrost-http/integrations/utils.go (1 hunks)
  • transports/bifrost-http/main.go (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
transports/bifrost-http/integrations/openai/router.go (3)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and handles the conversion internally, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and always returns a pointer to a valid context. It starts with context.Background() and only adds values to it, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:0-0
Timestamp: 2025-06-09T14:03:34.227Z
Learning: In the Bifrost HTTP transport layer (transports/bifrost-http/integrations/), request validation like checking for empty messages should be handled by the provider rather than at the transport layer. The transport layer should forward requests to Bifrost core/providers for validation.
🧬 Code Graph Analysis (2)
transports/bifrost-http/integrations/genai/types.go (2)
core/schemas/bifrost.go (2)
  • BifrostRequest (54-64)
  • Vertex (39-39)
core/schemas/provider.go (1)
  • Provider (142-149)
transports/bifrost-http/main.go (3)
transports/bifrost-http/integrations/utils.go (1)
  • ExtensionRouter (15-17)
transports/bifrost-http/integrations/genai/router.go (1)
  • NewGenAIRouter (19-41)
transports/bifrost-http/integrations/openai/router.go (1)
  • NewOpenAIRouter (16-37)
🔇 Additional comments (3)
transports/bifrost-http/integrations/openai/types.go (1)

278-289: Assistant message may duplicate legacy + modern tool-calls

If both tool_calls and function_call are present (some SDKs send both),
the legacy branch is skipped, which is correct.
However, if tool_calls is absent but function_call contains a non-function
tool (future spec), we will silently coerce it into function.

Please double-check the spec and add a guard / type switch so that only a real
function call is mapped here.

transports/bifrost-http/main.go (1)

194-197: Good: router slice kept alphabetical

OpenAI router addition follows existing order and keeps the slice tidy.

transports/bifrost-http/integrations/genai/types.go (1)

24-31: Model field is optional but required downstream

GeminiChatRequest.ConvertToBifrostRequest now relies on r.Model. If the
URL pre-callback fails to set it (e.g., malformed route), the provider will get
an empty model string and likely 4xx/5xx later.

Consider an explicit if r.Model == "" { return nil /* or error */ } early in
the converter, letting GenericRouter translate that into 400.

@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 06-09-feat_openai_integration_added_to_http_transport branch from 4cf3b95 to 72f5791 Compare June 10, 2025 10:25
Copy link
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: 7

🔭 Outside diff range comments (1)
transports/bifrost-http/integrations/genai/types.go (1)

65-68: 🧹 Nitpick (assertive)

Redundant nil-guard after guaranteed allocation

ChatCompletionInput is initialised at line 28, so the subsequent nil check is dead code.
Simplify to avoid misleading future readers:

-if bifrostReq.Input.ChatCompletionInput != nil {
-    *bifrostReq.Input.ChatCompletionInput = append(*bifrostReq.Input.ChatCompletionInput, bifrostMsg)
-}
+*bifrostReq.Input.ChatCompletionInput = append(*bifrostReq.Input.ChatCompletionInput, bifrostMsg)
♻️ Duplicate comments (2)
transports/bifrost-http/main.go (1)

16-30: Doc-block still duplicates endpoint lists

The new “Integration Support” section (lines 16-30) lists provider-specific paths, yet lines 4-6 above still enumerate only /v1/* routes. This resurrects the same duplication/contradiction flagged in the previous review.

Please consolidate the two lists into a single, ordered set so autogenerated docs and readers see an accurate, non-redundant surface area.

transports/bifrost-http/integrations/openai/types.go (1)

92-117: 🛠️ Refactor suggestion

⚠️ Potential issue

Silently drops all but the last image in multi-image prompts

Every time an image_url part is encountered, imageContent is overwritten, so only the URL from the final part survives. The vision spec explicitly allows multiple images; at the moment they are lost without warning.

-        var imageContent *schemas.ImageContent
+        var imageList []schemas.ImageContent
 ...
-                                imageContent = &schemas.ImageContent{
-                                    URL: url,
-                                }
+                                img := schemas.ImageContent{URL: url}
+                                if detail, detailExists := imageURL["detail"].(string); detailExists {
+                                    img.Detail = &detail
+                                }
+                                imageList = append(imageList, img)
 ...
-        return textContent, imageContent
+        switch len(imageList) {
+        case 0:
+            return textContent, nil
+        case 1:
+            return textContent, &imageList[0]
+        default:
+            return nil, nil // or return an error stating multi-image not yet supported
+        }

Either collect all images and propagate a slice downstream, or reject multi-image requests with an explicit error to avoid silent data loss.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4cf3b95 and 72f5791.

📒 Files selected for processing (6)
  • transports/bifrost-http/integrations/genai/router.go (1 hunks)
  • transports/bifrost-http/integrations/genai/types.go (2 hunks)
  • transports/bifrost-http/integrations/openai/router.go (1 hunks)
  • transports/bifrost-http/integrations/openai/types.go (1 hunks)
  • transports/bifrost-http/integrations/utils.go (1 hunks)
  • transports/bifrost-http/main.go (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
transports/bifrost-http/integrations/openai/router.go (3)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and handles the conversion internally, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and always returns a pointer to a valid context. It starts with context.Background() and only adds values to it, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:0-0
Timestamp: 2025-06-09T14:03:34.227Z
Learning: In the Bifrost HTTP transport layer (transports/bifrost-http/integrations/), request validation like checking for empty messages should be handled by the provider rather than at the transport layer. The transport layer should forward requests to Bifrost core/providers for validation.
🧬 Code Graph Analysis (2)
transports/bifrost-http/main.go (3)
transports/bifrost-http/integrations/utils.go (1)
  • ExtensionRouter (15-17)
transports/bifrost-http/integrations/genai/router.go (1)
  • NewGenAIRouter (19-41)
transports/bifrost-http/integrations/openai/router.go (1)
  • NewOpenAIRouter (16-37)
transports/bifrost-http/integrations/genai/types.go (2)
core/schemas/bifrost.go (2)
  • BifrostRequest (54-64)
  • Vertex (39-39)
core/schemas/provider.go (1)
  • Provider (142-149)
🔇 Additional comments (1)
transports/bifrost-http/integrations/openai/types.go (1)

139-141: 🧹 Nitpick (assertive)

Avoid taking the address of a composite slice literal

&[]schemas.BifrostMessage{} allocates an unnecessary pointer; a zero-value slice is already nil, and you can append to it directly.

-    Input: schemas.RequestInput{
-        ChatCompletionInput: &[]schemas.BifrostMessage{},
-    },
+    Input: schemas.RequestInput{},
 ...
 // later
- *bifrostReq.Input.ChatCompletionInput = append(...)
+ bifrostReq.Input.ChatCompletionInput =
+     append(bifrostReq.Input.ChatCompletionInput, bifrostMsg)

This removes one level of indirection and simplifies subsequent code.

⛔ Skipped due to learnings
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#54
File: core/schemas/bifrost.go:46-49
Timestamp: 2025-06-04T09:22:18.123Z
Learning: In core/schemas/bifrost.go, the RequestInput struct uses ChatCompletionInput *[]BifrostMessage (pointer-to-slice) rather than []BifrostMessage to properly represent union type semantics. For text completion requests, ChatCompletionInput should be nil to indicate "no chat payload at all", while for chat completion requests it should be non-nil (even if empty slice). This distinguishes between different request types rather than just empty vs non-empty chat messages.

@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 06-09-feat_openai_integration_added_to_http_transport branch from 72f5791 to d68ae37 Compare June 10, 2025 11:04
@akshaydeo akshaydeo marked this pull request as ready for review June 10, 2025 11:38
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Bug: Race Condition in `GenericRouter` Causes Data Corruption

The GenericRouter has a race condition where the config.RequestType instance is reused across concurrent HTTP requests. This causes multiple goroutines to unmarshal JSON into the same shared object, leading to data corruption, unpredictable behavior, and data leakage. A new instance of the request type must be created for each request.

transports/bifrost-http/integrations/utils.go#L95-L110

return func(ctx *fasthttp.RequestCtx) {
// Parse request body into the integration-specific request type
// Skip JSON unmarshalling for methods that typically don't have request bodies
req := config.RequestType
method := string(ctx.Method())
if method != "GET" && method != "DELETE" {
// Use ctx.Request.Body() instead of ctx.PostBody() to support all HTTP methods
body := ctx.Request.Body()
if len(body) > 0 {
if err := json.Unmarshal(body, req); err != nil {
g.sendError(ctx, fasthttp.StatusBadRequest, "Invalid JSON: "+err.Error())
return
}
}
}

Fix in Cursor


BugBot free trial expires on June 17, 2025
You have used $0.00 of your $50.00 spend limit so far. Manage your spend limit in the Cursor dashboard.

Was this report helpful? Give feedback by reacting with 👍 or 👎

Copy link
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

♻️ Duplicate comments (8)
transports/bifrost-http/main.go (1)

47-47: OpenAI integration successfully integrated into the HTTP transport.

The OpenAI router is properly imported and registered alongside GenAI using the new generic routing infrastructure. The implementation follows the established pattern.

Also applies to: 194-197

transports/bifrost-http/integrations/openai/router.go (1)

16-37: Router configuration follows the established pattern correctly.

The route configuration properly defines the OpenAI endpoint with appropriate converters. The implementation leverages the generic router effectively.

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

19-41: Well-structured route configuration with appropriate callbacks.

The route configuration properly uses the generic framework with a pre-request callback for model extraction, demonstrating good use of the extensibility features.


43-71: Model extraction logic correctly handles URL parameters.

The extractAndSetModelFromURL function properly extracts, normalizes, and sets the model parameter with appropriate error handling.

transports/bifrost-http/integrations/utils.go (3)

101-110: Appropriate handling of request body parsing for different HTTP methods.

The code correctly skips body parsing for GET and DELETE methods, avoiding unnecessary JSON unmarshal errors.


183-187: Fixed: Marshal errors are now properly handled.

The code now checks for JSON marshaling errors and sends an appropriate error response instead of silently ignoring failures.


42-43: ⚠️ Potential issue

Critical: Documentation states "Factory function" but field type doesn't match.

The comment describes RequestType as a "Factory function to create request instance", but the field is declared as interface{} rather than a function type. This mismatch between documentation and implementation is confusing and the current implementation causes thread safety issues.

transports/bifrost-http/integrations/openai/types.go (1)

80-127: Multi-image payloads still silently drop all but the last image
The function keeps overwriting imageContent, so only the final image_url survives. This limitation was highlighted (and acknowledged) in earlier PR rounds and is still present.

I’m not re-opening the architectural discussion, just linking the prior finding for completeness.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 72f5791 and d68ae37.

📒 Files selected for processing (6)
  • transports/bifrost-http/integrations/genai/router.go (1 hunks)
  • transports/bifrost-http/integrations/genai/types.go (2 hunks)
  • transports/bifrost-http/integrations/openai/router.go (1 hunks)
  • transports/bifrost-http/integrations/openai/types.go (1 hunks)
  • transports/bifrost-http/integrations/utils.go (1 hunks)
  • transports/bifrost-http/main.go (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
transports/bifrost-http/integrations/openai/router.go (5)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and handles the conversion internally, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:62-64
Timestamp: 2025-06-09T11:27:00.925Z
Learning: The `lib.ConvertToBifrostContext` function in the bifrost HTTP transport never returns nil and always returns a pointer to a valid context. It starts with context.Background() and only adds values to it, so nil checks are not needed when calling this function.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/router.go:0-0
Timestamp: 2025-06-09T14:03:34.227Z
Learning: In the Bifrost HTTP transport layer (transports/bifrost-http/integrations/), request validation like checking for empty messages should be handled by the provider rather than at the transport layer. The transport layer should forward requests to Bifrost core/providers for validation.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.578Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error, making additional nil checks in individual router implementations redundant.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#67
File: transports/bifrost-http/integrations/anthropic/router.go:26-34
Timestamp: 2025-06-10T11:19:29.578Z
Learning: The Generic router in transports/bifrost-http/integrations/utils.go already handles nil pointers from RequestConverter functions. When a RequestConverter returns a nil *schemas.BifrostRequest, the Generic router automatically returns an HTTP 400 error with "Invalid request" message, making additional nil checks in individual router implementations redundant.
transports/bifrost-http/integrations/openai/types.go (4)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:89-119
Timestamp: 2025-06-10T11:00:02.852Z
Learning: In the Bifrost OpenAI integration (transports/bifrost-http/integrations/openai/types.go), the convertOpenAIContent function currently only handles the last image URL when multiple images are present in a content array. The user Pratham-Mishra04 has acknowledged this limitation and indicated it's part of a larger architectural issue that will be addressed comprehensively later, rather than with piecemeal fixes.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#64
File: transports/bifrost-http/integrations/genai/types.go:273-313
Timestamp: 2025-06-09T16:35:26.914Z
Learning: In convertGenerationConfigToParams method in transports/bifrost-http/integrations/genai/types.go, pre-allocating the ExtraParams map is preferred over lazy allocation because the method has multiple potential ExtraParams assignments, making the computational overhead of conditional checks exceed the memory savings of an empty map.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#63
File: transports/bifrost-http/integrations/openai/types.go:223-231
Timestamp: 2025-06-10T11:06:06.651Z
Learning: The OpenAI `name` field on messages cannot be preserved when converting to Bifrost format because the `schemas.BifrostMessage` struct in bifrost/core does not support a Name field. This is a known limitation of the Bifrost core schema design.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#64
File: transports/bifrost-http/integrations/genai/types.go:470-515
Timestamp: 2025-06-10T11:06:57.681Z
Learning: Bifrost currently only supports images and does not support non-image blob types like audio, PDF, or other binary data formats.
🧬 Code Graph Analysis (2)
transports/bifrost-http/main.go (3)
transports/bifrost-http/integrations/utils.go (1)
  • ExtensionRouter (15-17)
transports/bifrost-http/integrations/genai/router.go (1)
  • NewGenAIRouter (19-41)
transports/bifrost-http/integrations/openai/router.go (1)
  • NewOpenAIRouter (16-37)
transports/bifrost-http/integrations/genai/types.go (2)
core/schemas/bifrost.go (2)
  • BifrostRequest (54-64)
  • Vertex (39-39)
core/schemas/provider.go (1)
  • Provider (142-149)
🔇 Additional comments (11)
transports/bifrost-http/main.go (1)

16-30: LGTM! Clear documentation of integration support.

The added documentation provides excellent clarity on Bifrost's multi-provider integration support, including the URL pattern and specific examples for each provider.

transports/bifrost-http/integrations/openai/router.go (1)

9-13: LGTM! Well-structured router implementation.

The router properly embeds GenericRouter and includes clear documentation about its capabilities.

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

15-15: Model field addition enables cleaner request handling.

Adding the Model field directly to the struct eliminates the need for parameter passing and aligns well with the generic router's pre-callback pattern.


24-27: Simplified method signature improves encapsulation.

The removal of the modelStr parameter and use of the struct's Model field makes the conversion method self-contained and cleaner.

transports/bifrost-http/integrations/genai/router.go (1)

14-16: Successful refactoring to use generic router infrastructure.

The GenAIRouter now properly embeds GenericRouter, eliminating code duplication and following the new integration pattern.

transports/bifrost-http/integrations/utils.go (6)

13-17: Clean interface definition for integration routers.

The ExtensionRouter interface provides a clear contract for all integration routers to implement.


19-36: Well-documented type definitions for the routing framework.

The converter and callback types are clearly defined with comprehensive documentation explaining their purpose and usage.


52-64: Well-designed generic router struct with clear documentation.

The GenericRouter provides a solid foundation for all integration routers with proper encapsulation of common functionality.


66-84: Comprehensive route registration with support for multiple HTTP methods.

The implementation properly handles different HTTP methods and provides a sensible default.


123-131: Proper validation of converted requests.

The handler appropriately checks for nil returns from the converter and validates required fields like the model parameter.


137-142: Improved error status code handling.

The code now properly uses the status code from BifrostError when available, providing more accurate HTTP status codes.

Copy link
Contributor

@Pratham-Mishra04 did you check Race condition comment by cursor?

Copy link
Collaborator Author

yes yes, fixed in next pr

Copy link
Contributor

akshaydeo commented Jun 10, 2025

Merge activity

  • Jun 10, 4:28 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 10, 4:28 PM UTC: @akshaydeo merged this pull request with Graphite.

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