mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-30 10:10:18 +00:00
fix: strip leading whitespace from sanitizeUserFacingText output (#16158)
* fix: strip leading whitespace from sanitizeUserFacingText output LLM responses frequently begin with \n\n, which survives through sanitizeUserFacingText and reaches the channel as visible blank lines. Root cause: the function used trimmed text for empty-checks but returned the untrimmed 'stripped' variable. Two one-line fixes: 1. Return empty string (not whitespace-only 'stripped') for blank input 2. Apply trimStart() to the final return value Fixes the same issue as #8052 and #10612 but at the root cause (sanitizeUserFacingText) rather than scattering trimStart across multiple delivery paths. * Changelog: note sanitizeUserFacingText whitespace normalization Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
@@ -56,6 +56,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Security/Audit: warn when `gateway.tools.allow` re-enables default-denied tools over HTTP `POST /tools/invoke`, since this can increase RCE blast radius if the gateway is reachable.
|
||||
- Security/Plugins/Hooks: harden npm-based installs by restricting specs to registry packages only, passing `--ignore-scripts` to `npm pack`, and cleaning up temp install directories.
|
||||
- Feishu: stop persistent Typing reaction on NO_REPLY/suppressed runs by wiring reply-dispatcher cleanup to remove typing indicators. (#15464) Thanks @arosstale.
|
||||
- Agents: strip leading whitespace/newlines from `sanitizeUserFacingText` output and normalize whitespace-only outputs to empty text. (#16158) Thanks @mcinteerj.
|
||||
- BlueBubbles: gracefully degrade when Private API is disabled by filtering private-only actions, skipping private-only reactions/reply effects, and avoiding private reply markers so non-private flows remain usable. (#16002) Thanks @L-U-C-K-Y.
|
||||
- Outbound: add a write-ahead delivery queue with crash-recovery retries to prevent lost outbound messages after gateway restarts. (#15636) Thanks @nabbilkhan, @thewilloftheshadow.
|
||||
- Auto-reply/Threading: auto-inject implicit reply threading so `replyToMode` works without requiring model-emitted `[[reply_to_current]]`, while preserving `replyToMode: "off"` behavior for implicit Slack replies and keeping block-streaming chunk coalescing stable under `replyToMode: "first"`. (#14976) Thanks @Diaspar4u.
|
||||
|
||||
@@ -69,4 +69,25 @@ describe("sanitizeUserFacingText", () => {
|
||||
const text = "Hello there!\n\nDifferent line.";
|
||||
expect(sanitizeUserFacingText(text)).toBe(text);
|
||||
});
|
||||
|
||||
it("strips leading newlines from LLM output", () => {
|
||||
expect(sanitizeUserFacingText("\n\nHello there!")).toBe("Hello there!");
|
||||
expect(sanitizeUserFacingText("\nHello there!")).toBe("Hello there!");
|
||||
expect(sanitizeUserFacingText("\n\n\nMultiple newlines")).toBe("Multiple newlines");
|
||||
});
|
||||
|
||||
it("strips leading whitespace and newlines combined", () => {
|
||||
expect(sanitizeUserFacingText("\n \n Hello")).toBe("Hello");
|
||||
expect(sanitizeUserFacingText(" \n\nHello")).toBe("Hello");
|
||||
});
|
||||
|
||||
it("preserves trailing whitespace and internal newlines", () => {
|
||||
expect(sanitizeUserFacingText("Hello\n\nWorld\n")).toBe("Hello\n\nWorld\n");
|
||||
expect(sanitizeUserFacingText("Line 1\nLine 2")).toBe("Line 1\nLine 2");
|
||||
});
|
||||
|
||||
it("returns empty for whitespace-only input", () => {
|
||||
expect(sanitizeUserFacingText("\n\n")).toBe("");
|
||||
expect(sanitizeUserFacingText(" \n ")).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -488,7 +488,7 @@ export function sanitizeUserFacingText(text: string, opts?: { errorContext?: boo
|
||||
const stripped = stripFinalTagsFromText(text);
|
||||
const trimmed = stripped.trim();
|
||||
if (!trimmed) {
|
||||
return stripped;
|
||||
return "";
|
||||
}
|
||||
|
||||
// Only apply error-pattern rewrites when the caller knows this text is an error payload.
|
||||
@@ -527,7 +527,7 @@ export function sanitizeUserFacingText(text: string, opts?: { errorContext?: boo
|
||||
}
|
||||
}
|
||||
|
||||
return collapseConsecutiveDuplicateBlocks(stripped);
|
||||
return collapseConsecutiveDuplicateBlocks(stripped).trimStart();
|
||||
}
|
||||
|
||||
export function isRateLimitAssistantError(msg: AssistantMessage | undefined): boolean {
|
||||
|
||||
Reference in New Issue
Block a user