fix(agent-core,memory-core): keep compaction summary and memory snippet truncation UTF-16 safe (#102542)

* fix(agent-core,memory-core): keep compaction summary and memory snippet truncation UTF-16 safe

* fix: make compaction and memory truncation UTF-16 safe

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
wings1029
2026-07-09 17:08:11 +08:00
committed by GitHub
parent b8a801930a
commit f7cc6ebe1e
6 changed files with 91 additions and 4 deletions
+1
View File
@@ -96,6 +96,7 @@
},
"dependencies": {
"@openclaw/ai": "workspace:*",
"@openclaw/normalization-core": "workspace:*",
"typebox": "1.3.3"
}
}
@@ -33,4 +33,18 @@ describe("serializeConversation", () => {
expect(serializeConversation(messages)).toBe(`[Tool result]: ${expected}`);
});
it("keeps truncated tool results UTF-16 safe and reports the exact omitted count", () => {
const prefix = "a".repeat(1_999);
const messages = [
{
role: "toolResult",
content: [{ type: "toolResult", content: `${prefix}🚀tail` }],
},
] as unknown as Message[];
expect(serializeConversation(messages)).toBe(
`[Tool result]: ${prefix}\n\n[... 6 more characters truncated]`,
);
});
});
@@ -1,4 +1,5 @@
// Agent Core helper module supports utils behavior.
import { truncateUtf16Safe } from "@openclaw/normalization-core/utf16-slice";
import type { Message } from "../../../../llm-core/src/index.js";
import type { AgentMessage } from "../../types.js";
@@ -105,8 +106,9 @@ function truncateForSummary(text: string, maxChars: number): string {
if (text.length <= maxChars) {
return text;
}
const truncatedChars = text.length - maxChars;
return `${text.slice(0, maxChars)}\n\n[... ${truncatedChars} more characters truncated]`;
const sliced = truncateUtf16Safe(text, maxChars);
const truncatedChars = text.length - sliced.length;
return `${sliced}\n\n[... ${truncatedChars} more characters truncated]`;
}
/** Extract text that compaction both estimates and includes in summary prompts. */