sendChat POSTs the request and returns the response on 200. On failure it returns the Event the caller forwards, populated with Kind/Err/Budget. The body is closed on every non-200 branch; 200 leaves it open for the caller.
(parent context.Context, msgs []chmctx.Message, tools []Tool)
| 353 | var stalled atomic.Bool |
| 354 | watchdog := time.AfterFunc(idle, func() { |
| 355 | stalled.Store(true) |
| 356 | resp.Body.Close() |
| 357 | }) |
| 358 | |
| 359 | budget := cloud.FromHeaders(resp.Header) |
| 360 | ctxWindow := cloud.ContextWindowFromHeaders(resp.Header) |
| 361 | final, tokens, promptTokens, err := readSSE(parent, resp.Body, budget, out, func() { watchdog.Reset(idle) }) |
| 362 | watchdog.Stop() |
| 363 | if err != nil { |
| 364 | if stalled.Load() { |
| 365 | err = fmt.Errorf("the server stopped sending data (no stream activity for %s)", idle) |
| 366 | } |
| 367 | sendEvent(parent, out, Event{Kind: EventError, Err: err}) |
| 368 | return |
| 369 | } |
| 370 | sendEvent(parent, out, Event{ |
| 371 | Kind: EventDone, |