feat(agent-core): increase compaction overflow retry limit and reduce more aggressively after 5 retries

This commit is contained in:
_Kerman 2026-06-02 16:25:58 +08:00
parent 1f8c36af28
commit 8a33a4fc06
5 changed files with 36 additions and 10 deletions

View file

@ -0,0 +1,6 @@
---
"@moonshot-ai/agent-core": patch
"@moonshot-ai/kimi-code": patch
---
Increase compaction overflow retry limit to 10 and reduce more aggressively after the fifth retry.

View file

@ -44,7 +44,7 @@ export interface CompactedHistory {
text: string;
}
export const MAX_COMPACTION_RETRY_ATTEMPTS = 5;
export const MAX_COMPACTION_RETRY_ATTEMPTS = 10;
class CompactionTruncatedError extends Error {
constructor() {
@ -283,7 +283,7 @@ export class FullCompaction {
break;
} catch (error) {
if (error instanceof APIContextOverflowError || error instanceof CompactionTruncatedError) {
compactedCount = this.strategy.reduceCompactOnOverflow(messagesToCompact);
compactedCount = this.strategy.reduceCompactOnOverflow(messagesToCompact, retryCount);
}
else if (!isRetryableGenerateError(error)) {
throw error;

View file

@ -28,7 +28,7 @@ export interface CompactionStrategy {
shouldCompact(usedSize: number): boolean;
shouldBlock(usedSize: number): boolean;
computeCompactCount(messages: readonly Message[], source: CompactionSource): number;
reduceCompactOnOverflow(messages: readonly Message[]): number;
reduceCompactOnOverflow(messages: readonly Message[], retry: number): number;
readonly checkAfterStep: boolean;
readonly maxCompactionPerTurn: number;
}
@ -118,10 +118,13 @@ export class DefaultCompactionStrategy implements CompactionStrategy {
return bestN ?? 0;
}
reduceCompactOnOverflow(messages: readonly Message[]): number {
reduceCompactOnOverflow(messages: readonly Message[], retry: number): number {
const ratio = retry > 5
? this.config.minOverflowReductionRatio * 2
: this.config.minOverflowReductionRatio;
const minReducedSize = Math.max(
1,
Math.ceil(this.maxSize * this.config.minOverflowReductionRatio),
Math.ceil(this.maxSize * ratio),
);
let reducedSize = 0;
let bestN: number | undefined;

View file

@ -146,7 +146,7 @@ describe('FullCompaction', () => {
]).flat(),
];
const reduced = strategy.reduceCompactOnOverflow(messages);
const reduced = strategy.reduceCompactOnOverflow(messages, 0);
const removed = messages.slice(reduced);
expect(reduced).toBeGreaterThan(0);
@ -749,7 +749,7 @@ describe('FullCompaction', () => {
await vi.advanceTimersByTimeAsync(60_000);
const events = await ctx.untilTurnEnd();
expect(attempts).toBe(5);
expect(attempts).toBe(10);
expect(events).toContainEqual(
expect.objectContaining({
event: 'turn.ended',
@ -788,14 +788,14 @@ describe('FullCompaction', () => {
await vi.advanceTimersByTimeAsync(60_000);
await failed;
expect(attempts).toBe(5);
expect(attempts).toBe(10);
expect(records).toContainEqual({
event: 'compaction_failed',
properties: {
trigger_type: 'manual',
before_tokens: 25,
duration_ms: expect.any(Number),
retry_count: 4,
retry_count: 9,
error_type: 'APIConnectionError',
},
});
@ -1763,7 +1763,7 @@ const alwaysCompactOnce: CompactionStrategy = {
shouldCompact: () => true,
shouldBlock: () => true,
computeCompactCount: (messages: readonly Message[]) => messages.length,
reduceCompactOnOverflow: (messages: readonly Message[]) => messages.length,
reduceCompactOnOverflow: (messages: readonly Message[], _retry: number) => messages.length,
checkAfterStep: true,
maxCompactionPerTurn: 1,
};

View file

@ -120,6 +120,23 @@ describe('DefaultCompactionStrategy', () => {
expect(strategy.shouldCompact(28_000)).toBe(true);
expect(strategy.shouldBlock(28_000)).toBe(true);
});
it('reduces more aggressively when retry count exceeds 5', () => {
const strategy = testCompactionStrategy(1_000);
const messages = [
textMessage('assistant', 'a'.repeat(192)),
textMessage('user', 'u'.repeat(4)),
textMessage('assistant', 'a'.repeat(192)),
textMessage('user', 'u'.repeat(4)),
textMessage('assistant', 'a'.repeat(192)),
textMessage('user', 'u'.repeat(4)),
textMessage('assistant', 'a'.repeat(192)),
];
expect(strategy.reduceCompactOnOverflow(messages, 0)).toBe(5);
expect(strategy.reduceCompactOnOverflow(messages, 5)).toBe(5);
expect(strategy.reduceCompactOnOverflow(messages, 6)).toBe(3);
});
});
function testCompactionStrategy(maxSize: number = 1_000): DefaultCompactionStrategy {