Skip to content

Commit b015950

Browse files
feat: openai integration added to http transport
1 parent ac54c86 commit b015950

File tree

3 files changed

+625
-1
lines changed

3 files changed

+625
-1
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package openai
2+
3+
import (
4+
"encoding/json"
5+
6+
"github.com/fasthttp/router"
7+
bifrost "github.com/maximhq/bifrost/core"
8+
"github.com/maximhq/bifrost/transports/bifrost-http/lib"
9+
"github.com/valyala/fasthttp"
10+
)
11+
12+
// OpenAIRouter holds route registrations for OpenAI endpoints.
13+
// It supports standard chat completions and image-enabled vision capabilities.
14+
//
15+
// Vision API Support:
16+
// The /openai/v1/chat/completions endpoint supports messages with mixed text and image content.
17+
//
18+
// Example Vision API Request:
19+
//
20+
// {
21+
// "model": "gpt-4o",
22+
// "messages": [{
23+
// "role": "user",
24+
// "content": [
25+
// {"type": "text", "text": "What's in this image? Keep the response short."},
26+
// {"type": "image_url", "image_url": {"url": "data:image/png;base64,..."}}
27+
// ]
28+
// }]
29+
// }
30+
type OpenAIRouter struct {
31+
client *bifrost.Bifrost
32+
}
33+
34+
// NewOpenAIRouter creates a new OpenAIRouter with the given bifrost client.
35+
func NewOpenAIRouter(client *bifrost.Bifrost) *OpenAIRouter {
36+
return &OpenAIRouter{client: client}
37+
}
38+
39+
// RegisterRoutes registers all OpenAI routes on the given router.
40+
func (o *OpenAIRouter) RegisterRoutes(r *router.Router) {
41+
r.POST("/openai/v1/chat/completions", o.handleChatCompletion)
42+
}
43+
44+
// handleChatCompletion handles POST /v1/chat/completions
45+
func (o *OpenAIRouter) handleChatCompletion(ctx *fasthttp.RequestCtx) {
46+
var req OpenAIChatRequest
47+
if err := json.Unmarshal(ctx.PostBody(), &req); err != nil {
48+
ctx.SetStatusCode(fasthttp.StatusBadRequest)
49+
errorResponse, _ := json.Marshal(map[string]string{"error": err.Error()})
50+
ctx.SetBody(errorResponse)
51+
return
52+
}
53+
54+
if req.Model == "" {
55+
ctx.SetStatusCode(fasthttp.StatusBadRequest)
56+
ctx.SetBodyString("Model parameter is required")
57+
return
58+
}
59+
60+
bifrostReq := req.ConvertToBifrostRequest()
61+
62+
bifrostCtx := lib.ConvertToBifrostContext(ctx)
63+
64+
result, err := o.client.ChatCompletionRequest(*bifrostCtx, bifrostReq)
65+
if err != nil {
66+
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
67+
errorResponse, _ := json.Marshal(err)
68+
ctx.SetBody(errorResponse)
69+
return
70+
}
71+
72+
openaiResponse := DeriveOpenAIFromBifrostResponse(result)
73+
ctx.SetStatusCode(fasthttp.StatusOK)
74+
ctx.SetContentType("application/json")
75+
responseBody, _ := json.Marshal(openaiResponse)
76+
ctx.SetBody(responseBody)
77+
}

0 commit comments

Comments
 (0)