Skip to content

Commit a187550

Browse files
committed
cleanup
1 parent e278714 commit a187550

File tree

1 file changed

+36
-44
lines changed

1 file changed

+36
-44
lines changed

lib/tools/utils.ts

Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,13 @@ import { partial_ratio } from "fuzzball"
22
import type { WithParts, CompressSummary } from "../state"
33
import type { Logger } from "../logger"
44

5-
/**
6-
* Configuration for fuzzy matching behavior
7-
*/
85
export interface FuzzyConfig {
9-
minScore: number // Minimum score to accept (0-100)
10-
minGap: number // Minimum gap between best and second-best match
6+
minScore: number
7+
minGap: number
118
}
129

1310
export const DEFAULT_FUZZY_CONFIG: FuzzyConfig = {
14-
minScore: 85,
11+
minScore: 95,
1512
minGap: 15,
1613
}
1714

@@ -22,10 +19,6 @@ interface MatchResult {
2219
matchType: "exact" | "fuzzy"
2320
}
2421

25-
/**
26-
* Extracts all textual content from a message for matching purposes.
27-
* Includes: text, reasoning, tool (input/output), compaction, and subtask parts.
28-
*/
2922
function extractMessageContent(msg: WithParts): string {
3023
const parts = Array.isArray(msg.parts) ? msg.parts : []
3124
let content = ""
@@ -83,9 +76,6 @@ function extractMessageContent(msg: WithParts): string {
8376
return content
8477
}
8578

86-
/**
87-
* Find all exact substring matches across messages and compress summaries.
88-
*/
8979
function findExactMatches(
9080
messages: WithParts[],
9181
searchString: string,
@@ -130,9 +120,6 @@ function findExactMatches(
130120
return matches
131121
}
132122

133-
/**
134-
* Find all fuzzy substring matches above the minimum score threshold.
135-
*/
136123
function findFuzzyMatches(
137124
messages: WithParts[],
138125
searchString: string,
@@ -180,12 +167,6 @@ function findFuzzyMatches(
180167
return matches
181168
}
182169

183-
/**
184-
* Searches messages for a string and returns the message ID where it's found.
185-
* Uses exact matching first, then falls back to fuzzy matching with confidence thresholds.
186-
* Searches in text parts, tool outputs, tool inputs, and compress summaries.
187-
* Throws an error if no confident match is found.
188-
*/
189170
export function findStringInMessages(
190171
messages: WithParts[],
191172
searchString: string,
@@ -194,47 +175,68 @@ export function findStringInMessages(
194175
stringType: "startString" | "endString",
195176
fuzzyConfig: FuzzyConfig = DEFAULT_FUZZY_CONFIG,
196177
): { messageId: string; messageIndex: number } {
197-
// ============ PHASE 1: Exact Match ============
198-
const exactMatches = findExactMatches(messages, searchString, compressSummaries)
178+
const searchableMessages = messages.length > 1 ? messages.slice(0, -1) : messages
179+
const lastMessage = messages.length > 0 ? messages[messages.length - 1] : undefined
180+
181+
const exactMatches = findExactMatches(searchableMessages, searchString, compressSummaries)
199182

200183
if (exactMatches.length === 1) {
201184
return { messageId: exactMatches[0].messageId, messageIndex: exactMatches[0].messageIndex }
202185
}
203186

204187
if (exactMatches.length > 1) {
205188
throw new Error(
206-
`Found multiple exact matches for ${stringType}. ` +
207-
`Provide more surrounding context to uniquely identify the intended match.`,
189+
`Found multiple matches for ${stringType}. ` +
190+
`Provide more surrounding context to uniquely identify the intended match.`,
208191
)
209192
}
210193

211-
// ============ PHASE 2: Fuzzy Match ============
212194
const fuzzyMatches = findFuzzyMatches(
213-
messages,
195+
searchableMessages,
214196
searchString,
215197
compressSummaries,
216198
fuzzyConfig.minScore,
217199
)
218200

219201
if (fuzzyMatches.length === 0) {
202+
if (lastMessage) {
203+
const lastMsgContent = extractMessageContent(lastMessage)
204+
const lastMsgIndex = messages.length - 1
205+
if (lastMsgContent.includes(searchString)) {
206+
// logger.info(
207+
// `${stringType} found in last message (last resort) at index ${lastMsgIndex}`,
208+
// )
209+
return {
210+
messageId: lastMessage.info.id,
211+
messageIndex: lastMsgIndex,
212+
}
213+
}
214+
}
215+
220216
throw new Error(
221-
`${stringType} not found in conversation (exact or fuzzy). ` +
222-
`Make sure the string exists and is spelled correctly.`,
217+
`${stringType} not found in conversation. ` +
218+
`Make sure the string exists and is spelled correctly.`,
223219
)
224220
}
225221

226-
// Sort by score descending to find best match
227222
fuzzyMatches.sort((a, b) => b.score - a.score)
228223

229224
const best = fuzzyMatches[0]
230225
const secondBest = fuzzyMatches[1]
231226

227+
// Log fuzzy match candidates
228+
// logger.info(
229+
// `Fuzzy match for ${stringType}: best=${best.score}% (msg ${best.messageIndex})` +
230+
// (secondBest
231+
// ? `, secondBest=${secondBest.score}% (msg ${secondBest.messageIndex})`
232+
// : ""),
233+
// )
234+
232235
// Check confidence gap - best must be significantly better than second best
233236
if (secondBest && best.score - secondBest.score < fuzzyConfig.minGap) {
234237
throw new Error(
235-
`Ambiguous fuzzy match for ${stringType}: ` +
236-
`two candidates scored similarly (${best.score}% vs ${secondBest.score}%). ` +
237-
`Provide more unique text to disambiguate.`,
238+
`Found multiple matches for ${stringType}. ` +
239+
`Provide more unique surrounding context to disambiguate.`,
238240
)
239241
}
240242

@@ -245,9 +247,6 @@ export function findStringInMessages(
245247
return { messageId: best.messageId, messageIndex: best.messageIndex }
246248
}
247249

248-
/**
249-
* Collects all tool callIDs from messages between start and end indices (inclusive).
250-
*/
251250
export function collectToolIdsInRange(
252251
messages: WithParts[],
253252
startIndex: number,
@@ -271,9 +270,6 @@ export function collectToolIdsInRange(
271270
return toolIds
272271
}
273272

274-
/**
275-
* Collects all message IDs from messages between start and end indices (inclusive).
276-
*/
277273
export function collectMessageIdsInRange(
278274
messages: WithParts[],
279275
startIndex: number,
@@ -291,10 +287,6 @@ export function collectMessageIdsInRange(
291287
return messageIds
292288
}
293289

294-
/**
295-
* Collects all textual content (text parts, tool inputs, and tool outputs)
296-
* from a range of messages. Used for token estimation.
297-
*/
298290
export function collectContentInRange(
299291
messages: WithParts[],
300292
startIndex: number,

0 commit comments

Comments
 (0)