Skip to content

Commit 93415a4

Browse files
committed
refac
1 parent f8b3a32 commit 93415a4

2 files changed

Lines changed: 59 additions & 22 deletions

File tree

backend/open_webui/routers/openai.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,9 @@ def convert_to_responses_payload(payload: dict) -> dict:
858858
if 'max_tokens' in responses_payload:
859859
responses_payload['max_output_tokens'] = responses_payload.pop('max_tokens')
860860

861+
if 'max_completion_tokens' in responses_payload:
862+
responses_payload['max_output_tokens'] = responses_payload.pop('max_completion_tokens')
863+
861864
# Remove Chat Completions-only parameters not supported by the Responses API
862865
for unsupported_key in (
863866
'stream_options',
@@ -896,11 +899,36 @@ def convert_to_responses_payload(payload: dict) -> dict:
896899

897900
def convert_responses_result(response: dict) -> dict:
898901
"""
899-
Convert non-streaming Responses API result.
900-
Just add done flag - pass through raw response, frontend handles output.
902+
Convert non-streaming Responses API result to Chat Completions format.
903+
904+
Extracts text from message output items so all downstream consumers
905+
(frontend tasks, get_content_from_response) work without modification.
901906
"""
902-
response['done'] = True
903-
return response
907+
output_items = response.get('output', [])
908+
909+
content = ''
910+
for item in output_items:
911+
if item.get('type') == 'message':
912+
for part in item.get('content', []):
913+
if part.get('type') == 'output_text':
914+
content += part.get('text', '')
915+
916+
return {
917+
'id': response.get('id', ''),
918+
'object': 'chat.completion',
919+
'model': response.get('model', ''),
920+
'choices': [
921+
{
922+
'index': 0,
923+
'message': {
924+
'role': 'assistant',
925+
'content': content,
926+
},
927+
'finish_reason': 'stop',
928+
}
929+
],
930+
'usage': response.get('usage', {}),
931+
}
904932

905933

906934
@router.post('/chat/completions')

backend/open_webui/utils/middleware.py

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3367,6 +3367,9 @@ def set_last_text(out, text):
33673367
usage = None
33683368
prior_output = []
33693369

3370+
def full_output():
3371+
return prior_output + output if prior_output else output
3372+
33703373
reasoning_tags_param = metadata.get('params', {}).get('reasoning_tags')
33713374
DETECT_REASONING_TAGS = reasoning_tags_param is not False
33723375
DETECT_CODE_INTERPRETER = metadata.get('features', {}).get('code_interpreter', False)
@@ -3476,8 +3479,8 @@ async def flush_pending_delta_data(threshold: int = 0):
34763479
output, response_metadata = handle_responses_streaming_event(data, output)
34773480

34783481
processed_data = {
3479-
'output': prior_output + output,
3480-
'content': serialize_output(prior_output + output),
3482+
'output': full_output(),
3483+
'content': serialize_output(full_output()),
34813484
}
34823485

34833486
# print(data)
@@ -3832,13 +3835,13 @@ async def flush_pending_delta_data(threshold: int = 0):
38323835
metadata['chat_id'],
38333836
metadata['message_id'],
38343837
{
3835-
'content': serialize_output(output),
3836-
'output': output,
3838+
'content': serialize_output(full_output()),
3839+
'output': full_output(),
38373840
},
38383841
)
38393842
else:
38403843
data = {
3841-
'content': serialize_output(output),
3844+
'content': serialize_output(full_output()),
38423845
}
38433846

38443847
if delta:
@@ -3952,26 +3955,32 @@ async def flush_pending_delta_data(threshold: int = 0):
39523955
response_tool_calls = tool_calls.pop(0)
39533956

39543957
# Append function_call items for each tool call
3958+
# (Responses API already has them from streaming, so skip duplicates)
3959+
existing_call_ids = {
3960+
item.get('call_id') for item in output
3961+
if item.get('type') == 'function_call'
3962+
}
39553963
for tc in response_tool_calls:
39563964
call_id = tc.get('id', '')
3957-
func = tc.get('function', {})
3958-
output.append(
3959-
{
3960-
'type': 'function_call',
3961-
'id': call_id or output_id('fc'),
3962-
'call_id': call_id,
3963-
'name': func.get('name', ''),
3964-
'arguments': func.get('arguments', '{}'),
3965-
'status': 'in_progress',
3966-
}
3967-
)
3965+
if call_id not in existing_call_ids:
3966+
func = tc.get('function', {})
3967+
output.append(
3968+
{
3969+
'type': 'function_call',
3970+
'id': call_id or output_id('fc'),
3971+
'call_id': call_id,
3972+
'name': func.get('name', ''),
3973+
'arguments': func.get('arguments', '{}'),
3974+
'status': 'in_progress',
3975+
}
3976+
)
39683977

39693978
await event_emitter(
39703979
{
39713980
'type': 'chat:completion',
39723981
'data': {
3973-
'content': serialize_output(output),
3974-
'output': output,
3982+
'content': serialize_output(full_output()),
3983+
'output': full_output(),
39753984
},
39763985
}
39773986
)

0 commit comments

Comments
 (0)