()
| 670 | // per-turn root on m.turnCtx / m.cancel. Cancel-old-then-install-new keeps |
| 671 | // Ctrl+C consistent: one m.cancel() always unwinds the whole current cascade. |
| 672 | func (m *Model) installTurnContext() { |
| 673 | if m.cancel != nil { |
| 674 | m.cancel() |
| 675 | } |
| 676 | m.turnCtx, m.cancel = context.WithCancel(context.Background()) |
| 677 | } |
| 678 | |
| 679 | // beginTurn installs a fresh per-turn context, flips phase to thinking, and |
| 680 | // returns the chat stream-reader Cmd. Every path starting a new LLM round |
| 681 | // funnels through here so one m.cancel() cancels the whole cascade. |
| 682 | func (m *Model) beginTurn() tea.Cmd { |
| 683 | m.installTurnContext() |
| 684 | m.turnStart = time.Now() |
no test coverage detected