@tuanhung303/opencode-acp 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +288 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/commands/context.d.ts +49 -0
- package/dist/lib/commands/context.d.ts.map +1 -0
- package/dist/lib/commands/context.js +191 -0
- package/dist/lib/commands/context.js.map +1 -0
- package/dist/lib/commands/help.d.ts +15 -0
- package/dist/lib/commands/help.d.ts.map +1 -0
- package/dist/lib/commands/help.js +26 -0
- package/dist/lib/commands/help.js.map +1 -0
- package/dist/lib/commands/stats.d.ts +15 -0
- package/dist/lib/commands/stats.d.ts.map +1 -0
- package/dist/lib/commands/stats.js +44 -0
- package/dist/lib/commands/stats.js.map +1 -0
- package/dist/lib/commands/sweep.d.ts +23 -0
- package/dist/lib/commands/sweep.d.ts.map +1 -0
- package/dist/lib/commands/sweep.js +191 -0
- package/dist/lib/commands/sweep.js.map +1 -0
- package/dist/lib/config.d.ts +82 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +864 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/hooks.d.ts +17 -0
- package/dist/lib/hooks.d.ts.map +1 -0
- package/dist/lib/hooks.js +123 -0
- package/dist/lib/hooks.js.map +1 -0
- package/dist/lib/logger.d.ts +31 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +189 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/messages/index.d.ts +3 -0
- package/dist/lib/messages/index.d.ts.map +1 -0
- package/dist/lib/messages/index.js +3 -0
- package/dist/lib/messages/index.js.map +1 -0
- package/dist/lib/messages/inject.d.ts +5 -0
- package/dist/lib/messages/inject.d.ts.map +1 -0
- package/dist/lib/messages/inject.js +127 -0
- package/dist/lib/messages/inject.js.map +1 -0
- package/dist/lib/messages/prune.d.ts +5 -0
- package/dist/lib/messages/prune.d.ts.map +1 -0
- package/dist/lib/messages/prune.js +86 -0
- package/dist/lib/messages/prune.js.map +1 -0
- package/dist/lib/messages/utils.d.ts +31 -0
- package/dist/lib/messages/utils.d.ts.map +1 -0
- package/dist/lib/messages/utils.js +228 -0
- package/dist/lib/messages/utils.js.map +1 -0
- package/dist/lib/prompts/discard-tool-spec.d.ts +2 -0
- package/dist/lib/prompts/discard-tool-spec.d.ts.map +1 -0
- package/dist/lib/prompts/discard-tool-spec.js +41 -0
- package/dist/lib/prompts/discard-tool-spec.js.map +1 -0
- package/dist/lib/prompts/extract-tool-spec.d.ts +2 -0
- package/dist/lib/prompts/extract-tool-spec.d.ts.map +1 -0
- package/dist/lib/prompts/extract-tool-spec.js +48 -0
- package/dist/lib/prompts/extract-tool-spec.js.map +1 -0
- package/dist/lib/prompts/index.d.ts +2 -0
- package/dist/lib/prompts/index.d.ts.map +1 -0
- package/dist/lib/prompts/index.js +34 -0
- package/dist/lib/prompts/index.js.map +1 -0
- package/dist/lib/prompts/nudge/both.d.ts +2 -0
- package/dist/lib/prompts/nudge/both.d.ts.map +1 -0
- package/dist/lib/prompts/nudge/both.js +11 -0
- package/dist/lib/prompts/nudge/both.js.map +1 -0
- package/dist/lib/prompts/nudge/discard.d.ts +2 -0
- package/dist/lib/prompts/nudge/discard.d.ts.map +1 -0
- package/dist/lib/prompts/nudge/discard.js +10 -0
- package/dist/lib/prompts/nudge/discard.js.map +1 -0
- package/dist/lib/prompts/nudge/extract.d.ts +2 -0
- package/dist/lib/prompts/nudge/extract.d.ts.map +1 -0
- package/dist/lib/prompts/nudge/extract.js +10 -0
- package/dist/lib/prompts/nudge/extract.js.map +1 -0
- package/dist/lib/prompts/system/both.d.ts +2 -0
- package/dist/lib/prompts/system/both.d.ts.map +1 -0
- package/dist/lib/prompts/system/both.js +61 -0
- package/dist/lib/prompts/system/both.js.map +1 -0
- package/dist/lib/prompts/system/discard.d.ts +2 -0
- package/dist/lib/prompts/system/discard.d.ts.map +1 -0
- package/dist/lib/prompts/system/discard.js +52 -0
- package/dist/lib/prompts/system/discard.js.map +1 -0
- package/dist/lib/prompts/system/extract.d.ts +2 -0
- package/dist/lib/prompts/system/extract.d.ts.map +1 -0
- package/dist/lib/prompts/system/extract.js +52 -0
- package/dist/lib/prompts/system/extract.js.map +1 -0
- package/dist/lib/protected-file-patterns.d.ts +12 -0
- package/dist/lib/protected-file-patterns.d.ts.map +1 -0
- package/dist/lib/protected-file-patterns.js +69 -0
- package/dist/lib/protected-file-patterns.js.map +1 -0
- package/dist/lib/shared-utils.d.ts +4 -0
- package/dist/lib/shared-utils.d.ts.map +1 -0
- package/dist/lib/shared-utils.js +14 -0
- package/dist/lib/shared-utils.js.map +1 -0
- package/dist/lib/state/index.d.ts +4 -0
- package/dist/lib/state/index.d.ts.map +1 -0
- package/dist/lib/state/index.js +4 -0
- package/dist/lib/state/index.js.map +1 -0
- package/dist/lib/state/persistence.d.ts +22 -0
- package/dist/lib/state/persistence.d.ts.map +1 -0
- package/dist/lib/state/persistence.js +107 -0
- package/dist/lib/state/persistence.js.map +1 -0
- package/dist/lib/state/state.d.ts +8 -0
- package/dist/lib/state/state.d.ts.map +1 -0
- package/dist/lib/state/state.js +115 -0
- package/dist/lib/state/state.js.map +1 -0
- package/dist/lib/state/tool-cache.d.ts +13 -0
- package/dist/lib/state/tool-cache.d.ts.map +1 -0
- package/dist/lib/state/tool-cache.js +77 -0
- package/dist/lib/state/tool-cache.js.map +1 -0
- package/dist/lib/state/types.d.ts +38 -0
- package/dist/lib/state/types.d.ts.map +1 -0
- package/dist/lib/state/types.js +2 -0
- package/dist/lib/state/types.js.map +1 -0
- package/dist/lib/state/utils.d.ts +2 -0
- package/dist/lib/state/utils.d.ts.map +1 -0
- package/dist/lib/state/utils.js +10 -0
- package/dist/lib/state/utils.js.map +1 -0
- package/dist/lib/strategies/deduplication.d.ts +10 -0
- package/dist/lib/strategies/deduplication.d.ts.map +1 -0
- package/dist/lib/strategies/deduplication.js +94 -0
- package/dist/lib/strategies/deduplication.js.map +1 -0
- package/dist/lib/strategies/head-tail-truncation.d.ts +15 -0
- package/dist/lib/strategies/head-tail-truncation.d.ts.map +1 -0
- package/dist/lib/strategies/head-tail-truncation.js +144 -0
- package/dist/lib/strategies/head-tail-truncation.js.map +1 -0
- package/dist/lib/strategies/index.d.ts +9 -0
- package/dist/lib/strategies/index.d.ts.map +1 -0
- package/dist/lib/strategies/index.js +9 -0
- package/dist/lib/strategies/index.js.map +1 -0
- package/dist/lib/strategies/placeholder-compression.d.ts +5 -0
- package/dist/lib/strategies/placeholder-compression.d.ts.map +1 -0
- package/dist/lib/strategies/placeholder-compression.js +148 -0
- package/dist/lib/strategies/placeholder-compression.js.map +1 -0
- package/dist/lib/strategies/prune-thinking.d.ts +15 -0
- package/dist/lib/strategies/prune-thinking.d.ts.map +1 -0
- package/dist/lib/strategies/prune-thinking.js +79 -0
- package/dist/lib/strategies/prune-thinking.js.map +1 -0
- package/dist/lib/strategies/purge-errors.d.ts +13 -0
- package/dist/lib/strategies/purge-errors.d.ts.map +1 -0
- package/dist/lib/strategies/purge-errors.js +59 -0
- package/dist/lib/strategies/purge-errors.js.map +1 -0
- package/dist/lib/strategies/read-consolidation.d.ts +21 -0
- package/dist/lib/strategies/read-consolidation.d.ts.map +1 -0
- package/dist/lib/strategies/read-consolidation.js +155 -0
- package/dist/lib/strategies/read-consolidation.js.map +1 -0
- package/dist/lib/strategies/supersede-writes.d.ts +13 -0
- package/dist/lib/strategies/supersede-writes.d.ts.map +1 -0
- package/dist/lib/strategies/supersede-writes.js +84 -0
- package/dist/lib/strategies/supersede-writes.js.map +1 -0
- package/dist/lib/strategies/tools.d.ts +14 -0
- package/dist/lib/strategies/tools.d.ts.map +1 -0
- package/dist/lib/strategies/tools.js +135 -0
- package/dist/lib/strategies/tools.js.map +1 -0
- package/dist/lib/strategies/utils.d.ts +11 -0
- package/dist/lib/strategies/utils.d.ts.map +1 -0
- package/dist/lib/strategies/utils.js +75 -0
- package/dist/lib/strategies/utils.js.map +1 -0
- package/dist/lib/ui/notification.d.ts +9 -0
- package/dist/lib/ui/notification.d.ts.map +1 -0
- package/dist/lib/ui/notification.js +77 -0
- package/dist/lib/ui/notification.js.map +1 -0
- package/dist/lib/ui/utils.d.ts +10 -0
- package/dist/lib/ui/utils.d.ts.map +1 -0
- package/dist/lib/ui/utils.js +87 -0
- package/dist/lib/ui/utils.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SessionState, WithParts } from "./index";
|
|
2
|
+
import type { Logger } from "../logger";
|
|
3
|
+
import { PluginConfig } from "../config";
|
|
4
|
+
/**
|
|
5
|
+
* Sync tool parameters from OpenCode's session.messages() API.
|
|
6
|
+
*/
|
|
7
|
+
export declare function syncToolCache(state: SessionState, config: PluginConfig, logger: Logger, messages: WithParts[]): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* Trim the tool parameters cache to prevent unbounded memory growth.
|
|
10
|
+
* Uses FIFO eviction - removes oldest entries first.
|
|
11
|
+
*/
|
|
12
|
+
export declare function trimToolParametersCache(state: SessionState): void;
|
|
13
|
+
//# sourceMappingURL=tool-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-cache.d.ts","sourceRoot":"","sources":["../../../lib/state/tool-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAc,SAAS,EAAE,MAAM,SAAS,CAAA;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAKxC;;GAEG;AACH,wBAAsB,aAAa,CAC/B,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,SAAS,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CAsEf;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAajE"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { isMessageCompacted } from "../shared-utils";
|
|
2
|
+
const MAX_TOOL_CACHE_SIZE = 1000;
|
|
3
|
+
/**
|
|
4
|
+
* Sync tool parameters from OpenCode's session.messages() API.
|
|
5
|
+
*/
|
|
6
|
+
export async function syncToolCache(state, config, logger, messages) {
|
|
7
|
+
try {
|
|
8
|
+
logger.info("Syncing tool parameters from OpenCode messages");
|
|
9
|
+
state.nudgeCounter = 0;
|
|
10
|
+
let turnCounter = 0;
|
|
11
|
+
for (const msg of messages) {
|
|
12
|
+
if (isMessageCompacted(state, msg)) {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
const parts = Array.isArray(msg.parts) ? msg.parts : [];
|
|
16
|
+
for (const part of parts) {
|
|
17
|
+
if (part.type === "step-start") {
|
|
18
|
+
turnCounter++;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (part.type !== "tool" || !part.callID) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const turnProtectionEnabled = config.turnProtection.enabled;
|
|
25
|
+
const turnProtectionTurns = config.turnProtection.turns;
|
|
26
|
+
const isProtectedByTurn = turnProtectionEnabled &&
|
|
27
|
+
turnProtectionTurns > 0 &&
|
|
28
|
+
state.currentTurn - turnCounter < turnProtectionTurns;
|
|
29
|
+
state.lastToolPrune =
|
|
30
|
+
(part.tool === "discard" || part.tool === "extract") &&
|
|
31
|
+
part.state.status === "completed";
|
|
32
|
+
const allProtectedTools = config.tools.settings.protectedTools;
|
|
33
|
+
if (part.tool === "discard" || part.tool === "extract") {
|
|
34
|
+
state.nudgeCounter = 0;
|
|
35
|
+
}
|
|
36
|
+
else if (!allProtectedTools.includes(part.tool) && !isProtectedByTurn) {
|
|
37
|
+
state.nudgeCounter++;
|
|
38
|
+
}
|
|
39
|
+
if (state.toolParameters.has(part.callID)) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (isProtectedByTurn) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
state.toolParameters.set(part.callID, {
|
|
46
|
+
tool: part.tool,
|
|
47
|
+
parameters: part.state?.input ?? {},
|
|
48
|
+
status: part.state.status,
|
|
49
|
+
error: part.state.status === "error" ? part.state.error : undefined,
|
|
50
|
+
turn: turnCounter,
|
|
51
|
+
});
|
|
52
|
+
logger.info(`Cached tool id: ${part.callID} (created on turn ${turnCounter})`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
logger.info(`Synced cache - size: ${state.toolParameters.size}, currentTurn: ${state.currentTurn}, nudgeCounter: ${state.nudgeCounter}`);
|
|
56
|
+
trimToolParametersCache(state);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
logger.warn("Failed to sync tool parameters from OpenCode", {
|
|
60
|
+
error: error instanceof Error ? error.message : String(error),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Trim the tool parameters cache to prevent unbounded memory growth.
|
|
66
|
+
* Uses FIFO eviction - removes oldest entries first.
|
|
67
|
+
*/
|
|
68
|
+
export function trimToolParametersCache(state) {
|
|
69
|
+
if (state.toolParameters.size <= MAX_TOOL_CACHE_SIZE) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const keysToRemove = Array.from(state.toolParameters.keys()).slice(0, state.toolParameters.size - MAX_TOOL_CACHE_SIZE);
|
|
73
|
+
for (const key of keysToRemove) {
|
|
74
|
+
state.toolParameters.delete(key);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=tool-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-cache.js","sourceRoot":"","sources":["../../../lib/state/tool-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Message, Part } from "@opencode-ai/sdk/v2";
|
|
2
|
+
export interface WithParts {
|
|
3
|
+
info: Message;
|
|
4
|
+
parts: Part[];
|
|
5
|
+
}
|
|
6
|
+
export type ToolStatus = "pending" | "running" | "completed" | "error";
|
|
7
|
+
export interface ToolParameterEntry {
|
|
8
|
+
tool: string;
|
|
9
|
+
parameters: any;
|
|
10
|
+
status?: ToolStatus;
|
|
11
|
+
error?: string;
|
|
12
|
+
turn: number;
|
|
13
|
+
}
|
|
14
|
+
export interface SessionStats {
|
|
15
|
+
pruneTokenCounter: number;
|
|
16
|
+
totalPruneTokens: number;
|
|
17
|
+
}
|
|
18
|
+
export interface Prune {
|
|
19
|
+
toolIds: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface ConsolidationEntry {
|
|
22
|
+
messageIndex: number;
|
|
23
|
+
callId: string;
|
|
24
|
+
}
|
|
25
|
+
export interface SessionState {
|
|
26
|
+
sessionId: string | null;
|
|
27
|
+
isSubAgent: boolean;
|
|
28
|
+
prune: Prune;
|
|
29
|
+
stats: SessionStats;
|
|
30
|
+
toolParameters: Map<string, ToolParameterEntry>;
|
|
31
|
+
nudgeCounter: number;
|
|
32
|
+
lastToolPrune: boolean;
|
|
33
|
+
lastCompaction: number;
|
|
34
|
+
currentTurn: number;
|
|
35
|
+
variant: string | undefined;
|
|
36
|
+
consolidationTracker?: Map<string, ConsolidationEntry>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../lib/state/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAEnD,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,IAAI,EAAE,CAAA;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAA;AAEtE,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,GAAG,CAAA;IACf,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,KAAK;IAClB,OAAO,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,kBAAkB;IAC/B,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,KAAK,CAAA;IACZ,KAAK,EAAE,YAAY,CAAA;IACnB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAC/C,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,OAAO,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,oBAAoB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;CACzD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../lib/state/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/state/utils.ts"],"names":[],"mappings":"AAAA,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOxF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../lib/state/utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAW,EAAE,SAAiB;IAClE,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAA;QACpE,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAA;IAClC,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,OAAO,KAAK,CAAA;IAChB,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PluginConfig } from "../config";
|
|
2
|
+
import { Logger } from "../logger";
|
|
3
|
+
import type { SessionState, WithParts } from "../state";
|
|
4
|
+
/**
|
|
5
|
+
* Deduplication strategy - prunes older tool calls that have identical
|
|
6
|
+
* tool name and parameters, keeping only the most recent occurrence.
|
|
7
|
+
* Modifies the session state in place to add pruned tool call IDs.
|
|
8
|
+
*/
|
|
9
|
+
export declare const deduplicate: (state: SessionState, logger: Logger, config: PluginConfig, messages: WithParts[]) => void;
|
|
10
|
+
//# sourceMappingURL=deduplication.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deduplication.d.ts","sourceRoot":"","sources":["../../../lib/strategies/deduplication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAKvD;;;;GAIG;AACH,eAAO,MAAM,WAAW,GACpB,OAAO,YAAY,EACnB,QAAQ,MAAM,EACd,QAAQ,YAAY,EACpB,UAAU,SAAS,EAAE,KACtB,IAiEF,CAAA"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { buildToolIdList } from "../messages/utils";
|
|
2
|
+
import { getFilePathFromParameters, isProtectedFilePath } from "../protected-file-patterns";
|
|
3
|
+
import { calculateTokensSaved } from "./utils";
|
|
4
|
+
/**
|
|
5
|
+
* Deduplication strategy - prunes older tool calls that have identical
|
|
6
|
+
* tool name and parameters, keeping only the most recent occurrence.
|
|
7
|
+
* Modifies the session state in place to add pruned tool call IDs.
|
|
8
|
+
*/
|
|
9
|
+
export const deduplicate = (state, logger, config, messages) => {
|
|
10
|
+
if (!config.strategies.deduplication.enabled) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
// Build list of all tool call IDs from messages (chronological order)
|
|
14
|
+
const allToolIds = buildToolIdList(state, messages, logger);
|
|
15
|
+
if (allToolIds.length === 0) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
// Filter out IDs already pruned
|
|
19
|
+
const alreadyPruned = new Set(state.prune.toolIds);
|
|
20
|
+
const unprunedIds = allToolIds.filter((id) => !alreadyPruned.has(id));
|
|
21
|
+
if (unprunedIds.length === 0) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const protectedTools = config.strategies.deduplication.protectedTools;
|
|
25
|
+
// Group by signature (tool name + normalized parameters)
|
|
26
|
+
const signatureMap = new Map();
|
|
27
|
+
for (const id of unprunedIds) {
|
|
28
|
+
const metadata = state.toolParameters.get(id);
|
|
29
|
+
if (!metadata) {
|
|
30
|
+
// logger.warn(`Missing metadata for tool call ID: ${id}`)
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
// Skip protected tools
|
|
34
|
+
if (protectedTools.includes(metadata.tool)) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const filePath = getFilePathFromParameters(metadata.parameters);
|
|
38
|
+
if (isProtectedFilePath(filePath, config.protectedFilePatterns)) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const signature = createToolSignature(metadata.tool, metadata.parameters);
|
|
42
|
+
if (!signatureMap.has(signature)) {
|
|
43
|
+
signatureMap.set(signature, []);
|
|
44
|
+
}
|
|
45
|
+
signatureMap.get(signature).push(id);
|
|
46
|
+
}
|
|
47
|
+
// Find duplicates - keep only the most recent (last) in each group
|
|
48
|
+
const newPruneIds = [];
|
|
49
|
+
for (const [, ids] of signatureMap.entries()) {
|
|
50
|
+
if (ids.length > 1) {
|
|
51
|
+
// All except last (most recent) should be pruned
|
|
52
|
+
const idsToRemove = ids.slice(0, -1);
|
|
53
|
+
newPruneIds.push(...idsToRemove);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
state.stats.totalPruneTokens += calculateTokensSaved(state, messages, newPruneIds);
|
|
57
|
+
if (newPruneIds.length > 0) {
|
|
58
|
+
state.prune.toolIds.push(...newPruneIds);
|
|
59
|
+
logger.debug(`Marked ${newPruneIds.length} duplicate tool calls for pruning`);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
function createToolSignature(tool, parameters) {
|
|
63
|
+
if (!parameters) {
|
|
64
|
+
return tool;
|
|
65
|
+
}
|
|
66
|
+
const normalized = normalizeParameters(parameters);
|
|
67
|
+
const sorted = sortObjectKeys(normalized);
|
|
68
|
+
return `${tool}::${JSON.stringify(sorted)}`;
|
|
69
|
+
}
|
|
70
|
+
function normalizeParameters(params) {
|
|
71
|
+
if (typeof params !== "object" || params === null)
|
|
72
|
+
return params;
|
|
73
|
+
if (Array.isArray(params))
|
|
74
|
+
return params;
|
|
75
|
+
const normalized = {};
|
|
76
|
+
for (const [key, value] of Object.entries(params)) {
|
|
77
|
+
if (value !== undefined && value !== null) {
|
|
78
|
+
normalized[key] = value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return normalized;
|
|
82
|
+
}
|
|
83
|
+
function sortObjectKeys(obj) {
|
|
84
|
+
if (typeof obj !== "object" || obj === null)
|
|
85
|
+
return obj;
|
|
86
|
+
if (Array.isArray(obj))
|
|
87
|
+
return obj.map(sortObjectKeys);
|
|
88
|
+
const sorted = {};
|
|
89
|
+
for (const key of Object.keys(obj).sort()) {
|
|
90
|
+
sorted[key] = sortObjectKeys(obj[key]);
|
|
91
|
+
}
|
|
92
|
+
return sorted;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=deduplication.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deduplication.js","sourceRoot":"","sources":["../../../lib/strategies/deduplication.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PluginConfig } from "../config";
|
|
2
|
+
import { Logger } from "../logger";
|
|
3
|
+
import type { SessionState, WithParts } from "../state";
|
|
4
|
+
/**
|
|
5
|
+
* Head-Tail Truncation Strategy
|
|
6
|
+
*
|
|
7
|
+
* Preserves the first 20% (head) and last 30% (tail) of tool outputs,
|
|
8
|
+
* removing the middle section which is often less important due to
|
|
9
|
+
* the "Lost in the Middle" phenomenon in LLMs.
|
|
10
|
+
*
|
|
11
|
+
* This preserves real content unlike placeholder compression which
|
|
12
|
+
* replaces everything with a generic hint.
|
|
13
|
+
*/
|
|
14
|
+
export declare function headTailTruncation(state: SessionState, logger: Logger, config: PluginConfig, messages: WithParts[]): void;
|
|
15
|
+
//# sourceMappingURL=head-tail-truncation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"head-tail-truncation.d.ts","sourceRoot":"","sources":["../../../lib/strategies/head-tail-truncation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAmDvD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAC9B,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,SAAS,EAAE,GACtB,IAAI,CAiHN"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { isMessageCompacted } from "../shared-utils";
|
|
2
|
+
import { countTokens } from "./utils";
|
|
3
|
+
/**
|
|
4
|
+
* Icon mapping by tool type for truncation markers
|
|
5
|
+
*/
|
|
6
|
+
const TOOL_ICONS = {
|
|
7
|
+
// File content
|
|
8
|
+
read: "📄",
|
|
9
|
+
"pdf-reader_read_pdf": "📄",
|
|
10
|
+
// Search results
|
|
11
|
+
glob: "🔍",
|
|
12
|
+
grep: "🔍",
|
|
13
|
+
"ddg-search_search": "🔍",
|
|
14
|
+
google_search: "🔍",
|
|
15
|
+
// Command output
|
|
16
|
+
bash: "💻",
|
|
17
|
+
// Web content
|
|
18
|
+
webfetch: "🌐",
|
|
19
|
+
"url-context-mcp_analyze_urls": "🌐",
|
|
20
|
+
"url-context-mcp_google_search": "🌐",
|
|
21
|
+
// Data/Excel
|
|
22
|
+
excel_read_data_from_excel: "📊",
|
|
23
|
+
// Default
|
|
24
|
+
default: "📋",
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Get the appropriate icon for a tool
|
|
28
|
+
*/
|
|
29
|
+
function getToolIcon(toolName) {
|
|
30
|
+
return TOOL_ICONS[toolName] || TOOL_ICONS.default;
|
|
31
|
+
}
|
|
32
|
+
// Tools that should NEVER be truncated (their output is critical)
|
|
33
|
+
const PROTECTED_TOOLS = new Set([
|
|
34
|
+
"write",
|
|
35
|
+
"edit",
|
|
36
|
+
"todowrite",
|
|
37
|
+
"todoread",
|
|
38
|
+
"discard",
|
|
39
|
+
"extract",
|
|
40
|
+
"task",
|
|
41
|
+
"question",
|
|
42
|
+
"batch",
|
|
43
|
+
"plan_enter",
|
|
44
|
+
"plan_exit",
|
|
45
|
+
"skill",
|
|
46
|
+
]);
|
|
47
|
+
/**
|
|
48
|
+
* Head-Tail Truncation Strategy
|
|
49
|
+
*
|
|
50
|
+
* Preserves the first 20% (head) and last 30% (tail) of tool outputs,
|
|
51
|
+
* removing the middle section which is often less important due to
|
|
52
|
+
* the "Lost in the Middle" phenomenon in LLMs.
|
|
53
|
+
*
|
|
54
|
+
* This preserves real content unlike placeholder compression which
|
|
55
|
+
* replaces everything with a generic hint.
|
|
56
|
+
*/
|
|
57
|
+
export function headTailTruncation(state, logger, config, messages) {
|
|
58
|
+
const strategyConfig = config.strategies.headTailTruncation;
|
|
59
|
+
if (!strategyConfig?.enabled) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const delayTurns = strategyConfig.delayTurns ?? 2;
|
|
63
|
+
const headRatio = strategyConfig.headRatio ?? 0.2;
|
|
64
|
+
const tailRatio = strategyConfig.tailRatio ?? 0.3;
|
|
65
|
+
const minOutputTokens = 200; // Don't truncate small outputs
|
|
66
|
+
const additionalProtected = new Set(strategyConfig.protectedTools ?? []);
|
|
67
|
+
let totalTokensSaved = 0;
|
|
68
|
+
let truncatedCount = 0;
|
|
69
|
+
const totalMessages = messages.length;
|
|
70
|
+
for (let i = 0; i < messages.length; i++) {
|
|
71
|
+
const msg = messages[i];
|
|
72
|
+
// Skip compacted messages
|
|
73
|
+
if (isMessageCompacted(state, msg)) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
// Calculate turn age (0 = most recent)
|
|
77
|
+
const turnAge = totalMessages - 1 - i;
|
|
78
|
+
// Skip recent turns
|
|
79
|
+
if (turnAge < delayTurns) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
// Process tool parts
|
|
83
|
+
const parts = Array.isArray(msg.parts) ? msg.parts : [];
|
|
84
|
+
for (const part of parts) {
|
|
85
|
+
// Only process tool parts with completed status
|
|
86
|
+
if (part.type !== "tool") {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const toolName = part.tool;
|
|
90
|
+
const toolState = part.state;
|
|
91
|
+
if (!toolName || !toolState)
|
|
92
|
+
continue;
|
|
93
|
+
// Skip if not completed
|
|
94
|
+
if (toolState.status !== "completed") {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
// Skip protected tools
|
|
98
|
+
if (PROTECTED_TOOLS.has(toolName) || additionalProtected.has(toolName)) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
// Get the output
|
|
102
|
+
const output = toolState.output;
|
|
103
|
+
if (output === undefined || output === null) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const outputStr = typeof output === "string" ? output : JSON.stringify(output);
|
|
107
|
+
// Skip already truncated outputs
|
|
108
|
+
if (outputStr.includes("[...") && outputStr.includes("tokens truncated...]")) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const outputTokens = countTokens(outputStr);
|
|
112
|
+
// Skip small outputs
|
|
113
|
+
if (outputTokens < minOutputTokens) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const icon = getToolIcon(toolName);
|
|
117
|
+
// Calculate head and tail sizes in characters
|
|
118
|
+
const headSize = Math.floor(outputStr.length * headRatio);
|
|
119
|
+
const tailSize = Math.floor(outputStr.length * tailRatio);
|
|
120
|
+
// Ensure we're actually truncating something meaningful
|
|
121
|
+
if (headSize + tailSize >= outputStr.length) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const head = outputStr.slice(0, headSize);
|
|
125
|
+
const tail = outputStr.slice(-tailSize);
|
|
126
|
+
const middleTokens = countTokens(outputStr.slice(headSize, -tailSize));
|
|
127
|
+
// Create truncation marker
|
|
128
|
+
const marker = `\n\n[...${icon} ${middleTokens} tokens truncated...]\n\n`;
|
|
129
|
+
// Replace output with truncated version
|
|
130
|
+
toolState.output = head + marker + tail;
|
|
131
|
+
const newTokens = countTokens(toolState.output);
|
|
132
|
+
const saved = outputTokens - newTokens;
|
|
133
|
+
if (saved > 0) {
|
|
134
|
+
totalTokensSaved += saved;
|
|
135
|
+
truncatedCount++;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (truncatedCount > 0) {
|
|
140
|
+
state.stats.totalPruneTokens += totalTokensSaved;
|
|
141
|
+
logger.debug(`Head-tail truncation: truncated ${truncatedCount} tool outputs (estimated ${totalTokensSaved} tokens saved)`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=head-tail-truncation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"head-tail-truncation.js","sourceRoot":"","sources":["../../../lib/strategies/head-tail-truncation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { deduplicate } from "./deduplication";
|
|
2
|
+
export { createDiscardTool, createExtractTool } from "./tools";
|
|
3
|
+
export { supersedeWrites } from "./supersede-writes";
|
|
4
|
+
export { purgeErrors } from "./purge-errors";
|
|
5
|
+
export { pruneThinking } from "./prune-thinking";
|
|
6
|
+
export { placeholderCompression } from "./placeholder-compression";
|
|
7
|
+
export { headTailTruncation } from "./head-tail-truncation";
|
|
8
|
+
export { readConsolidation } from "./read-consolidation";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/strategies/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { deduplicate } from "./deduplication";
|
|
2
|
+
export { createDiscardTool, createExtractTool } from "./tools";
|
|
3
|
+
export { supersedeWrites } from "./supersede-writes";
|
|
4
|
+
export { purgeErrors } from "./purge-errors";
|
|
5
|
+
export { pruneThinking } from "./prune-thinking";
|
|
6
|
+
export { placeholderCompression } from "./placeholder-compression";
|
|
7
|
+
export { headTailTruncation } from "./head-tail-truncation";
|
|
8
|
+
export { readConsolidation } from "./read-consolidation";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../lib/strategies/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { PluginConfig } from "../config";
|
|
2
|
+
import { Logger } from "../logger";
|
|
3
|
+
import type { SessionState, WithParts } from "../state";
|
|
4
|
+
export declare const placeholderCompression: (state: SessionState, logger: Logger, config: PluginConfig, messages: WithParts[]) => void;
|
|
5
|
+
//# sourceMappingURL=placeholder-compression.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placeholder-compression.d.ts","sourceRoot":"","sources":["../../../lib/strategies/placeholder-compression.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAyEvD,eAAO,MAAM,sBAAsB,GAC/B,OAAO,YAAY,EACnB,QAAQ,MAAM,EACd,QAAQ,YAAY,EACpB,UAAU,SAAS,EAAE,KACtB,IAuGF,CAAA"}
|