sendEvent puts e on out, bailing if parent cancels first, so a slow or vanished consumer after Ctrl+C can't wedge the stream goroutine on a full buffer.
(parent context.Context, out chan<- Event, e Event)
| 341 | // retry-free: its job is fast feedback on a misconfigured profile. |
| 342 | resp, errEvt := c.sendChat(parent, msgs, tools) |
| 343 | for attempt := 0; errEvt != nil && attempt < len(c.RetryBackoff) && retryable(errEvt.Err); attempt++ { |
| 344 | delay := c.RetryBackoff[attempt] |
| 345 | hint := fmt.Sprintf("retry %d/%d in %s", attempt+1, len(c.RetryBackoff), delay) |
| 346 | if !sendEvent(parent, out, Event{Kind: EventRetry, Content: hint, Err: errEvt.Err}) { |
| 347 | return |
| 348 | } |
| 349 | select { |
| 350 | case <-time.After(delay): |
| 351 | case <-parent.Done(): |
| 352 | // Ctrl+C during the wait: unwind silently, exactly like a |
| 353 | // cancelled sendEvent — the TUI already aborted the turn. |
no outgoing calls