@@ -436,16 +436,45 @@ async def chat_stream(
436436 ) -> AsyncGenerator [Dict [str , Any ], None ]: # pragma: no cover
437437 """Stream responses with optional tool calls using OpenAI Responses API."""
438438 try :
439- # Extract system prompt from messages if present
439+ # Extract system prompt from messages and convert to Responses API format
440440 instructions = None
441441 input_items = []
442442 for msg in messages :
443443 role = msg .get ("role" , "" )
444- content = msg .get ("content" , "" )
444+ content = msg .get ("content" )
445+
445446 if role == "system" :
446447 instructions = content
447- else :
448- input_items .append ({"role" : role , "content" : content })
448+ elif role == "user" :
449+ # User messages: simple text content
450+ input_items .append ({"role" : "user" , "content" : content or "" })
451+ elif role == "assistant" :
452+ # Assistant messages may have tool_calls or text content
453+ tool_calls = msg .get ("tool_calls" )
454+ if tool_calls :
455+ # Convert each tool call to Responses API function_call format
456+ for tc in tool_calls :
457+ func = tc .get ("function" , {})
458+ input_items .append (
459+ {
460+ "type" : "function_call" ,
461+ "call_id" : tc .get ("id" , "" ),
462+ "name" : func .get ("name" , "" ),
463+ "arguments" : func .get ("arguments" , "{}" ),
464+ }
465+ )
466+ elif content :
467+ # Regular assistant text response
468+ input_items .append ({"role" : "assistant" , "content" : content })
469+ elif role == "tool" :
470+ # Tool result messages: convert to function_call_output format
471+ input_items .append (
472+ {
473+ "type" : "function_call_output" ,
474+ "call_id" : msg .get ("tool_call_id" , "" ),
475+ "output" : content or "" ,
476+ }
477+ )
449478
450479 request_params : Dict [str , Any ] = {
451480 "model" : model or self .text_model ,
0 commit comments