Skip to content
Merged
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
4 changes: 3 additions & 1 deletion core/changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
feat: send back raw request in extra fields
feat: added support for reasoning in chat completions
feat: enhanced reasoning support in responses api
enhancement: improved internal inter provider conversions for integrations
enhancement: improved internal inter provider conversions for integrations
feat: switched to gemini native api
feat: fallback to supported request type for custom models used in integration
6 changes: 6 additions & 0 deletions core/providers/cohere/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -690,5 +690,11 @@ func (cm *CohereMessage) ToBifrostChatMessage() *schemas.ChatMessage {
Content: messageContent,
ChatAssistantMessage: assistantMessage,
}

if cm.Role == "tool" {
bifrostMessage.ChatToolMessage = &schemas.ChatToolMessage{
ToolCallID: cm.ToolCallID,
}
}
return bifrostMessage
}
13 changes: 2 additions & 11 deletions core/providers/gemini/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ func (response *GenerateContentResponse) ToBifrostChatCompletionStream() (*schem

candidate := response.Candidates[0]

// Determine if this is the last chunk based on finish reason or usage metadata
isLastChunk := candidate.FinishReason != "" && candidate.FinishReason != FinishReasonUnspecified
// Determine if this is the last chunk based on finish reason and usage metadata
isLastChunk := candidate.FinishReason != "" && response.UsageMetadata != nil

// Create the streaming response
streamResponse := &schemas.BifrostChatResponse{
Expand Down Expand Up @@ -256,15 +256,6 @@ func (response *GenerateContentResponse) ToBifrostChatCompletionStream() (*schem
},
}

// Preserve thought signature if present (required for Gemini 3 Pro)
if len(part.ThoughtSignature) > 0 {
toolCall.ExtraContent = map[string]interface{}{
"google": map[string]interface{}{
"thought_signature": string(part.ThoughtSignature),
},
}
}

toolCalls = append(toolCalls, toolCall)

case part.FunctionResponse != nil:
Expand Down
36 changes: 36 additions & 0 deletions core/providers/gemini/gemini.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,12 @@ func (provider *GeminiProvider) ChatCompletion(ctx context.Context, key schemas.
bifrostResponse.ExtraFields.ModelRequested = request.Model
bifrostResponse.ExtraFields.Latency = latency.Milliseconds()

// Set raw request if enabled
if providerUtils.ShouldSendBackRawRequest(ctx, provider.sendBackRawRequest) {
providerUtils.ParseAndSetRawRequest(&bifrostResponse.ExtraFields, jsonData)
}

// Set raw response if enabled
if providerUtils.ShouldSendBackRawResponse(ctx, provider.sendBackRawResponse) {
bifrostResponse.ExtraFields.RawResponse = rawResponse
}
Expand Down Expand Up @@ -291,6 +297,7 @@ func (provider *GeminiProvider) ChatCompletionStream(ctx context.Context, postHo
jsonData,
headers,
provider.networkConfig.ExtraHeaders,
providerUtils.ShouldSendBackRawRequest(ctx, provider.sendBackRawRequest),
providerUtils.ShouldSendBackRawResponse(ctx, provider.sendBackRawResponse),
provider.GetProviderKey(),
request.Model,
Expand All @@ -308,6 +315,7 @@ func HandleGeminiChatCompletionStream(
jsonBody []byte,
headers map[string]string,
extraHeaders map[string]string,
sendBackRawRequest bool,
sendBackRawResponse bool,
providerName schemas.ModelProvider,
model string,
Expand Down Expand Up @@ -378,6 +386,11 @@ func HandleGeminiChatCompletionStream(
var modelName string

for scanner.Scan() {
select {
case <-ctx.Done():
return
default:
}
line := scanner.Text()

// Skip empty lines and comments
Expand Down Expand Up @@ -473,6 +486,9 @@ func HandleGeminiChatCompletionStream(
chunkIndex++

if isLastChunk {
if sendBackRawRequest {
providerUtils.ParseAndSetRawRequest(&response.ExtraFields, jsonBody)
}
response.ExtraFields.Latency = time.Since(startTime).Milliseconds()
ctx = context.WithValue(ctx, schemas.BifrostContextKeyStreamEndIndicator, true)
providerUtils.ProcessAndSendResponse(ctx, postHookRunner, providerUtils.GetBifrostResponseForStreamResponse(nil, response, nil, nil, nil), responseChan)
Expand Down Expand Up @@ -584,6 +600,7 @@ func (provider *GeminiProvider) ResponsesStream(ctx context.Context, postHookRun
jsonData,
headers,
provider.networkConfig.ExtraHeaders,
providerUtils.ShouldSendBackRawRequest(ctx, provider.sendBackRawRequest),
providerUtils.ShouldSendBackRawResponse(ctx, provider.sendBackRawResponse),
provider.GetProviderKey(),
request.Model,
Expand All @@ -601,6 +618,7 @@ func HandleGeminiResponsesStream(
jsonBody []byte,
headers map[string]string,
extraHeaders map[string]string,
sendBackRawRequest bool,
sendBackRawResponse bool,
providerName schemas.ModelProvider,
model string,
Expand Down Expand Up @@ -675,6 +693,11 @@ func HandleGeminiResponsesStream(
var lastUsageMetadata *GenerateContentResponseUsageMetadata

for scanner.Scan() {
select {
case <-ctx.Done():
return
default:
}
line := scanner.Text()

// Skip empty lines and comments
Expand Down Expand Up @@ -771,6 +794,9 @@ func HandleGeminiResponsesStream(
}

if isLastChunk {
if sendBackRawRequest {
providerUtils.ParseAndSetRawRequest(&response.ExtraFields, jsonBody)
}
response.ExtraFields.Latency = time.Since(startTime).Milliseconds()
ctx = context.WithValue(ctx, schemas.BifrostContextKeyStreamEndIndicator, true)
providerUtils.ProcessAndSendResponse(ctx, postHookRunner, providerUtils.GetBifrostResponseForStreamResponse(nil, nil, response, nil, nil), responseChan)
Expand Down Expand Up @@ -985,6 +1011,11 @@ func (provider *GeminiProvider) SpeechStream(ctx context.Context, postHookRunner
lastChunkTime := startTime

for scanner.Scan() {
select {
case <-ctx.Done():
return
default:
}
line := scanner.Text()

// Skip empty lines
Expand Down Expand Up @@ -1243,6 +1274,11 @@ func (provider *GeminiProvider) TranscriptionStream(ctx context.Context, postHoo
var fullTranscriptionText string

for scanner.Scan() {
select {
case <-ctx.Done():
return
default:
}
line := scanner.Text()

// Skip empty lines
Expand Down
Loading