@@ -164,7 +164,7 @@ export class Task extends EventEmitter<ClineEvents> {
164164 consecutiveMistakeCount : number = 0
165165 consecutiveMistakeLimit : number
166166 consecutiveMistakeCountForApplyDiff : Map < string , number > = new Map ( )
167- private toolUsage : ToolUsage = { }
167+ toolUsage : ToolUsage = { }
168168
169169 // Checkpoints
170170 enableCheckpoints : boolean
@@ -488,56 +488,81 @@ export class Task extends EventEmitter<ClineEvents> {
488488 partial ?: boolean ,
489489 checkpoint ?: Record < string , unknown > ,
490490 progressStatus ?: ToolProgressStatus ,
491+ options : {
492+ isNonInteractive ?: boolean
493+ } = { } ,
491494 ) : Promise < undefined > {
492495 if ( this . abort ) {
493496 throw new Error ( `[Cline#say] task ${ this . taskId } .${ this . instanceId } aborted` )
494497 }
495498
496499 if ( partial !== undefined ) {
497500 const lastMessage = this . clineMessages . at ( - 1 )
501+
498502 const isUpdatingPreviousPartial =
499503 lastMessage && lastMessage . partial && lastMessage . type === "say" && lastMessage . say === type
504+
500505 if ( partial ) {
501506 if ( isUpdatingPreviousPartial ) {
502- // existing partial message, so update it
507+ // Existing partial message, so update it.
503508 lastMessage . text = text
504509 lastMessage . images = images
505510 lastMessage . partial = partial
506511 lastMessage . progressStatus = progressStatus
507512 this . updateClineMessage ( lastMessage )
508513 } else {
509- // this is a new partial message, so add it with partial state
514+ // This is a new partial message, so add it with partial state.
510515 const sayTs = Date . now ( )
511- this . lastMessageTs = sayTs
516+
517+ if ( ! options . isNonInteractive ) {
518+ this . lastMessageTs = sayTs
519+ }
520+
512521 await this . addToClineMessages ( { ts : sayTs , type : "say" , say : type , text, images, partial } )
513522 }
514523 } else {
515524 // New now have a complete version of a previously partial message.
525+ // This is the complete version of a previously partial
526+ // message, so replace the partial with the complete version.
516527 if ( isUpdatingPreviousPartial ) {
517- // This is the complete version of a previously partial
518- // message, so replace the partial with the complete version.
519- this . lastMessageTs = lastMessage . ts
520- // lastMessage.ts = sayTs
528+ if ( ! options . isNonInteractive ) {
529+ this . lastMessageTs = lastMessage . ts
530+ }
531+
521532 lastMessage . text = text
522533 lastMessage . images = images
523534 lastMessage . partial = false
524535 lastMessage . progressStatus = progressStatus
536+
525537 // Instead of streaming partialMessage events, we do a save
526538 // and post like normal to persist to disk.
527539 await this . saveClineMessages ( )
528- // More performant than an entire postStateToWebview.
540+
541+ // More performant than an entire `postStateToWebview`.
529542 this . updateClineMessage ( lastMessage )
530543 } else {
531544 // This is a new and complete message, so add it like normal.
532545 const sayTs = Date . now ( )
533- this . lastMessageTs = sayTs
546+
547+ if ( ! options . isNonInteractive ) {
548+ this . lastMessageTs = sayTs
549+ }
550+
534551 await this . addToClineMessages ( { ts : sayTs , type : "say" , say : type , text, images } )
535552 }
536553 }
537554 } else {
538- // this is a new non-partial message, so add it like normal
555+ // This is a new non-partial message, so add it like normal.
539556 const sayTs = Date . now ( )
540- this . lastMessageTs = sayTs
557+
558+ // A "non-interactive" message is a message is one that the user
559+ // does not need to respond to. We don't want these message types
560+ // to trigger an update to `lastMessageTs` since they can be created
561+ // asynchronously and could interrupt a pending ask.
562+ if ( ! options . isNonInteractive ) {
563+ this . lastMessageTs = sayTs
564+ }
565+
541566 await this . addToClineMessages ( { ts : sayTs , type : "say" , say : type , text, images, checkpoint } )
542567 }
543568 }
@@ -555,8 +580,12 @@ export class Task extends EventEmitter<ClineEvents> {
555580 // Start / Abort / Resume
556581
557582 private async startTask ( task ?: string , images ?: string [ ] ) : Promise < void > {
558- // conversationHistory (for API) and clineMessages (for webview) need to be in sync
559- // if the extension process were killed, then on restart the clineMessages might not be empty, so we need to set it to [] when we create a new Cline client (otherwise webview would show stale messages from previous session)
583+ // `conversationHistory` (for API) and `clineMessages` (for webview)
584+ // need to be in sync.
585+ // If the extension process were killed, then on restart the
586+ // `clineMessages` might not be empty, so we need to set it to [] when
587+ // we create a new Cline client (otherwise webview would show stale
588+ // messages from previous session).
560589 this . clineMessages = [ ]
561590 this . apiConversationHistory = [ ]
562591 await this . providerRef . deref ( ) ?. postStateToWebview ( )
@@ -578,28 +607,25 @@ export class Task extends EventEmitter<ClineEvents> {
578607 }
579608
580609 public async resumePausedTask ( lastMessage : string ) {
581- // release this Cline instance from paused state
610+ // Release this Cline instance from paused state.
582611 this . isPaused = false
583612 this . emit ( "taskUnpaused" )
584613
585- // fake an answer from the subtask that it has completed running and this is the result of what it has done
586- // add the message to the chat history and to the webview ui
614+ // Fake an answer from the subtask that it has completed running and
615+ // this is the result of what it has done add the message to the chat
616+ // history and to the webview ui.
587617 try {
588618 await this . say ( "subtask_result" , lastMessage )
589619
590620 await this . addToApiConversationHistory ( {
591621 role : "user" ,
592- content : [
593- {
594- type : "text" ,
595- text : `[new_task completed] Result: ${ lastMessage } ` ,
596- } ,
597- ] ,
622+ content : [ { type : "text" , text : `[new_task completed] Result: ${ lastMessage } ` } ] ,
598623 } )
599624 } catch ( error ) {
600625 this . providerRef
601626 . deref ( )
602627 ?. log ( `Error failed to add reply from subtast into conversation of parent task, error: ${ error } ` )
628+
603629 throw error
604630 }
605631 }
@@ -1629,17 +1655,9 @@ export class Task extends EventEmitter<ClineEvents> {
16291655 }
16301656 }
16311657
1632- public getToolUsage ( ) {
1633- return this . toolUsage
1634- }
1635-
16361658 // Getters
16371659
16381660 public get cwd ( ) {
16391661 return this . workspacePath
16401662 }
1641-
1642- public getFileContextTracker ( ) : FileContextTracker {
1643- return this . fileContextTracker
1644- }
16451663}
0 commit comments