@tuanhung303/opencode-dcp 2.0.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 +249 -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 +69 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +754 -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 +121 -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 +33 -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/index.d.ts +7 -0
- package/dist/lib/strategies/index.d.ts.map +1 -0
- package/dist/lib/strategies/index.js +7 -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/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 +63 -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,33 @@
|
|
|
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 SessionState {
|
|
22
|
+
sessionId: string | null;
|
|
23
|
+
isSubAgent: boolean;
|
|
24
|
+
prune: Prune;
|
|
25
|
+
stats: SessionStats;
|
|
26
|
+
toolParameters: Map<string, ToolParameterEntry>;
|
|
27
|
+
nudgeCounter: number;
|
|
28
|
+
lastToolPrune: boolean;
|
|
29
|
+
lastCompaction: number;
|
|
30
|
+
currentTurn: number;
|
|
31
|
+
variant: string | undefined;
|
|
32
|
+
}
|
|
33
|
+
//# 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,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;CAC9B"}
|
|
@@ -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,7 @@
|
|
|
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
|
+
//# 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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
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
|
+
//# 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"}
|
|
@@ -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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { isMessageCompacted } from "../shared-utils";
|
|
2
|
+
import { countTokens } from "./utils";
|
|
3
|
+
/**
|
|
4
|
+
* Placeholder Compression Strategy
|
|
5
|
+
*
|
|
6
|
+
* Replaces verbose tool outputs with actionable placeholder hints while preserving
|
|
7
|
+
* the tool call structure (name + input) as breadcrumbs for the agent.
|
|
8
|
+
*
|
|
9
|
+
* This allows the agent to see what actions were taken and re-execute if needed,
|
|
10
|
+
* while dramatically reducing context size.
|
|
11
|
+
*
|
|
12
|
+
* Based on: https://www.hadijaveed.me/2025/11/26/escaping-context-amnesia-ai-agents/
|
|
13
|
+
*/
|
|
14
|
+
// Tool-specific placeholder templates
|
|
15
|
+
const PLACEHOLDER_TEMPLATES = {
|
|
16
|
+
read: (input) => `[File read previously. Read again if needed: ${input?.filePath || input?.path || 'unknown'}]`,
|
|
17
|
+
glob: (input) => `[Glob search completed for pattern: ${input?.pattern || 'unknown'}. Search again if needed]`,
|
|
18
|
+
grep: (input) => `[Content search completed for: ${input?.pattern || 'unknown'}. Search again if needed]`,
|
|
19
|
+
bash: (input) => `[Command executed: ${truncate(input?.command || input?.description || 'unknown', 80)}. Re-run if needed]`,
|
|
20
|
+
webfetch: (input) => `[URL fetched: ${truncate(input?.url || 'unknown', 60)}. Fetch again if needed]`,
|
|
21
|
+
"ddg-search_search": (input) => `[Search completed for: ${input?.query || 'unknown'}. Search again for current results]`,
|
|
22
|
+
"ddg-search_fetch_content": (input) => `[Content fetched from: ${truncate(input?.url || 'unknown', 60)}]`,
|
|
23
|
+
"google_search": (input) => `[Google search completed for: ${input?.query || 'unknown'}. Search again if needed]`,
|
|
24
|
+
"context7_query-docs": (input) => `[Docs queried for: ${input?.query || 'unknown'}. Query again if needed]`,
|
|
25
|
+
"context7_resolve-library-id": (input) => `[Library resolved: ${input?.libraryName || 'unknown'}. Resolve again if needed]`,
|
|
26
|
+
"excel_read_data_from_excel": (input) => `[Excel data read from: ${input?.filepath || 'unknown'}. Read again if needed]`,
|
|
27
|
+
"pdf-reader_read_pdf": () => `[PDF content read. Read again if needed]`,
|
|
28
|
+
"url-context-mcp_analyze_urls": (input) => `[URLs analyzed. Analyze again if needed: ${truncate(JSON.stringify(input?.urls || []), 60)}]`,
|
|
29
|
+
"url-context-mcp_google_search": (input) => `[Search completed for: ${input?.query || 'unknown'}. Search again if needed]`,
|
|
30
|
+
list: (input) => `[Directory listed: ${input?.path || 'current'}. List again if needed]`,
|
|
31
|
+
codesearch: (input) => `[Code search completed for: ${input?.query || 'unknown'}. Search again if needed]`,
|
|
32
|
+
websearch: (input) => `[Web search completed for: ${input?.query || 'unknown'}. Search again if needed]`,
|
|
33
|
+
};
|
|
34
|
+
// Default placeholder for tools not in the template list
|
|
35
|
+
const DEFAULT_PLACEHOLDER = (toolName, input) => {
|
|
36
|
+
const inputHint = input ? ` with: ${truncate(JSON.stringify(input), 80)}` : '';
|
|
37
|
+
return `[${toolName} executed${inputHint}. Re-run if needed]`;
|
|
38
|
+
};
|
|
39
|
+
// Tools that should NEVER be compressed (their output is critical)
|
|
40
|
+
const PROTECTED_TOOLS = new Set([
|
|
41
|
+
'write',
|
|
42
|
+
'edit',
|
|
43
|
+
'todowrite',
|
|
44
|
+
'todoread',
|
|
45
|
+
'discard',
|
|
46
|
+
'extract',
|
|
47
|
+
'task',
|
|
48
|
+
'question',
|
|
49
|
+
'batch',
|
|
50
|
+
'plan_enter',
|
|
51
|
+
'plan_exit',
|
|
52
|
+
'skill',
|
|
53
|
+
]);
|
|
54
|
+
// Tools whose output should be preserved for schema/structure understanding
|
|
55
|
+
const SCHEMA_TOOLS = new Set([
|
|
56
|
+
'excel_get_workbook_metadata',
|
|
57
|
+
'excel_get_data_validation_info',
|
|
58
|
+
'word-document-server_get_document_outline',
|
|
59
|
+
'word-document-server_get_document_info',
|
|
60
|
+
]);
|
|
61
|
+
function truncate(str, maxLen) {
|
|
62
|
+
if (!str)
|
|
63
|
+
return 'unknown';
|
|
64
|
+
if (str.length <= maxLen)
|
|
65
|
+
return str;
|
|
66
|
+
return str.slice(0, maxLen - 3) + '...';
|
|
67
|
+
}
|
|
68
|
+
export const placeholderCompression = (state, logger, config, messages) => {
|
|
69
|
+
const compressionConfig = config.strategies.placeholderCompression;
|
|
70
|
+
if (!compressionConfig?.enabled) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const delayTurns = compressionConfig.delayTurns ?? 2;
|
|
74
|
+
const minOutputTokens = compressionConfig.minOutputTokens ?? 100;
|
|
75
|
+
const additionalProtected = new Set(compressionConfig.protectedTools ?? []);
|
|
76
|
+
let compressedCount = 0;
|
|
77
|
+
let tokensSaved = 0;
|
|
78
|
+
// Calculate current turn from messages
|
|
79
|
+
const totalMessages = messages.length;
|
|
80
|
+
for (let i = 0; i < messages.length; i++) {
|
|
81
|
+
const msg = messages[i];
|
|
82
|
+
// Skip compacted messages
|
|
83
|
+
if (isMessageCompacted(state, msg)) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
// Calculate turn age (0 = most recent)
|
|
87
|
+
const turnAge = totalMessages - 1 - i;
|
|
88
|
+
// Skip recent turns to preserve cache and allow agent to reference
|
|
89
|
+
if (turnAge < delayTurns) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
// Process tool parts
|
|
93
|
+
const parts = Array.isArray(msg.parts) ? msg.parts : [];
|
|
94
|
+
for (const part of parts) {
|
|
95
|
+
// Only process tool parts with completed status
|
|
96
|
+
if (part.type !== "tool") {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const toolName = part.tool;
|
|
100
|
+
const toolState = part.state;
|
|
101
|
+
if (!toolName || !toolState)
|
|
102
|
+
continue;
|
|
103
|
+
// Skip if not completed (errors handled by purgeErrors)
|
|
104
|
+
if (toolState.status !== "completed") {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
// Skip protected tools
|
|
108
|
+
if (PROTECTED_TOOLS.has(toolName) || additionalProtected.has(toolName)) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
// Skip schema tools
|
|
112
|
+
if (SCHEMA_TOOLS.has(toolName)) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
// Get the output
|
|
116
|
+
const output = toolState.output;
|
|
117
|
+
if (output === undefined || output === null) {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
// Calculate output size
|
|
121
|
+
const outputStr = typeof output === 'string' ? output : JSON.stringify(output);
|
|
122
|
+
const outputTokens = countTokens(outputStr);
|
|
123
|
+
// Only compress if output is large enough
|
|
124
|
+
if (outputTokens < minOutputTokens) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
// Generate placeholder
|
|
128
|
+
const template = PLACEHOLDER_TEMPLATES[toolName];
|
|
129
|
+
const placeholder = template
|
|
130
|
+
? template(toolState.input)
|
|
131
|
+
: DEFAULT_PLACEHOLDER(toolName, toolState.input);
|
|
132
|
+
// Calculate savings
|
|
133
|
+
const placeholderTokens = countTokens(placeholder);
|
|
134
|
+
const saved = outputTokens - placeholderTokens;
|
|
135
|
+
if (saved > 0) {
|
|
136
|
+
// Replace output with placeholder
|
|
137
|
+
toolState.output = placeholder;
|
|
138
|
+
tokensSaved += saved;
|
|
139
|
+
compressedCount++;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (compressedCount > 0) {
|
|
144
|
+
state.stats.totalPruneTokens += tokensSaved;
|
|
145
|
+
logger.debug(`Placeholder compression: compressed ${compressedCount} tool outputs (estimated ${tokensSaved} tokens saved)`);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=placeholder-compression.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placeholder-compression.js","sourceRoot":"","sources":["../../../lib/strategies/placeholder-compression.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
|
+
* Prune Thinking strategy - removes extended thinking tokens from assistant messages
|
|
6
|
+
* after they are older than a configurable number of turns.
|
|
7
|
+
*
|
|
8
|
+
* Thinking tokens (Claude's <thinking> blocks, OpenAI's reasoning field) consume
|
|
9
|
+
* significant context but provide no utility after the response is generated.
|
|
10
|
+
*
|
|
11
|
+
* This strategy strips thinking content from older messages to save context space.
|
|
12
|
+
* Recent turns are preserved to maintain cache efficiency.
|
|
13
|
+
*/
|
|
14
|
+
export declare const pruneThinking: (state: SessionState, logger: Logger, config: PluginConfig, messages: WithParts[]) => void;
|
|
15
|
+
//# sourceMappingURL=prune-thinking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune-thinking.d.ts","sourceRoot":"","sources":["../../../lib/strategies/prune-thinking.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;AAEvD;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,GACtB,OAAO,YAAY,EACnB,QAAQ,MAAM,EACd,QAAQ,YAAY,EACpB,UAAU,SAAS,EAAE,KACtB,IA2EF,CAAA"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prune Thinking strategy - removes extended thinking tokens from assistant messages
|
|
3
|
+
* after they are older than a configurable number of turns.
|
|
4
|
+
*
|
|
5
|
+
* Thinking tokens (Claude's <thinking> blocks, OpenAI's reasoning field) consume
|
|
6
|
+
* significant context but provide no utility after the response is generated.
|
|
7
|
+
*
|
|
8
|
+
* This strategy strips thinking content from older messages to save context space.
|
|
9
|
+
* Recent turns are preserved to maintain cache efficiency.
|
|
10
|
+
*/
|
|
11
|
+
export const pruneThinking = (state, logger, config, messages) => {
|
|
12
|
+
if (!config.strategies.pruneThinking?.enabled) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const delayTurns = config.strategies.pruneThinking.delayTurns ?? 1;
|
|
16
|
+
let prunedCount = 0;
|
|
17
|
+
let tokensSaved = 0;
|
|
18
|
+
for (let i = 0; i < messages.length; i++) {
|
|
19
|
+
const msg = messages[i];
|
|
20
|
+
// Only process assistant messages
|
|
21
|
+
if (msg.info.role !== "assistant") {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
// Calculate turn age (messages are in chronological order)
|
|
25
|
+
// Use message index as a proxy for turn age
|
|
26
|
+
const turnAge = messages.length - 1 - i;
|
|
27
|
+
// Skip recent turns to preserve cache
|
|
28
|
+
if (turnAge < delayTurns) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
// Handle array content (parts array)
|
|
32
|
+
if (Array.isArray(msg.parts)) {
|
|
33
|
+
const originalLength = msg.parts.length;
|
|
34
|
+
// Filter out thinking blocks
|
|
35
|
+
msg.parts = msg.parts.filter((part) => {
|
|
36
|
+
// Anthropic thinking block format
|
|
37
|
+
if (part.type === "thinking") {
|
|
38
|
+
tokensSaved += estimateTokens(part.thinking || "");
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
// Text part that contains thinking tags
|
|
42
|
+
if (part.type === "text" && typeof part.text === "string") {
|
|
43
|
+
const thinkingMatch = part.text.match(/<thinking>[\s\S]*?<\/thinking>/g);
|
|
44
|
+
if (thinkingMatch) {
|
|
45
|
+
for (const match of thinkingMatch) {
|
|
46
|
+
tokensSaved += estimateTokens(match);
|
|
47
|
+
}
|
|
48
|
+
part.text = part.text.replace(/<thinking>[\s\S]*?<\/thinking>/g, "").trim();
|
|
49
|
+
// Remove empty text parts
|
|
50
|
+
if (!part.text) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
});
|
|
57
|
+
if (msg.parts.length < originalLength) {
|
|
58
|
+
prunedCount++;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Handle OpenAI reasoning field on the info object
|
|
62
|
+
if (msg.info.reasoning) {
|
|
63
|
+
tokensSaved += estimateTokens(msg.info.reasoning);
|
|
64
|
+
delete msg.info.reasoning;
|
|
65
|
+
prunedCount++;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (prunedCount > 0) {
|
|
69
|
+
state.stats.totalPruneTokens += tokensSaved;
|
|
70
|
+
logger.debug(`Pruned thinking tokens from ${prunedCount} messages (estimated ${tokensSaved} tokens saved)`);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Rough token estimation (1 token ≈ 4 characters for English text)
|
|
75
|
+
*/
|
|
76
|
+
function estimateTokens(text) {
|
|
77
|
+
return Math.ceil(text.length / 4);
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=prune-thinking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune-thinking.js","sourceRoot":"","sources":["../../../lib/strategies/prune-thinking.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CACzB,KAAmB,EACnB,MAAc,EACd,MAAoB,EACpB,QAAqB,EACjB,EAAE;IACN,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,EAAE,OAAO,EAAE,CAAC;QAC5C,OAAM;IACV,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,UAAU,IAAI,CAAC,CAAA;IAClE,IAAI,WAAW,GAAG,CAAC,CAAA;IACnB,IAAI,WAAW,GAAG,CAAC,CAAA;IAEnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;QAEvB,kCAAkC;QAClC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAChC,SAAQ;QACZ,CAAC;QAED,2DAA2D;QAC3D,4CAA4C;QAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAA;QAEvC,sCAAsC;QACtC,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;YACvB,SAAQ;QACZ,CAAC;QAED,qCAAqC;QACrC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAA;YAEvC,6BAA6B;YAC7B,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAS,EAAE,EAAE;gBACvC,kCAAkC;gBAClC,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBAC3B,WAAW,IAAI,cAAc,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAA;oBAClD,OAAO,KAAK,CAAA;gBAChB,CAAC;gBAED,wCAAwC;gBACxC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACxD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAA;oBACxE,IAAI,aAAa,EAAE,CAAC;wBAChB,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;4BAChC,WAAW,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;wBACxC,CAAC;wBACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,iCAAiC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;wBAC3E,0BAA0B;wBAC1B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;4BACb,OAAO,KAAK,CAAA;wBAChB,CAAC;oBACL,CAAC;gBACL,CAAC;gBAED,OAAO,IAAI,CAAA;YACf,CAAC,CAAC,CAAA;YAEF,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;gBACpC,WAAW,EAAE,CAAA;YACjB,CAAC;QACL,CAAC;QAED,mDAAmD;QACnD,IAAK,GAAG,CAAC,IAAY,CAAC,SAAS,EAAE,CAAC;YAC9B,WAAW,IAAI,cAAc,CAAE,GAAG,CAAC,IAAY,CAAC,SAAS,CAAC,CAAA;YAC1D,OAAQ,GAAG,CAAC,IAAY,CAAC,SAAS,CAAA;YAClC,WAAW,EAAE,CAAA;QACjB,CAAC;IACL,CAAC;IAED,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QAClB,KAAK,CAAC,KAAK,CAAC,gBAAgB,IAAI,WAAW,CAAA;QAC3C,MAAM,CAAC,KAAK,CACR,+BAA+B,WAAW,wBAAwB,WAAW,gBAAgB,CAChG,CAAA;IACL,CAAC;AACL,CAAC,CAAA;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,IAAY;IAChC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AACrC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PluginConfig } from "../config";
|
|
2
|
+
import { Logger } from "../logger";
|
|
3
|
+
import type { SessionState, WithParts } from "../state";
|
|
4
|
+
/**
|
|
5
|
+
* Purge Errors strategy - prunes tool inputs for tools that errored
|
|
6
|
+
* after they are older than a configurable number of turns.
|
|
7
|
+
* The error message is preserved, but the (potentially large) inputs
|
|
8
|
+
* are removed to save context.
|
|
9
|
+
*
|
|
10
|
+
* Modifies the session state in place to add pruned tool call IDs.
|
|
11
|
+
*/
|
|
12
|
+
export declare const purgeErrors: (state: SessionState, logger: Logger, config: PluginConfig, messages: WithParts[]) => void;
|
|
13
|
+
//# sourceMappingURL=purge-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purge-errors.d.ts","sourceRoot":"","sources":["../../../lib/strategies/purge-errors.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;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GACpB,OAAO,YAAY,EACnB,QAAQ,MAAM,EACd,QAAQ,YAAY,EACpB,UAAU,SAAS,EAAE,KACtB,IA2DF,CAAA"}
|