fix(acpx): preserve Unicode in catalog tool arguments (#109589)

Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
Wynne668
2026-07-16 21:21:04 -07:00
committed by GitHub
co-authored by Peter Steinberger
parent d275942136
commit 7b6c6a0802
2 changed files with 17 additions and 2 deletions
+15 -1
View File
@@ -50,6 +50,7 @@ const originalPath = process.env.PATH;
async function createPiStore(
assistantText = "hi",
sessionName = "Pi catalog session",
toolArguments: unknown = { command: "pwd" },
): Promise<string> {
const directory = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-pi-catalog-"));
temporaryDirectories.push(directory);
@@ -82,7 +83,7 @@ async function createPiStore(
content: [
{ type: "thinking", thinking: "thinking" },
{ type: "text", text: assistantText },
{ type: "toolCall", id: "call-1", name: "bash", arguments: { command: "pwd" } },
{ type: "toolCall", id: "call-1", name: "bash", arguments: toolArguments },
],
},
},
@@ -293,6 +294,19 @@ describe("Pi session catalog", () => {
expect(Buffer.byteLength(JSON.stringify(transcript), "utf8")).toBeLessThan(20 * 1024 * 1024);
});
it("keeps truncated tool arguments on a valid UTF-16 boundary", async () => {
await createPiStore("hi", "Pi catalog session", {
value: `${"x".repeat(19_989)}🎉`,
});
const transcript = await readLocalPiTranscriptPage({ threadId: "pi-session", limit: 20 });
const toolCall = transcript.items.find((item) => item.type === "toolCall");
expect(toolCall?.text).toMatch(/$/u);
expect(toolCall?.text).not.toMatch(
/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u,
);
});
it("reads legacy linear sessions and visible extended messages", async () => {
const directory = await createPiStore();
const entries = [
+2 -1
View File
@@ -5,6 +5,7 @@ import type {
SessionsCatalogReadResult,
} from "openclaw/plugin-sdk/session-catalog";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
import { listPiSummaryPage, readPiSessionById } from "./pi-session-store.js";
const LOCAL_HOST_ID = "gateway";
@@ -225,7 +226,7 @@ function isoTimestamp(
function jsonText(value: unknown, maxLength = 20_000): string | undefined {
try {
const text = JSON.stringify(value);
return text.length > maxLength ? `${text.slice(0, maxLength)}` : text;
return text.length > maxLength ? `${truncateUtf16Safe(text, maxLength)}` : text;
} catch {
return undefined;
}