mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-03-30 03:43:39 +00:00
fix: map Responses reasoning stream to chat completion deltas
fix: default summary = detailed fix ReasoningContent fix ReasoningContent fix ReasoningContent fix ReasoningContent Revert "fix ReasoningContent" This reverts commit 45a88f78b91ce2376bca68745d19374bb9e95e88. fix ReasoningContent fix ReasoningContent
This commit is contained in:
@@ -352,6 +352,11 @@ type ResponsesOutputContent struct {
|
||||
Annotations []interface{} `json:"annotations"`
|
||||
}
|
||||
|
||||
type ResponsesReasoningSummaryPart struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
const (
|
||||
BuildInToolWebSearchPreview = "web_search_preview"
|
||||
BuildInToolFileSearch = "file_search"
|
||||
@@ -374,8 +379,11 @@ type ResponsesStreamResponse struct {
|
||||
Item *ResponsesOutput `json:"item,omitempty"`
|
||||
// - response.function_call_arguments.delta
|
||||
// - response.function_call_arguments.done
|
||||
OutputIndex *int `json:"output_index,omitempty"`
|
||||
ItemID string `json:"item_id,omitempty"`
|
||||
OutputIndex *int `json:"output_index,omitempty"`
|
||||
ContentIndex *int `json:"content_index,omitempty"`
|
||||
SummaryIndex *int `json:"summary_index,omitempty"`
|
||||
ItemID string `json:"item_id,omitempty"`
|
||||
Part *ResponsesReasoningSummaryPart `json:"part,omitempty"`
|
||||
}
|
||||
|
||||
// GetOpenAIError 从动态错误类型中提取OpenAIError结构
|
||||
|
||||
@@ -18,6 +18,26 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func responsesStreamIndexKey(itemID string, idx *int) string {
|
||||
if itemID == "" {
|
||||
return ""
|
||||
}
|
||||
if idx == nil {
|
||||
return itemID
|
||||
}
|
||||
return fmt.Sprintf("%s:%d", itemID, *idx)
|
||||
}
|
||||
|
||||
func stringDeltaFromPrefix(prev string, next string) string {
|
||||
if next == "" {
|
||||
return ""
|
||||
}
|
||||
if prev != "" && strings.HasPrefix(next, prev) {
|
||||
return next[len(prev):]
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
func OaiResponsesToChatHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Response) (*dto.Usage, *types.NewAPIError) {
|
||||
if resp == nil || resp.Body == nil {
|
||||
return nil, types.NewOpenAIError(fmt.Errorf("invalid response"), types.ErrorCodeBadResponse, http.StatusInternalServerError)
|
||||
@@ -86,6 +106,7 @@ func OaiResponsesToChatStreamHandler(c *gin.Context, info *relaycommon.RelayInfo
|
||||
toolCallArgsByID := make(map[string]string)
|
||||
toolCallNameSent := make(map[string]bool)
|
||||
toolCallCanonicalIDByItemID := make(map[string]string)
|
||||
//reasoningSummaryTextByKey := make(map[string]string)
|
||||
|
||||
sendStartIfNeeded := func() bool {
|
||||
if sentStart {
|
||||
@@ -99,6 +120,66 @@ func OaiResponsesToChatStreamHandler(c *gin.Context, info *relaycommon.RelayInfo
|
||||
return true
|
||||
}
|
||||
|
||||
//sendReasoningDelta := func(delta string) bool {
|
||||
// if delta == "" {
|
||||
// return true
|
||||
// }
|
||||
// if !sendStartIfNeeded() {
|
||||
// return false
|
||||
// }
|
||||
//
|
||||
// usageText.WriteString(delta)
|
||||
// chunk := &dto.ChatCompletionsStreamResponse{
|
||||
// Id: responseId,
|
||||
// Object: "chat.completion.chunk",
|
||||
// Created: createAt,
|
||||
// Model: model,
|
||||
// Choices: []dto.ChatCompletionsStreamResponseChoice{
|
||||
// {
|
||||
// Index: 0,
|
||||
// Delta: dto.ChatCompletionsStreamResponseChoiceDelta{
|
||||
// ReasoningContent: &delta,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// if err := helper.ObjectData(c, chunk); err != nil {
|
||||
// streamErr = types.NewOpenAIError(err, types.ErrorCodeBadResponse, http.StatusInternalServerError)
|
||||
// return false
|
||||
// }
|
||||
// return true
|
||||
//}
|
||||
|
||||
sendReasoningSummaryDelta := func(delta string) bool {
|
||||
if delta == "" {
|
||||
return true
|
||||
}
|
||||
if !sendStartIfNeeded() {
|
||||
return false
|
||||
}
|
||||
|
||||
usageText.WriteString(delta)
|
||||
chunk := &dto.ChatCompletionsStreamResponse{
|
||||
Id: responseId,
|
||||
Object: "chat.completion.chunk",
|
||||
Created: createAt,
|
||||
Model: model,
|
||||
Choices: []dto.ChatCompletionsStreamResponseChoice{
|
||||
{
|
||||
Index: 0,
|
||||
Delta: dto.ChatCompletionsStreamResponseChoiceDelta{
|
||||
ReasoningContent: &delta,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := helper.ObjectData(c, chunk); err != nil {
|
||||
streamErr = types.NewOpenAIError(err, types.ErrorCodeBadResponse, http.StatusInternalServerError)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
sendToolCallDelta := func(callID string, name string, argsDelta string) bool {
|
||||
if callID == "" {
|
||||
return true
|
||||
@@ -188,6 +269,37 @@ func OaiResponsesToChatStreamHandler(c *gin.Context, info *relaycommon.RelayInfo
|
||||
}
|
||||
}
|
||||
|
||||
//case "response.reasoning_text.delta":
|
||||
//if !sendReasoningDelta(streamResp.Delta) {
|
||||
// return false
|
||||
//}
|
||||
|
||||
//case "response.reasoning_text.done":
|
||||
|
||||
case "response.reasoning_summary_text.delta":
|
||||
if !sendReasoningSummaryDelta(streamResp.Delta) {
|
||||
return false
|
||||
}
|
||||
|
||||
case "response.reasoning_summary_text.done":
|
||||
|
||||
//case "response.reasoning_summary_part.added", "response.reasoning_summary_part.done":
|
||||
// key := responsesStreamIndexKey(strings.TrimSpace(streamResp.ItemID), streamResp.SummaryIndex)
|
||||
// if key == "" || streamResp.Part == nil {
|
||||
// break
|
||||
// }
|
||||
// // Only handle summary text parts, ignore other part types.
|
||||
// if streamResp.Part.Type != "" && streamResp.Part.Type != "summary_text" {
|
||||
// break
|
||||
// }
|
||||
// prev := reasoningSummaryTextByKey[key]
|
||||
// next := streamResp.Part.Text
|
||||
// delta := stringDeltaFromPrefix(prev, next)
|
||||
// reasoningSummaryTextByKey[key] = next
|
||||
// if !sendReasoningSummaryDelta(delta) {
|
||||
// return false
|
||||
// }
|
||||
|
||||
case "response.output_text.delta":
|
||||
if !sendStartIfNeeded() {
|
||||
return false
|
||||
|
||||
@@ -346,9 +346,10 @@ func ChatCompletionsRequestToResponsesRequest(req *dto.GeneralOpenAIRequest) (*d
|
||||
Metadata: req.Metadata,
|
||||
}
|
||||
|
||||
if req.ReasoningEffort != "" && req.ReasoningEffort != "none" {
|
||||
if req.ReasoningEffort != "" {
|
||||
out.Reasoning = &dto.Reasoning{
|
||||
Effort: req.ReasoningEffort,
|
||||
Effort: req.ReasoningEffort,
|
||||
Summary: "detailed",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user