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
+6
View File
@@ -63,6 +63,7 @@ const (
AdvancedCustomConverterAnthropicMessagesToOpenAIChatCompletions = "anthropic_messages_to_openai_chat_completions"
AdvancedCustomConverterOpenAIChatCompletionsToAnthropicMessages = "openai_chat_completions_to_anthropic_messages"
AdvancedCustomConverterOpenAIChatCompletionsToOpenAIResponses = "openai_chat_completions_to_openai_responses"
AdvancedCustomConverterOpenAIResponsesToOpenAIChatCompletions = "openai_responses_to_openai_chat_completions"
AdvancedCustomConverterGeminiGenerateContentToOpenAIChatCompletions = "gemini_generate_content_to_openai_chat_completions"
AdvancedCustomConverterOpenAIChatCompletionsToGeminiGenerateContent = "openai_chat_completions_to_gemini_generate_content"
)
@@ -147,6 +148,7 @@ func IsAdvancedCustomConverterAllowed(converter string) bool {
AdvancedCustomConverterAnthropicMessagesToOpenAIChatCompletions,
AdvancedCustomConverterOpenAIChatCompletionsToAnthropicMessages,
AdvancedCustomConverterOpenAIChatCompletionsToOpenAIResponses,
AdvancedCustomConverterOpenAIResponsesToOpenAIChatCompletions,
AdvancedCustomConverterGeminiGenerateContentToOpenAIChatCompletions,
AdvancedCustomConverterOpenAIChatCompletionsToGeminiGenerateContent:
return true
@@ -240,6 +242,10 @@ func validateAdvancedCustomConverterPath(index int, incomingPath string, convert
if incomingPath == "/v1/chat/completions" {
return nil
}
case AdvancedCustomConverterOpenAIResponsesToOpenAIChatCompletions:
if incomingPath == "/v1/responses" {
return nil
}
case AdvancedCustomConverterGeminiGenerateContentToOpenAIChatCompletions:
if strings.Contains(incomingPath, ":generateContent") || strings.Contains(incomingPath, ":streamGenerateContent") {
return nil