Merge branch 'master' into fix/compaction-kv-cache-reuse

# Conflicts:
#	packages/compact/compact-basic/src/index.ts
#	packages/compact/compact-basic/src/summarizer.ts
#	packages/compact/compact-basic/tests/compact-basic.spec.ts
This commit is contained in:
Tianyi Cui
2026-07-21 19:45:43 +08:00
623 changed files with 21230 additions and 3010 deletions
@@ -8,7 +8,10 @@ import { defineTool } from '@deepseek-ai/dsh-tools'
import type { Agent } from '@deepseek-ai/dsh-agent'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit'
import * as Invariants from '@deepseek-ai/dsh-invariants'
import InvariantService from '@deepseek-ai/dsh-invariants'
import * as SessionInvariant from '@deepseek-ai/dsh-session/invariant'
import * as AgentInvariant from '@deepseek-ai/dsh-agent/invariant'
import * as AgentLoopInvariant from '@deepseek-ai/dsh-agent-loop/invariant'
import { BasicCompactService } from '@deepseek-ai/dsh-compact-basic'
import TokenMeterService from '@deepseek-ai/dsh-token-meter'
import * as LlmRetry from '@deepseek-ai/dsh-llm-retry'
@@ -38,6 +41,10 @@ class StepwiseToolAdapter extends LlmAdapter {
super()
}
override resolveModelContext(): Promise<{ contextWindow: number }> {
return Promise.resolve({ contextWindow: 400 })
}
async * stream(_options: GenerateOptions): AsyncIterable<StreamChunk> {
const n = this.calls
this.calls += 1
@@ -69,6 +76,10 @@ class OverflowRecoveryAdapter extends LlmAdapter {
super()
}
override resolveModelContext(): Promise<{ contextWindow: number }> {
return Promise.resolve({ contextWindow: 128 })
}
override async * stream(options: GenerateOptions): AsyncIterable<StreamChunk> {
// The cache-reusing summarizer replays the conversation prefix and marks
// its call only by the compaction instruction in the trailing user message.
@@ -109,12 +120,19 @@ class OverflowRecoveryAdapter extends LlmAdapter {
}
}
async function mountInvariants(ctx: Context): Promise<void> {
await ctx.plugin(InvariantService)
await ctx.plugin(SessionInvariant)
await ctx.plugin(AgentInvariant)
await ctx.plugin(AgentLoopInvariant)
}
async function harness(toolSteps: number): Promise<{ ctx: Context; compact: ReproCompactService }> {
const ctx = new Context()
await mountAgentLoopTestDependencies(ctx)
await ctx.plugin(Invariants)
await mountInvariants(ctx)
await ctx.plugin(AgentLoop, { agents: [] })
await ctx.plugin(TokenMeterService, { contextWindow: 400 })
await ctx.plugin(TokenMeterService)
ctx.llm.registerAdapter(['mock'], new StepwiseToolAdapter(toolSteps))
ctx.tools.register(defineTool({
name: 'work',
@@ -130,7 +148,6 @@ async function harness(toolSteps: number): Promise<{ ctx: Context; compact: Repr
auto: true,
thresholdRatio: 0.5,
retainTokens: 50,
summarizationModel: '',
maxTokens: 8192,
compactionRetries: 1,
})
@@ -260,9 +277,9 @@ describe('context-overflow recovery across the real loop and compact-basic', ()
const ctx = new Context()
const adapter = new OverflowRecoveryAdapter(delivery)
await mountAgentLoopTestDependencies(ctx)
await ctx.plugin(Invariants)
await mountInvariants(ctx)
await ctx.plugin(AgentLoop, { agents: [] })
await ctx.plugin(TokenMeterService, { contextWindow: 128 })
await ctx.plugin(TokenMeterService)
ctx.llm.registerAdapter(['mock'], adapter)
ctx.on('agent/request', async (_agent, _turn, _step, config) => ({ ...config, provider: 'mock', model: 'mock' }))
await ctx.plugin(BasicCompactService, {
@@ -322,7 +339,7 @@ describe('context-overflow recovery across the real loop and compact-basic', ()
const ctx = new Context()
const adapter = new OverflowRecoveryAdapter('thrown', true)
await mountAgentLoopTestDependencies(ctx)
await ctx.plugin(Invariants)
await mountInvariants(ctx)
await ctx.plugin(LlmRetry, {
maxTransientRetries: 1,
initialDelayMs: 1,
@@ -330,7 +347,7 @@ describe('context-overflow recovery across the real loop and compact-basic', ()
jitterRatio: 0,
})
await ctx.plugin(AgentLoop, { agents: [] })
await ctx.plugin(TokenMeterService, { contextWindow: 128 })
await ctx.plugin(TokenMeterService)
ctx.llm.registerAdapter(['mock'], adapter)
await ctx.plugin(BasicCompactService, {
thresholdRatio: 1,