mirror of
https://github.com/open-webui/open-webui.git
synced 2026-08-13 01:02:25 -06:00
fix: apply response.output_item.done instead of ignoring it (#28310)
The Responses API handler had a branch for response.output_item.done whose own comment said it was handled specifically below, but it never ran. The generic branch matching any response.*.done event came first in the chain and matched this event too, so it fell through and returned the accumulated output unchanged, leaving the dedicated branch below unreachable since the feature was added. Moving the dedicated branch above the generic one makes the event apply. On a compliant stream this changes nothing, since response.completed replaces the whole output with the same data straight afterwards. It matters when a provider is less tidy: one that never sends response.content_part.added leaves the assistant's own reply unextractable from the next turn's context, and one that omits response.content_part.done drops the annotations that only arrive with the finished item. Both are repaired by honouring the event. Worth knowing: the item replaces whatever the deltas accumulated, with no guard against a provider sending back less than it streamed. A reasoning item arriving without its content would therefore lose the reasoning body, which is the same shape of provider brokenness that #27800 already needed a guard for.
This commit is contained in:
@@ -667,6 +667,18 @@ def handle_responses_streaming_event(
|
||||
|
||||
return current_output, None
|
||||
|
||||
elif event_type == 'response.output_item.done':
|
||||
# Delta Event: Output item complete
|
||||
item = data.get('item')
|
||||
output_index = data.get('output_index', len(current_output) - 1)
|
||||
|
||||
new_output = list(current_output)
|
||||
if item and 0 <= output_index < len(current_output):
|
||||
new_output[output_index] = item
|
||||
elif item:
|
||||
new_output.append(item)
|
||||
return new_output, {}
|
||||
|
||||
elif event_type.startswith('response.') and event_type.endswith('.done'):
|
||||
# Delta Events: response.content_part.done, response.text.done, etc.
|
||||
parts = event_type.split('.')
|
||||
@@ -711,12 +723,8 @@ def handle_responses_streaming_event(
|
||||
return new_output, {}
|
||||
return current_output, None
|
||||
|
||||
# 2. Skip Output Item done (handled specifically below)
|
||||
if type_name == 'output_item':
|
||||
pass
|
||||
|
||||
# 3. Generic Field Done (text.done, audio.done)
|
||||
elif type_name not in ['completed', 'failed']:
|
||||
# 2. Generic Field Done (text.done, audio.done)
|
||||
if type_name not in ['completed', 'failed']:
|
||||
output_index = data.get('output_index', len(current_output) - 1)
|
||||
if current_output and 0 <= output_index < len(current_output):
|
||||
key = (
|
||||
@@ -760,18 +768,6 @@ def handle_responses_streaming_event(
|
||||
|
||||
return current_output, None
|
||||
|
||||
elif event_type == 'response.output_item.done':
|
||||
# Delta Event: Output item complete
|
||||
item = data.get('item')
|
||||
output_index = data.get('output_index', len(current_output) - 1)
|
||||
|
||||
new_output = list(current_output)
|
||||
if item and 0 <= output_index < len(current_output):
|
||||
new_output[output_index] = item
|
||||
elif item:
|
||||
new_output.append(item)
|
||||
return new_output, {}
|
||||
|
||||
elif event_type == 'response.completed':
|
||||
# State Machine Event: Completed
|
||||
response_data = data.get('response', {})
|
||||
|
||||
Reference in New Issue
Block a user