mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 21:07:01 -06:00
fix(agents): keep exec auto-reviewer rationale truncation UTF-16 safe (#101513)
* fix(agents): keep exec auto-reviewer rationale truncation UTF-16 safe String.prototype.slice at offset 500 can split surrogate pairs in LLM-generated review rationale text, rendering broken U+FFFD in exec approval UI payloads. Replace raw slice(0, 500) with truncateUtf16Safe. * fix(agents): keep exec reviewer rationale and prompt template description truncation UTF-16 safe String.prototype.slice can split surrogate pairs at truncation boundaries, producing broken U+FFFD in both exec approval rationale (500 chars) and session prompt-template descriptions (60 chars). Replace raw slice with truncateUtf16Safe in both locations. * test(exec): cover UTF-16-safe reviewer rationale --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -118,6 +118,24 @@ describe("parseExecAutoReviewResponse", () => {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("does not split surrogate pairs when truncating rationale", () => {
|
||||
const rationale = "x".repeat(499) + "🚀tail";
|
||||
|
||||
expect(
|
||||
parseExecAutoReviewResponse(
|
||||
JSON.stringify({
|
||||
decision: "ask",
|
||||
risk: "medium",
|
||||
rationale,
|
||||
}),
|
||||
),
|
||||
).toEqual({
|
||||
decision: "ask",
|
||||
risk: "medium",
|
||||
rationale: "x".repeat(499),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("createModelExecAutoReviewer", () => {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion";
|
||||
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
|
||||
import { truncateUtf16Safe } from "@openclaw/normalization-core/utf16-slice";
|
||||
import { z } from "zod";
|
||||
import type { AgentModelConfig } from "../config/types.agents-shared.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
@@ -76,7 +77,7 @@ function buildReviewerUserPrompt(input: ExecAutoReviewInput): string {
|
||||
|
||||
function normalizeRationale(value: unknown, fallback: string): string {
|
||||
const text = normalizeOptionalString(typeof value === "string" ? value : undefined);
|
||||
return (text ?? fallback).slice(0, 500);
|
||||
return truncateUtf16Safe(text ?? fallback, 500);
|
||||
}
|
||||
|
||||
function textLooksLikeReviewerDirective(value: string): boolean {
|
||||
|
||||
Reference in New Issue
Block a user