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:
@@ -43,6 +43,10 @@ export const ADVANCED_CUSTOM_CONVERTER_OPTIONS: Array<{
|
||||
value: 'openai_chat_completions_to_openai_responses',
|
||||
label: 'OpenAI Chat to OpenAI Responses',
|
||||
},
|
||||
{
|
||||
value: 'openai_responses_to_openai_chat_completions',
|
||||
label: 'OpenAI Responses to OpenAI Chat',
|
||||
},
|
||||
{
|
||||
value: 'gemini_generate_content_to_openai_chat_completions',
|
||||
label: 'Gemini Generate Content to OpenAI Chat',
|
||||
@@ -326,6 +330,9 @@ export function getAdvancedCustomUpstreamPathPlaceholder(
|
||||
if (converter === 'openai_chat_completions_to_anthropic_messages') {
|
||||
return '/v1/messages'
|
||||
}
|
||||
if (converter === 'openai_responses_to_openai_chat_completions') {
|
||||
return '/v1/chat/completions'
|
||||
}
|
||||
return '/v1/chat/completions'
|
||||
}
|
||||
|
||||
@@ -573,6 +580,9 @@ function isConverterPathAllowed(
|
||||
) {
|
||||
return incomingPath === '/v1/chat/completions'
|
||||
}
|
||||
if (converter === 'openai_responses_to_openai_chat_completions') {
|
||||
return incomingPath === '/v1/responses'
|
||||
}
|
||||
return (
|
||||
incomingPath.includes(':generateContent') ||
|
||||
incomingPath.includes(':streamGenerateContent')
|
||||
|
||||
+1
@@ -131,6 +131,7 @@ export type AdvancedCustomConverter =
|
||||
| 'anthropic_messages_to_openai_chat_completions'
|
||||
| 'openai_chat_completions_to_anthropic_messages'
|
||||
| 'openai_chat_completions_to_openai_responses'
|
||||
| 'openai_responses_to_openai_chat_completions'
|
||||
| 'gemini_generate_content_to_openai_chat_completions'
|
||||
| 'openai_chat_completions_to_gemini_generate_content'
|
||||
|
||||
|
||||
Vendored
+2
-1
@@ -2995,6 +2995,7 @@
|
||||
"OpenAI Rerank": "OpenAI Rerank",
|
||||
"OpenAI Responses": "OpenAI Responses",
|
||||
"OpenAI Responses Compact": "OpenAI Responses Compact",
|
||||
"OpenAI Responses to OpenAI Chat": "OpenAI Responses to OpenAI Chat",
|
||||
"OpenAI, Anthropic, etc.": "OpenAI, Anthropic, etc.",
|
||||
"OpenAI, Anthropic, Google, etc.": "OpenAI, Anthropic, Google, etc.",
|
||||
"OpenAIMax": "OpenAIMax",
|
||||
@@ -3675,8 +3676,8 @@
|
||||
"Resetting...": "Resetting...",
|
||||
"Resolve Conflicts": "Resolve Conflicts",
|
||||
"Resource Configuration": "Resource Configuration",
|
||||
"Responding...": "Responding...",
|
||||
"Resources": "Resources",
|
||||
"Responding...": "Responding...",
|
||||
"Response": "Response",
|
||||
"Response Time": "Response Time",
|
||||
"Response time: {{duration}}": "Response time: {{duration}}",
|
||||
|
||||
Vendored
+2
-1
@@ -2995,6 +2995,7 @@
|
||||
"OpenAI Rerank": "OpenAI Rerank",
|
||||
"OpenAI Responses": "OpenAI Responses",
|
||||
"OpenAI Responses Compact": "OpenAI Responses Compact",
|
||||
"OpenAI Responses to OpenAI Chat": "OpenAI Responses vers OpenAI Chat",
|
||||
"OpenAI, Anthropic, etc.": "OpenAI, Anthropic, etc.",
|
||||
"OpenAI, Anthropic, Google, etc.": "OpenAI, Anthropic, Google, etc.",
|
||||
"OpenAIMax": "OpenAIMax",
|
||||
@@ -3675,8 +3676,8 @@
|
||||
"Resetting...": "Réinitialisation...",
|
||||
"Resolve Conflicts": "Résoudre les conflits",
|
||||
"Resource Configuration": "Configuration des ressources",
|
||||
"Responding...": "Réponse en cours...",
|
||||
"Resources": "Ressources",
|
||||
"Responding...": "Réponse en cours...",
|
||||
"Response": "Réponse",
|
||||
"Response Time": "Temps de réponse",
|
||||
"Response time: {{duration}}": "Temps de réponse : {{duration}}",
|
||||
|
||||
Vendored
+2
-1
@@ -2995,6 +2995,7 @@
|
||||
"OpenAI Rerank": "OpenAI 再ランク付け",
|
||||
"OpenAI Responses": "OpenAI レスポンス",
|
||||
"OpenAI Responses Compact": "OpenAI レスポンス圧縮",
|
||||
"OpenAI Responses to OpenAI Chat": "OpenAI Responses から OpenAI Chat",
|
||||
"OpenAI, Anthropic, etc.": "OpenAI、Anthropicなど",
|
||||
"OpenAI, Anthropic, Google, etc.": "OpenAI、Anthropic、Googleなど",
|
||||
"OpenAIMax": "OpenAIMax",
|
||||
@@ -3675,8 +3676,8 @@
|
||||
"Resetting...": "リセット中...",
|
||||
"Resolve Conflicts": "競合を解決",
|
||||
"Resource Configuration": "リソース設定",
|
||||
"Responding...": "応答中...",
|
||||
"Resources": "リソース",
|
||||
"Responding...": "応答中...",
|
||||
"Response": "レスポンス",
|
||||
"Response Time": "応答時間",
|
||||
"Response time: {{duration}}": "応答時間: {{duration}}",
|
||||
|
||||
Vendored
+2
-1
@@ -2995,6 +2995,7 @@
|
||||
"OpenAI Rerank": "Реранжирование OpenAI",
|
||||
"OpenAI Responses": "Ответы OpenAI",
|
||||
"OpenAI Responses Compact": "Компактные ответы OpenAI",
|
||||
"OpenAI Responses to OpenAI Chat": "OpenAI Responses в OpenAI Chat",
|
||||
"OpenAI, Anthropic, etc.": "OpenAI, Anthropic и т.д.",
|
||||
"OpenAI, Anthropic, Google, etc.": "OpenAI, Anthropic, Google и т.д.",
|
||||
"OpenAIMax": "OpenAIMax",
|
||||
@@ -3675,8 +3676,8 @@
|
||||
"Resetting...": "Сброс...",
|
||||
"Resolve Conflicts": "Разрешить конфликты",
|
||||
"Resource Configuration": "Конфигурация ресурсов",
|
||||
"Responding...": "Отвечаем...",
|
||||
"Resources": "Ресурсы",
|
||||
"Responding...": "Отвечаем...",
|
||||
"Response": "Ответ",
|
||||
"Response Time": "Время ответа",
|
||||
"Response time: {{duration}}": "Время ответа: {{duration}}",
|
||||
|
||||
Vendored
+2
-1
@@ -2995,6 +2995,7 @@
|
||||
"OpenAI Rerank": "OpenAI Rerank",
|
||||
"OpenAI Responses": "OpenAI Responses",
|
||||
"OpenAI Responses Compact": "OpenAI Responses Compact",
|
||||
"OpenAI Responses to OpenAI Chat": "OpenAI Responses sang OpenAI Chat",
|
||||
"OpenAI, Anthropic, etc.": "OpenAI, Anthropic, v.v.",
|
||||
"OpenAI, Anthropic, Google, etc.": "OpenAI, Anthropic, Google, v.v.",
|
||||
"OpenAIMax": "OpenAIMax",
|
||||
@@ -3675,8 +3676,8 @@
|
||||
"Resetting...": "Đang đặt lại...",
|
||||
"Resolve Conflicts": "Giải quyết Xung đột",
|
||||
"Resource Configuration": "Cấu hình tài nguyên",
|
||||
"Responding...": "Đang phản hồi...",
|
||||
"Resources": "Tài nguyên",
|
||||
"Responding...": "Đang phản hồi...",
|
||||
"Response": "Phản hồi",
|
||||
"Response Time": "Thời gian phản hồi",
|
||||
"Response time: {{duration}}": "Thời gian phản hồi: {{duration}}",
|
||||
|
||||
Vendored
+2
-1
@@ -2995,6 +2995,7 @@
|
||||
"OpenAI Rerank": "OpenAI 重排序",
|
||||
"OpenAI Responses": "OpenAI 响应",
|
||||
"OpenAI Responses Compact": "OpenAI 响应压缩",
|
||||
"OpenAI Responses to OpenAI Chat": "OpenAI Responses 到 OpenAI Chat",
|
||||
"OpenAI, Anthropic, etc.": "OpenAI、Anthropic 等",
|
||||
"OpenAI, Anthropic, Google, etc.": "OpenAI、Anthropic、Google 等",
|
||||
"OpenAIMax": "OpenAIMax",
|
||||
@@ -3675,8 +3676,8 @@
|
||||
"Resetting...": "重置中...",
|
||||
"Resolve Conflicts": "解决冲突",
|
||||
"Resource Configuration": "资源配置",
|
||||
"Responding...": "正在回复...",
|
||||
"Resources": "资源",
|
||||
"Responding...": "正在回复...",
|
||||
"Response": "响应",
|
||||
"Response Time": "响应时间",
|
||||
"Response time: {{duration}}": "响应时间:{{duration}}",
|
||||
|
||||
Reference in New Issue
Block a user