mirror of
https://github.com/open-webui/open-webui.git
synced 2026-09-27 01:40:33 -04:00
refac
Co-Authored-By: Classic298 <27028174+Classic298@users.noreply.github.com>
This commit is contained in:
co-authored by
Classic298
parent
30881dbcc9
commit
478d1785fd
@@ -1083,7 +1083,8 @@ async def _make_channel_emitter(request_info):
|
||||
state['output'] = copy.deepcopy(output)
|
||||
|
||||
now = time.time()
|
||||
if done or (now - state['last_emit_at']) >= THROTTLE_INTERVAL:
|
||||
# Tool boundaries must publish all results before waiting on the next model response.
|
||||
if done or data.get('flush') or (now - state['last_emit_at']) >= THROTTLE_INTERVAL:
|
||||
state['last_emit_at'] = now
|
||||
await _emit_channel_update(content, done, output if isinstance(output, list) else None)
|
||||
|
||||
|
||||
@@ -4974,6 +4974,14 @@ async def streaming_chat_response_handler(response, ctx):
|
||||
**response_data,
|
||||
'output_index': response_data['output_index'] + len(prior_output),
|
||||
}
|
||||
if prior_output and isinstance(response_data.get('response'), dict):
|
||||
# response.output is this round only; the response.completed reducer drops earlier rounds
|
||||
return {
|
||||
**response_data,
|
||||
'response': {
|
||||
key: value for key, value in response_data['response'].items() if key != 'output'
|
||||
},
|
||||
}
|
||||
return response_data
|
||||
|
||||
async def flush_pending_delta_data(threshold: int = 0):
|
||||
@@ -5808,6 +5816,7 @@ async def streaming_chat_response_handler(response, ctx):
|
||||
if responses_api_tool_calls:
|
||||
tool_calls.append(_split_tool_calls(responses_api_tool_calls))
|
||||
|
||||
output_start = len(prior_output)
|
||||
try:
|
||||
await stream_body_handler(response, form_data)
|
||||
finally:
|
||||
@@ -5839,6 +5848,42 @@ async def streaming_chat_response_handler(response, ctx):
|
||||
get_content_from_message(original_system_message) if original_system_message else None
|
||||
)
|
||||
|
||||
async def emit_output():
|
||||
# Channels publish whole messages; Continue can merge into the preceding item.
|
||||
snapshot = continuing or (metadata.get('chat_id') or '').startswith('channel:')
|
||||
frontend_output = []
|
||||
for item in full_output() if snapshot else full_output()[output_start:]:
|
||||
if item.get('type') == 'function_call_output':
|
||||
# input_image parts are base64 data URIs only for the LLM, via convert_output_to_messages
|
||||
item = {
|
||||
**item,
|
||||
'output': [
|
||||
part for part in item.get('output', []) if part.get('type') != 'input_image'
|
||||
],
|
||||
}
|
||||
frontend_output.append(item)
|
||||
|
||||
if snapshot:
|
||||
await event_emitter(
|
||||
{
|
||||
'type': 'chat:completion',
|
||||
'data': {'output': frontend_output, 'flush': True},
|
||||
}
|
||||
)
|
||||
return
|
||||
|
||||
for output_index, item in enumerate(frontend_output, start=output_start):
|
||||
await event_emitter(
|
||||
{
|
||||
'type': 'response:completion',
|
||||
'data': {
|
||||
'type': 'response.output_item.done',
|
||||
'output_index': output_index,
|
||||
'item': item,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
while tool_calls and (
|
||||
max_tool_call_iterations is None or tool_call_iterations < max_tool_call_iterations
|
||||
):
|
||||
@@ -5906,14 +5951,7 @@ async def streaming_chat_response_handler(response, ctx):
|
||||
)
|
||||
return
|
||||
|
||||
await event_emitter(
|
||||
{
|
||||
'type': 'chat:completion',
|
||||
'data': {
|
||||
'output': full_output(),
|
||||
},
|
||||
}
|
||||
)
|
||||
await emit_output()
|
||||
|
||||
tools = metadata.get('tools', {})
|
||||
|
||||
@@ -6180,25 +6218,7 @@ async def streaming_chat_response_handler(response, ctx):
|
||||
)
|
||||
tool_call_sources.clear()
|
||||
|
||||
# Strip input_image parts (large base64 data URIs) from the
|
||||
# output sent to the frontend — they're only for LLM consumption
|
||||
# via convert_output_to_messages.
|
||||
frontend_output = []
|
||||
for item in full_output():
|
||||
if item.get('type') == 'function_call_output':
|
||||
parts = item.get('output', [])
|
||||
if any(p.get('type') == 'input_image' for p in parts):
|
||||
item = {**item, 'output': [p for p in parts if p.get('type') != 'input_image']}
|
||||
frontend_output.append(item)
|
||||
|
||||
await event_emitter(
|
||||
{
|
||||
'type': 'chat:completion',
|
||||
'data': {
|
||||
'output': frontend_output,
|
||||
},
|
||||
}
|
||||
)
|
||||
await emit_output()
|
||||
|
||||
try:
|
||||
new_form_data = {
|
||||
@@ -6297,6 +6317,7 @@ async def streaming_chat_response_handler(response, ctx):
|
||||
if not msg_parts or (len(msg_parts) == 1 and not msg_parts[0].get('text', '').strip()):
|
||||
prior_output.pop()
|
||||
output = []
|
||||
output_start = len(prior_output)
|
||||
await stream_body_handler(res, new_form_data)
|
||||
output = full_output()
|
||||
prior_output = []
|
||||
|
||||
Reference in New Issue
Block a user