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
+13 -5
View File
@@ -2,21 +2,29 @@ package service
import (
"github.com/QuantumNous/new-api/dto"
"github.com/QuantumNous/new-api/service/openaicompat"
"github.com/QuantumNous/new-api/service/relayconvert"
)
func ChatCompletionsRequestToResponsesRequest(req *dto.GeneralOpenAIRequest) (*dto.OpenAIResponsesRequest, error) {
return openaicompat.ChatCompletionsRequestToResponsesRequest(req)
return relayconvert.ChatCompletionsRequestToResponsesRequest(req)
}
func ResponsesRequestToChatCompletionsRequest(req *dto.OpenAIResponsesRequest) (*dto.GeneralOpenAIRequest, error) {
return relayconvert.ResponsesRequestToChatCompletionsRequest(req)
}
func ChatCompletionsResponseToResponsesResponse(resp *dto.OpenAITextResponse, id string) (*dto.OpenAIResponsesResponse, *dto.Usage, error) {
return relayconvert.ChatCompletionsResponseToResponsesResponse(resp, id)
}
func ResponsesResponseToChatCompletionsResponse(resp *dto.OpenAIResponsesResponse, id string) (*dto.OpenAITextResponse, *dto.Usage, error) {
return openaicompat.ResponsesResponseToChatCompletionsResponse(resp, id)
return relayconvert.ResponsesResponseToChatCompletionsResponse(resp, id)
}
func ResponsesFinishReasonFromStatus(resp *dto.OpenAIResponsesResponse) (string, bool) {
return openaicompat.ResponsesFinishReasonFromStatus(resp)
return relayconvert.ResponsesFinishReasonFromStatus(resp)
}
func ExtractOutputTextFromResponses(resp *dto.OpenAIResponsesResponse) string {
return openaicompat.ExtractOutputTextFromResponses(resp)
return relayconvert.ExtractOutputTextFromResponses(resp)
}