fix(msteams): keep truncated parent context text well-formed (#96569) · openclaw/openclaw@4b9e018
llagy009
·
2026-06-27
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -10,6 +10,11 @@ import {
|
10 | 10 | summarizeParentMessage, |
11 | 11 | } from "./thread-parent-context.js"; |
12 | 12 | |
| 13 | +// Matches an unpaired UTF-16 surrogate (lone high or lone low), without relying |
| 14 | +// on the ES2024 String.prototype.isWellFormed() runtime API. |
| 15 | +const UNPAIRED_SURROGATE_RE = |
| 16 | +/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/; |
| 17 | + |
13 | 18 | describe("summarizeParentMessage", () => { |
14 | 19 | it("returns undefined for missing message", () => { |
15 | 20 | expect(summarizeParentMessage(undefined)).toBeUndefined(); |
@@ -81,6 +86,20 @@ describe("summarizeParentMessage", () => {
|
81 | 86 | expect(summary?.text.length).toBeLessThanOrEqual(400); |
82 | 87 | expect(summary?.text.endsWith("…")).toBe(true); |
83 | 88 | }); |
| 89 | + |
| 90 | +it("keeps truncated parent text well-formed when truncating surrogate pairs", () => { |
| 91 | +const msg: GraphThreadMessage = { |
| 92 | +id: "p1", |
| 93 | +from: { user: { displayName: "Dana" } }, |
| 94 | +body: { content: `${"a".repeat(398)}🦞${"b".repeat(50)}`, contentType: "text" }, |
| 95 | +}; |
| 96 | + |
| 97 | +const summary = summarizeParentMessage(msg); |
| 98 | + |
| 99 | +expect(summary?.text).not.toMatch(UNPAIRED_SURROGATE_RE); |
| 100 | +expect(summary?.text).toBe(`${"a".repeat(398)}…`); |
| 101 | +expect(summary?.text.endsWith("\ud83e…")).toBe(false); |
| 102 | +}); |
84 | 103 | }); |
85 | 104 | |
86 | 105 | describe("formatParentContextEvent", () => { |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -17,6 +17,7 @@ import {
|
17 | 17 | asDateTimestampMs, |
18 | 18 | resolveExpiresAtMsFromDurationMs, |
19 | 19 | } from "openclaw/plugin-sdk/number-runtime"; |
| 20 | +import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime"; |
20 | 21 | import { fetchChannelMessage, stripHtmlFromTeamsMessage } from "./graph-thread.js"; |
21 | 22 | import type { GraphThreadMessage } from "./graph-thread.js"; |
22 | 23 | |
@@ -138,7 +139,9 @@ export function summarizeParentMessage(
|
138 | 139 | return { |
139 | 140 | sender, |
140 | 141 | text: |
141 | | -text.length > PARENT_TEXT_MAX_CHARS ? `${text.slice(0, PARENT_TEXT_MAX_CHARS - 1)}…` : text, |
| 142 | +text.length > PARENT_TEXT_MAX_CHARS |
| 143 | + ? `${truncateUtf16Safe(text, PARENT_TEXT_MAX_CHARS - 1)}…` |
| 144 | + : text, |
142 | 145 | }; |
143 | 146 | } |
144 | 147 | |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。