@@ -81,6 +81,7 @@ import {
8181 useComposerDraftSettings ,
8282} from "./use-composer-drafts" ;
8383import {
84+ isCompactCommandText ,
8485 resolveComposerDispatchMode ,
8586 type ActiveTurnComposerAction ,
8687} from "@t3tools/client-runtime/state/composer-dispatch" ;
@@ -333,24 +334,19 @@ export function useThreadComposerState() {
333334 ? deriveThreadActivityRun ( selectedThreadProjection . projection )
334335 : ( selectedThreadShell ?. latestRun ?? null ) ;
335336
336- const isCompacting = ( ( ) => {
337+ const activeRunId =
338+ selectedThreadRuntime ?. activeRunId && threadRuntimeIsActive ( selectedThreadRuntime )
339+ ? selectedThreadRuntime . activeRunId
340+ : null ;
341+ const compactCommandIsActive = ( ( ) => {
337342 const queuedCompact = selectedThreadQueuedMessages . some (
338343 ( message ) =>
339344 message . messageId === dispatchingQueuedMessageId &&
340345 message . text . trim ( ) . toLowerCase ( ) === "/compact" &&
341346 message . attachments . length === 0 ,
342347 ) ;
343348 if ( queuedCompact ) return true ;
344- const activeRunId = selectedThreadRuntime ?. activeRunId ;
345- if ( ! activeRunId || ! threadRuntimeIsActive ( selectedThreadRuntime ) ) return false ;
346- if (
347- selectedThreadVisibleTurnItems . some (
348- ( { item } ) =>
349- item . runId === activeRunId && item . type === "compaction" && item . status === "running" ,
350- )
351- ) {
352- return true ;
353- }
349+ if ( ! activeRunId ) return false ;
354350 const compactMessage = selectedThreadVisibleTurnItems . findLast (
355351 ( { item } ) =>
356352 item . runId === activeRunId &&
@@ -369,8 +365,26 @@ export function useThreadComposerState() {
369365 item . status === "cancelled" ) ,
370366 ) ;
371367 } ) ( ) ;
372- // A compacting turn cannot take steering input, so follow-ups queue meanwhile.
373- const canSteerActiveTurn = queueWorkflow ?. canPromoteToSteer === true && ! isCompacting ;
368+ const compactionRunning =
369+ activeRunId !== null &&
370+ selectedThreadVisibleTurnItems . some (
371+ ( { item } ) =>
372+ item . runId === activeRunId && item . type === "compaction" && item . status === "running" ,
373+ ) ;
374+ const isCompacting = compactCommandIsActive || compactionRunning ;
375+ // Only an explicit compaction refuses steering. Automatic compaction runs
376+ // inside an ordinary turn, which still accepts it.
377+ const explicitCompactionIsActive =
378+ compactCommandIsActive ||
379+ ( compactionRunning &&
380+ selectedThreadVisibleTurnItems . some (
381+ ( { item } ) =>
382+ item . runId === activeRunId &&
383+ item . type === "user_message" &&
384+ isCompactCommandText ( item . text ) ,
385+ ) ) ;
386+ const canSteerActiveTurn =
387+ queueWorkflow ?. canPromoteToSteer === true && ! explicitCompactionIsActive ;
374388 // A stop or a restart holds the queue, completion wakes included, until it
375389 // is resumed; the queue sheet lists only the user's own messages.
376390 const queueHeld = queueWorkflow ?. isHeld === true ;
0 commit comments