executeStreamingTurn runs the streaming path. It also drives the watchdog for stalled streams and pushes provider-reported usage into the cost tracker against whichever provider+model actually served the turn.
( ctx context.Context, sc client.StreamingClient, activeClient client.LLMClient, userInput, additionalContext string, tempHistory []models.Message, effectiveMaxTokens int, resolution SkillClientResolution, stopSpinner func(), )
| 585 | // watchdog for stalled streams and pushes provider-reported usage into the |
| 586 | // cost tracker against whichever provider+model actually served the turn. |
| 587 | func (cli *ChatCLI) executeStreamingTurn( |
| 588 | ctx context.Context, |
| 589 | sc client.StreamingClient, |
| 590 | activeClient client.LLMClient, |
| 591 | userInput, additionalContext string, |
| 592 | tempHistory []models.Message, |
| 593 | effectiveMaxTokens int, |
| 594 | resolution SkillClientResolution, |
| 595 | stopSpinner func(), |
| 596 | ) (string, error) { |
| 597 | chunks, err := sc.SendPromptStream(ctx, userInput+additionalContext, tempHistory, effectiveMaxTokens) |
| 598 | if err != nil && cli.refreshClientOnAuthError(err) { |
| 599 | chunks, err = sc.SendPromptStream(ctx, userInput+additionalContext, tempHistory, effectiveMaxTokens) |
| 600 | } |
| 601 | |
| 602 | cli.animation.StopThinkingAnimation() |
| 603 | stopSpinner() |
| 604 | cli.interactionState = StateNormal |
| 605 | cli.forceRefreshPrompt() |
| 606 | time.Sleep(50 * time.Millisecond) |
| 607 | |
| 608 | if err != nil { |
| 609 | return "", err |
| 610 | } |
| 611 | fmt.Printf("%s\n", colorize(activeClient.GetModelName()+":", ColorPurple)) |
| 612 | |
| 613 | result := client.WatchStream(ctx, chunks, client.DefaultWatchdogConfig(), cli.logger) |
| 614 | if result.WasStalled { |
| 615 | fmt.Printf("\n%s\n", colorize(i18n.T("sw.cmd.stream_stalled"), ColorYellow)) |
| 616 | } |
| 617 | if result.Usage != nil && cli.costTracker != nil { |
| 618 | cli.costTracker.RecordRealUsage(resolution.Provider, resolution.Model, result.Usage) |
| 619 | } |
| 620 | return result.Text, nil |
| 621 | } |
| 622 | |
| 623 | // executeBufferedTurn runs the non-streaming path. The animation/spinner |
| 624 | // must stop as soon as the provider responds (success or failure) so the |
no test coverage detected