@@ -21,6 +21,25 @@ const SAFETY_MARGIN = 1.2
2121const SUMMARIZATION_OVERHEAD_TOKENS = 4096
2222const SUMMARY_OUTPUT_TOKENS_CAP = 2048
2323
24+ const createAbortError = ( ) : Error => {
25+ if ( typeof DOMException !== 'undefined' ) {
26+ return new DOMException ( 'Aborted' , 'AbortError' )
27+ }
28+
29+ const error = new Error ( 'Aborted' )
30+ error . name = 'AbortError'
31+ return error
32+ }
33+
34+ const throwIfAbortRequested = ( signal ?: AbortSignal ) : void => {
35+ if ( signal ?. aborted ) {
36+ throw createAbortError ( )
37+ }
38+ }
39+
40+ const isAbortError = ( error : unknown ) : boolean =>
41+ error instanceof Error && ( error . name === 'AbortError' || error . name === 'CanceledError' )
42+
2443export type ModelSpec = {
2544 providerId : string
2645 modelId : string
@@ -215,8 +234,11 @@ export class CompactionService {
215234 supportsVision : boolean
216235 preserveInterleavedReasoning : boolean
217236 newUserContent : string | SendMessageInput
237+ signal ?: AbortSignal
218238 } ) : Promise < CompactionIntent | null > {
239+ throwIfAbortRequested ( params . signal )
219240 const settings = await this . getCompactionSettings ( params . sessionId )
241+ throwIfAbortRequested ( params . signal )
220242 if ( ! settings . enabled ) {
221243 return null
222244 }
@@ -245,8 +267,11 @@ export class CompactionService {
245267 reserveTokens : number
246268 supportsVision : boolean
247269 preserveInterleavedReasoning : boolean
270+ signal ?: AbortSignal
248271 } ) : Promise < CompactionIntent | null > {
272+ throwIfAbortRequested ( params . signal )
249273 const settings = await this . getCompactionSettings ( params . sessionId )
274+ throwIfAbortRequested ( params . signal )
250275 if ( ! settings . enabled ) {
251276 return null
252277 }
@@ -279,14 +304,19 @@ export class CompactionService {
279304 } )
280305 }
281306
282- async applyCompaction ( intent : CompactionIntent ) : Promise < CompactionExecutionResult > {
307+ async applyCompaction (
308+ intent : CompactionIntent ,
309+ signal ?: AbortSignal
310+ ) : Promise < CompactionExecutionResult > {
283311 try {
312+ throwIfAbortRequested ( signal )
284313 const nextSummary = await this . generateRollingSummary ( {
285314 sessionId : intent . sessionId ,
286315 previousSummary : intent . previousState . summaryText ,
287316 summaryBlocks : intent . summaryBlocks ,
288317 currentModel : intent . currentModel ,
289- reserveTokens : intent . reserveTokens
318+ reserveTokens : intent . reserveTokens ,
319+ signal
290320 } )
291321
292322 const updatedState : SessionSummaryState = {
@@ -313,6 +343,9 @@ export class CompactionService {
313343 summaryState : compareAndSet . currentState
314344 }
315345 } catch ( error ) {
346+ if ( signal ?. aborted || isAbortError ( error ) ) {
347+ throw error
348+ }
316349 console . warn ( `[CompactionService] Failed to compact session ${ intent . sessionId } :` , error )
317350 return {
318351 succeeded : false ,
@@ -496,9 +529,12 @@ export class CompactionService {
496529 summaryBlocks : string [ ]
497530 currentModel : ModelSpec
498531 reserveTokens : number
532+ signal ?: AbortSignal
499533 } ) : Promise < string > {
534+ throwIfAbortRequested ( params . signal )
500535 const currentModel = params . currentModel
501536 const assistantModel = await this . getAssistantModelSpec ( params . sessionId , currentModel )
537+ throwIfAbortRequested ( params . signal )
502538 const previousSummaryTokens = approximateTokenSize ( params . previousSummary || '' )
503539 const blockTokens = params . summaryBlocks . reduce (
504540 ( total , block ) => total + approximateTokenSize ( block ) ,
@@ -515,7 +551,8 @@ export class CompactionService {
515551 return await this . summarizeBlocks ( params . summaryBlocks , {
516552 previousSummary : params . previousSummary ,
517553 model : preferredModel ,
518- reserveTokens : params . reserveTokens
554+ reserveTokens : params . reserveTokens ,
555+ signal : params . signal
519556 } )
520557 }
521558
@@ -525,8 +562,10 @@ export class CompactionService {
525562 previousSummary : string | null
526563 model : ModelSpec
527564 reserveTokens : number
565+ signal ?: AbortSignal
528566 }
529567 ) : Promise < string > {
568+ throwIfAbortRequested ( options . signal )
530569 const normalizedBlocks = blocks . map ( ( block ) => block . trim ( ) ) . filter ( Boolean )
531570 if ( normalizedBlocks . length === 0 ) {
532571 const normalizedPrevious = options . previousSummary ?. trim ( )
@@ -546,7 +585,8 @@ export class CompactionService {
546585 options . model ,
547586 options . reserveTokens ,
548587 options . previousSummary ,
549- normalizedBlocks . join ( '\n\n' )
588+ normalizedBlocks . join ( '\n\n' ) ,
589+ options . signal
550590 )
551591 }
552592
@@ -569,7 +609,8 @@ export class CompactionService {
569609 options . model ,
570610 options . reserveTokens ,
571611 options . previousSummary ,
572- joinedSplitBlocks
612+ joinedSplitBlocks ,
613+ options . signal
573614 )
574615 }
575616
@@ -596,16 +637,20 @@ export class CompactionService {
596637 previousSummary : string | null
597638 model : ModelSpec
598639 reserveTokens : number
640+ signal ?: AbortSignal
599641 }
600642 ) : Promise < string > {
643+ throwIfAbortRequested ( options . signal )
601644 const chunkSummaries : string [ ] = [ ]
602645 for ( const chunk of chunkGroups ) {
646+ throwIfAbortRequested ( options . signal )
603647 chunkSummaries . push (
604648 await this . generateSummaryText (
605649 options . model ,
606650 options . reserveTokens ,
607651 null ,
608- chunk . join ( '\n\n' )
652+ chunk . join ( '\n\n' ) ,
653+ options . signal
609654 )
610655 )
611656 }
@@ -701,9 +746,17 @@ export class CompactionService {
701746 model : ModelSpec ,
702747 reserveTokens : number ,
703748 previousSummary : string | null ,
704- spanText : string
749+ spanText : string ,
750+ signal ?: AbortSignal
705751 ) : Promise < string > {
752+ throwIfAbortRequested ( signal )
706753 const prompt = this . buildSummaryPrompt ( previousSummary , spanText )
754+ if ( signal ) {
755+ await this . llmProviderPresenter . executeWithRateLimit ( model . providerId , { signal } )
756+ } else {
757+ await this . llmProviderPresenter . executeWithRateLimit ( model . providerId )
758+ }
759+ throwIfAbortRequested ( signal )
707760 const response = await this . llmProviderPresenter . generateText (
708761 model . providerId ,
709762 prompt ,
0 commit comments