@@ -479,74 +479,103 @@ func (c *Client) ChatWithMessagesContext(ctx context.Context, model string, conv
479479 TotalTokens int `json:"total_tokens"`
480480 }
481481
482- scanner := bufio .NewScanner (resp .Body )
483- for scanner .Scan () {
484- // Check if context was cancelled
485- select {
486- case <- ctx .Done ():
487- return assistantResponse .String (), ctx .Err ()
488- default :
489- }
482+ // Detect streaming vs non-streaming response via Content-Type header
483+ isStreaming := strings .HasPrefix (resp .Header .Get ("Content-Type" ), "text/event-stream" )
490484
491- line := scanner .Text ()
492- if line == "" {
493- continue
485+ if ! isStreaming {
486+ // Non-streaming JSON response
487+ body , err := io .ReadAll (resp .Body )
488+ if err != nil {
489+ return assistantResponse .String (), fmt .Errorf ("error reading response body: %w" , err )
494490 }
495491
496- if ! strings .HasPrefix (line , "data: " ) {
497- continue
492+ var nonStreamResp OpenAIChatResponse
493+ if err := json .Unmarshal (body , & nonStreamResp ); err != nil {
494+ return assistantResponse .String (), fmt .Errorf ("error parsing response: %w" , err )
498495 }
499496
500- data := strings .TrimPrefix (line , "data: " )
501-
502- if data == "[DONE]" {
503- break
497+ // Extract content from non-streaming response
498+ if len (nonStreamResp .Choices ) > 0 && nonStreamResp .Choices [0 ].Message .Content != "" {
499+ content := nonStreamResp .Choices [0 ].Message .Content
500+ outputFunc (content )
501+ assistantResponse .WriteString (content )
504502 }
505503
506- var streamResp OpenAIChatResponse
507- if err := json .Unmarshal ([]byte (data ), & streamResp ); err != nil {
508- return assistantResponse .String (), fmt .Errorf ("error parsing stream response: %w" , err )
504+ if nonStreamResp .Usage != nil {
505+ finalUsage = nonStreamResp .Usage
509506 }
507+ } else {
508+ // SSE streaming response - process line by line
509+ scanner := bufio .NewScanner (resp .Body )
510+
511+ for scanner .Scan () {
512+ // Check if context was cancelled
513+ select {
514+ case <- ctx .Done ():
515+ return assistantResponse .String (), ctx .Err ()
516+ default :
517+ }
510518
511- if streamResp .Usage != nil {
512- finalUsage = streamResp .Usage
513- }
519+ line := scanner .Text ()
520+ if line == "" {
521+ continue
522+ }
514523
515- if len (streamResp .Choices ) > 0 {
516- if streamResp .Choices [0 ].Delta .ReasoningContent != "" {
517- chunk := streamResp .Choices [0 ].Delta .ReasoningContent
518- if printerState == chatPrinterContent {
519- outputFunc ("\n \n " )
520- }
521- if printerState != chatPrinterReasoning {
522- const thinkingHeader = "Thinking:\n "
524+ if ! strings .HasPrefix (line , "data: " ) {
525+ continue
526+ }
527+
528+ data := strings .TrimPrefix (line , "data: " )
529+
530+ if data == "[DONE]" {
531+ break
532+ }
533+
534+ var streamResp OpenAIChatResponse
535+ if err := json .Unmarshal ([]byte (data ), & streamResp ); err != nil {
536+ return assistantResponse .String (), fmt .Errorf ("error parsing stream response: %w" , err )
537+ }
538+
539+ if streamResp .Usage != nil {
540+ finalUsage = streamResp .Usage
541+ }
542+
543+ if len (streamResp .Choices ) > 0 {
544+ if streamResp .Choices [0 ].Delta .ReasoningContent != "" {
545+ chunk := streamResp .Choices [0 ].Delta .ReasoningContent
546+ if printerState == chatPrinterContent {
547+ outputFunc ("\n \n " )
548+ }
549+ if printerState != chatPrinterReasoning {
550+ const thinkingHeader = "Thinking:\n "
551+ if reasoningFmt != nil {
552+ reasoningFmt .Print (thinkingHeader )
553+ } else {
554+ outputFunc (thinkingHeader )
555+ }
556+ }
557+ printerState = chatPrinterReasoning
523558 if reasoningFmt != nil {
524- reasoningFmt .Print (thinkingHeader )
559+ reasoningFmt .Print (chunk )
525560 } else {
526- outputFunc (thinkingHeader )
561+ outputFunc (chunk )
527562 }
528563 }
529- printerState = chatPrinterReasoning
530- if reasoningFmt != nil {
531- reasoningFmt .Print (chunk )
532- } else {
564+ if streamResp .Choices [0 ].Delta .Content != "" {
565+ chunk := streamResp .Choices [0 ].Delta .Content
566+ if printerState == chatPrinterReasoning {
567+ outputFunc ("\n \n --\n \n " )
568+ }
569+ printerState = chatPrinterContent
533570 outputFunc (chunk )
571+ assistantResponse .WriteString (chunk )
534572 }
535573 }
536- if streamResp .Choices [0 ].Delta .Content != "" {
537- chunk := streamResp .Choices [0 ].Delta .Content
538- if printerState == chatPrinterReasoning {
539- outputFunc ("\n \n --\n \n " )
540- }
541- printerState = chatPrinterContent
542- outputFunc (chunk )
543- assistantResponse .WriteString (chunk )
544- }
545574 }
546- }
547575
548- if err := scanner .Err (); err != nil {
549- return assistantResponse .String (), fmt .Errorf ("error reading response stream: %w" , err )
576+ if err := scanner .Err (); err != nil {
577+ return assistantResponse .String (), fmt .Errorf ("error reading response stream: %w" , err )
578+ }
550579 }
551580
552581 if finalUsage != nil {
0 commit comments