Files
docker-agent/pkg/app
Arnaud Héritier adfc822182 fix(app): synthesize StreamStopped when the runtime stream closes without one
The runtime documents the events channel close (not receipt of
StreamStoppedEvent) as the terminal signal, and drops the event under
back-pressure at teardown (LocalRuntime.finalizeEventChannel's
non-blocking emit). A fast local model streaming faster than the
synchronous per-delta SQLite writes reliably hits this. The chat page,
supervisor, and leantui only clear their busy state on receipt of the
event, so the TUI is left showing "Working…" forever until Esc.

forwardRunStreamEvents and RunSkillFork now track whether a
StreamStoppedEvent for the relevant session was actually forwarded
during the drain loop, and synthesize one when the channel closes
without it. Reason is canceled/error/normal depending on ctx state and
whether a root ErrorEvent was seen.

Also exports the turnEndReason* constants (TurnEndReasonNormal/Error/
Canceled) so app and the TUI stop duplicating those string literals.

Fixes #4136. Root cause and fix plan validated in a companion
investigation; the runtime-side drop (LocalRuntime.finalizeEventChannel)
is fixed separately, tracing back to the best-effort emit introduced by
#3074/#3275.
2026-09-03 18:33:30 +00:00
..
2026-06-01 13:29:55 +02:00