@@ -377,17 +377,21 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
377377 throw handleOpenAIError ( error , this . providerName )
378378 }
379379
380- // Extract text from the Responses API response
380+ // Extract text from the Responses API response — collect ALL output_text parts
381381 if ( response ?. output && Array . isArray ( response . output ) ) {
382+ const textParts : string [ ] = [ ]
382383 for ( const outputItem of response . output ) {
383384 if ( outputItem . type === "message" && outputItem . content ) {
384385 for ( const content of outputItem . content ) {
385386 if ( content . type === "output_text" && content . text ) {
386- return content . text
387+ textParts . push ( content . text )
387388 }
388389 }
389390 }
390391 }
392+ if ( textParts . length > 0 ) {
393+ return textParts . join ( "" )
394+ }
391395 }
392396
393397 // Fallback: check for direct text in response
@@ -595,12 +599,13 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
595599 // Build tools in Responses API format (flat structure, not nested under function)
596600 const tools = this . _convertToolsForResponsesApi ( metadata ?. tools )
597601
598- // Build the request body
602+ const useStreaming = this . options . openAiStreamingEnabled ?? true
603+
604+ // Build the request body (stream flag added per path below)
599605 const requestBody : any = {
600606 model : model . id ,
601607 input : formattedInput ,
602- stream : true ,
603- store : false ,
608+ store : metadata ?. store ?? false ,
604609 instructions : systemPrompt ,
605610 ...( tools && tools . length > 0 ? { tools } : { } ) ,
606611 ...( metadata ?. tool_choice ? { tool_choice : metadata . tool_choice } : { } ) ,
@@ -617,6 +622,68 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
617622 requestBody . max_output_tokens = this . options . modelMaxTokens || model . info . maxTokens
618623 }
619624
625+ if ( ! useStreaming ) {
626+ // Non-streaming path: await the full response then yield results
627+ try {
628+ const response = await ( this . client as any ) . responses . create ( {
629+ ...requestBody ,
630+ stream : false ,
631+ } )
632+
633+ // Extract text, tool calls, and reasoning from response output
634+ if ( Array . isArray ( response ?. output ) ) {
635+ for ( const outputItem of response . output ) {
636+ if ( outputItem ?. type === "function_call" || outputItem ?. type === "tool_call" ) {
637+ const callId = outputItem . call_id || outputItem . tool_call_id || outputItem . id
638+ const name = outputItem . name || outputItem . function ?. name
639+ const argsRaw = outputItem . arguments || outputItem . function ?. arguments || outputItem . input
640+ const args =
641+ typeof argsRaw === "string"
642+ ? argsRaw
643+ : argsRaw && typeof argsRaw === "object"
644+ ? JSON . stringify ( argsRaw )
645+ : ""
646+ if ( typeof callId === "string" && callId . length > 0 && typeof name === "string" && name . length > 0 ) {
647+ yield { type : "tool_call" , id : callId , name, arguments : args }
648+ }
649+ } else if ( ( outputItem ?. type === "text" || outputItem ?. type === "output_text" ) && outputItem ?. text ) {
650+ yield { type : "text" , text : outputItem . text }
651+ } else if ( outputItem ?. type === "message" && Array . isArray ( outputItem . content ) ) {
652+ for ( const content of outputItem . content ) {
653+ if ( ( content ?. type === "text" || content ?. type === "output_text" ) && content ?. text ) {
654+ yield { type : "text" , text : content . text }
655+ }
656+ }
657+ } else if ( outputItem ?. type === "reasoning" && outputItem ?. summary ) {
658+ for ( const summary of outputItem . summary ) {
659+ if ( summary ?. text ) {
660+ yield { type : "reasoning" , text : summary . text }
661+ }
662+ }
663+ }
664+ }
665+ }
666+
667+ // Extract usage from non-streaming response
668+ const usage = response ?. usage
669+ if ( usage ) {
670+ yield {
671+ type : "usage" ,
672+ inputTokens : usage . input_tokens ?? usage . prompt_tokens ?? 0 ,
673+ outputTokens : usage . output_tokens ?? usage . completion_tokens ?? 0 ,
674+ cacheWriteTokens : usage . cache_creation_input_tokens || undefined ,
675+ cacheReadTokens : usage . cache_read_input_tokens || undefined ,
676+ }
677+ }
678+ } catch ( error ) {
679+ throw handleOpenAIError ( error , this . providerName )
680+ }
681+ return
682+ }
683+
684+ // Streaming path
685+ requestBody . stream = true
686+
620687 // State tracking for streaming
621688 let pendingToolCallId : string | undefined
622689 let pendingToolCallName : string | undefined
0 commit comments