@@ -729,6 +729,16 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
729729 return undefined
730730 }
731731
732+ async nextClineMessageTimestamp_kilocode ( ) {
733+ let ts = Date . now ( )
734+ while ( ts <= ( this . clineMessages ?. at ( - 1 ) ?. ts ?? 0 ) ) {
735+ console . warn ( "nextClineMessageTimeStamp: timestamp already taken" , ts )
736+ await new Promise < void > ( ( resolve ) => setTimeout ( ( ) => resolve ( ) , 1 ) )
737+ ts = Date . now ( )
738+ }
739+ return ts
740+ }
741+
732742 // Note that `partial` has three valid states true (partial message),
733743 // false (completion of partial message), undefined (individual complete
734744 // message).
@@ -775,7 +785,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
775785 } else {
776786 // This is a new partial message, so add it with partial
777787 // state.
778- askTs = Date . now ( )
788+ askTs = await this . nextClineMessageTimestamp_kilocode ( )
779789 this . lastMessageTs = askTs
780790 await this . addToClineMessages ( { ts : askTs , type : "ask" , ask : type , text, partial, isProtected } )
781791 throw new Error ( "Current ask promise was ignored (#2)" )
@@ -812,7 +822,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
812822 this . askResponse = undefined
813823 this . askResponseText = undefined
814824 this . askResponseImages = undefined
815- askTs = Date . now ( )
825+ askTs = await this . nextClineMessageTimestamp_kilocode ( )
816826 this . lastMessageTs = askTs
817827 await this . addToClineMessages ( { ts : askTs , type : "ask" , ask : type , text, isProtected } )
818828 }
@@ -822,7 +832,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
822832 this . askResponse = undefined
823833 this . askResponseText = undefined
824834 this . askResponseImages = undefined
825- askTs = Date . now ( )
835+ askTs = await this . nextClineMessageTimestamp_kilocode ( )
826836 this . lastMessageTs = askTs
827837 await this . addToClineMessages ( { ts : askTs , type : "ask" , ask : type , text, isProtected } )
828838 }
@@ -1123,7 +1133,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
11231133 this . updateClineMessage ( lastMessage )
11241134 } else {
11251135 // This is a new partial message, so add it with partial state.
1126- const sayTs = Date . now ( )
1136+ const sayTs = await this . nextClineMessageTimestamp_kilocode ( )
11271137
11281138 if ( ! options . isNonInteractive ) {
11291139 this . lastMessageTs = sayTs
@@ -1170,7 +1180,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
11701180 this . updateClineMessage ( lastMessage )
11711181 } else {
11721182 // This is a new and complete message, so add it like normal.
1173- const sayTs = Date . now ( )
1183+ const sayTs = await this . nextClineMessageTimestamp_kilocode ( )
11741184
11751185 if ( ! options . isNonInteractive ) {
11761186 this . lastMessageTs = sayTs
@@ -1189,7 +1199,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
11891199 }
11901200 } else {
11911201 // This is a new non-partial message, so add it like normal.
1192- const sayTs = Date . now ( )
1202+ const sayTs = await this . nextClineMessageTimestamp_kilocode ( )
11931203
11941204 // A "non-interactive" message is a message is one that the user
11951205 // does not need to respond to. We don't want these message types
0 commit comments