4 Commits

Author SHA1 Message Date
can1357 ae1c9c981d test(coding-agent): make coalescing tests deterministic 2026-08-05 01:12:02 +02:00
Slava Zavadsky 326fb24367 fix(coding-agent): chain every queued dispatch onto the current tail
The previous #runSerialized waited on the shared #dispatchTail, then ran
unconditionally: when two or more events queued behind an in-flight run,
each resumed from the same settled await and started its own run in
parallel, defeating the ordering guarantee for a burst landing in one
coalescing window (message_end + agent_end behind a suspended flush).

Each waiter now chains its own link onto the current tail
(tail.then(run, run)), so queued runs start strictly one after another;
the idle path still runs synchronously, preserving the flush timing the
coalescing tests assert on. The in-flight flag clears only when the
settling link is still the tail, so a later chained link's settle does
not clear it early.

Regression test: two message_end events queued behind a suspended window
flush stay serialized (init call count steps 1 -> 2 -> 3 as each gate
opens); fails on the previous implementation.
2026-08-04 17:42:54 -04:00
Slava Zavadsky 50ee839c51 fix(modes): serialize dispatch so a stream tail cannot overtake the coalesced flush
AgentSession.#emit fires listeners fire-and-forget, and the coalesced
message_update flush fires from its own 33ms timer — neither path awaited
the other. A rapid stream tail (message_update -> message_end ->
agent_end) could therefore run the end handlers while the flush was
suspended mid-await, agent_end removing streamingComponent before
#handleMessageEnd finalizes and records the final message (issue #7443
follow-up).

- #runSerialized chains listener dispatch and the timer flush through one
  promise chain; an in-flight run holds later events until it completes.
  Idle dispatch stays synchronous (no added microtask), preserving the
  timing the coalescing tests assert on.
- Regression test: a message_end landing while the window flush is
  suspended on init is queued behind it (initCalls 1 while suspended,
  then 2), where the pristine code ran both concurrently (2 while
  suspended). Fails without the fix.
2026-08-04 16:35:56 -04:00
Slava Zavadsky fed51f1ffc fix(coding-agent): coalesce streaming message_update handler work per render window (#7443) 2026-08-03 14:06:48 -04:00