@@ -447,23 +447,24 @@ export interface ChatDirectorOptions {
447447 * uses a switched model still stamp the previous id — the director learns
448448 * the new id from that inference's completion event.
449449 *
450- * - getLiveFleetCount → static config (allowIdleWithFleet below). The count
451- * is genuinely external (subagent lane statuses the reactor never sees —
452- * its own tasks only carry todo/doing/done/cancelled), so neither
453- * BaseEnv-derived nor reactor-supplied can reproduce its liveness.
454- * Idle-with-fleet itself is unchanged (fleet-running TUI sessions allow
455- * the terminal wait). Accepted loss: a drained fleet no longer resumes
456- * the open-task nudge — bounded, since the nudge capitulates to terminal
457- * after its cap anyway .
450+ * - getLiveFleetCount → seeded config + live narrow setter
451+ * (setAllowIdleWithFleet below). The count is genuinely external (subagent
452+ * lane statuses the reactor never sees — its own tasks only carry
453+ * todo/doing/done/cancelled), so neither BaseEnv-derived nor
454+ * reactor-supplied can reproduce its liveness. Idle-with-fleet itself is
455+ * unchanged (fleet-running TUI sessions allow the terminal wait); the
456+ * fleet-wake publisher drives the setter on count transitions, so a
457+ * drained fleet resumes the open-task nudge .
458458 */
459459 /** Explicit retry policy; when set, skips the default Corbits policy. */
460460 retryPolicy ?: RetryPolicy | undefined ;
461461 /**
462- * Static idle-with-fleet allowance (CL-7918 replacement for the former
462+ * Initial idle-with-fleet allowance (CL-7918 replacement for the former
463463 * getLiveFleetCount closure). When true the director allows a terminal
464464 * wait/reply with open tasks; when omitted or false it keeps the open-task
465- * nudge. The TUI sets this (fleet lanes may appear mid-session); exec
466- * omits it.
465+ * nudge. The TUI seeds this (fleet lanes may appear mid-session); exec
466+ * omits it. The live fleet-wake publisher then keeps it current through
467+ * setAllowIdleWithFleet, so a drained fleet resumes the nudge.
467468 */
468469 allowIdleWithFleet ?: boolean | undefined ;
469470}
@@ -515,8 +516,8 @@ class ChatDirectorImpl extends DefaultDirector {
515516 // refreshed on every inference completion, so mid-session /model switches
516517 // remap without rebuilding the agent.
517518 private currentSourceId : string | undefined ;
518- /** CL-7918 static replacement for the former getLiveFleetCount closure. */
519- private readonly allowIdleWithFleet : boolean ;
519+ /** CL-7918 live replacement for the former getLiveFleetCount closure. */
520+ private allowIdleWithFleet : boolean ;
520521 // Consecutive assistant turns that contain tool calls and no text. Reset on
521522 // any turn with text and on every fresh user message — a weak model that
522523 // spins in place on one thread of tool calls still converges to the
@@ -578,6 +579,13 @@ class ChatDirectorImpl extends DefaultDirector {
578579 this . workflowCoordinator = coordinator ;
579580 }
580581
582+ // Narrow live setter for the idle-with-fleet allowance (CL-7972): the
583+ // fleet-wake publisher drives this on fleet-count transitions, so a drained
584+ // fleet resumes the open-task nudge instead of holding the seeded value.
585+ setAllowIdleWithFleet ( value : boolean ) : void {
586+ this . allowIdleWithFleet = value ;
587+ }
588+
581589 updateToolDefinitions ( toolDefinitions : ToolDefinition [ ] ) : void {
582590 const before = toolSetDigest ( this . _toolDefinitions ) ;
583591 const after = toolSetDigest ( toolDefinitions ) ;
@@ -1095,9 +1103,10 @@ class ChatDirectorImpl extends DefaultDirector {
10951103 ( a ) => a . type === "wait" || a . type === "reply" ,
10961104 ) ;
10971105 if ( hasTerminal ) {
1098- // CL-7918: static idle-with-fleet allowance (replaces the former
1099- // getLiveFleetCount closure). TUI sessions set allowIdleWithFleet;
1100- // exec omits it and keeps the nudge.
1106+ // CL-7918 live idle-with-fleet allowance (replaces the former
1107+ // getLiveFleetCount closure): seeded at construction, then kept
1108+ // current by the fleet-wake publisher. TUI seeds true (fleet lanes
1109+ // may appear mid-session); exec omits it and keeps the nudge.
11011110 if ( this . allowIdleWithFleet ) {
11021111 return base ;
11031112 }
@@ -1172,6 +1181,7 @@ export function hydrateTasksFromTurns(turns: ConversationTurn[]): Task[] {
11721181export interface ChatDirector extends ReactorDirector {
11731182 updateToolDefinitions ( toolDefinitions : ToolDefinition [ ] ) : void ;
11741183 setWorkflowCoordinator ( coordinator : WorkflowCoordinator | undefined ) : void ;
1184+ setAllowIdleWithFleet ( value : boolean ) : void ;
11751185 getTasks ( ) : Task [ ] ;
11761186 restoreTasks ( tasks : Task [ ] ) : void ;
11771187 getContextEstimate ( ) : { tokens : number ; isEstimate : boolean } ;
0 commit comments