@@ -308,8 +308,6 @@ async def responses_full_generator(
308
308
assert final_res is not None
309
309
assert len (final_res .outputs ) == 1
310
310
final_output = final_res .outputs [0 ]
311
- print ("-" * 70 )
312
- print (f"Final output: { final_output } " )
313
311
if self .reasoning_parser :
314
312
try :
315
313
reasoning_parser = self .reasoning_parser (tokenizer )
@@ -323,85 +321,92 @@ async def responses_full_generator(
323
321
else :
324
322
reasoning_content = None
325
323
content = final_output .text
326
-
327
- outputs = []
328
- output = None
329
- if self .tool_parser :
330
- function_calls : list [FunctionCall ] = []
331
- if request .tool_choice and \
332
- isinstance (request .tool_choice ,
333
- ToolChoiceFunction ):
334
- # Forced Function Call
335
- function_calls .append (
336
- FunctionCall (name = request .tool_choice .name ,
337
- arguments = content ))
338
- elif request .tool_choice is None or request .tool_choice == "none" :
339
- pass
340
- elif request .tool_choice == "required" :
341
- assert content is not None
342
- tool_calls = TypeAdapter (
343
- list [FunctionDefinition ]).validate_json (content )
344
- function_calls .extend ([
345
- FunctionCall (name = tool_call .name ,
346
- arguments = json .dumps (tool_call .parameters ,
347
- ensure_ascii = False ))
348
- for tool_call in tool_calls
349
- ])
350
- elif request .tool_choice == "auto" :
351
- try :
352
- tool_parser = self .tool_parser (tokenizer )
353
- except RuntimeError as e :
354
- logger .exception ("Error in tool parser creation." )
355
- return self .create_error_response (str (e ))
356
- tool_call_info = tool_parser .extract_tool_calls (
357
- content if content is not None else "" , request = request )
358
- if tool_call_info is not None and tool_call_info .tools_called :
359
- function_calls .extend (
360
- FunctionCall (
361
- name = tool_call .function .name ,
362
- arguments = tool_call .function .arguments ,
363
- ) for tool_call in tool_call_info .tool_calls )
364
- else :
365
- logger .warning (
366
- "Unknown tool choice: %s. "
367
- "Using 'none' as the default tool choice." ,
368
- request .tool_choice )
369
- if function_calls :
370
- output = [
371
- ResponseFunctionToolCall (
372
- id = f"fc_{ random_fc_uuid ()} " ,
373
- call_id = f"call_{ random_uuid ()} " ,
374
- type = "function_call" ,
375
- status = "completed" ,
376
- name = tool_call .name ,
377
- arguments = tool_call .arguments ,
378
- ) for tool_call in function_calls
379
- ]
380
- # If no tool call is generated, we still need to return an output.
381
- if reasoning_content and output is None :
382
- output = ResponseReasoningItem (
324
+ reasoning_item = None
325
+ message_item = None
326
+ if reasoning_content :
327
+ reasoning_item = ResponseReasoningItem (
383
328
text = reasoning_content ,
384
329
status = None , # NOTE: Only the last output item has status.
385
330
)
386
- # If no tool call is generated, we still need to return an output.
387
- if content and output is None :
331
+ if content :
388
332
output_text = ResponseOutputText (
389
333
text = content ,
390
334
annotations = [], # TODO
391
335
type = "output_text" ,
392
336
logprobs = None , # TODO
393
337
)
394
- output = ResponseOutputMessage (
338
+ message_item = ResponseOutputMessage (
395
339
id = f"msg_{ random_uuid ()} " ,
396
340
content = [output_text ],
397
341
role = "assistant" ,
398
342
status = "completed" ,
399
343
type = "message" ,
400
344
)
401
- if isinstance (output , list ):
402
- outputs .extend (output )
345
+ outputs = []
346
+ function_calls : list [FunctionCall ] = []
347
+ if (not self .enable_auto_tools or not self .tool_parser ):
348
+ # Tools are not enabled
349
+ if reasoning_item :
350
+ outputs .append (reasoning_item )
351
+ if message_item :
352
+ outputs .append (message_item )
353
+ elif request .tool_choice is None or request .tool_choice == "none" :
354
+ # No tool calls.
355
+ if reasoning_item :
356
+ outputs .append (reasoning_item )
357
+ if message_item :
358
+ outputs .append (message_item )
359
+ elif request .tool_choice and \
360
+ isinstance (request .tool_choice ,
361
+ ToolChoiceFunction ):
362
+ # Forced Function Call
363
+ function_calls .append (
364
+ FunctionCall (name = request .tool_choice .name , arguments = content ))
365
+ elif request .tool_choice == "required" :
366
+ assert content is not None
367
+ tool_calls = TypeAdapter (
368
+ list [FunctionDefinition ]).validate_json (content )
369
+ function_calls .extend ([
370
+ FunctionCall (name = tool_call .name ,
371
+ arguments = json .dumps (tool_call .parameters ,
372
+ ensure_ascii = False ))
373
+ for tool_call in tool_calls
374
+ ])
375
+ elif request .tool_choice == "auto" :
376
+ try :
377
+ tool_parser = self .tool_parser (tokenizer )
378
+ except RuntimeError as e :
379
+ logger .exception ("Error in tool parser creation." )
380
+ return self .create_error_response (str (e ))
381
+ tool_call_info = tool_parser .extract_tool_calls (
382
+ content if content is not None else "" , request = request )
383
+ if tool_call_info is not None and tool_call_info .tools_called :
384
+ function_calls .extend (
385
+ FunctionCall (
386
+ name = tool_call .function .name ,
387
+ arguments = tool_call .function .arguments ,
388
+ ) for tool_call in tool_call_info .tool_calls )
389
+ else :
390
+ # No tool calls.
391
+ if reasoning_item :
392
+ outputs .append (reasoning_item )
393
+ if message_item :
394
+ outputs .append (message_item )
403
395
else :
404
- outputs .append (output )
396
+ return self .create_error_response (
397
+ f"Invalid tool_choice: { request .tool_choice } " )
398
+
399
+ if function_calls :
400
+ outputs .extend ([
401
+ ResponseFunctionToolCall (
402
+ id = f"fc_{ random_fc_uuid ()} " ,
403
+ call_id = f"call_{ random_uuid ()} " ,
404
+ type = "function_call" ,
405
+ status = "completed" ,
406
+ name = tool_call .name ,
407
+ arguments = tool_call .arguments ,
408
+ ) for tool_call in function_calls
409
+ ])
405
410
406
411
# Calculate usage.
407
412
assert final_res .prompt_token_ids is not None
0 commit comments