@tarquinen/opencode-dcp 2.1.2 → 2.1.4
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/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +24 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/hooks.js +4 -1
- package/dist/lib/hooks.js.map +1 -1
- package/dist/lib/message-ids.d.ts +19 -0
- package/dist/lib/message-ids.d.ts.map +1 -0
- package/dist/lib/message-ids.js +97 -0
- package/dist/lib/message-ids.js.map +1 -0
- package/dist/lib/messages/index.d.ts +1 -0
- package/dist/lib/messages/index.d.ts.map +1 -1
- package/dist/lib/messages/index.js +1 -0
- package/dist/lib/messages/index.js.map +1 -1
- package/dist/lib/messages/inject.d.ts +1 -0
- package/dist/lib/messages/inject.d.ts.map +1 -1
- package/dist/lib/messages/inject.js +35 -7
- package/dist/lib/messages/inject.js.map +1 -1
- package/dist/lib/messages/prune.js +8 -6
- package/dist/lib/messages/prune.js.map +1 -1
- package/dist/lib/messages/utils.d.ts +10 -4
- package/dist/lib/messages/utils.d.ts.map +1 -1
- package/dist/lib/messages/utils.js +37 -11
- package/dist/lib/messages/utils.js.map +1 -1
- package/dist/lib/prompts/_codegen/compress.generated.d.ts +1 -1
- package/dist/lib/prompts/_codegen/compress.generated.d.ts.map +1 -1
- package/dist/lib/prompts/_codegen/compress.generated.js +26 -16
- package/dist/lib/prompts/_codegen/compress.generated.js.map +1 -1
- package/dist/lib/prompts/_codegen/system.generated.d.ts +1 -1
- package/dist/lib/prompts/_codegen/system.generated.d.ts.map +1 -1
- package/dist/lib/prompts/_codegen/system.generated.js +2 -2
- package/dist/lib/state/persistence.d.ts.map +1 -1
- package/dist/lib/state/persistence.js +37 -7
- package/dist/lib/state/persistence.js.map +1 -1
- package/dist/lib/state/state.d.ts.map +1 -1
- package/dist/lib/state/state.js +16 -1
- package/dist/lib/state/state.js.map +1 -1
- package/dist/lib/state/types.d.ts +7 -0
- package/dist/lib/state/types.d.ts.map +1 -1
- package/dist/lib/state/utils.d.ts.map +1 -1
- package/dist/lib/state/utils.js +5 -0
- package/dist/lib/state/utils.js.map +1 -1
- package/dist/lib/strategies/purge-errors.js +1 -1
- package/dist/lib/strategies/purge-errors.js.map +1 -1
- package/dist/lib/tools/compress-utils.d.ts +59 -0
- package/dist/lib/tools/compress-utils.d.ts.map +1 -0
- package/dist/lib/tools/compress-utils.js +405 -0
- package/dist/lib/tools/compress-utils.js.map +1 -0
- package/dist/lib/tools/compress.d.ts.map +1 -1
- package/dist/lib/tools/compress.js +52 -96
- package/dist/lib/tools/compress.js.map +1 -1
- package/package.json +1 -3
- package/dist/lib/tools/utils.d.ts +0 -14
- package/dist/lib/tools/utils.d.ts.map +0 -1
- package/dist/lib/tools/utils.js +0 -171
- package/dist/lib/tools/utils.js.map +0 -1
|
@@ -2,10 +2,10 @@ import { tool } from "@opencode-ai/plugin";
|
|
|
2
2
|
import { ensureSessionInitialized } from "../state";
|
|
3
3
|
import { saveSessionState } from "../state/persistence";
|
|
4
4
|
import { loadPrompt } from "../prompts";
|
|
5
|
-
import { getCurrentParams, getTotalToolTokens
|
|
6
|
-
import { findStringInMessages, collectToolIdsInRange, collectMessageIdsInRange } from "./utils";
|
|
5
|
+
import { getCurrentParams, getTotalToolTokens } from "../strategies/utils";
|
|
7
6
|
import { sendCompressNotification } from "../ui/notification";
|
|
8
|
-
import {
|
|
7
|
+
import { assignMessageRefs } from "../message-ids";
|
|
8
|
+
import { addCompressedBlockHeader, allocateBlockId, buildSearchContext, fetchSessionMessages, injectBlockPlaceholders, parseBlockPlaceholders, resolveAnchorMessageId, resolveBoundaryIds, resolveRange, upsertCompressedSummary, validateCompressArgs, validateSummaryPlaceholders, } from "./compress-utils";
|
|
9
9
|
const COMPRESS_TOOL_DESCRIPTION = loadPrompt("compress-tool-spec");
|
|
10
10
|
export function createCompressTool(ctx) {
|
|
11
11
|
return tool({
|
|
@@ -16,17 +16,17 @@ export function createCompressTool(ctx) {
|
|
|
16
16
|
.describe("Short label (3-5 words) for display - e.g., 'Auth System Exploration'"),
|
|
17
17
|
content: tool.schema
|
|
18
18
|
.object({
|
|
19
|
-
|
|
19
|
+
startId: tool.schema
|
|
20
20
|
.string()
|
|
21
|
-
.describe("
|
|
22
|
-
|
|
21
|
+
.describe("Message or block ID marking the beginning of range (e.g. m0000, b2)"),
|
|
22
|
+
endId: tool.schema
|
|
23
23
|
.string()
|
|
24
|
-
.describe("
|
|
24
|
+
.describe("Message or block ID marking the end of range (e.g. m0012, b5)"),
|
|
25
25
|
summary: tool.schema
|
|
26
26
|
.string()
|
|
27
27
|
.describe("Complete technical summary replacing all content in range"),
|
|
28
28
|
})
|
|
29
|
-
.describe("
|
|
29
|
+
.describe("Compression details: ID boundaries and replacement summary"),
|
|
30
30
|
},
|
|
31
31
|
async execute(args, toolCtx) {
|
|
32
32
|
const { client, state, logger } = ctx;
|
|
@@ -37,84 +37,29 @@ export function createCompressTool(ctx) {
|
|
|
37
37
|
always: ["*"],
|
|
38
38
|
metadata: {},
|
|
39
39
|
});
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// JSON.stringify({
|
|
57
|
-
// startString: startString?.substring(0, 50) + "...",
|
|
58
|
-
// endString: endString?.substring(0, 50) + "...",
|
|
59
|
-
// topic: topic,
|
|
60
|
-
// summaryLength: summary?.length,
|
|
61
|
-
// }),
|
|
62
|
-
// )
|
|
63
|
-
const messagesResponse = await client.session.messages({
|
|
64
|
-
path: { id: sessionId },
|
|
65
|
-
});
|
|
66
|
-
const messages = messagesResponse.data || messagesResponse;
|
|
67
|
-
await ensureSessionInitialized(client, state, sessionId, logger, messages, ctx.config.manualMode.enabled);
|
|
68
|
-
const transformedMessages = structuredClone(messages);
|
|
69
|
-
applyPruneTransforms(state, logger, ctx.config, transformedMessages);
|
|
70
|
-
const startResult = findStringInMessages(transformedMessages, startString, logger, "startString");
|
|
71
|
-
const endResult = findStringInMessages(transformedMessages, endString, logger, "endString");
|
|
72
|
-
let rawStartIndex = messages.findIndex((m) => m.info.id === startResult.messageId);
|
|
73
|
-
let rawEndIndex = messages.findIndex((m) => m.info.id === endResult.messageId);
|
|
74
|
-
// If a boundary matched inside a synthetic compress summary message,
|
|
75
|
-
// resolve it back to the summary's anchor message in the raw messages
|
|
76
|
-
if (rawStartIndex === -1) {
|
|
77
|
-
const summary = state.compressSummaries.find((s) => s.summary.includes(startString));
|
|
78
|
-
if (summary) {
|
|
79
|
-
rawStartIndex = messages.findIndex((m) => m.info.id === summary.anchorMessageId);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
if (rawEndIndex === -1) {
|
|
83
|
-
const summary = state.compressSummaries.find((s) => s.summary.includes(endString));
|
|
84
|
-
if (summary) {
|
|
85
|
-
rawEndIndex = messages.findIndex((m) => m.info.id === summary.anchorMessageId);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
if (rawStartIndex === -1 || rawEndIndex === -1) {
|
|
89
|
-
throw new Error(`Failed to map boundary matches back to raw messages`);
|
|
90
|
-
}
|
|
91
|
-
if (rawStartIndex > rawEndIndex) {
|
|
92
|
-
throw new Error(`startString appears after endString in the conversation. Start must come before end.`);
|
|
93
|
-
}
|
|
94
|
-
const containedToolIds = collectToolIdsInRange(messages, rawStartIndex, rawEndIndex);
|
|
95
|
-
const containedMessageIds = collectMessageIdsInRange(messages, rawStartIndex, rawEndIndex);
|
|
96
|
-
// Remove any existing summaries whose anchors are now inside this range
|
|
97
|
-
// This prevents duplicate injections when a larger compress subsumes a smaller one
|
|
98
|
-
const removedSummaries = state.compressSummaries.filter((s) => containedMessageIds.includes(s.anchorMessageId));
|
|
99
|
-
if (removedSummaries.length > 0) {
|
|
100
|
-
state.compressSummaries = state.compressSummaries.filter((s) => !containedMessageIds.includes(s.anchorMessageId));
|
|
101
|
-
}
|
|
102
|
-
const compressSummary = {
|
|
103
|
-
anchorMessageId: startResult.messageId,
|
|
104
|
-
summary: summary,
|
|
105
|
-
};
|
|
106
|
-
state.compressSummaries.push(compressSummary);
|
|
107
|
-
const compressedMessageIds = containedMessageIds.filter((id) => !state.prune.messages.has(id));
|
|
108
|
-
const compressedToolIds = containedToolIds.filter((id) => !state.prune.tools.has(id));
|
|
40
|
+
const compressArgs = args;
|
|
41
|
+
validateCompressArgs(compressArgs);
|
|
42
|
+
const rawMessages = await fetchSessionMessages(client, sessionId);
|
|
43
|
+
await ensureSessionInitialized(client, state, sessionId, logger, rawMessages, ctx.config.manualMode.enabled);
|
|
44
|
+
assignMessageRefs(state, rawMessages);
|
|
45
|
+
const searchContext = buildSearchContext(state, rawMessages);
|
|
46
|
+
const { startReference, endReference } = resolveBoundaryIds(searchContext, state, compressArgs.content.startId, compressArgs.content.endId);
|
|
47
|
+
const range = resolveRange(searchContext, startReference, endReference);
|
|
48
|
+
const anchorMessageId = resolveAnchorMessageId(range.startReference);
|
|
49
|
+
const parsedPlaceholders = parseBlockPlaceholders(compressArgs.content.summary);
|
|
50
|
+
validateSummaryPlaceholders(parsedPlaceholders, range.requiredBlockIds, range.startReference, range.endReference, searchContext.summaryByBlockId);
|
|
51
|
+
const injected = injectBlockPlaceholders(compressArgs.content.summary, parsedPlaceholders, searchContext.summaryByBlockId, range.startReference, range.endReference);
|
|
52
|
+
const blockId = allocateBlockId(state.compressSummaries);
|
|
53
|
+
const storedSummary = addCompressedBlockHeader(blockId, injected.expandedSummary);
|
|
54
|
+
state.compressSummaries = upsertCompressedSummary(state.compressSummaries, blockId, anchorMessageId, storedSummary, injected.consumedBlockIds);
|
|
55
|
+
const compressedMessageIds = range.messageIds.filter((id) => !state.prune.messages.has(id));
|
|
109
56
|
let textTokens = 0;
|
|
110
|
-
for (const
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
textTokens += tokens;
|
|
115
|
-
state.prune.messages.set(msgId, tokens);
|
|
116
|
-
}
|
|
57
|
+
for (const messageId of compressedMessageIds) {
|
|
58
|
+
const tokenCount = range.messageTokenById.get(messageId) || 0;
|
|
59
|
+
textTokens += tokenCount;
|
|
60
|
+
state.prune.messages.set(messageId, tokenCount);
|
|
117
61
|
}
|
|
62
|
+
const compressedToolIds = range.toolIds.filter((id) => !state.prune.tools.has(id));
|
|
118
63
|
const toolTokens = getTotalToolTokens(state, compressedToolIds);
|
|
119
64
|
for (const id of compressedToolIds) {
|
|
120
65
|
const entry = state.toolParameters.get(id);
|
|
@@ -122,23 +67,34 @@ export function createCompressTool(ctx) {
|
|
|
122
67
|
}
|
|
123
68
|
const estimatedCompressedTokens = textTokens + toolTokens;
|
|
124
69
|
state.stats.pruneTokenCounter += estimatedCompressedTokens;
|
|
125
|
-
const rawStartResult = {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
70
|
+
const rawStartResult = {
|
|
71
|
+
messageId: getBoundaryMessageId(startReference),
|
|
72
|
+
messageIndex: startReference.rawIndex,
|
|
73
|
+
};
|
|
74
|
+
const rawEndResult = {
|
|
75
|
+
messageId: getBoundaryMessageId(endReference),
|
|
76
|
+
messageIndex: endReference.rawIndex,
|
|
77
|
+
};
|
|
78
|
+
const currentParams = getCurrentParams(state, rawMessages, logger);
|
|
79
|
+
await sendCompressNotification(client, logger, ctx.config, state, sessionId, compressedToolIds, compressedMessageIds, compressArgs.topic, injected.expandedSummary, rawStartResult, rawEndResult, rawMessages.length, currentParams);
|
|
129
80
|
state.stats.totalPruneTokens += state.stats.pruneTokenCounter;
|
|
130
81
|
state.stats.pruneTokenCounter = 0;
|
|
131
82
|
state.nudgeCounter = 0;
|
|
132
|
-
|
|
133
|
-
// startMessageId: startResult.messageId,
|
|
134
|
-
// endMessageId: endResult.messageId,
|
|
135
|
-
// toolIdsRemoved: containedToolIds.length,
|
|
136
|
-
// messagesInRange: containedMessageIds.length,
|
|
137
|
-
// estimatedTokens: estimatedCompressedTokens,
|
|
138
|
-
// })
|
|
139
|
-
saveSessionState(state, logger).catch((err) => logger.error("Failed to persist state", { error: err.message }));
|
|
83
|
+
await saveSessionState(state, logger);
|
|
140
84
|
return `Compressed ${compressedMessageIds.length} messages (${compressedToolIds.length} tool calls) into summary. The content will be replaced with your summary.`;
|
|
141
85
|
},
|
|
142
86
|
});
|
|
143
87
|
}
|
|
88
|
+
function getBoundaryMessageId(reference) {
|
|
89
|
+
if (reference.kind === "message") {
|
|
90
|
+
if (!reference.messageId) {
|
|
91
|
+
throw new Error("Failed to map boundary matches back to raw messages");
|
|
92
|
+
}
|
|
93
|
+
return reference.messageId;
|
|
94
|
+
}
|
|
95
|
+
if (!reference.anchorMessageId) {
|
|
96
|
+
throw new Error("Failed to map boundary matches back to raw messages");
|
|
97
|
+
}
|
|
98
|
+
return reference.anchorMessageId;
|
|
99
|
+
}
|
|
144
100
|
//# sourceMappingURL=compress.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compress.js","sourceRoot":"","sources":["../../../lib/tools/compress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAG1C,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"compress.js","sourceRoot":"","sources":["../../../lib/tools/compress.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@tarquinen/opencode-dcp",
|
|
4
|
-
"version": "2.1.
|
|
4
|
+
"version": "2.1.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "OpenCode plugin that optimizes token usage by pruning obsolete tool outputs from conversation context",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -44,9 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@anthropic-ai/tokenizer": "^0.0.4",
|
|
46
46
|
"@opencode-ai/sdk": "^1.1.48",
|
|
47
|
-
"fuzzball": "^2.2.3",
|
|
48
47
|
"jsonc-parser": "^3.3.1",
|
|
49
|
-
"ulid": "^3.0.2",
|
|
50
48
|
"zod": "^4.3.6"
|
|
51
49
|
},
|
|
52
50
|
"devDependencies": {
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { WithParts } from "../state";
|
|
2
|
-
import type { Logger } from "../logger";
|
|
3
|
-
export interface FuzzyConfig {
|
|
4
|
-
minScore: number;
|
|
5
|
-
minGap: number;
|
|
6
|
-
}
|
|
7
|
-
export declare const DEFAULT_FUZZY_CONFIG: FuzzyConfig;
|
|
8
|
-
export declare function findStringInMessages(messages: WithParts[], searchString: string, logger: Logger, stringType: "startString" | "endString", fuzzyConfig?: FuzzyConfig): {
|
|
9
|
-
messageId: string;
|
|
10
|
-
messageIndex: number;
|
|
11
|
-
};
|
|
12
|
-
export declare function collectToolIdsInRange(messages: WithParts[], startIndex: number, endIndex: number): string[];
|
|
13
|
-
export declare function collectMessageIdsInRange(messages: WithParts[], startIndex: number, endIndex: number): string[];
|
|
14
|
-
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/tools/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAGvC,MAAM,WAAW,WAAW;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,oBAAoB,EAAE,WAGlC,CAAA;AAsHD,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,SAAS,EAAE,EACrB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,aAAa,GAAG,WAAW,EACvC,WAAW,GAAE,WAAkC,GAChD;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAkE7C;AAED,wBAAgB,qBAAqB,CACjC,QAAQ,EAAE,SAAS,EAAE,EACrB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACjB,MAAM,EAAE,CAiBV;AAED,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,SAAS,EAAE,EACrB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACjB,MAAM,EAAE,CAWV"}
|
package/dist/lib/tools/utils.js
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { partial_ratio } from "fuzzball";
|
|
2
|
-
import { isIgnoredUserMessage } from "../messages/utils";
|
|
3
|
-
export const DEFAULT_FUZZY_CONFIG = {
|
|
4
|
-
minScore: 95,
|
|
5
|
-
minGap: 15,
|
|
6
|
-
};
|
|
7
|
-
function extractMessageContent(msg) {
|
|
8
|
-
const parts = Array.isArray(msg.parts) ? msg.parts : [];
|
|
9
|
-
let content = "";
|
|
10
|
-
for (const part of parts) {
|
|
11
|
-
const p = part;
|
|
12
|
-
if (part.ignored) {
|
|
13
|
-
continue;
|
|
14
|
-
}
|
|
15
|
-
switch (part.type) {
|
|
16
|
-
case "text":
|
|
17
|
-
case "reasoning":
|
|
18
|
-
if (typeof p.text === "string") {
|
|
19
|
-
content += " " + p.text;
|
|
20
|
-
}
|
|
21
|
-
break;
|
|
22
|
-
case "tool": {
|
|
23
|
-
const state = p.state;
|
|
24
|
-
if (!state)
|
|
25
|
-
break;
|
|
26
|
-
// Include tool output (completed or error)
|
|
27
|
-
if (state.status === "completed" && typeof state.output === "string") {
|
|
28
|
-
content += " " + state.output;
|
|
29
|
-
}
|
|
30
|
-
else if (state.status === "error" && typeof state.error === "string") {
|
|
31
|
-
content += " " + state.error;
|
|
32
|
-
}
|
|
33
|
-
// Include tool input
|
|
34
|
-
if (state.input) {
|
|
35
|
-
content +=
|
|
36
|
-
" " +
|
|
37
|
-
(typeof state.input === "string"
|
|
38
|
-
? state.input
|
|
39
|
-
: JSON.stringify(state.input));
|
|
40
|
-
}
|
|
41
|
-
break;
|
|
42
|
-
}
|
|
43
|
-
case "compaction":
|
|
44
|
-
if (typeof p.summary === "string") {
|
|
45
|
-
content += " " + p.summary;
|
|
46
|
-
}
|
|
47
|
-
break;
|
|
48
|
-
case "subtask":
|
|
49
|
-
if (typeof p.summary === "string") {
|
|
50
|
-
content += " " + p.summary;
|
|
51
|
-
}
|
|
52
|
-
if (typeof p.result === "string") {
|
|
53
|
-
content += " " + p.result;
|
|
54
|
-
}
|
|
55
|
-
break;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return content;
|
|
59
|
-
}
|
|
60
|
-
function findExactMatches(messages, searchString) {
|
|
61
|
-
const matches = [];
|
|
62
|
-
for (let i = 0; i < messages.length; i++) {
|
|
63
|
-
const msg = messages[i];
|
|
64
|
-
if (isIgnoredUserMessage(msg)) {
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
const content = extractMessageContent(msg);
|
|
68
|
-
if (content.includes(searchString)) {
|
|
69
|
-
matches.push({
|
|
70
|
-
messageId: msg.info.id,
|
|
71
|
-
messageIndex: i,
|
|
72
|
-
score: 100,
|
|
73
|
-
matchType: "exact",
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return matches;
|
|
78
|
-
}
|
|
79
|
-
function findFuzzyMatches(messages, searchString, minScore) {
|
|
80
|
-
const matches = [];
|
|
81
|
-
for (let i = 0; i < messages.length; i++) {
|
|
82
|
-
const msg = messages[i];
|
|
83
|
-
if (isIgnoredUserMessage(msg)) {
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
const content = extractMessageContent(msg);
|
|
87
|
-
const score = partial_ratio(searchString, content);
|
|
88
|
-
if (score >= minScore) {
|
|
89
|
-
matches.push({
|
|
90
|
-
messageId: msg.info.id,
|
|
91
|
-
messageIndex: i,
|
|
92
|
-
score,
|
|
93
|
-
matchType: "fuzzy",
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return matches;
|
|
98
|
-
}
|
|
99
|
-
export function findStringInMessages(messages, searchString, logger, stringType, fuzzyConfig = DEFAULT_FUZZY_CONFIG) {
|
|
100
|
-
const searchableMessages = messages.length > 1 ? messages.slice(0, -1) : messages;
|
|
101
|
-
const lastMessage = messages.length > 0 ? messages[messages.length - 1] : undefined;
|
|
102
|
-
const exactMatches = findExactMatches(searchableMessages, searchString);
|
|
103
|
-
if (exactMatches.length === 1) {
|
|
104
|
-
return { messageId: exactMatches[0].messageId, messageIndex: exactMatches[0].messageIndex };
|
|
105
|
-
}
|
|
106
|
-
if (exactMatches.length > 1) {
|
|
107
|
-
throw new Error(`Found multiple matches for ${stringType}. ` +
|
|
108
|
-
`Provide more surrounding context to uniquely identify the intended match.`);
|
|
109
|
-
}
|
|
110
|
-
const fuzzyMatches = findFuzzyMatches(searchableMessages, searchString, fuzzyConfig.minScore);
|
|
111
|
-
if (fuzzyMatches.length === 0) {
|
|
112
|
-
if (lastMessage && !isIgnoredUserMessage(lastMessage)) {
|
|
113
|
-
const lastMsgContent = extractMessageContent(lastMessage);
|
|
114
|
-
const lastMsgIndex = messages.length - 1;
|
|
115
|
-
if (lastMsgContent.includes(searchString)) {
|
|
116
|
-
// logger.info(
|
|
117
|
-
// `${stringType} found in last message (last resort) at index ${lastMsgIndex}`,
|
|
118
|
-
// )
|
|
119
|
-
return {
|
|
120
|
-
messageId: lastMessage.info.id,
|
|
121
|
-
messageIndex: lastMsgIndex,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
throw new Error(`${stringType} not found in conversation. ` +
|
|
126
|
-
`Make sure the string exists and is spelled exactly as it appears.`);
|
|
127
|
-
}
|
|
128
|
-
fuzzyMatches.sort((a, b) => b.score - a.score);
|
|
129
|
-
const best = fuzzyMatches[0];
|
|
130
|
-
const secondBest = fuzzyMatches[1];
|
|
131
|
-
// Log fuzzy match candidates
|
|
132
|
-
// logger.info(
|
|
133
|
-
// `Fuzzy match for ${stringType}: best=${best.score}% (msg ${best.messageIndex})` +
|
|
134
|
-
// (secondBest
|
|
135
|
-
// ? `, secondBest=${secondBest.score}% (msg ${secondBest.messageIndex})`
|
|
136
|
-
// : ""),
|
|
137
|
-
// )
|
|
138
|
-
// Check confidence gap - best must be significantly better than second best
|
|
139
|
-
if (secondBest && best.score - secondBest.score < fuzzyConfig.minGap) {
|
|
140
|
-
throw new Error(`Found multiple matches for ${stringType}. ` +
|
|
141
|
-
`Provide more unique surrounding context to disambiguate.`);
|
|
142
|
-
}
|
|
143
|
-
logger.info(`Fuzzy matched ${stringType} with ${best.score}% confidence at message index ${best.messageIndex}`);
|
|
144
|
-
return { messageId: best.messageId, messageIndex: best.messageIndex };
|
|
145
|
-
}
|
|
146
|
-
export function collectToolIdsInRange(messages, startIndex, endIndex) {
|
|
147
|
-
const toolIds = [];
|
|
148
|
-
for (let i = startIndex; i <= endIndex; i++) {
|
|
149
|
-
const msg = messages[i];
|
|
150
|
-
const parts = Array.isArray(msg.parts) ? msg.parts : [];
|
|
151
|
-
for (const part of parts) {
|
|
152
|
-
if (part.type === "tool" && part.callID) {
|
|
153
|
-
if (!toolIds.includes(part.callID)) {
|
|
154
|
-
toolIds.push(part.callID);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return toolIds;
|
|
160
|
-
}
|
|
161
|
-
export function collectMessageIdsInRange(messages, startIndex, endIndex) {
|
|
162
|
-
const messageIds = [];
|
|
163
|
-
for (let i = startIndex; i <= endIndex; i++) {
|
|
164
|
-
const msgId = messages[i].info.id;
|
|
165
|
-
if (!messageIds.includes(msgId)) {
|
|
166
|
-
messageIds.push(msgId);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return messageIds;
|
|
170
|
-
}
|
|
171
|
-
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../lib/tools/utils.ts"],"names":[],"mappings":"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"}
|