fix(agents): truncate console text on code-point boundaries (#96296) · openclaw/openclaw@ad8e7dc
ly-wang19
·
2026-06-29
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +// Console sanitizer tests cover control-char filtering and code-point-safe truncation. |
| 2 | +import { describe, expect, it } from "vitest"; |
| 3 | +import { sanitizeForConsole } from "./console-sanitize.js"; |
| 4 | + |
| 5 | +const hasLoneSurrogate = (value: string) => |
| 6 | +/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/.test(value); |
| 7 | + |
| 8 | +describe("sanitizeForConsole", () => { |
| 9 | +it("truncates on code-point boundaries without splitting a surrogate pair", () => { |
| 10 | +const grin = String.fromCodePoint(0x1f600); // 😀 — two UTF-16 code units |
| 11 | +const out = sanitizeForConsole(grin.repeat(6), 3); |
| 12 | +expect(out).toBe(`${grin.repeat(3)}…`); |
| 13 | +expect(out !== undefined && hasLoneSurrogate(out)).toBe(false); |
| 14 | +}); |
| 15 | + |
| 16 | +it("filters control chars, flattens whitespace, and leaves short strings intact", () => { |
| 17 | +expect(sanitizeForConsole(" hello\tworld ")).toBe("hello world"); |
| 18 | +expect(sanitizeForConsole(undefined)).toBeUndefined(); |
| 19 | +}); |
| 20 | +}); |
| Original file line number | Diff line number | Diff line change |
|---|
@@ -22,5 +22,11 @@ export function sanitizeForConsole(text: string | undefined, maxChars = 200): st
|
22 | 22 | .replace(/[\r\n\t]+/g, " ") |
23 | 23 | .replace(/\s+/g, " ") |
24 | 24 | .trim(); |
25 | | -return sanitized.length > maxChars ? `${sanitized.slice(0, maxChars)}…` : sanitized; |
| 25 | +const codePoints = Array.from(sanitized); |
| 26 | +if (codePoints.length <= maxChars) { |
| 27 | +return sanitized; |
| 28 | +} |
| 29 | +// Cap on code-point boundaries so a maxChars cut never splits a surrogate pair (emoji/astral) and |
| 30 | +// leaves a lone surrogate before the ellipsis. |
| 31 | +return `${codePoints.slice(0, maxChars).join("")}…`; |
26 | 32 | } |
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。