@tuanhung303/opencode-acp 0.0.1
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 +166 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +79 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/commands/budget.d.ts +15 -0
- package/dist/lib/commands/budget.d.ts.map +1 -0
- package/dist/lib/commands/budget.js +120 -0
- package/dist/lib/commands/budget.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 +28 -0
- package/dist/lib/commands/help.js.map +1 -0
- package/dist/lib/commands/protected.d.ts +17 -0
- package/dist/lib/commands/protected.d.ts.map +1 -0
- package/dist/lib/commands/protected.js +50 -0
- package/dist/lib/commands/protected.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 +64 -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 +194 -0
- package/dist/lib/commands/sweep.js.map +1 -0
- package/dist/lib/config-schema.d.ts +119 -0
- package/dist/lib/config-schema.d.ts.map +1 -0
- package/dist/lib/config-schema.js +97 -0
- package/dist/lib/config-schema.js.map +1 -0
- package/dist/lib/config.d.ts +59 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +426 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/hooks.d.ts +31 -0
- package/dist/lib/hooks.d.ts.map +1 -0
- package/dist/lib/hooks.js +230 -0
- package/dist/lib/hooks.js.map +1 -0
- package/dist/lib/logger.d.ts +55 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +230 -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 +10 -0
- package/dist/lib/messages/inject.d.ts.map +1 -0
- package/dist/lib/messages/inject.js +10 -0
- package/dist/lib/messages/inject.js.map +1 -0
- package/dist/lib/messages/prune.d.ts +13 -0
- package/dist/lib/messages/prune.d.ts.map +1 -0
- package/dist/lib/messages/prune.js +173 -0
- package/dist/lib/messages/prune.js.map +1 -0
- package/dist/lib/messages/utils.d.ts +43 -0
- package/dist/lib/messages/utils.d.ts.map +1 -0
- package/dist/lib/messages/utils.js +262 -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 +54 -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 +56 -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 +29 -0
- package/dist/lib/prompts/index.js.map +1 -0
- package/dist/lib/prompts/restore-tool-spec.d.ts +2 -0
- package/dist/lib/prompts/restore-tool-spec.d.ts.map +1 -0
- package/dist/lib/prompts/restore-tool-spec.js +37 -0
- package/dist/lib/prompts/restore-tool-spec.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 +65 -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 +55 -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 +55 -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/safe-execute.d.ts +20 -0
- package/dist/lib/safe-execute.d.ts.map +1 -0
- package/dist/lib/safe-execute.js +38 -0
- package/dist/lib/safe-execute.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 +27 -0
- package/dist/lib/state/persistence.d.ts.map +1 -0
- package/dist/lib/state/persistence.js +165 -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 +166 -0
- package/dist/lib/state/state.js.map +1 -0
- package/dist/lib/state/tool-cache.d.ts +15 -0
- package/dist/lib/state/tool-cache.d.ts.map +1 -0
- package/dist/lib/state/tool-cache.js +99 -0
- package/dist/lib/state/tool-cache.js.map +1 -0
- package/dist/lib/state/types.d.ts +83 -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 +11 -0
- package/dist/lib/strategies/deduplication.d.ts.map +1 -0
- package/dist/lib/strategies/deduplication.js +178 -0
- package/dist/lib/strategies/deduplication.js.map +1 -0
- package/dist/lib/strategies/index.d.ts +5 -0
- package/dist/lib/strategies/index.d.ts.map +1 -0
- package/dist/lib/strategies/index.js +5 -0
- package/dist/lib/strategies/index.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 +62 -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 +90 -0
- package/dist/lib/strategies/supersede-writes.js.map +1 -0
- package/dist/lib/strategies/tools.d.ts +15 -0
- package/dist/lib/strategies/tools.d.ts.map +1 -0
- package/dist/lib/strategies/tools.js +288 -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 +12 -0
- package/dist/lib/ui/notification.d.ts.map +1 -0
- package/dist/lib/ui/notification.js +81 -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 +113 -0
- package/dist/lib/ui/utils.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State persistence module for ACP plugin.
|
|
3
|
+
* Persists pruned tool IDs across sessions so they survive OpenCode restarts.
|
|
4
|
+
* Storage location: ~/.local/share/opencode/storage/plugin/acp/{sessionId}.json
|
|
5
|
+
*
|
|
6
|
+
* Uses atomic writes (temp file + rename) to prevent data corruption.
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from "fs/promises";
|
|
9
|
+
import { existsSync } from "fs";
|
|
10
|
+
import { homedir } from "os";
|
|
11
|
+
import { join } from "path";
|
|
12
|
+
const STORAGE_DIR = join(homedir(), ".local", "share", "opencode", "storage", "plugin", "acp");
|
|
13
|
+
// Write lock to prevent concurrent writes to the same file
|
|
14
|
+
const writeLocks = new Map();
|
|
15
|
+
async function ensureStorageDir() {
|
|
16
|
+
if (!existsSync(STORAGE_DIR)) {
|
|
17
|
+
await fs.mkdir(STORAGE_DIR, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function getSessionFilePath(sessionId) {
|
|
21
|
+
return join(STORAGE_DIR, `${sessionId}.json`);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Atomically write content to a file using temp file + rename pattern.
|
|
25
|
+
* This prevents data corruption from partial writes or crashes.
|
|
26
|
+
*/
|
|
27
|
+
async function atomicWriteFile(filePath, content) {
|
|
28
|
+
const tempPath = `${filePath}.tmp`;
|
|
29
|
+
try {
|
|
30
|
+
// Write to temp file first
|
|
31
|
+
await fs.writeFile(tempPath, content, "utf-8");
|
|
32
|
+
// Atomic rename (on POSIX systems, rename is atomic)
|
|
33
|
+
await fs.rename(tempPath, filePath);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
// Clean up temp file on failure
|
|
37
|
+
try {
|
|
38
|
+
await fs.unlink(tempPath);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Ignore cleanup errors
|
|
42
|
+
}
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Acquire a write lock for a specific file path.
|
|
48
|
+
* Ensures only one write operation happens at a time per file.
|
|
49
|
+
*/
|
|
50
|
+
async function withWriteLock(filePath, fn) {
|
|
51
|
+
// Wait for any existing write to complete
|
|
52
|
+
const existingLock = writeLocks.get(filePath);
|
|
53
|
+
if (existingLock) {
|
|
54
|
+
await existingLock.catch(() => { }); // Ignore errors from previous writes
|
|
55
|
+
}
|
|
56
|
+
// Create new lock
|
|
57
|
+
let resolve;
|
|
58
|
+
const lockPromise = new Promise((r) => {
|
|
59
|
+
resolve = r;
|
|
60
|
+
});
|
|
61
|
+
writeLocks.set(filePath, lockPromise);
|
|
62
|
+
try {
|
|
63
|
+
return await fn();
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
resolve();
|
|
67
|
+
writeLocks.delete(filePath);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export async function saveSessionState(sessionState, logger, sessionName) {
|
|
71
|
+
try {
|
|
72
|
+
if (!sessionState.sessionId) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
await ensureStorageDir();
|
|
76
|
+
const state = {
|
|
77
|
+
sessionName: sessionName,
|
|
78
|
+
prune: sessionState.prune,
|
|
79
|
+
stats: sessionState.stats,
|
|
80
|
+
lastUpdated: new Date().toISOString(),
|
|
81
|
+
// Hash-based discard system (convert Maps to objects)
|
|
82
|
+
hashToCallId: Object.fromEntries(sessionState.hashToCallId),
|
|
83
|
+
callIdToHash: Object.fromEntries(sessionState.callIdToHash),
|
|
84
|
+
discardHistory: sessionState.discardHistory,
|
|
85
|
+
};
|
|
86
|
+
const filePath = getSessionFilePath(sessionState.sessionId);
|
|
87
|
+
const content = JSON.stringify(state, null, 2);
|
|
88
|
+
// Use write lock and atomic write to prevent corruption
|
|
89
|
+
await withWriteLock(filePath, async () => {
|
|
90
|
+
await atomicWriteFile(filePath, content);
|
|
91
|
+
});
|
|
92
|
+
logger.info("Saved session state to disk", {
|
|
93
|
+
sessionId: sessionState.sessionId,
|
|
94
|
+
totalTokensSaved: state.stats.totalPruneTokens,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
logger.error("Failed to save session state", {
|
|
99
|
+
sessionId: sessionState.sessionId,
|
|
100
|
+
error: error?.message,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export async function loadSessionState(sessionId, logger) {
|
|
105
|
+
try {
|
|
106
|
+
const filePath = getSessionFilePath(sessionId);
|
|
107
|
+
if (!existsSync(filePath)) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
111
|
+
const state = JSON.parse(content);
|
|
112
|
+
if (!state || !state.prune || !Array.isArray(state.prune.toolIds) || !state.stats) {
|
|
113
|
+
logger.warn("Invalid session state file, ignoring", {
|
|
114
|
+
sessionId: sessionId,
|
|
115
|
+
});
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
logger.info("Loaded session state from disk", {
|
|
119
|
+
sessionId: sessionId,
|
|
120
|
+
});
|
|
121
|
+
return state;
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
logger.warn("Failed to load session state", {
|
|
125
|
+
sessionId: sessionId,
|
|
126
|
+
error: error?.message,
|
|
127
|
+
});
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export async function loadAllSessionStats(logger) {
|
|
132
|
+
const result = {
|
|
133
|
+
totalTokens: 0,
|
|
134
|
+
totalTools: 0,
|
|
135
|
+
sessionCount: 0,
|
|
136
|
+
};
|
|
137
|
+
try {
|
|
138
|
+
if (!existsSync(STORAGE_DIR)) {
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
const files = await fs.readdir(STORAGE_DIR);
|
|
142
|
+
const jsonFiles = files.filter((f) => f.endsWith(".json"));
|
|
143
|
+
for (const file of jsonFiles) {
|
|
144
|
+
try {
|
|
145
|
+
const filePath = join(STORAGE_DIR, file);
|
|
146
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
147
|
+
const state = JSON.parse(content);
|
|
148
|
+
if (state?.stats?.totalPruneTokens && state?.prune?.toolIds) {
|
|
149
|
+
result.totalTokens += state.stats.totalPruneTokens;
|
|
150
|
+
result.totalTools += state.prune.toolIds.length;
|
|
151
|
+
result.sessionCount++;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Skip invalid files
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
logger.debug("Loaded all-time stats", result);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
logger.warn("Failed to load all-time stats", { error: error?.message });
|
|
162
|
+
}
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=persistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.js","sourceRoot":"","sources":["../../../lib/state/persistence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SessionState, WithParts } from "./types";
|
|
2
|
+
import type { Logger } from "../logger";
|
|
3
|
+
export declare const checkSession: (client: any, state: SessionState, logger: Logger, messages: WithParts[]) => Promise<void>;
|
|
4
|
+
export declare function createSessionState(): SessionState;
|
|
5
|
+
export declare function resetSessionState(state: SessionState): void;
|
|
6
|
+
export declare function ensureSessionInitialized(client: any, state: SessionState, sessionId: string, logger: Logger, messages: WithParts[]): Promise<void>;
|
|
7
|
+
export declare function countTurns(state: SessionState, messages: WithParts[]): number;
|
|
8
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../lib/state/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAsB,SAAS,EAAmB,MAAM,SAAS,CAAA;AAC3F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAKvC,eAAO,MAAM,YAAY,GACrB,QAAQ,GAAG,EACX,OAAO,YAAY,EACnB,QAAQ,MAAM,EACd,UAAU,SAAS,EAAE,KACtB,OAAO,CAAC,IAAI,CA4Bd,CAAA;AAED,wBAAgB,kBAAkB,IAAI,YAAY,CAkCjD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAgC3D;AAED,wBAAsB,wBAAwB,CAC1C,MAAM,EAAE,GAAG,EACX,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,SAAS,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CAiDf;AAYD,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAc7E"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { loadSessionState } from "./persistence";
|
|
2
|
+
import { isSubAgentSession } from "./utils";
|
|
3
|
+
import { getLastUserMessage, isMessageCompacted } from "../shared-utils";
|
|
4
|
+
export const checkSession = async (client, state, logger, messages) => {
|
|
5
|
+
const lastUserMessage = getLastUserMessage(messages);
|
|
6
|
+
if (!lastUserMessage) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const lastSessionId = lastUserMessage.info.sessionID;
|
|
10
|
+
if (state.sessionId === null || state.sessionId !== lastSessionId) {
|
|
11
|
+
logger.info(`Session changed: ${state.sessionId} -> ${lastSessionId}`);
|
|
12
|
+
try {
|
|
13
|
+
await ensureSessionInitialized(client, state, lastSessionId, logger, messages);
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
logger.error("Failed to initialize session state", { error: err.message });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const lastCompactionTimestamp = findLastCompactionTimestamp(messages);
|
|
20
|
+
if (lastCompactionTimestamp > state.lastCompaction) {
|
|
21
|
+
state.lastCompaction = lastCompactionTimestamp;
|
|
22
|
+
state.toolParameters.clear();
|
|
23
|
+
state.prune.toolIds = [];
|
|
24
|
+
logger.info("Detected compaction from messages - cleared tool cache", {
|
|
25
|
+
timestamp: lastCompactionTimestamp,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
state.currentTurn = countTurns(state, messages);
|
|
29
|
+
};
|
|
30
|
+
export function createSessionState() {
|
|
31
|
+
return {
|
|
32
|
+
sessionId: null,
|
|
33
|
+
isSubAgent: false,
|
|
34
|
+
prune: {
|
|
35
|
+
toolIds: [],
|
|
36
|
+
},
|
|
37
|
+
stats: {
|
|
38
|
+
pruneTokenCounter: 0,
|
|
39
|
+
totalPruneTokens: 0,
|
|
40
|
+
pruneMessageCounter: 0,
|
|
41
|
+
totalPruneMessages: 0,
|
|
42
|
+
strategyStats: {
|
|
43
|
+
deduplication: { count: 0, tokens: 0 },
|
|
44
|
+
supersedeWrites: { count: 0, tokens: 0 },
|
|
45
|
+
purgeErrors: { count: 0, tokens: 0 },
|
|
46
|
+
manualDiscard: { count: 0, tokens: 0 },
|
|
47
|
+
extraction: { count: 0, tokens: 0 },
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
toolParameters: new Map(),
|
|
51
|
+
lastToolPrune: false,
|
|
52
|
+
lastCompaction: 0,
|
|
53
|
+
currentTurn: 0,
|
|
54
|
+
variant: undefined,
|
|
55
|
+
lastDiscardStats: null,
|
|
56
|
+
lastUserMessageId: null,
|
|
57
|
+
// Hash-based discard system
|
|
58
|
+
hashToCallId: new Map(),
|
|
59
|
+
callIdToHash: new Map(),
|
|
60
|
+
discardHistory: [],
|
|
61
|
+
// Soft prune cache for restore capability
|
|
62
|
+
softPrunedTools: new Map(),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function resetSessionState(state) {
|
|
66
|
+
state.sessionId = null;
|
|
67
|
+
state.isSubAgent = false;
|
|
68
|
+
state.prune = {
|
|
69
|
+
toolIds: [],
|
|
70
|
+
};
|
|
71
|
+
state.stats = {
|
|
72
|
+
pruneTokenCounter: 0,
|
|
73
|
+
totalPruneTokens: 0,
|
|
74
|
+
pruneMessageCounter: 0,
|
|
75
|
+
totalPruneMessages: 0,
|
|
76
|
+
strategyStats: {
|
|
77
|
+
deduplication: { count: 0, tokens: 0 },
|
|
78
|
+
supersedeWrites: { count: 0, tokens: 0 },
|
|
79
|
+
purgeErrors: { count: 0, tokens: 0 },
|
|
80
|
+
manualDiscard: { count: 0, tokens: 0 },
|
|
81
|
+
extraction: { count: 0, tokens: 0 },
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
state.toolParameters.clear();
|
|
85
|
+
state.lastToolPrune = false;
|
|
86
|
+
state.lastCompaction = 0;
|
|
87
|
+
state.currentTurn = 0;
|
|
88
|
+
state.variant = undefined;
|
|
89
|
+
state.lastDiscardStats = null;
|
|
90
|
+
state.lastUserMessageId = null;
|
|
91
|
+
// Hash-based discard system
|
|
92
|
+
state.hashToCallId.clear();
|
|
93
|
+
state.callIdToHash.clear();
|
|
94
|
+
state.discardHistory = [];
|
|
95
|
+
// Soft prune cache for restore capability
|
|
96
|
+
state.softPrunedTools.clear();
|
|
97
|
+
}
|
|
98
|
+
export async function ensureSessionInitialized(client, state, sessionId, logger, messages) {
|
|
99
|
+
if (state.sessionId === sessionId) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
logger.info("session ID = " + sessionId);
|
|
103
|
+
logger.info("Initializing session state", { sessionId: sessionId });
|
|
104
|
+
resetSessionState(state);
|
|
105
|
+
state.sessionId = sessionId;
|
|
106
|
+
const isSubAgent = await isSubAgentSession(client, sessionId);
|
|
107
|
+
state.isSubAgent = isSubAgent;
|
|
108
|
+
logger.info("isSubAgent = " + isSubAgent);
|
|
109
|
+
state.lastCompaction = findLastCompactionTimestamp(messages);
|
|
110
|
+
state.currentTurn = countTurns(state, messages);
|
|
111
|
+
const persisted = await loadSessionState(sessionId, logger);
|
|
112
|
+
if (persisted === null) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
state.prune = {
|
|
116
|
+
toolIds: persisted.prune.toolIds || [],
|
|
117
|
+
};
|
|
118
|
+
state.stats = {
|
|
119
|
+
pruneTokenCounter: persisted.stats?.pruneTokenCounter || 0,
|
|
120
|
+
totalPruneTokens: persisted.stats?.totalPruneTokens || 0,
|
|
121
|
+
pruneMessageCounter: persisted.stats?.pruneMessageCounter || 0,
|
|
122
|
+
totalPruneMessages: persisted.stats?.totalPruneMessages || 0,
|
|
123
|
+
strategyStats: persisted.stats?.strategyStats || {
|
|
124
|
+
deduplication: { count: 0, tokens: 0 },
|
|
125
|
+
supersedeWrites: { count: 0, tokens: 0 },
|
|
126
|
+
purgeErrors: { count: 0, tokens: 0 },
|
|
127
|
+
manualDiscard: { count: 0, tokens: 0 },
|
|
128
|
+
extraction: { count: 0, tokens: 0 },
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
// Restore hash-based discard system (convert objects back to Maps)
|
|
132
|
+
if (persisted.hashToCallId) {
|
|
133
|
+
state.hashToCallId = new Map(Object.entries(persisted.hashToCallId));
|
|
134
|
+
}
|
|
135
|
+
if (persisted.callIdToHash) {
|
|
136
|
+
state.callIdToHash = new Map(Object.entries(persisted.callIdToHash));
|
|
137
|
+
}
|
|
138
|
+
if (persisted.discardHistory) {
|
|
139
|
+
state.discardHistory = persisted.discardHistory;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function findLastCompactionTimestamp(messages) {
|
|
143
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
144
|
+
const msg = messages[i];
|
|
145
|
+
if (msg && msg.info.role === "assistant" && msg.info.summary === true) {
|
|
146
|
+
return msg.info.time.created;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return 0;
|
|
150
|
+
}
|
|
151
|
+
export function countTurns(state, messages) {
|
|
152
|
+
let turnCount = 0;
|
|
153
|
+
for (const msg of messages) {
|
|
154
|
+
if (isMessageCompacted(state, msg)) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const parts = Array.isArray(msg.parts) ? msg.parts : [];
|
|
158
|
+
for (const part of parts) {
|
|
159
|
+
if (part.type === "step-start") {
|
|
160
|
+
turnCount++;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return turnCount;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../lib/state/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
* Also generates stable hashes for each tool call.
|
|
7
|
+
*/
|
|
8
|
+
export declare function syncToolCache(state: SessionState, config: PluginConfig, logger: Logger, messages: WithParts[]): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Trim the tool parameters cache to prevent unbounded memory growth.
|
|
11
|
+
* Uses FIFO eviction - removes oldest entries first.
|
|
12
|
+
* Also cleans up corresponding hash mappings to prevent memory leaks.
|
|
13
|
+
*/
|
|
14
|
+
export declare function trimToolParametersCache(state: SessionState): void;
|
|
15
|
+
//# 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;AAMxC;;;GAGG;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,CAyFf;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAoBjE"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { isMessageCompacted } from "../shared-utils";
|
|
2
|
+
import { generateToolHash } from "../messages/utils";
|
|
3
|
+
const MAX_TOOL_CACHE_SIZE = 1000;
|
|
4
|
+
/**
|
|
5
|
+
* Sync tool parameters from OpenCode's session.messages() API.
|
|
6
|
+
* Also generates stable hashes for each tool call.
|
|
7
|
+
*/
|
|
8
|
+
export async function syncToolCache(state, config, logger, messages) {
|
|
9
|
+
try {
|
|
10
|
+
logger.info("Syncing tool parameters from OpenCode messages");
|
|
11
|
+
let turnCounter = 0;
|
|
12
|
+
for (const msg of messages) {
|
|
13
|
+
if (isMessageCompacted(state, msg)) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
const parts = Array.isArray(msg.parts) ? msg.parts : [];
|
|
17
|
+
for (const part of parts) {
|
|
18
|
+
if (part.type === "step-start") {
|
|
19
|
+
turnCounter++;
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (part.type !== "tool" || !part.callID) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const turnProtectionEnabled = config.turnProtection.enabled;
|
|
26
|
+
const turnProtectionTurns = config.turnProtection.turns;
|
|
27
|
+
const isProtectedByTurn = turnProtectionEnabled &&
|
|
28
|
+
turnProtectionTurns > 0 &&
|
|
29
|
+
state.currentTurn - turnCounter < turnProtectionTurns;
|
|
30
|
+
state.lastToolPrune =
|
|
31
|
+
(part.tool === "discard" || part.tool === "extract") &&
|
|
32
|
+
part.state.status === "completed";
|
|
33
|
+
if (state.toolParameters.has(part.callID)) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (isProtectedByTurn) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const allProtectedTools = config.tools.settings.protectedTools;
|
|
40
|
+
// Skip hash generation for protected tools
|
|
41
|
+
if (!allProtectedTools.includes(part.tool)) {
|
|
42
|
+
// Generate hash for this tool call
|
|
43
|
+
const baseHash = generateToolHash(part.tool, part.state?.input ?? {});
|
|
44
|
+
// Handle collision: if hash exists for a different callID, append sequence number
|
|
45
|
+
let finalHash = baseHash;
|
|
46
|
+
if (state.hashToCallId.has(baseHash) &&
|
|
47
|
+
state.hashToCallId.get(baseHash) !== part.callID) {
|
|
48
|
+
let seq = 2;
|
|
49
|
+
while (state.hashToCallId.has(`${baseHash.slice(0, -1)}_${seq}#`)) {
|
|
50
|
+
seq++;
|
|
51
|
+
}
|
|
52
|
+
finalHash = `${baseHash.slice(0, -1)}_${seq}#`;
|
|
53
|
+
logger.warn(`Hash collision detected for ${part.tool}, using ${finalHash}`);
|
|
54
|
+
}
|
|
55
|
+
// Store bidirectional mapping
|
|
56
|
+
state.hashToCallId.set(finalHash, part.callID);
|
|
57
|
+
state.callIdToHash.set(part.callID, finalHash);
|
|
58
|
+
}
|
|
59
|
+
state.toolParameters.set(part.callID, {
|
|
60
|
+
tool: part.tool,
|
|
61
|
+
parameters: part.state?.input ?? {},
|
|
62
|
+
status: part.state.status,
|
|
63
|
+
error: part.state.status === "error" ? part.state.error : undefined,
|
|
64
|
+
turn: turnCounter,
|
|
65
|
+
});
|
|
66
|
+
const hash = state.callIdToHash.get(part.callID) || "(protected)";
|
|
67
|
+
logger.info(`Cached tool id: ${part.callID} hash: ${hash} (turn ${turnCounter})`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
logger.info(`Synced cache - size: ${state.toolParameters.size}, hashes: ${state.hashToCallId.size}, currentTurn: ${state.currentTurn}`);
|
|
71
|
+
trimToolParametersCache(state);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
logger.warn("Failed to sync tool parameters from OpenCode", {
|
|
75
|
+
error: error instanceof Error ? error.message : String(error),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Trim the tool parameters cache to prevent unbounded memory growth.
|
|
81
|
+
* Uses FIFO eviction - removes oldest entries first.
|
|
82
|
+
* Also cleans up corresponding hash mappings to prevent memory leaks.
|
|
83
|
+
*/
|
|
84
|
+
export function trimToolParametersCache(state) {
|
|
85
|
+
if (state.toolParameters.size <= MAX_TOOL_CACHE_SIZE) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const keysToRemove = Array.from(state.toolParameters.keys()).slice(0, state.toolParameters.size - MAX_TOOL_CACHE_SIZE);
|
|
89
|
+
for (const callId of keysToRemove) {
|
|
90
|
+
state.toolParameters.delete(callId);
|
|
91
|
+
// Clean up hash mappings for evicted entries
|
|
92
|
+
const hash = state.callIdToHash.get(callId);
|
|
93
|
+
if (hash) {
|
|
94
|
+
state.hashToCallId.delete(hash);
|
|
95
|
+
state.callIdToHash.delete(callId);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# 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,83 @@
|
|
|
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
|
+
pruneMessageCounter: number;
|
|
18
|
+
totalPruneMessages: number;
|
|
19
|
+
strategyStats: {
|
|
20
|
+
deduplication: {
|
|
21
|
+
count: number;
|
|
22
|
+
tokens: number;
|
|
23
|
+
};
|
|
24
|
+
supersedeWrites: {
|
|
25
|
+
count: number;
|
|
26
|
+
tokens: number;
|
|
27
|
+
};
|
|
28
|
+
purgeErrors: {
|
|
29
|
+
count: number;
|
|
30
|
+
tokens: number;
|
|
31
|
+
};
|
|
32
|
+
manualDiscard: {
|
|
33
|
+
count: number;
|
|
34
|
+
tokens: number;
|
|
35
|
+
};
|
|
36
|
+
extraction: {
|
|
37
|
+
count: number;
|
|
38
|
+
tokens: number;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface Prune {
|
|
43
|
+
toolIds: string[];
|
|
44
|
+
}
|
|
45
|
+
export interface LastDiscardStats {
|
|
46
|
+
itemCount: number;
|
|
47
|
+
tokensSaved: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Statistics for a single discard operation.
|
|
51
|
+
* Used to track token savings per discard.
|
|
52
|
+
*/
|
|
53
|
+
export interface DiscardStats {
|
|
54
|
+
timestamp: number;
|
|
55
|
+
hashes: string[];
|
|
56
|
+
tokensSaved: number;
|
|
57
|
+
reason: string;
|
|
58
|
+
}
|
|
59
|
+
export interface SessionState {
|
|
60
|
+
sessionId: string | null;
|
|
61
|
+
isSubAgent: boolean;
|
|
62
|
+
prune: Prune;
|
|
63
|
+
stats: SessionStats;
|
|
64
|
+
toolParameters: Map<string, ToolParameterEntry>;
|
|
65
|
+
lastToolPrune: boolean;
|
|
66
|
+
lastCompaction: number;
|
|
67
|
+
currentTurn: number;
|
|
68
|
+
variant: string | undefined;
|
|
69
|
+
lastDiscardStats: LastDiscardStats | null;
|
|
70
|
+
lastUserMessageId: string | null;
|
|
71
|
+
hashToCallId: Map<string, string>;
|
|
72
|
+
callIdToHash: Map<string, string>;
|
|
73
|
+
discardHistory: DiscardStats[];
|
|
74
|
+
softPrunedTools: Map<string, SoftPrunedEntry>;
|
|
75
|
+
}
|
|
76
|
+
export interface SoftPrunedEntry {
|
|
77
|
+
originalOutput: string;
|
|
78
|
+
tool: string;
|
|
79
|
+
parameters: any;
|
|
80
|
+
prunedAt: number;
|
|
81
|
+
hash: string;
|
|
82
|
+
}
|
|
83
|
+
//# 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;IACxB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,kBAAkB,EAAE,MAAM,CAAA;IAE1B,aAAa,EAAE;QACX,aAAa,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;QAChD,eAAe,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;QAClD,WAAW,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;QAC9C,aAAa,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;QAChD,UAAU,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;KAChD,CAAA;CACJ;AAED,MAAM,WAAW,KAAK;IAClB,OAAO,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,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,aAAa,EAAE,OAAO,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACzC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAGhC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,cAAc,EAAE,YAAY,EAAE,CAAA;IAG9B,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CAChD;AAED,MAAM,WAAW,eAAe;IAC5B,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,GAAG,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACf"}
|
|
@@ -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,11 @@
|
|
|
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
|
+
* Also handles fuzzy deduplication for overlapping file reads.
|
|
8
|
+
* Modifies the session state in place to add pruned tool call IDs.
|
|
9
|
+
*/
|
|
10
|
+
export declare const deduplicate: (state: SessionState, logger: Logger, config: PluginConfig, messages: WithParts[]) => void;
|
|
11
|
+
//# 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;AAevD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GACpB,OAAO,YAAY,EACnB,QAAQ,MAAM,EACd,QAAQ,YAAY,EACpB,UAAU,SAAS,EAAE,KACtB,IA8EF,CAAA"}
|