@@ -193,7 +193,14 @@ export const createLLMEventPublisher = (bus: Pick<Bus.Interface, "publish">, inp
193193 const flush = Effect . fnUntraced ( function * ( ) {
194194 for ( const id of Array . from ( chunks . keys ( ) ) ) yield * end ( id )
195195 } )
196- return { start, append, end, flush, has : ( id : string ) => chunks . has ( id ) }
196+ /** Publish batched deltas now, keeping every fragment open. */
197+ const publishPending = Effect . fnUntraced ( function * ( ) {
198+ for ( const [ id , current ] of Array . from ( chunks ) ) {
199+ if ( current . timer ) yield * Fiber . interrupt ( current . timer )
200+ yield * publishDelta ( id )
201+ }
202+ } )
203+ return { start, append, end, flush, publishPending, has : ( id : string ) => chunks . has ( id ) }
197204 }
198205
199206 const text = fragments (
@@ -255,6 +262,13 @@ export const createLLMEventPublisher = (bus: Pick<Bus.Interface, "publish">, inp
255262 } ) ,
256263 )
257264
265+ // Deltas are batched, but block starts are not. Publishing held deltas first keeps each
266+ // block's content ahead of the next block, so the published order matches the model's.
267+ const publishPendingDeltas = Effect . fnUntraced ( function * ( ) {
268+ yield * text . publishPending ( )
269+ yield * reasoning . publishPending ( )
270+ } )
271+
258272 const flushFragments = Effect . fnUntraced ( function * ( ) {
259273 yield * text . flush ( )
260274 yield * reasoning . flush ( )
@@ -276,6 +290,7 @@ export const createLLMEventPublisher = (bus: Pick<Bus.Interface, "publish">, inp
276290 }
277291 tools . set ( event . id , tool )
278292 yield * toolInput . start ( event . id )
293+ yield * publishPendingDeltas ( )
279294 yield * bus . publish ( SessionEvent . Tool . Input . Started , {
280295 sessionID : input . sessionID ,
281296 assistantMessageID,
@@ -390,6 +405,7 @@ export const createLLMEventPublisher = (bus: Pick<Bus.Interface, "publish">, inp
390405 case "text-start" :
391406 outputStarted = true
392407 const startedTextOrdinal = yield * text . start ( event . id , providerState ( event . providerMetadata ) )
408+ yield * publishPendingDeltas ( )
393409 yield * bus . publish ( SessionEvent . Text . Started , {
394410 sessionID : input . sessionID ,
395411 assistantMessageID : yield * startAssistant ( ) ,
@@ -405,6 +421,7 @@ export const createLLMEventPublisher = (bus: Pick<Bus.Interface, "publish">, inp
405421 case "reasoning-start" :
406422 outputStarted = true
407423 const startedReasoningOrdinal = yield * reasoning . start ( event . id , providerState ( event . providerMetadata ) )
424+ yield * publishPendingDeltas ( )
408425 yield * bus . publish ( SessionEvent . Reasoning . Started , {
409426 sessionID : input . sessionID ,
410427 assistantMessageID : yield * startAssistant ( ) ,
0 commit comments