@@ -21,16 +21,18 @@ import {
2121 type ClineMessage ,
2222 type ClineSay ,
2323 type ClineAsk ,
24- type BlockingAsk ,
24+ type IdleAsk ,
25+ type InteractiveAsk ,
2526 type ToolProgressStatus ,
2627 type HistoryItem ,
2728 RooCodeEventName ,
2829 TelemetryEventName ,
2930 TodoItem ,
31+ DEFAULT_CONSECUTIVE_MISTAKE_LIMIT ,
3032 getApiProtocol ,
3133 getModelId ,
32- DEFAULT_CONSECUTIVE_MISTAKE_LIMIT ,
33- isBlockingAsk ,
34+ isIdleAsk ,
35+ isInteractiveAsk ,
3436} from "@roo-code/types"
3537import { TelemetryService } from "@roo-code/telemetry"
3638import { CloudService , ExtensionBridgeService } from "@roo-code/cloud"
@@ -182,7 +184,8 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
182184 providerRef : WeakRef < ClineProvider >
183185 private readonly globalStoragePath : string
184186 abort : boolean = false
185- blockingAsk ?: BlockingAsk
187+ idleAsk ?: IdleAsk
188+ interactiveAsk ?: InteractiveAsk
186189 didFinishAbortingStream = false
187190 abandoned = false
188191 isInitialized = false
@@ -713,12 +716,29 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
713716 await this . addToClineMessages ( { ts : askTs , type : "ask" , ask : type , text, isProtected } )
714717 }
715718
716- // Detect if the task will enter an idle state.
717- const isReady = this . askResponse !== undefined || this . lastMessageTs !== askTs
719+ // The state is mutable if the message is complete and the task will
720+ // block (via the `pWaitFor`).
721+ const isBlocking = ! ( this . askResponse !== undefined || this . lastMessageTs !== askTs )
722+ const isStateMutable = ! partial && isBlocking
718723
719- if ( ! partial && ! isReady && isBlockingAsk ( type ) ) {
720- this . blockingAsk = type
721- this . emit ( RooCodeEventName . TaskIdle , this . taskId )
724+ // The task will enter an idle state.
725+ let goIdleTimeout : NodeJS . Timeout | undefined
726+
727+ if ( isStateMutable && isIdleAsk ( type ) ) {
728+ goIdleTimeout = setTimeout ( ( ) => {
729+ this . idleAsk = undefined
730+ this . emit ( RooCodeEventName . TaskActive , this . taskId )
731+ } , 1000 )
732+ }
733+
734+ // The task will enter a "user interaction required" state.
735+ let goInteractiveTimeout : NodeJS . Timeout | undefined
736+
737+ if ( isStateMutable && ! isInteractiveAsk ( type ) ) {
738+ goInteractiveTimeout = setTimeout ( ( ) => {
739+ this . interactiveAsk = undefined
740+ this . emit ( RooCodeEventName . TaskActive , this . taskId )
741+ } , 1000 )
722742 }
723743
724744 console . log ( `[Task#${ this . taskId } ] pWaitFor askResponse(${ type } ) -> blocking` )
@@ -737,9 +757,22 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
737757 this . askResponseText = undefined
738758 this . askResponseImages = undefined
739759
760+ // Cancel the timeouts if they are still running.
761+ if ( goIdleTimeout ) {
762+ clearTimeout ( goIdleTimeout )
763+ }
764+
765+ if ( goInteractiveTimeout ) {
766+ clearTimeout ( goInteractiveTimeout )
767+ }
768+
769+ goIdleTimeout = undefined
770+ goInteractiveTimeout = undefined
771+
740772 // Switch back to an active state.
741- if ( this . blockingAsk ) {
742- this . blockingAsk = undefined
773+ if ( this . idleAsk || this . interactiveAsk ) {
774+ this . idleAsk = undefined
775+ this . interactiveAsk = undefined
743776 this . emit ( RooCodeEventName . TaskActive , this . taskId )
744777 }
745778
0 commit comments