Skip to content

Commit 38e0e34

Browse files
committed
fix(memory-lancedb): keep memory recall/text preview truncation UTF-16 safe
Replace two raw .slice(0,) calls with truncateUtf16Safe in memory create/store (100-code-unit preview) and search/list (60-code-unit preview) paths, preventing dangling surrogates when memory text contains emoji or CJK characters at the boundary.
1 parent bd7da9d commit 38e0e34

1 file changed

Lines changed: 32 additions & 8 deletions

File tree

extensions/memory-lancedb/index.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,10 @@ function stripLeadingMessageToolDeliveryHints(text: string): string {
994994

995995
function findFirstInboundEnvelopeIndex(
996996
text: string,
997-
options?: { allowAmbiguousMarkerFree?: boolean; skipReplyQuoteLine?: boolean },
997+
options?: {
998+
allowAmbiguousMarkerFree?: boolean;
999+
skipReplyQuoteLine?: boolean;
1000+
},
9981001
) {
9991002
for (const match of text.matchAll(BRACKETED_PREFIX_RE)) {
10001003
const index = match.index;
@@ -1498,7 +1501,9 @@ export default definePluginEntry({
14981501
"Search through long-term memories. Use when you need context about user preferences, past decisions, or previously discussed topics.",
14991502
parameters: Type.Object({
15001503
query: Type.String({ description: "Search query" }),
1501-
limit: optionalPositiveIntegerSchema({ description: "Max results (default: 5)" }),
1504+
limit: optionalPositiveIntegerSchema({
1505+
description: "Max results (default: 5)",
1506+
}),
15021507
}),
15031508
async execute(_toolCallId, params) {
15041509
const rawParams = params as Record<string, unknown>;
@@ -1658,7 +1663,12 @@ export default definePluginEntry({
16581663
});
16591664

16601665
return {
1661-
content: [{ type: "text", text: `Stored: "${text.slice(0, 100)}..."` }],
1666+
content: [
1667+
{
1668+
type: "text",
1669+
text: `Stored: "${truncateUtf16Safe(text, 100)}..."`,
1670+
},
1671+
],
16621672
details: { action: "created", id: entry.id },
16631673
};
16641674
},
@@ -1676,7 +1686,10 @@ export default definePluginEntry({
16761686
memoryId: Type.Optional(Type.String({ description: "Specific memory ID" })),
16771687
}),
16781688
async execute(_toolCallId, params) {
1679-
const { query, memoryId } = params as { query?: string; memoryId?: string };
1689+
const { query, memoryId } = params as {
1690+
query?: string;
1691+
memoryId?: string;
1692+
};
16801693

16811694
if (memoryId) {
16821695
await db.delete(memoryId);
@@ -1703,13 +1716,18 @@ export default definePluginEntry({
17031716
if (results.length === 1 && results[0].score > 0.9) {
17041717
await db.delete(results[0].entry.id);
17051718
return {
1706-
content: [{ type: "text", text: `Forgotten: "${results[0].entry.text}"` }],
1719+
content: [
1720+
{
1721+
type: "text",
1722+
text: `Forgotten: "${results[0].entry.text}"`,
1723+
},
1724+
],
17071725
details: { action: "deleted", id: results[0].entry.id },
17081726
};
17091727
}
17101728

17111729
const list = results
1712-
.map((r) => `- [${r.entry.id}] ${r.entry.text.slice(0, 60)}...`)
1730+
.map((r) => `- [${r.entry.id}] ${truncateUtf16Safe(r.entry.text, 60)}...`)
17131731
.join("\n");
17141732

17151733
// Strip vector data for serialization
@@ -1727,7 +1745,10 @@ export default definePluginEntry({
17271745
text: `Found ${results.length} candidates. Specify memoryId:\n${list}`,
17281746
},
17291747
],
1730-
details: { action: "candidates", candidates: sanitizedCandidates },
1748+
details: {
1749+
action: "candidates",
1750+
candidates: sanitizedCandidates,
1751+
},
17311752
};
17321753
}
17331754

@@ -1897,7 +1918,10 @@ export default definePluginEntry({
18971918

18981919
// Filter contaminated memories, then cap at the prompt-budget bound.
18991920
const cleanResults = cleanMemorySearchResults(recall.value)
1900-
.map(({ result, text }) => ({ category: result.entry.category, text }))
1921+
.map(({ result, text }) => ({
1922+
category: result.entry.category,
1923+
text,
1924+
}))
19011925
.slice(0, DEFAULT_AUTO_RECALL_RESULT_CAP);
19021926

19031927
if (cleanResults.length === 0) {

0 commit comments

Comments
 (0)