From d0af37bbc6c9974e0f68b57269c0f3ff905f3e30 Mon Sep 17 00:00:00 2001 From: _Kerman Date: Wed, 8 Jul 2026 20:16:49 +0800 Subject: [PATCH] fix: v2 full compaction --- .../fullCompaction/fullCompactionService.ts | 23 +++++++++++++++---- .../test/fullCompaction/full.test.ts | 19 +++++++++------ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.ts b/packages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.ts index 217bfcf06..523cb41e9 100644 --- a/packages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.ts +++ b/packages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.ts @@ -239,7 +239,9 @@ export class AgentFullCompactionService extends Disposable implements IAgentFull next: () => Promise, ): Promise { const isOverflow = - isContextOverflowError(context.error) || this.shouldRecoverFromPlain413(context.error); + isContextOverflowError(context.error) || + findAPIStatusError(context.error) instanceof APIContextOverflowError || + this.shouldRecoverFromPlain413(context.error); if (!isOverflow) { await next(); return; @@ -525,9 +527,10 @@ export class AgentFullCompactionService extends Disposable implements IAgentFull tokens_after: result.tokensAfter, duration_ms: Date.now() - startedAt, compacted_count: result.compactedCount, + dropped_count: result.droppedCount, retry_count: retryCount, round, - thinking_level: this.profile.data().thinkingLevel, + thinking_effort: this.profile.data().thinkingLevel, ...usageTelemetry(attempt.usage), }); return result; @@ -539,7 +542,7 @@ export class AgentFullCompactionService extends Disposable implements IAgentFull duration_ms: Date.now() - startedAt, round, retry_count: retryCount, - thinking_level: this.profile.data().thinkingLevel, + thinking_effort: this.profile.data().thinkingLevel, error_type: error instanceof Error ? error.name : 'Unknown', }); if (isKimiError(error) && error.code === ErrorCodes.AUTH_LOGIN_REQUIRED) throw error; @@ -567,7 +570,8 @@ export class AgentFullCompactionService extends Disposable implements IAgentFull error: unknown, estimatedRequestTokens = this.tokenCountWithPending(), ): boolean { - if (!(error instanceof APIStatusError) || error.statusCode !== 413) return false; + const statusError = findAPIStatusError(error); + if (statusError === undefined || statusError.statusCode !== 413) return false; const maxContextTokens = this.profile.getModelCapabilities().max_context_tokens; return ( maxContextTokens > 0 && @@ -584,6 +588,17 @@ export class AgentFullCompactionService extends Disposable implements IAgentFull } } +function findAPIStatusError(error: unknown): APIStatusError | undefined { + let current: unknown = error; + const seen = new Set(); + while (current !== undefined && current !== null && !seen.has(current)) { + if (current instanceof APIStatusError) return current; + seen.add(current); + current = current instanceof Error ? current.cause : undefined; + } + return undefined; +} + function collectSummary(finish: LLMRequestFinish): CompactionAttemptResult { if (finish.providerFinishReason === 'truncated') { throw new CompactionTruncatedError(); diff --git a/packages/agent-core-v2/test/fullCompaction/full.test.ts b/packages/agent-core-v2/test/fullCompaction/full.test.ts index 2d31d3241..0562b5ddb 100644 --- a/packages/agent-core-v2/test/fullCompaction/full.test.ts +++ b/packages/agent-core-v2/test/fullCompaction/full.test.ts @@ -274,7 +274,7 @@ describe('FullCompaction', () => { duration_ms: expect.any(Number), compacted_count: 6, retry_count: 0, - thinking_level: 'off', + thinking_effort: 'off', input_other: 1181, output: 8, input_cache_read: 0, @@ -1975,12 +1975,16 @@ describe('FullCompaction', () => { await ctx.untilTurnEnd(); expect(callCount).toBe(3); - expect(providerThinkingEfforts).toEqual(['high', 'high', 'high']); + // The catalogued model declares no supportEfforts, so the Kimi provider + // normalizes to boolean thinking and reports 'on' rather than the + // requested 'high'. The stored thinkingLevel still carries 'high' across + // compaction, which is asserted through telemetry below. + expect(providerThinkingEfforts).toEqual(['on', 'on', 'on']); expect(records).toContainEqual({ event: 'compaction_finished', properties: expect.objectContaining({ source: 'auto', - thinking_level: 'high', + thinking_effort: 'high', }), }); }); @@ -2014,10 +2018,11 @@ describe('FullCompaction', () => { const modelResolver = ctx.modelResolver; if (modelResolver === undefined) throw new Error('Expected model provider'); const resolve = modelResolver.resolve.bind(modelResolver); - modelResolver.resolve = (model: string) => ({ - ...resolve(model), - modelCapabilities: UNKNOWN_CAPABILITY, - }); + modelResolver.resolve = (model: string) => { + const resolved = resolve(model); + Object.defineProperty(resolved, 'capabilities', { value: UNKNOWN_CAPABILITY }); + return resolved; + }; expect(ctx.get(IAgentProfileService).data().modelCapabilities.max_context_tokens).toBe(0); ctx.appendExchange(1, 'old user one', 'old assistant one', 20); ctx.newEvents();