Conversation
|
Caution Review failedThe pull request is closed. Summary by CodeRabbit
Summary by CodeRabbit
WalkthroughThese changes introduce Anthropic API compatibility to the Bifrost HTTP transport layer. New files define request/response types and conversion logic between Anthropic and Bifrost schemas. An Anthropic router is added, handling Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant AnthropicRouter
participant BifrostClient
participant CoreProvider
Client->>AnthropicRouter: POST /anthropic/v1/messages (AnthropicMessageRequest)
AnthropicRouter->>AnthropicRouter: Convert AnthropicMessageRequest to BifrostRequest
AnthropicRouter->>BifrostClient: ChatCompletionRequest(BifrostRequest)
BifrostClient->>CoreProvider: Process request
CoreProvider-->>BifrostClient: BifrostResponse
BifrostClient-->>AnthropicRouter: BifrostResponse
AnthropicRouter->>AnthropicRouter: Convert BifrostResponse to AnthropicMessageResponse
AnthropicRouter-->>Client: 200 OK (AnthropicMessageResponse)
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (7)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
This stack of pull requests is managed by Graphite. Learn more about stacking. |
There was a problem hiding this comment.
Actionable comments posted: 9
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (4)
core/providers/anthropic.go(1 hunks)transports/bifrost-http/integrations/anthropic/router.go(1 hunks)transports/bifrost-http/integrations/anthropic/types.go(1 hunks)transports/bifrost-http/main.go(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
transports/bifrost-http/main.go (1)
transports/bifrost-http/integrations/anthropic/router.go (1)
NewAnthropicRouter(18-20)
transports/bifrost-http/integrations/anthropic/router.go (3)
core/bifrost.go (2)
Bifrost(39-51)ChatCompletionRequest(24-24)transports/bifrost-http/integrations/anthropic/types.go (2)
AnthropicMessageRequest(90-102)DeriveAnthropicFromBifrostResponse(314-377)transports/bifrost-http/lib/ctx.go (1)
ConvertToBifrostContext(43-73)
🔇 Additional comments (5)
transports/bifrost-http/main.go (2)
32-33: Import side-effect looks goodAnthropic integration is cleanly added to the imports; no issues spotted.
184-185: Router registration order OK but watch for route collisionsAdding
anthropic.NewAnthropicRouterafter OpenAI/GenAI is fine; routes are namespaced (/anthropic/...) so no collisions expected.core/providers/anthropic.go (1)
486-488: Nice consolidation of switch casesThe
fallthroughcorrectly deduplicates logic for"function"vs"tool"types. 👍transports/bifrost-http/integrations/anthropic/router.go (2)
1-10: LGTM! Clean package structure and appropriate imports.The package declaration and imports are well-organized and include all necessary dependencies for the Anthropic integration.
12-25: LGTM! Well-structured router with clean separation of concerns.The AnthropicRouter struct, constructor, and route registration follow Go best practices and properly encapsulate the Bifrost client dependency.
70efb6c to
9bc0828
Compare
dde6b39 to
2cbc913
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (4)
transports/bifrost-http/integrations/anthropic/router.go (2)
34-35: Don’t ignore JSON-marshal errors
Silently discardingjson.Marshalfailures makes diagnosis impossible. At minimum, log and fall back to 500.
40-42: Inconsistent error format (plain text vs JSON)
The 400 branch returns a plain string whereas all other branches return JSON.transports/bifrost-http/integrations/anthropic/types.go (2)
283-292: Swallowed marshal errors hide malformed inputs
jsonifyInputreturns"{}"on marshal failure, discarding information that could aid debugging and corrupting arguments.
104-112:⚠️ Potential issue
Streamflag is dropped – streaming requests executed in non-streaming mode
AnthropicMessageRequest.Streamis parsed but never propagated toschemas.BifrostRequest, breaking the contract for callers expecting SSE.Input: schemas.RequestInput{ ChatCompletionInput: &[]schemas.BifrostMessage{}, }, + Stream: r.Stream, }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (4)
core/providers/anthropic.go(1 hunks)transports/bifrost-http/integrations/anthropic/router.go(1 hunks)transports/bifrost-http/integrations/anthropic/types.go(1 hunks)transports/bifrost-http/main.go(2 hunks)
🧰 Additional context used
🧠 Learnings (2)
core/providers/anthropic.go (1)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:483-494
Timestamp: 2025-06-04T09:36:27.956Z
Learning: In the Anthropic provider (core/providers/anthropic.go), the user has confirmed through practical experience that the tool_choice parameter should always use an object format with a "type" field (e.g., {"type": "auto"}, {"type": "tool", "name": "function_name"}), even though the official documentation examples sometimes show "auto" as a direct string. The current implementation correctly handles all tool choice types with the object format.
transports/bifrost-http/integrations/anthropic/types.go (1)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:483-494
Timestamp: 2025-06-04T09:36:27.956Z
Learning: In the Anthropic provider (core/providers/anthropic.go), the user has confirmed through practical experience that the tool_choice parameter should always use an object format with a "type" field (e.g., {"type": "auto"}, {"type": "tool", "name": "function_name"}), even though the official documentation examples sometimes show "auto" as a direct string. The current implementation correctly handles all tool choice types with the object format.
🧬 Code Graph Analysis (2)
transports/bifrost-http/main.go (1)
transports/bifrost-http/integrations/anthropic/router.go (1)
NewAnthropicRouter(18-20)
transports/bifrost-http/integrations/anthropic/types.go (3)
core/utils.go (1)
Ptr(3-5)core/schemas/bifrost.go (21)
ToolChoiceTypeFunction(126-126)ToolChoice(137-140)BifrostRequest(54-64)Anthropic(36-36)RequestInput(46-49)BifrostMessage(143-152)ModelChatMessageRoleSystem(25-25)ModelChatMessageRole(20-20)ToolCall(266-270)Function(101-105)FunctionCall(260-263)AssistantMessage(166-171)ModelChatMessageRoleTool(27-27)ToolMessage(160-163)ModelParameters(75-89)Tool(108-112)FunctionParameters(92-98)ToolChoiceType(116-116)ToolChoiceFunction(132-134)BifrostResponse(184-194)LLMUsage(197-203)core/providers/anthropic.go (1)
AnthropicToolChoice(20-24)
🔇 Additional comments (4)
transports/bifrost-http/main.go (2)
32-35: Anthropic router import fits project layering – no action neededThe additional import is scoped to the HTTP transport layer and preserves the existing dependency direction. Good incremental extension.
184-185: Router slice now includes Anthropic – LGTMThe new router is appended after OpenAI; ordering is non-critical because each registers unique paths. No further changes required.
core/providers/anthropic.go (1)
486-491: Correct mapping offunction→"tool"keeps Anthropic happyUnifying
ToolChoiceTypeFunctionand"tool"avoids the scenario where"function"would reach the wire even though Anthropic only accepts"tool". Implementation is concise and usesfallthroughproperly.transports/bifrost-http/integrations/anthropic/router.go (1)
47-51:⚠️ Potential issueNil-pointer panic possible when context conversion fails
lib.ConvertToBifrostContextcan returnnil(see main.go error handling) yet*bifrostCtxis dereferenced unconditionally. A malformed or cancelled request would crash the handler.bifrostCtx := lib.ConvertToBifrostContext(ctx) - result, err := a.client.ChatCompletionRequest(*bifrostCtx, bifrostReq) + if bifrostCtx == nil { + ctx.SetStatusCode(fasthttp.StatusInternalServerError) + ctx.SetContentType("application/json") + _ = json.NewEncoder(ctx).Encode(map[string]string{"error": "failed to convert context"}) + return + } + result, err := a.client.ChatCompletionRequest(*bifrostCtx, bifrostReq)⛔ Skipped due to learnings
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.
9bc0828 to
e339c57
Compare
2cbc913 to
2b7b78a
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (9)
transports/bifrost-http/integrations/anthropic/router.go (4)
29-38: Missing streaming-flag validation still unresolved.
The handler silently ignoresreq.Stream, leading clients to believe they are getting a streaming response while the request is executed in non-streaming mode. Return501 Not Implemented(or wire through once supported).
30-37: JSON marshal error ignored – identical issue persists.
json.Marshal(errResponse)errors are discarded (_). This was flagged previously and is still unfixed. Propagate or at least log the marshal failure.
40-42: Inconsistent error payload format.Unlike other error paths, this branch returns a plain string and no
Content-Type. Standardise on JSON.
49-55: Marshaling provider error loses detail & may fail.Serialising
errdirectly may recurse on internal pointers and omit fields. Use a structured error or theErrorfield already present inschemas.BifrostError. Also capture marshal errors.transports/bifrost-http/integrations/anthropic/types.go (5)
105-113:Streamflag still not propagated to Bifrost.Streaming intent is dropped; downstream layers never see it.
151-160:tool_resultconversion still drops non-string payloads and ID mapping.Only plain text is copied; structured outputs/images are lost and
contentis ignored. Preserve the full JSON.
261-277:ToolChoicehandling gated behindToolspresence – logic bug remains.Valid
tool_choicewithouttoolsarray is ignored.
265-269: Enum casing not normalised.Upper-case values pass straight through; Anthropic expects lower-case.
284-291:jsonifyInputswallows marshal errors.Returning
"{}"hides schema issues; log or propagate the error.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (4)
core/providers/anthropic.go(1 hunks)transports/bifrost-http/integrations/anthropic/router.go(1 hunks)transports/bifrost-http/integrations/anthropic/types.go(1 hunks)transports/bifrost-http/main.go(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
transports/bifrost-http/integrations/anthropic/types.go (1)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:483-494
Timestamp: 2025-06-04T09:36:27.956Z
Learning: In the Anthropic provider (core/providers/anthropic.go), the user has confirmed through practical experience that the tool_choice parameter should always use an object format with a "type" field (e.g., {"type": "auto"}, {"type": "tool", "name": "function_name"}), even though the official documentation examples sometimes show "auto" as a direct string. The current implementation correctly handles all tool choice types with the object format.
🧬 Code Graph Analysis (1)
transports/bifrost-http/main.go (1)
transports/bifrost-http/integrations/anthropic/router.go (1)
NewAnthropicRouter(18-20)
🔇 Additional comments (4)
transports/bifrost-http/main.go (2)
32-35: Import order OK – no action needed.The additional Anthropic import is correct and does not introduce cyclic dependencies.
181-185: Router slice update looks good.
anthropic.NewAnthropicRouter(client)is appended toextensions; no side-effects or ordering constraints.core/providers/anthropic.go (1)
483-490:fallthroughcorrectly unifies “function” / “tool” cases.The added
fallthroughmakes both enum strings map to the same payload, fixing prior incompatibility.transports/bifrost-http/integrations/anthropic/router.go (1)
47-52:⚠️ Potential issueNil-pointer risk when
ConvertToBifrostContextfails.
bifrostCtxmay benil; dereferencing with*bifrostCtxpanics.bifrostCtx := lib.ConvertToBifrostContext(ctx) +if bifrostCtx == nil { + ctx.SetStatusCode(fasthttp.StatusInternalServerError) + ctx.SetContentType("application/json") + ctx.SetBodyString(`{"error":"internal context conversion failed"}`) + return +} -result, err := a.client.ChatCompletionRequest(*bifrostCtx, bifrostReq) +result, err := a.client.ChatCompletionRequest(*bifrostCtx, bifrostReq)⛔ Skipped due to learnings
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.
2b7b78a to
c30de52
Compare
e339c57 to
1618f5d
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
transports/bifrost-http/integrations/anthropic/types.go (1)
261-278:⚠️ Potential issue
tool_choiceignored unlesstoolssupplied
Placing the conversion insideif r.Tools != nilmeans a valid request like
{"tool_choice":{"type":"auto"}}is silently discarded when the caller provides notoolsarray.- if r.Tools != nil { - ... - bifrostReq.Params.Tools = &tools - - // Convert tool choice - if r.ToolChoice != nil { - ... - } - } + if r.Tools != nil { + ... + bifrostReq.Params.Tools = &tools + } + + // Convert tool choice (independent of tools) + if r.ToolChoice != nil { + toolChoice := &schemas.ToolChoice{ + Type: func() schemas.ToolChoiceType { + if r.ToolChoice.Type == "tool" { + return schemas.ToolChoiceTypeFunction + } + return schemas.ToolChoiceType(strings.ToLower(r.ToolChoice.Type)) + }(), + } + if r.ToolChoice.Type == "tool" && r.ToolChoice.Name != "" { + toolChoice.Function = schemas.ToolChoiceFunction{Name: r.ToolChoice.Name} + } + if bifrostReq.Params == nil { + bifrostReq.Params = &schemas.ModelParameters{} + } + bifrostReq.Params.ToolChoice = toolChoice + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
core/providers/anthropic.go(1 hunks)transports/bifrost-http/integrations/anthropic/router.go(1 hunks)transports/bifrost-http/integrations/anthropic/types.go(1 hunks)transports/bifrost-http/integrations/genai/router.go(1 hunks)transports/bifrost-http/integrations/openai/router.go(1 hunks)transports/bifrost-http/integrations/utils.go(2 hunks)transports/bifrost-http/main.go(2 hunks)
🧰 Additional context used
🧠 Learnings (2)
core/providers/anthropic.go (1)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:483-494
Timestamp: 2025-06-04T09:36:27.956Z
Learning: In the Anthropic provider (core/providers/anthropic.go), the user has confirmed through practical experience that the tool_choice parameter should always use an object format with a "type" field (e.g., {"type": "auto"}, {"type": "tool", "name": "function_name"}), even though the official documentation examples sometimes show "auto" as a direct string. The current implementation correctly handles all tool choice types with the object format.
transports/bifrost-http/integrations/anthropic/types.go (1)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:483-494
Timestamp: 2025-06-04T09:36:27.956Z
Learning: In the Anthropic provider (core/providers/anthropic.go), the user has confirmed through practical experience that the tool_choice parameter should always use an object format with a "type" field (e.g., {"type": "auto"}, {"type": "tool", "name": "function_name"}), even though the official documentation examples sometimes show "auto" as a direct string. The current implementation correctly handles all tool choice types with the object format.
🧬 Code Graph Analysis (4)
transports/bifrost-http/main.go (1)
transports/bifrost-http/integrations/anthropic/router.go (1)
NewAnthropicRouter(16-39)
transports/bifrost-http/integrations/openai/router.go (1)
transports/bifrost-http/integrations/openai/types.go (1)
OpenAIChatRequest(36-57)
transports/bifrost-http/integrations/genai/router.go (1)
transports/bifrost-http/integrations/genai/types.go (1)
GeminiChatRequest(28-39)
transports/bifrost-http/integrations/anthropic/types.go (3)
core/utils.go (1)
Ptr(3-5)core/schemas/bifrost.go (21)
ToolChoiceTypeFunction(126-126)ToolChoice(137-140)BifrostRequest(54-64)Anthropic(36-36)RequestInput(46-49)BifrostMessage(143-152)ModelChatMessageRoleSystem(25-25)ModelChatMessageRole(20-20)ToolCall(266-270)Function(101-105)FunctionCall(260-263)AssistantMessage(166-171)ModelChatMessageRoleTool(27-27)ToolMessage(160-163)ModelParameters(75-89)Tool(108-112)FunctionParameters(92-98)ToolChoiceType(116-116)ToolChoiceFunction(132-134)BifrostResponse(184-194)LLMUsage(197-203)core/providers/anthropic.go (1)
AnthropicToolChoice(20-24)
🔇 Additional comments (7)
transports/bifrost-http/main.go (2)
32-32: Proper import structure for Anthropic integration.The import follows the established pattern and naming convention used by other integrations.
184-184: Correct registration of Anthropic router.The Anthropic router is properly registered in the extensions slice, following the same pattern as GenAI and OpenAI routers. This ensures the
/anthropic/v1/messagesendpoint will be available.core/providers/anthropic.go (1)
485-487: Improved tool choice handling with unified logic.The
fallthroughstatement effectively consolidates the handling ofschemas.ToolChoiceTypeFunctionand"tool"cases, ensuring both execute the same logic that setstool_choicewith type"tool"and the function name. This reduces code duplication and aligns with the established pattern of using object format for tool choices.transports/bifrost-http/integrations/utils.go (2)
42-42: Enhanced concurrency safety with factory function pattern.Replacing the static
RequestTypefield withGetRequestTypeInstancefunction ensures each HTTP request gets a fresh request instance, preventing potential data races and memory issues in concurrent scenarios.
97-97: Correct implementation of factory function usage.The call to
config.GetRequestTypeInstance()properly creates a new request instance for each handler invocation, supporting the thread-safe request processing architecture.transports/bifrost-http/integrations/genai/router.go (1)
24-26: Proper adoption of factory function pattern.The GenAI router correctly implements the new
GetRequestTypeInstancepattern, ensuring freshGeminiChatRequestinstances for each request. This change aligns with the broader refactoring to improve concurrency safety across all integration routers.transports/bifrost-http/integrations/openai/router.go (1)
21-23: Factory func is the right call – good alignment with utils refactor
Replacing the staticRequestTypewithGetRequestTypeInstanceprevents cross-request data leakage. Looks clean.
1618f5d to
bb0425c
Compare
15286f9 to
5e6692a
Compare
bb0425c to
c664c44
Compare
5e6692a to
2841d24
Compare
efe4ba6 to
46def42
Compare
2841d24 to
a008712
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
transports/bifrost-http/integrations/utils.go (1)
98-110:⚠️ Potential issueReturned request instance can be nil
json.Unmarshalwith anildestination triggerspanic: runtime error: invalid memory address.
Even with the above struct check, a buggy factory function could still returnnil. Add a guard before unmarshalling.- if method != "GET" && method != "DELETE" { + if req == nil { + g.sendError(ctx, fasthttp.StatusInternalServerError, "request factory returned nil") + return + } + + if method != "GET" && method != "DELETE" {
♻️ Duplicate comments (6)
transports/bifrost-http/integrations/anthropic/router.go (1)
21-33: 💡 Verification agent🧩 Analysis chain
ResponseFuncmay return nil → sends200 null
DeriveAnthropicFromBifrostResponsecan legitimately returnnil(e.g., internal error).
GenericRouter.sendSuccesswill happily marshal that as the literal JSON wordnullwith status 200.Consider hard-failing or mapping to a structured error instead:
- ResponseFunc: func(resp *schemas.BifrostResponse) interface{} { - return DeriveAnthropicFromBifrostResponse(resp) - }, + ResponseFunc: func(resp *schemas.BifrostResponse) interface{} { + out := DeriveAnthropicFromBifrostResponse(resp) + if out == nil { + return map[string]string{"error": "empty response from core"} + } + return out + },
🏁 Script executed:
#!/bin/bash set -e # Locate the Anthropich router file file=$(rg -l "AnthropicMessageRequest") echo "Found file: $file" # Find the DeriveAnthropicFromBifrostResponse references and definition echo -e "\n=== References to DeriveAnthropicFromBifrostResponse ===" rg -n "DeriveAnthropicFromBifrostResponse" "$file" echo -e "\n=== Implementation of DeriveAnthropicFromBifrostResponse ===" rg -n "func DeriveAnthropicFromBifrostResponse" -C5 "$file" # Inspect GenericRouter.sendSuccess to see how nil is handled echo -e "\n=== sendSuccess implementation (context) ===" rg -n "sendSuccess" -C5 .Length of output: 862
🏁 Script executed:
#!/bin/bash set -e echo "=== DeriveAnthropicFromBifrostResponse references in anthropic directory ===" rg -n "DeriveAnthropicFromBifrostResponse" -C3 transports/bifrost-http/integrations/anthropic echo -e "\n=== Definition of DeriveAnthropicFromBifrostResponse ===" rg -n "func .*DeriveAnthropicFromBifrostResponse" -C5 . echo -e "\n=== sendSuccess implementation in GenericRouter ===" rg -n "sendSuccess" -C5 .Length of output: 4884
🏁 Script executed:
#!/bin/bash set -e echo "=== Integration wrapper error handling & response flow ===" sed -n '130,200p' transports/bifrost-http/integrations/utils.goLength of output: 1972
Prevent
200 nullby guarding against nil in ResponseFuncThe current
ResponseFuncreturnsnilwhenDeriveAnthropicFromBifrostResponseyieldsnil(e.g. if the core response is nil), andsendSuccessthen serializes that as a literal JSONnullwith HTTP 200. To avoid returning an empty payload, explicitly map nil outputs to a structured error.• File:
transports/bifrost-http/integrations/anthropic/router.go
• Update theResponseFuncblock as follows:- ResponseFunc: func(resp *schemas.BifrostResponse) interface{} { - return DeriveAnthropicFromBifrostResponse(resp) - }, + ResponseFunc: func(resp *schemas.BifrostResponse) interface{} { + out := DeriveAnthropicFromBifrostResponse(resp) + if out == nil { + // surface an error instead of 200 null + return map[string]string{"error": "empty response from core"} + } + return out + },This ensures callers receive a JSON error object instead of an unhelpful
null.transports/bifrost-http/integrations/anthropic/types.go (5)
11-12: 🧹 Nitpick (assertive)Inline the function-type pointer – global var adds needless indirection
This was raised earlier and is still unresolved.
fnTypePtris used once; inlinebifrost.Ptr(string(schemas.ToolChoiceTypeFunction))where needed and drop the global.
125-161:⚠️ Potential issueImage, structured
tool_result, and multimodal content are silently discardedThe switch only handles
"text","tool_use", and a very lossy"tool_result"mapping.
All"image"blocks and non-stringtool_result.contentare ignored, leading to data loss for multimodal requests and structured tool output.Recommend:
- Add a case for
"image"that maps to an appropriateschemas.ImageContentor preserves raw payload.- Preserve entire
tool_result.content(marshal to JSON string, store inToolMessage.Content, etc.) instead of extracting only strings.
206-278: 🛠️ Refactor suggestion
tool_choiceconversion still gated byr.Tools != nilWhen a caller sends
tool_choicebut omits atoolsarray (valid Anthropic usage), the choice is silently dropped because this block is nested insideif r.Tools != nil. Move the choice mapping outside the guard.Also,
Typeis forwarded without case normalisation –"Auto"becomes invalid upstream.- if r.Tools != nil { ... - // Convert tool choice - if r.ToolChoice != nil { + if r.Tools != nil { ... + } + + // Convert tool choice (independent of tools presence) + if r.ToolChoice != nil { toolChoice := &schemas.ToolChoice{ - Type: func() schemas.ToolChoiceType { - if r.ToolChoice.Type == "tool" { - return schemas.ToolChoiceTypeFunction - } - return schemas.ToolChoiceType(r.ToolChoice.Type) - }(), + Type: func() schemas.ToolChoiceType { + t := strings.ToLower(r.ToolChoice.Type) + if t == "tool" { + return schemas.ToolChoiceTypeFunction + } + return schemas.ToolChoiceType(t) + }(), }
284-292: 🧹 Nitpick (assertive)
jsonifyInputswallows marshal errors – hides bad schemasReturning
"{}"masks real problems and complicates debugging.Either propagate the error back (preferred) or at least log it:
- jsonBytes, err := json.Marshal(input) - if err != nil { - return "{}" - } - return string(jsonBytes) + jsonBytes, err := json.Marshal(input) + if err != nil { + log.Printf("[anthropic] failed to marshal tool input: %v", err) + return "{}" + } + return string(jsonBytes)
335-372:⚠️ Potential issue
DeriveAnthropicFromBifrostResponsedropsthinkingandtool_resultblocks & may emitcontent:null
- Assistant thoughts (
AssistantMessage.Thought) andtool_resultmessages are not propagated, breaking round-trip fidelity.- If no content is generated,
anthropicResp.Contentstaysnil→ JSON"content": null, which violates Anthropic’s spec (must be an array).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
core/providers/anthropic.go(1 hunks)transports/bifrost-http/integrations/anthropic/router.go(1 hunks)transports/bifrost-http/integrations/anthropic/types.go(1 hunks)transports/bifrost-http/integrations/genai/router.go(1 hunks)transports/bifrost-http/integrations/openai/router.go(1 hunks)transports/bifrost-http/integrations/utils.go(2 hunks)transports/bifrost-http/main.go(2 hunks)
🧰 Additional context used
🧠 Learnings (2)
core/providers/anthropic.go (1)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:483-494
Timestamp: 2025-06-04T09:36:27.956Z
Learning: In the Anthropic provider (core/providers/anthropic.go), the user has confirmed through practical experience that the tool_choice parameter should always use an object format with a "type" field (e.g., {"type": "auto"}, {"type": "tool", "name": "function_name"}), even though the official documentation examples sometimes show "auto" as a direct string. The current implementation correctly handles all tool choice types with the object format.
transports/bifrost-http/integrations/anthropic/types.go (2)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:483-494
Timestamp: 2025-06-04T09:36:27.956Z
Learning: In the Anthropic provider (core/providers/anthropic.go), the user has confirmed through practical experience that the tool_choice parameter should always use an object format with a "type" field (e.g., {"type": "auto"}, {"type": "tool", "name": "function_name"}), even though the official documentation examples sometimes show "auto" as a direct string. The current implementation correctly handles all tool choice types with the object format.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:105-113
Timestamp: 2025-06-09T14:56:14.936Z
Learning: Streaming functionality is not yet supported in the Bifrost system, so Stream flags are intentionally not propagated from integration requests to BifrostRequest.
🧬 Code Graph Analysis (3)
transports/bifrost-http/main.go (1)
transports/bifrost-http/integrations/anthropic/router.go (1)
NewAnthropicRouter(16-39)
transports/bifrost-http/integrations/openai/router.go (1)
transports/bifrost-http/integrations/openai/types.go (1)
OpenAIChatRequest(36-57)
transports/bifrost-http/integrations/genai/router.go (1)
transports/bifrost-http/integrations/genai/types.go (1)
GeminiChatRequest(29-40)
🔇 Additional comments (4)
transports/bifrost-http/main.go (1)
46-46: LGTM! Clean integration of Anthropic router.The import and router registration follow the established pattern used for GenAI and OpenAI integrations. The documentation already includes the Anthropic endpoint example, showing good consistency.
Also applies to: 198-198
core/providers/anthropic.go (1)
485-487: LGTM! Improved tool choice handling for Anthropic integration.The fallthrough ensures that both
ToolChoiceTypeFunctionand"tool"types are handled consistently, setting the tool choice with"type": "tool"format. This aligns with Anthropic's API requirements and supports the new integration.transports/bifrost-http/integrations/openai/router.go (1)
21-23: LGTM! Improved request instance handling.The factory function pattern ensures fresh
OpenAIChatRequestinstances per request, preventing potential issues with reusing instances across concurrent requests. This follows the consistent refactoring pattern applied across integration routers.transports/bifrost-http/integrations/genai/router.go (1)
24-26: LGTM! Consistent request instance handling.The factory function pattern ensures fresh
GeminiChatRequestinstances per request, maintaining consistency with the refactoring applied across all integration routers for improved thread safety.
a008712 to
78ab5c4
Compare
46def42 to
65a8762
Compare
78ab5c4 to
14088f7
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (7)
transports/bifrost-http/integrations/utils.go (2)
40-46: Still missing nil-guards on factory / converter – runtime panic remains possiblePrior feedback already highlighted that
GetRequestTypeInstanceandRequestConvertermust be checked fornilbefore use.
Neither the struct tag norcreateHandleradds such guards, so an accidentally un-initialised route will crash the server on first request.
Please add the defensive checks shown in the previous review.
98-98: Dereferencing uncheckedGetRequestTypeInstancerepeats the panic risk
req := config.GetRequestTypeInstance()is executed unconditionally.
If the factory isnilthe handler panics, taking down the entire HTTP process.
Add:+if config.GetRequestTypeInstance == nil { + g.sendError(ctx, fasthttp.StatusInternalServerError, "route mis-configuration") + return +}transports/bifrost-http/integrations/anthropic/types.go (5)
11-11: Inline the constant – extra global adds noise
fnTypePtris just a pointer to the literal"function". Inlinebifrost.Ptr(string(schemas.ToolChoiceTypeFunction))where used and drop the package-level var.
262-278:tool_choiceconversion is skipped whentoolsis nilThe mapping sits inside the
if r.Tools != nilblock, so valid requests that specifytool_choicewithout atoolsarray drop the field.Move the
tool_choicelogic outside the tools branch as flagged earlier.
285-293:jsonifyInputswallows marshal errors – hides bad tool inputsReturning
"{}"on error masks schema problems and makes debugging painful.
Log the error or propagate it so callers can react.
335-384: Nilcontentencodes asnull, violating Anthropic specWhen no blocks are added,
contentstaysniland JSON marshals tonull.
Initialise an empty slice to ensure"content":[].var content []AnthropicContent ... - anthropicResp.Content = content + if content == nil { + content = []AnthropicContent{} + } + anthropicResp.Content = content
157-171: 🛠️ Refactor suggestion
tool_resultcontent loses the actual result payloadOnly
ToolCallID(and maybe an image) gets forwarded;content.Content(the tool’s return data) is silently discarded.
Downstream consumers therefore cannot read the tool output.case "tool_result": if content.ToolUseID != nil { bifrostMsg.ToolMessage = &schemas.ToolMessage{ ToolCallID: content.ToolUseID, + // Preserve textual / structured result if present + Content: func() *string { + if content.Content == nil { + return nil + } + bytes, _ := json.Marshal(content.Content) + s := string(bytes) + return &s + }(), } ... }Adjust the field names to match
schemas.ToolMessage.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
core/providers/anthropic.go(1 hunks)transports/bifrost-http/integrations/anthropic/router.go(1 hunks)transports/bifrost-http/integrations/anthropic/types.go(1 hunks)transports/bifrost-http/integrations/genai/router.go(1 hunks)transports/bifrost-http/integrations/openai/router.go(1 hunks)transports/bifrost-http/integrations/utils.go(2 hunks)transports/bifrost-http/main.go(2 hunks)
🧰 Additional context used
🧠 Learnings (2)
transports/bifrost-http/integrations/anthropic/router.go (1)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/router.go:19-33
Timestamp: 2025-06-09T16:46:31.997Z
Learning: In the GenericRouter (transports/bifrost-http/integrations), ResponseFunc is not called if the BifrostResponse parameter is nil, providing built-in protection against nil response marshaling.
transports/bifrost-http/integrations/anthropic/types.go (4)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:261-278
Timestamp: 2025-06-09T17:12:55.169Z
Learning: Anthropic's API consistently returns tool_choice enum values in lowercase only ("auto", "none", "any", "tool"), so case normalization is not needed when processing these values in the Anthropic integration layer.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:483-494
Timestamp: 2025-06-04T09:36:27.956Z
Learning: In the Anthropic provider (core/providers/anthropic.go), the user has confirmed through practical experience that the tool_choice parameter should always use an object format with a "type" field (e.g., {"type": "auto"}, {"type": "tool", "name": "function_name"}), even though the official documentation examples sometimes show "auto" as a direct string. The current implementation correctly handles all tool choice types with the object format.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:105-113
Timestamp: 2025-06-09T14:56:14.936Z
Learning: Streaming functionality is not yet supported in the Bifrost system, so Stream flags are intentionally not propagated from integration requests to BifrostRequest.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:326-376
Timestamp: 2025-06-09T16:56:44.370Z
Learning: In Anthropic's message format, `tool_result` content blocks are inputs sent TO the LLM (typically from user/system after tool execution), not outputs generated BY the LLM. LLM responses should only contain `text` and `tool_use` content types.
🧬 Code Graph Analysis (4)
transports/bifrost-http/main.go (1)
transports/bifrost-http/integrations/anthropic/router.go (1)
NewAnthropicRouter(16-39)
transports/bifrost-http/integrations/genai/router.go (1)
transports/bifrost-http/integrations/genai/types.go (1)
GeminiChatRequest(28-39)
transports/bifrost-http/integrations/anthropic/router.go (2)
transports/bifrost-http/integrations/utils.go (4)
GenericRouter(52-55)RouteConfig(39-47)RequestConverter(21-21)NewGenericRouter(59-64)transports/bifrost-http/integrations/anthropic/types.go (2)
AnthropicMessageRequest(90-102)DeriveAnthropicFromBifrostResponse(315-386)
transports/bifrost-http/integrations/anthropic/types.go (3)
core/utils.go (1)
Ptr(3-5)core/schemas/bifrost.go (21)
ToolChoiceTypeFunction(126-126)ToolChoice(137-140)BifrostRequest(54-64)Anthropic(36-36)RequestInput(46-49)BifrostMessage(143-152)ModelChatMessageRole(20-20)ToolCall(266-270)UserMessage(155-157)ImageContent(174-179)Function(101-105)FunctionCall(260-263)ToolMessage(160-163)AssistantMessage(166-171)ModelParameters(75-89)Tool(108-112)FunctionParameters(92-98)ToolChoiceType(116-116)ToolChoiceFunction(132-134)BifrostResponse(184-194)LLMUsage(197-203)core/providers/anthropic.go (1)
AnthropicToolChoice(20-24)
🔇 Additional comments (4)
transports/bifrost-http/main.go (1)
48-48: LGTM! Clean integration of Anthropic support.The import and router registration follow the established pattern for AI provider integrations. The implementation is consistent with the existing GenAI and OpenAI integrations.
Also applies to: 200-200
core/providers/anthropic.go (1)
486-487: LGTM! Unifies tool choice handling.The fallthrough statement correctly unifies handling of both "function" and "tool" types, ensuring compatibility between different tool choice representations while maintaining the same parameter structure for Anthropic's API.
transports/bifrost-http/integrations/openai/router.go (1)
21-23: LGTM! Improved thread safety with factory pattern.The factory function ensures each HTTP request gets a fresh
OpenAIChatRequestinstance, preventing potential shared state issues between concurrent requests.transports/bifrost-http/integrations/genai/router.go (1)
24-26: LGTM! Consistent factory pattern implementation.The factory function correctly mirrors the same pattern applied to the OpenAI router, ensuring fresh
GeminiChatRequestinstances per HTTP request and maintaining consistency across all integration routers.
14088f7 to
317ed8a
Compare
e009a8b to
0709d38
Compare
c9f43b6 to
4c58221
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
transports/bifrost-http/integrations/anthropic/types.go (2)
11-12: Redundant globalfnTypePtrvariableThe helper is only used in one place and can be inlined with
bifrost.Ptr(...). Removing the package-level var reduces indirection.
310-318:jsonifyInputhides marshal errors, hampering debuggingReturning
"{}"silently whenjson.Marshalfails makes diagnosing schema issues difficult.
Log the error (or propagate it) before falling back.This concern has been raised previously but is still unresolved.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
core/providers/anthropic.go(1 hunks)transports/bifrost-http/integrations/anthropic/router.go(1 hunks)transports/bifrost-http/integrations/anthropic/types.go(1 hunks)transports/bifrost-http/integrations/genai/router.go(1 hunks)transports/bifrost-http/integrations/openai/router.go(1 hunks)transports/bifrost-http/integrations/utils.go(5 hunks)transports/bifrost-http/main.go(2 hunks)
🧰 Additional context used
🧠 Learnings (4)
core/providers/anthropic.go (1)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:483-494
Timestamp: 2025-06-04T09:36:27.956Z
Learning: In the Anthropic provider (core/providers/anthropic.go), the user has confirmed through practical experience that the tool_choice parameter should always use an object format with a "type" field (e.g., {"type": "auto"}, {"type": "tool", "name": "function_name"}), even though the official documentation examples sometimes show "auto" as a direct string. The current implementation correctly handles all tool choice types with the object format.
transports/bifrost-http/integrations/anthropic/router.go (3)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/router.go:19-33
Timestamp: 2025-06-09T16:46:32.018Z
Learning: In the GenericRouter (transports/bifrost-http/integrations), ResponseFunc is not called if the BifrostResponse parameter is nil, providing built-in protection against nil response marshaling.
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/utils.go (3)
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.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/utils.go:169-173
Timestamp: 2025-06-09T17:33:52.234Z
Learning: The ChatCompletionRequest method in the Bifrost client follows a contract where the result parameter will never be nil if the error parameter is nil. This means when error checking passes (err == nil), the result is guaranteed to be valid and can be safely used without additional nil checks.
transports/bifrost-http/integrations/anthropic/types.go (9)
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:131-180
Timestamp: 2025-06-10T13:11:37.842Z
Learning: In Anthropic API integration for Bifrost, messages won't contain both image and tool_result content blocks in the same message, so defensive guards against multiple embedded message structs are unnecessary in the content processing loop.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:261-278
Timestamp: 2025-06-09T17:12:55.222Z
Learning: Anthropic's API consistently returns tool_choice enum values in lowercase only ("auto", "none", "any", "tool"), so case normalization is not needed when processing these values in the Anthropic integration layer.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#55
File: core/providers/anthropic.go:483-494
Timestamp: 2025-06-04T09:36:27.956Z
Learning: In the Anthropic provider (core/providers/anthropic.go), the user has confirmed through practical experience that the tool_choice parameter should always use an object format with a "type" field (e.g., {"type": "auto"}, {"type": "tool", "name": "function_name"}), even though the official documentation examples sometimes show "auto" as a direct string. The current implementation correctly handles all tool choice types with the object format.
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#65
File: transports/bifrost-http/integrations/anthropic/types.go:105-113
Timestamp: 2025-06-09T14:56:14.951Z
Learning: Streaming functionality is not yet supported in the Bifrost system, so Stream flags are intentionally not propagated from integration requests to BifrostRequest.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:326-376
Timestamp: 2025-06-09T16:56:44.395Z
Learning: In Anthropic's message format, `tool_result` content blocks are inputs sent TO the LLM (typically from user/system after tool execution), not outputs generated BY the LLM. LLM responses should only contain `text` and `tool_use` content types.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#64
File: transports/bifrost-http/integrations/genai/types.go:383-395
Timestamp: 2025-06-09T16:26:05.777Z
Learning: In the Bifrost schema (core/schemas/bifrost.go), only UserMessage and ToolMessage structs have ImageContent fields. AssistantMessage does not have an ImageContent field and cannot contain images. The schema design intentionally limits image content to user and tool messages only.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:129-145
Timestamp: 2025-06-10T11:12:26.840Z
Learning: Anthropic API does not support tool roles and images can only be present in user messages, not assistant or tool messages. Therefore, in Anthropic integration code, image content should always be assigned to UserMessage regardless of any other considerations.
Learnt from: Pratham-Mishra04
PR: maximhq/bifrost#65
File: transports/bifrost-http/integrations/anthropic/types.go:131-180
Timestamp: 2025-06-10T13:03:26.975Z
Learning: In Anthropic API message format, tool_result content blocks are sent by users in response to assistant tool calls, while image content blocks are typically sent in initial user messages. These content types follow different conversation flows and wouldn't naturally appear together in a single message, making defensive guards against multiple embedded message types unnecessary.
🧬 Code Graph Analysis (3)
transports/bifrost-http/main.go (1)
transports/bifrost-http/integrations/anthropic/router.go (1)
NewAnthropicRouter(16-39)
transports/bifrost-http/integrations/genai/router.go (1)
transports/bifrost-http/integrations/genai/types.go (1)
GeminiChatRequest(28-39)
transports/bifrost-http/integrations/anthropic/types.go (3)
core/utils.go (1)
Ptr(3-5)core/schemas/bifrost.go (23)
ToolChoiceTypeFunction(126-126)ToolChoice(137-140)BifrostRequest(54-64)Anthropic(36-36)RequestInput(46-49)BifrostMessage(143-152)ModelChatMessageRoleSystem(25-25)ModelChatMessageRole(20-20)ToolCall(273-277)UserMessage(155-157)ImageContent(181-186)Function(101-105)FunctionCall(267-270)ToolMessage(160-163)ModelChatMessageRoleTool(27-27)AssistantMessage(166-171)ModelParameters(75-89)Tool(108-112)FunctionParameters(92-98)ToolChoiceType(116-116)ToolChoiceFunction(132-134)BifrostResponse(191-201)LLMUsage(204-210)core/providers/anthropic.go (1)
AnthropicToolChoice(20-24)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Graphite / mergeability_check
- GitHub Check: Graphite / mergeability_check
🔇 Additional comments (7)
transports/bifrost-http/main.go (1)
48-48: LGTM! Clean integration following established patterns.The Anthropic integration is properly imported and registered alongside existing providers, maintaining consistency with the established architecture.
Also applies to: 200-200
core/providers/anthropic.go (1)
492-493: LGTM! Proper unification of equivalent tool choice types.The fallthrough correctly consolidates handling of
schemas.ToolChoiceTypeFunctionand"tool"since both should use the same object format in Anthropic's API.transports/bifrost-http/integrations/openai/router.go (1)
21-23: LGTM! Improved thread safety with dynamic request instantiation.Replacing the static
RequestTypewithGetRequestTypeInstanceensures each request gets a fresh instance, preventing potential data leakage between concurrent requests.transports/bifrost-http/integrations/genai/router.go (1)
24-26: LGTM! Consistent dynamic instantiation pattern.The change maintains consistency with other integration routers and provides the same thread safety benefits through dynamic request instantiation.
transports/bifrost-http/integrations/utils.go (3)
72-89: Excellent startup validation implementation!The comprehensive validation at route registration time addresses previous performance concerns by failing fast during startup rather than checking on every request. The validation covers all critical fields and even tests the factory function.
119-119: LGTM! Dynamic request instantiation improves thread safety.Using
GetRequestTypeInstance()ensures each request gets a fresh instance, preventing potential data corruption in concurrent scenarios.
176-179: Good defensive programming with the post-callback nil check.While the Bifrost client contract guarantees non-nil results when there's no error, this additional check provides protection against potential issues introduced by post-request callbacks.
Merge activity
|
4c58221 to
684f6ee
Compare
There was a problem hiding this comment.
Bug: Image Overwrite and Type Mismatch Bug
In ConvertToBifrostRequest, when an Anthropic message contains multiple image content blocks, only the last image is preserved for both UserMessage and ToolMessage image content, as previous images are overwritten. Additionally, the Type field within schemas.ImageContent is incorrectly assigned a *string from content.Source.Type instead of the expected *schemas.ImageContentType enum value.
transports/bifrost-http/integrations/anthropic/types.go#L137-L147
bifrost/transports/bifrost-http/integrations/anthropic/types.go
Lines 137 to 147 in 684f6ee
Was this report helpful? Give feedback by reacting with 👍 or 👎
# Add Anthropic API Compatibility Layer This PR adds a native Anthropic API compatibility layer to Bifrost, allowing applications built for Anthropic's API to work with Bifrost without modification. Key changes: - Added `/anthropic/v1/messages` endpoint that mirrors Anthropic's Messages API - Implemented request/response conversion between Anthropic and Bifrost formats - Added support for Anthropic's content types including text, tool_use, and tool_result - Enhanced tool choice handling in the Anthropic provider to support both "tool" and "function" types - Registered the Anthropic router alongside existing OpenAI and GenAI compatibility layers This implementation handles all Anthropic-specific features including: - Message format with array-based content blocks - Tool definitions and tool choice parameters - Proper conversion of tool calls and results between formats - Usage statistics in Anthropic's expected format

Add Anthropic API Compatibility Layer
This PR adds a native Anthropic API compatibility layer to Bifrost, allowing applications built for Anthropic's API to work with Bifrost without modification.
Key changes:
/anthropic/v1/messagesendpoint that mirrors Anthropic's Messages APIThis implementation handles all Anthropic-specific features including: