@@ -470,13 +470,10 @@ async function runCliAgentWithLifecycleInternal(
470470 ...( params . runParams . sessionKey ? { sessionKey : params . runParams . sessionKey } : { } ) ,
471471 } ) ;
472472 try {
473- if ( params . onFastModeAutoProgress ) {
474- params . onActivity ?.( ) ;
475- await params . onFastModeAutoProgress ( {
476- text : summary ,
477- channelData : { openclawProgressKind : FAST_MODE_AUTO_PROGRESS_KIND } ,
478- } ) ;
479- }
473+ await params . onFastModeAutoProgress ?.( {
474+ text : summary ,
475+ channelData : { openclawProgressKind : FAST_MODE_AUTO_PROGRESS_KIND } ,
476+ } ) ;
480477 } catch {
481478 // Progress hints are best-effort; a channel failure must not fail the agent turn.
482479 }
@@ -528,53 +525,54 @@ async function runCliAgentWithLifecycleInternal(
528525 } ,
529526 } ) ;
530527 }
531- // One activity seam for every delivered CLI event: stamping per-callback at
532- // call sites drifted (a queued-followup callback missed one), which lets
533- // stale-takeover reclaim a run that is visibly producing output .
534- const withActivity = < T > (
535- deliver : ( ( payload : T ) => Promise < void > ) | undefined ,
536- ) : ( ( payload : T ) => Promise < void > ) | undefined =>
537- deliver && params . onActivity
538- ? async ( payload : T ) => {
528+ // One delivery-independent activity seam for every CLI agent event.
529+ // Suppressed (silentExpected) runs still emit real events and must keep
530+ // stamping, or a healthy silent stream looks stale to the takeover window .
531+ const activityBridge = params . onActivity
532+ ? createAgentEventBridge < Record < string , never > > ( {
533+ runId : params . runId ,
534+ read : ( ) => ( { } ) ,
535+ deliver : async ( ) => {
539536 params . onActivity ?.( ) ;
540- await deliver ( payload ) ;
541- }
542- : deliver ;
537+ } ,
538+ } )
539+ : undefined ;
543540 const assistantBridge = createAssistantTextBridge ( {
544541 runId : params . runId ,
545542 suppressed : params . suppressAssistantBridge ,
546- deliver : withActivity ( params . onAssistantText ) ,
543+ deliver : params . onAssistantText ,
547544 } ) ;
548545 let finalReasoningText : string | undefined ;
549546 const reasoningBridge = createReasoningTextBridge ( {
550547 runId : params . runId ,
551548 suppressed : params . suppressAssistantBridge ,
552- deliver : withActivity ( async ( payload : ReasoningTextPayload ) => {
549+ deliver : async ( payload : ReasoningTextPayload ) => {
553550 finalReasoningText = normalizeOptionalString ( payload . text ) ;
554551 await params . onReasoningText ?.( payload ) ;
555- } ) ,
552+ } ,
556553 } ) ;
557554 const reasoningProgressBridge = createReasoningProgressBridge ( {
558555 runId : params . runId ,
559556 suppressed : params . suppressAssistantBridge ,
560- deliver : withActivity ( params . onReasoningProgress ) ,
557+ deliver : params . onReasoningProgress ,
561558 } ) ;
562559 const toolBridge = createToolEventBridge ( {
563560 runId : params . runId ,
564561 suppressed : params . suppressAssistantBridge ,
565- deliver : withActivity ( params . onToolEvent ) ,
562+ deliver : params . onToolEvent ,
566563 } ) ;
567564 const commentaryBridge = createCommentaryEventBridge ( {
568565 runId : params . runId ,
569566 suppressed : params . suppressAssistantBridge ,
570- deliver : withActivity ( params . onCommentaryText ) ,
567+ deliver : params . onCommentaryText ,
571568 } ) ;
572569 const toolBoundaryBridge = createToolBoundaryBridge ( {
573570 runId : params . runId ,
574571 suppressed : params . suppressAssistantBridge ,
575572 deliver : maybeAnnounceFastModeAutoOff ,
576573 } ) ;
577574 const bridges = [
575+ activityBridge ,
578576 assistantBridge ,
579577 reasoningBridge ,
580578 reasoningProgressBridge ,
0 commit comments