diff --git a/backend/internal/service/openai_gateway_messages.go b/backend/internal/service/openai_gateway_messages.go index 7a4862d3..a72b9bbf 100644 --- a/backend/internal/service/openai_gateway_messages.go +++ b/backend/internal/service/openai_gateway_messages.go @@ -270,6 +270,7 @@ func (s *OpenAIGatewayService) handleAnthropicBufferedStreamingResponse( var finalResponse *apicompat.ResponsesResponse var usage OpenAIUsage + acc := apicompat.NewBufferedResponseAccumulator() for scanner.Scan() { line := scanner.Text() @@ -288,8 +289,12 @@ func (s *OpenAIGatewayService) handleAnthropicBufferedStreamingResponse( continue } + // Accumulate delta content for fallback when terminal output is empty. + acc.ProcessEvent(&event) + // Terminal events carry the complete ResponsesResponse with output + usage. - if (event.Type == "response.completed" || event.Type == "response.incomplete" || event.Type == "response.failed") && + 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 { @@ -318,6 +323,10 @@ func (s *OpenAIGatewayService) handleAnthropicBufferedStreamingResponse( 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) + anthropicResp := apicompat.ResponsesToAnthropic(finalResponse, originalModel) if s.responseHeaderFilter != nil {