feat(compaction): add dynamic context pruning as recovery stage
Implements DCP-style pruning strategies inspired by opencode-dynamic-context-pruning plugin: - Deduplication: removes duplicate tool calls (same tool + args) - Supersede writes: prunes write inputs when file subsequently read - Purge errors: removes old error tool inputs after N turns Integration: - Added as Stage 2.5 in compaction pipeline (after truncation, before summarize) - Configurable via experimental.dynamic_context_pruning - Opt-in by default (experimental feature) - Protected tools list prevents pruning critical tools Configuration: - Turn protection (default: 3 turns) - Per-strategy enable/disable - Aggressive/conservative modes for supersede writes - Configurable error purge threshold (default: 5 turns) - Toast notifications (off/minimal/detailed) Testing: - Added unit tests for deduplication signature creation - Type check passes - Schema regenerated Closes #271
This commit is contained in:
@@ -6,6 +6,7 @@ import type {
|
||||
} from "./types";
|
||||
import type { ExperimentalConfig } from "../../config";
|
||||
import { FALLBACK_CONFIG, RETRY_CONFIG, TRUNCATE_CONFIG } from "./types";
|
||||
import { executeDynamicContextPruning } from "./pruning-executor";
|
||||
import {
|
||||
findLargestToolResult,
|
||||
truncateToolResult,
|
||||
@@ -383,6 +384,40 @@ export async function executeCompact(
|
||||
}
|
||||
}
|
||||
|
||||
if (experimental?.dynamic_context_pruning?.enabled) {
|
||||
log("[auto-compact] attempting DCP before truncation", { sessionID });
|
||||
|
||||
try {
|
||||
const pruningResult = await executeDynamicContextPruning(
|
||||
sessionID,
|
||||
experimental.dynamic_context_pruning,
|
||||
client
|
||||
);
|
||||
|
||||
if (pruningResult.itemsPruned > 0) {
|
||||
log("[auto-compact] DCP successful, resuming", {
|
||||
itemsPruned: pruningResult.itemsPruned,
|
||||
tokensSaved: pruningResult.totalTokensSaved,
|
||||
});
|
||||
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
await (client as Client).session.prompt_async({
|
||||
path: { sessionID },
|
||||
body: { parts: [{ type: "text", text: "Continue" }] },
|
||||
query: { directory },
|
||||
});
|
||||
} catch {}
|
||||
}, 500);
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
log("[auto-compact] DCP failed, continuing to truncation", {
|
||||
error: String(error),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let skipSummarize = false;
|
||||
|
||||
if (truncateState.truncateAttempt < TRUNCATE_CONFIG.maxTruncateAttempts) {
|
||||
|
||||
Reference in New Issue
Block a user