fix(slack): sanitize internal tool-trace lines from outbound text (#97367)

Wrap the slack outbound sanitizeText hook with sanitizeAssistantVisibleText so assistant internal tool-trace scaffolding is stripped before delivery, matching the sibling channel fixes under #90684 (Telegram #95774, Google Chat #95084, IRC #97214).
This commit is contained in:
Masato Hoshino
2026-06-28 12:14:35 -07:00
committed by GitHub
parent 20645753a4
commit cd6d0f9b00
2 changed files with 21 additions and 0 deletions
+2
View File
@@ -30,6 +30,7 @@ import {
normalizeLowercaseStringOrEmpty,
normalizeOptionalString,
} from "openclaw/plugin-sdk/string-coerce-runtime";
import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
import {
resolveDefaultSlackAccountId,
resolveSlackAccount,
@@ -423,6 +424,7 @@ const slackChannelOutbound: ChannelOutboundAdapter = {
deliveryMode: "direct",
chunker: null,
textChunkLimit: SLACK_TEXT_LIMIT,
sanitizeText: ({ text }) => sanitizeAssistantVisibleText(text),
normalizePayload: ({ payload, cfg, accountId }) =>
isSlackInteractiveRepliesEnabled({ cfg, accountId })
? compileSlackInteractiveReplies(payload)
@@ -0,0 +1,19 @@
// Slack outbound must strip assistant internal tool-trace scaffolding, matching
// the sibling channel fixes tracked under #90684 (Telegram #95774 / Google Chat
// #95084 / IRC #97214). sanitizeAssistantVisibleText keeps mrkdwn formatting.
import { describe, expect, it } from "vitest";
import { slackPlugin } from "./channel.js";
describe("slack outbound sanitizeText", () => {
it("strips internal tool-trace banners before outbound delivery", () => {
const text = "Done.\n⚠️ 🛠️ `search repos (agent)` failed";
expect(slackPlugin.outbound?.sanitizeText?.({ text, payload: { text } })).toBe("Done.");
});
it("preserves ordinary assistant prose while sanitizing", () => {
const text = "The pipeline has 3 open deals.";
expect(slackPlugin.outbound?.sanitizeText?.({ text, payload: { text } })).toBe(text);
});
});