Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions bifrost.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ func createProviderFromProviderKey(providerKey interfaces.SupportedModelProvider
return providers.NewOpenAIProvider(config), nil
case interfaces.Anthropic:
return providers.NewAnthropicProvider(config), nil
case interfaces.Bedrock:
return providers.NewBedrockProvider(config), nil
default:
return nil, fmt.Errorf("unsupported provider: %s", providerKey)
}
Expand Down Expand Up @@ -99,6 +101,7 @@ func Init(account interfaces.Account, plugins []interfaces.Plugin, configs map[i
}

bifrost.requestQueues = make(map[interfaces.SupportedModelProvider]chan ChannelMessage)
bifrost.configs = configs

// Create buffered channels for each provider and start workers
for _, providerKey := range providerKeys {
Expand Down Expand Up @@ -184,9 +187,9 @@ func (bifrost *Bifrost) processRequests(provider interfaces.Provider, queue chan
}

if req.Type == TextCompletionRequest {
result, err = provider.TextCompletion(req.Model, key, *req.Input.StringInput, req.Params)
result, err = provider.TextCompletion(req.Model, key, *req.Input.TextInput, req.Params)
} else if req.Type == ChatCompletionRequest {
result, err = provider.ChatCompletion(req.Model, key, *req.Input.MessageInput, req.Params)
result, err = provider.ChatCompletion(req.Model, key, *req.Input.ChatInput, req.Params)
}

if err != nil {
Expand Down
24 changes: 22 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
module bifrost

go 1.21.1
go 1.23.0

toolchain go1.24.1

require github.com/joho/godotenv v1.5.1

require github.com/maximhq/maxim-go v0.1.1
require (
github.com/aws/aws-sdk-go-v2 v1.36.3
github.com/aws/aws-sdk-go-v2/config v1.29.11
github.com/maximhq/maxim-go v0.1.1
)

require (
github.com/aws/aws-sdk-go-v2/credentials v1.17.64 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.25.2 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 // indirect
github.com/aws/smithy-go v1.22.2 // indirect
)
26 changes: 26 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
github.com/aws/aws-sdk-go-v2/config v1.29.11 h1:/hkJIxaQzFQy0ebFjG5NHmAcLCrvNSuXeHnxLfeCz1Y=
github.com/aws/aws-sdk-go-v2/config v1.29.11/go.mod h1:OFPRZVQxC4mKqy2Go6Cse/m9NOStAo6YaMvAcTMUROg=
github.com/aws/aws-sdk-go-v2/credentials v1.17.64 h1:NH4RAQJEXBDQDUudTqMNHdyyEVa5CvMn0tQicqv48jo=
github.com/aws/aws-sdk-go-v2/credentials v1.17.64/go.mod h1:tUoJfj79lzEcalHDbyNkpnZZTRg/2ayYOK/iYnRfPbo=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=
github.com/aws/aws-sdk-go-v2/service/sso v1.25.2 h1:pdgODsAhGo4dvzC3JAG5Ce0PX8kWXrTZGx+jxADD+5E=
github.com/aws/aws-sdk-go-v2/service/sso v1.25.2/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.2 h1:wK8O+j2dOolmpNVY1EWIbLgxrGCHJKVPm08Hv/u80M8=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.2/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 h1:PZV5W8yk4OtH1JAuhV2PXwwO9v5G5Aoj+eMCn4T+1Kc=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.17/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=
github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/maximhq/maxim-go v0.1.1 h1:69uUQjjDPmUGcKg/M4/3AO0fbD+70Agt66pH/UCsI5M=
Expand Down
4 changes: 2 additions & 2 deletions interfaces/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package interfaces
import "context"

type RequestInput struct {
StringInput *string
MessageInput *[]Message
TextInput *string
ChatInput *[]Message
}

type BifrostRequest struct {
Expand Down
45 changes: 21 additions & 24 deletions interfaces/provider.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package interfaces

import "encoding/json"

// LLMUsage represents token usage information
type LLMUsage struct {
PromptTokens int `json:"prompt_tokens"`
Expand Down Expand Up @@ -55,9 +57,11 @@ type FunctionCall struct {

// ToolCall represents a tool call in a message
type ToolCall struct {
Type string `json:"type"`
ID string `json:"id"`
Function FunctionCall `json:"function"`
Type *string `json:"type"`
ID string `json:"id"`
Name *string `json:"name"`
Input json.RawMessage `json:"input"`
Function *FunctionCall `json:"function"`
}

// ModelChatMessageRole represents the role of a chat message
Expand All @@ -73,18 +77,19 @@ const (

// CompletionResponseChoice represents a choice in the completion response
type CompletionResponseChoice struct {
Role ModelChatMessageRole `json:"role"`
Content string `json:"content"`
FunctionCall *FunctionCall `json:"function_call"`
ToolCalls *[]ToolCall `json:"tool_calls"`
Role ModelChatMessageRole `json:"role"`
Content string `json:"content"`
Image json.RawMessage `json:"image"`
ToolCalls *[]ToolCall `json:"tool_calls"`
}

// CompletionResultChoice represents a choice in the completion result
type CompletionResultChoice struct {
Index int `json:"index"`
Message CompletionResponseChoice `json:"message"`
FinishReason *string `json:"finish_reason"`
LogProbs *interface{} `json:"logprobs"`
Index int `json:"index"`
Message CompletionResponseChoice `json:"message"`
StopReason *string `json:"stop_reason"`
Stop *string `json:"stop"`
LogProbs *interface{} `json:"logprobs"`
}

// ToolResult represents the result of a tool call
Expand Down Expand Up @@ -147,27 +152,19 @@ const (
Lmstudio SupportedModelProvider = "lmstudio"
)

type Role string

const (
UserRole Role = "user"
AssistantRole Role = "assistant"
SystemRole Role = "system"
)

type Message struct {
//* strict check for roles
Role Role `json:"role"`
Role ModelChatMessageRole `json:"role"`
//* need to make sure either content or imagecontent is provided
Content *string `json:"content"`
ImageContent *ImageContent `json:"imageContent"`
ToolCalls *[]ToolCall `json:"toolCall"`
}

type ImageContent struct {
Type string `json:"type"`
ImageURL struct {
URL string `json:"url"`
} `json:"image_url"`
Type string `json:"type"`
URL string `json:"url"`
MediaType string `json:"media_type"`
}

// type Content struct {
Expand Down
18 changes: 13 additions & 5 deletions providers/anthropic.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"io"
"net/http"
"time"

"github.com/maximhq/maxim-go"
)

type AnthropicTextResponse struct {
Expand Down Expand Up @@ -62,6 +64,8 @@ func (provider *AnthropicProvider) GetProviderKey() interfaces.SupportedModelPro

// TextCompletion implements text completion using Anthropic's API
func (provider *AnthropicProvider) TextCompletion(model, key, text string, params *interfaces.ModelParameters) (*interfaces.CompletionResult, error) {
startTime := time.Now()

preparedParams := PrepareParams(params)

// Merge additional parameters
Expand Down Expand Up @@ -122,6 +126,9 @@ func (provider *AnthropicProvider) TextCompletion(model, key, text string, param
return nil, fmt.Errorf("error parsing response: %v", err)
}

// Calculate latency
latency := time.Since(startTime).Seconds()

// Create the completion result
completionResult := &interfaces.CompletionResult{
ID: response.ID,
Expand All @@ -138,6 +145,7 @@ func (provider *AnthropicProvider) TextCompletion(model, key, text string, param
PromptTokens: response.Usage.InputTokens,
CompletionTokens: response.Usage.OutputTokens,
TotalTokens: response.Usage.InputTokens + response.Usage.OutputTokens,
Latency: &latency,
},
Model: response.Model,
Provider: interfaces.Anthropic,
Expand Down Expand Up @@ -214,7 +222,7 @@ func (provider *AnthropicProvider) ChatCompletion(model, key string, messages []
// Process the response into our CompletionResult format
var content string
var toolCalls []interfaces.ToolCall
var finishReason string
var stopReason string

// Process content and tool calls
for _, c := range anthropicResponse.Content {
Expand All @@ -228,14 +236,14 @@ func (provider *AnthropicProvider) ChatCompletion(model, key string, messages []
case "tool_use":
if c.ToolUse != nil {
toolCalls = append(toolCalls, interfaces.ToolCall{
Type: "function",
Type: maxim.StrPtr("function"),
ID: c.ToolUse.ID,
Function: interfaces.FunctionCall{
Function: &interfaces.FunctionCall{
Name: c.ToolUse.Name,
Arguments: string(must(json.Marshal(c.ToolUse.Input))),
},
})
finishReason = "tool_calls"
stopReason = "tool_calls"
}
}
}
Expand All @@ -251,7 +259,7 @@ func (provider *AnthropicProvider) ChatCompletion(model, key string, messages []
Content: content,
ToolCalls: &toolCalls,
},
FinishReason: &finishReason,
StopReason: &stopReason,
},
},
Usage: interfaces.LLMUsage{
Expand Down
Loading