fix: adapting return format for openrouter think content (#793)

This commit is contained in:
Sh1n3zZ
2025-03-06 19:16:26 +08:00
parent 7f74a9664e
commit b95142bbac
3 changed files with 25 additions and 12 deletions

View File

@@ -99,6 +99,7 @@ type Message struct {
Name *string `json:"name,omitempty"` Name *string `json:"name,omitempty"`
Prefix *bool `json:"prefix,omitempty"` Prefix *bool `json:"prefix,omitempty"`
ReasoningContent string `json:"reasoning_content,omitempty"` ReasoningContent string `json:"reasoning_content,omitempty"`
Reasoning string `json:"reasoning,omitempty"`
ToolCalls json.RawMessage `json:"tool_calls,omitempty"` ToolCalls json.RawMessage `json:"tool_calls,omitempty"`
ToolCallId string `json:"tool_call_id,omitempty"` ToolCallId string `json:"tool_call_id,omitempty"`
parsedContent []MediaContent parsedContent []MediaContent

View File

@@ -64,6 +64,7 @@ type ChatCompletionsStreamResponseChoice struct {
type ChatCompletionsStreamResponseChoiceDelta struct { type ChatCompletionsStreamResponseChoiceDelta struct {
Content *string `json:"content,omitempty"` Content *string `json:"content,omitempty"`
ReasoningContent *string `json:"reasoning_content,omitempty"` ReasoningContent *string `json:"reasoning_content,omitempty"`
Reasoning *string `json:"reasoning,omitempty"`
Role string `json:"role,omitempty"` Role string `json:"role,omitempty"`
ToolCalls []ToolCallResponse `json:"tool_calls,omitempty"` ToolCalls []ToolCallResponse `json:"tool_calls,omitempty"`
} }
@@ -80,14 +81,18 @@ func (c *ChatCompletionsStreamResponseChoiceDelta) GetContentString() string {
} }
func (c *ChatCompletionsStreamResponseChoiceDelta) GetReasoningContent() string { func (c *ChatCompletionsStreamResponseChoiceDelta) GetReasoningContent() string {
if c.ReasoningContent == nil { if c.ReasoningContent == nil && c.Reasoning == nil {
return "" return ""
} }
return *c.ReasoningContent if c.ReasoningContent != nil {
return *c.ReasoningContent
}
return *c.Reasoning
} }
func (c *ChatCompletionsStreamResponseChoiceDelta) SetReasoningContent(s string) { func (c *ChatCompletionsStreamResponseChoiceDelta) SetReasoningContent(s string) {
c.ReasoningContent = &s c.ReasoningContent = &s
c.Reasoning = &s
} }
type ToolCallResponse struct { type ToolCallResponse struct {

View File

@@ -4,10 +4,6 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/bytedance/gopkg/util/gopool"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
"io" "io"
"math" "math"
"mime/multipart" "mime/multipart"
@@ -21,6 +17,11 @@ import (
"one-api/service" "one-api/service"
"os" "os"
"strings" "strings"
"github.com/bytedance/gopkg/util/gopool"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
) )
func sendStreamData(c *gin.Context, info *relaycommon.RelayInfo, data string, forceFormat bool, thinkToContent bool) error { func sendStreamData(c *gin.Context, info *relaycommon.RelayInfo, data string, forceFormat bool, thinkToContent bool) error {
@@ -55,7 +56,8 @@ func sendStreamData(c *gin.Context, info *relaycommon.RelayInfo, data string, fo
response := lastStreamResponse.Copy() response := lastStreamResponse.Copy()
for i := range response.Choices { for i := range response.Choices {
response.Choices[i].Delta.SetContentString("<think>\n") response.Choices[i].Delta.SetContentString("<think>\n")
response.Choices[i].Delta.SetReasoningContent("") response.Choices[i].Delta.ReasoningContent = nil
response.Choices[i].Delta.Reasoning = nil
} }
info.ThinkingContentInfo.IsFirstThinkingContent = false info.ThinkingContentInfo.IsFirstThinkingContent = false
return helper.ObjectData(c, response) return helper.ObjectData(c, response)
@@ -74,8 +76,9 @@ func sendStreamData(c *gin.Context, info *relaycommon.RelayInfo, data string, fo
if len(choice.Delta.GetContentString()) > 0 && !info.ThinkingContentInfo.SendLastThinkingContent { if len(choice.Delta.GetContentString()) > 0 && !info.ThinkingContentInfo.SendLastThinkingContent {
response := lastStreamResponse.Copy() response := lastStreamResponse.Copy()
for j := range response.Choices { for j := range response.Choices {
response.Choices[j].Delta.SetContentString("\n</think>\n\n") response.Choices[j].Delta.SetContentString("\n</think>")
response.Choices[j].Delta.SetReasoningContent("") response.Choices[j].Delta.ReasoningContent = nil
response.Choices[j].Delta.Reasoning = nil
} }
info.ThinkingContentInfo.SendLastThinkingContent = true info.ThinkingContentInfo.SendLastThinkingContent = true
helper.ObjectData(c, response) helper.ObjectData(c, response)
@@ -84,7 +87,8 @@ func sendStreamData(c *gin.Context, info *relaycommon.RelayInfo, data string, fo
// Convert reasoning content to regular content // Convert reasoning content to regular content
if len(choice.Delta.GetReasoningContent()) > 0 { if len(choice.Delta.GetReasoningContent()) > 0 {
lastStreamResponse.Choices[i].Delta.SetContentString(choice.Delta.GetReasoningContent()) lastStreamResponse.Choices[i].Delta.SetContentString(choice.Delta.GetReasoningContent())
lastStreamResponse.Choices[i].Delta.SetReasoningContent("") lastStreamResponse.Choices[i].Delta.ReasoningContent = nil
lastStreamResponse.Choices[i].Delta.Reasoning = nil
} }
} }
@@ -178,7 +182,10 @@ func OaiStreamHandler(c *gin.Context, resp *http.Response, info *relaycommon.Rel
//} //}
for _, choice := range streamResponse.Choices { for _, choice := range streamResponse.Choices {
responseTextBuilder.WriteString(choice.Delta.GetContentString()) responseTextBuilder.WriteString(choice.Delta.GetContentString())
// handle both reasoning_content and reasoning
responseTextBuilder.WriteString(choice.Delta.GetReasoningContent()) responseTextBuilder.WriteString(choice.Delta.GetReasoningContent())
if choice.Delta.ToolCalls != nil { if choice.Delta.ToolCalls != nil {
if len(choice.Delta.ToolCalls) > toolCount { if len(choice.Delta.ToolCalls) > toolCount {
toolCount = len(choice.Delta.ToolCalls) toolCount = len(choice.Delta.ToolCalls)
@@ -199,7 +206,7 @@ func OaiStreamHandler(c *gin.Context, resp *http.Response, info *relaycommon.Rel
//} //}
for _, choice := range streamResponse.Choices { for _, choice := range streamResponse.Choices {
responseTextBuilder.WriteString(choice.Delta.GetContentString()) responseTextBuilder.WriteString(choice.Delta.GetContentString())
responseTextBuilder.WriteString(choice.Delta.GetReasoningContent()) responseTextBuilder.WriteString(choice.Delta.GetReasoningContent()) // This will handle both reasoning_content and reasoning
if choice.Delta.ToolCalls != nil { if choice.Delta.ToolCalls != nil {
if len(choice.Delta.ToolCalls) > toolCount { if len(choice.Delta.ToolCalls) > toolCount {
toolCount = len(choice.Delta.ToolCalls) toolCount = len(choice.Delta.ToolCalls)
@@ -291,7 +298,7 @@ func OpenaiHandler(c *gin.Context, resp *http.Response, promptTokens int, model
if simpleResponse.Usage.TotalTokens == 0 || (simpleResponse.Usage.PromptTokens == 0 && simpleResponse.Usage.CompletionTokens == 0) { if simpleResponse.Usage.TotalTokens == 0 || (simpleResponse.Usage.PromptTokens == 0 && simpleResponse.Usage.CompletionTokens == 0) {
completionTokens := 0 completionTokens := 0
for _, choice := range simpleResponse.Choices { for _, choice := range simpleResponse.Choices {
ctkm, _ := service.CountTextToken(choice.Message.StringContent()+choice.Message.ReasoningContent, model) ctkm, _ := service.CountTextToken(choice.Message.StringContent()+choice.Message.ReasoningContent+choice.Message.Reasoning, model)
completionTokens += ctkm completionTokens += ctkm
} }
simpleResponse.Usage = dto.Usage{ simpleResponse.Usage = dto.Usage{