fix: 非流式路径在上游终态事件output为空时从delta事件重建响应内容

上游API近期更新后,response.completed终态SSE事件的output字段可能为空,
实际内容仅通过response.output_text.delta等增量事件下发。流式路径不受影响,
但chat_completions非流式路径和responses OAuth非流式路径只依赖终态事件的
output,导致返回空响应。

新增BufferedResponseAccumulator累积器,在SSE扫描过程中收集delta事件内容
(文本、function_call、reasoning),当终态output为空时补充重建。

同时修复handleChatBufferedStreamingResponse遗漏response.done事件类型的问题。
This commit is contained in:
shaw
2026-04-07 19:30:45 +08:00
parent 08b454423b
commit b2e379cf7a
4 changed files with 345 additions and 1 deletions

View File

@@ -244,6 +244,7 @@ func (s *OpenAIGatewayService) handleChatBufferedStreamingResponse(
var finalResponse *apicompat.ResponsesResponse
var usage OpenAIUsage
acc := apicompat.NewBufferedResponseAccumulator()
for scanner.Scan() {
line := scanner.Text()
@@ -261,7 +262,11 @@ func (s *OpenAIGatewayService) handleChatBufferedStreamingResponse(
continue
}
if (event.Type == "response.completed" || event.Type == "response.incomplete" || event.Type == "response.failed") &&
// Accumulate delta content for fallback when terminal output is empty.
acc.ProcessEvent(&event)
if (event.Type == "response.completed" || event.Type == "response.done" ||
event.Type == "response.incomplete" || event.Type == "response.failed") &&
event.Response != nil {
finalResponse = event.Response
if event.Response.Usage != nil {
@@ -290,6 +295,10 @@ func (s *OpenAIGatewayService) handleChatBufferedStreamingResponse(
return nil, fmt.Errorf("upstream stream ended without terminal event")
}
// When the terminal event has an empty output array, reconstruct from
// accumulated delta events so the client receives the full content.
acc.SupplementResponseOutput(finalResponse)
chatResp := apicompat.ResponsesToChatCompletions(finalResponse, originalModel)
if s.responseHeaderFilter != nil {