feat: support Responses to Chat (#5787)

* fix(openai): harden Chat-to-Responses compatibility

Add a shared Responses-to-Chat stream state machine and use it from the OpenAI relay path. Preserve assistant text alongside tool calls, bind tool argument deltas by output_index, map incomplete finish reasons, support reasoning/custom tool events, and buffer upstream SSE for non-stream Chat clients.

Add deterministic service tests and relay SSE tests for the conversion path.

Related to #5745.

* refactor: rename openaicompat to relayconvert for improved clarity

* feat(gemini): support responses request conversion

* feat: add responses to chat conversion support

* fix: harden responses chat conversion edge cases
This commit is contained in:
Calcium-Ion
2026-06-28 14:25:47 +08:00
committed by GitHub
parent 3a506f50f0
commit 2d5a041639
35 changed files with 2731 additions and 40 deletions
+5 -5
View File
@@ -14,7 +14,7 @@ import (
relaycommon "github.com/QuantumNous/new-api/relay/common"
"github.com/QuantumNous/new-api/relay/helper"
"github.com/QuantumNous/new-api/service"
"github.com/QuantumNous/new-api/service/openaicompat"
"github.com/QuantumNous/new-api/service/relayconvert"
"github.com/QuantumNous/new-api/types"
"github.com/gin-gonic/gin"
@@ -78,7 +78,7 @@ func OaiResponsesToChatBufferedStreamHandler(c *gin.Context, info *relaycommon.R
}
defer service.CloseResponseBodyGracefully(resp)
accumulator := openaicompat.NewResponsesBufferedAccumulator()
accumulator := relayconvert.NewResponsesBufferedAccumulator()
var finalResponse *dto.OpenAIResponsesResponse
var streamErr *types.NewAPIError
@@ -184,7 +184,7 @@ func OaiResponsesToChatStreamHandler(c *gin.Context, info *relaycommon.RelayInfo
responseId := helper.GetResponseID(c)
createAt := time.Now().Unix()
state := openaicompat.NewResponsesToChatStreamState(info.UpstreamModelName, false)
state := relayconvert.NewResponsesToChatStreamState(info.UpstreamModelName, false)
state.ID = responseId
state.Created = createAt
streamErr := (*types.NewAPIError)(nil)
@@ -243,7 +243,7 @@ func OaiResponsesToChatStreamHandler(c *gin.Context, info *relaycommon.RelayInfo
return
}
chunks, err := openaicompat.ResponsesStreamEventToChatChunks(&streamResp, state)
chunks, err := relayconvert.ResponsesStreamEventToChatChunks(&streamResp, state)
if err != nil {
streamErr = types.NewOpenAIError(err, types.ErrorCodeBadResponse, http.StatusInternalServerError)
sr.Stop(streamErr)
@@ -270,7 +270,7 @@ func OaiResponsesToChatStreamHandler(c *gin.Context, info *relaycommon.RelayInfo
if info.RelayFormat == types.RelayFormatClaude && info.ClaudeConvertInfo != nil {
info.ClaudeConvertInfo.Usage = usage
}
for _, chunk := range openaicompat.FinalizeResponsesToChatStream(state) {
for _, chunk := range relayconvert.FinalizeResponsesToChatStream(state) {
if !sendChatChunk(chunk) {
return nil, streamErr
}