Skip to content

Commit 2f0180b

Browse files
authored
fix: rate limit (#1422)
* fix(agent): restore chat rate limiting * fix(agent): compact rate limit feedback * fix(agent): address rate limit reviews * fix(agent): handle abort review gaps
1 parent 677e4ed commit 2f0180b

43 files changed

Lines changed: 1496 additions & 143 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/main/presenter/deepchatAgentPresenter/compactionService.ts

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@ const SAFETY_MARGIN = 1.2
2121
const SUMMARIZATION_OVERHEAD_TOKENS = 4096
2222
const 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+
2443
export 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

Comments
 (0)