From 5497662408a626e87ccc2bb5f5a98cd7223bfa99 Mon Sep 17 00:00:00 2001 From: lzyyzznl Date: Thu, 9 Jul 2026 19:41:38 +0800 Subject: [PATCH] fix(active-memory): keep search queries UTF-16 safe (#102621) Co-authored-by: Peter Steinberger --- extensions/active-memory/index.test.ts | 25 +++++++++++++++++++++++++ extensions/active-memory/index.ts | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/extensions/active-memory/index.test.ts b/extensions/active-memory/index.test.ts index 16863c882ba1..9f27b53f36b4 100644 --- a/extensions/active-memory/index.test.ts +++ b/extensions/active-memory/index.test.ts @@ -5097,6 +5097,31 @@ describe("active-memory plugin", () => { expect(prompt).not.toContain("Recent conversation tail:"); }); + it("keeps a whole code point when the bounded search query crosses an emoji", async () => { + api.pluginConfig = { + agents: ["main"], + queryMode: "message", + }; + plugin.register(api as unknown as OpenClawPluginApi); + const prefix = "a".repeat(479); + + await hooks.before_prompt_build( + { + prompt: `${prefix}😀tail`, + messages: [], + }, + { + agentId: "main", + trigger: "user", + sessionKey: "agent:main:main", + messageProvider: "webchat", + }, + ); + + const query = lastEmbeddedPrompt().match(/Bounded memory search query:\n([^\n]*)/u)?.[1]; + expect(query).toBe(prefix); + }); + it("sends a bounded latest-message query instead of channel metadata to memory search", async () => { api.pluginConfig = { agents: ["main"], diff --git a/extensions/active-memory/index.ts b/extensions/active-memory/index.ts index a06458ff3d4c..221b68828cfb 100644 --- a/extensions/active-memory/index.ts +++ b/extensions/active-memory/index.ts @@ -2711,7 +2711,7 @@ function normalizeSearchQueryText(text: string): string { function clampSearchQuery(text: string): string { const normalized = text.replace(/\s+/g, " ").trim(); return normalized.length > MAX_ACTIVE_MEMORY_SEARCH_QUERY_CHARS - ? normalized.slice(0, MAX_ACTIVE_MEMORY_SEARCH_QUERY_CHARS).trim() + ? truncateUtf16Safe(normalized, MAX_ACTIVE_MEMORY_SEARCH_QUERY_CHARS).trim() : normalized; }