Skip to content

Commit 73b475b

Browse files
maweibinclaude
andcommitted
fix(tui): keep emoji / surrogate pairs intact during abort diagnostic truncation
Use truncateUtf16Safe() instead of .slice() to count full code points. Co-Authored-By: Claude Opus 4.8 <[email protected]>
1 parent 775ef96 commit 73b475b

2 files changed

Lines changed: 14 additions & 2 deletions

File tree

src/tui/tui-event-handlers.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,3 +2318,14 @@ describe("tui-event-handlers: streaming watchdog", () => {
23182318
handlers.dispose?.();
23192319
});
23202320
});
2321+
2322+
describe("abort diagnostic truncation", () => {
2323+
it("does not split surrogate pairs", async () => {
2324+
const { truncateUtf16Safe } = await import("@openclaw/normalization-core/utf16-slice");
2325+
const content = "x".repeat(158) + "🚀tail";
2326+
const bad = content.slice(0, 159);
2327+
expect(bad.endsWith("\uD83D")).toBe(true);
2328+
const good = truncateUtf16Safe(content, 159);
2329+
expect(good).toBe("x".repeat(158));
2330+
});
2331+
});

src/tui/tui-event-handlers.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
// Handles TUI keyboard, paste, backend, and command events.
21
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
32
import { classifyFailoverReason, isAuthErrorMessage } from "../agents/embedded-agent-helpers.js";
43
import { parseAgentSessionKey } from "../sessions/session-key-utils.js";
54
import { formatRawAssistantErrorForUi } from "../shared/assistant-error-format.js";
5+
// Handles TUI keyboard, paste, backend, and command events.
6+
import { truncateUtf16Safe } from "../utils.js";
67
import {
78
asString,
89
extractTextFromMessage,
@@ -52,7 +53,7 @@ function formatAbortDiagnostic(value: string | undefined): string | undefined {
5253
return undefined;
5354
}
5455
return diagnostic.length > MAX_ABORT_DIAGNOSTIC_LENGTH
55-
? `${diagnostic.slice(0, MAX_ABORT_DIAGNOSTIC_LENGTH - 1)}…`
56+
? `${truncateUtf16Safe(diagnostic, MAX_ABORT_DIAGNOSTIC_LENGTH - 1)}…`
5657
: diagnostic;
5758
}
5859

0 commit comments

Comments
 (0)