mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
fix(qqbot): sanitize outbound text to strip reasoning/thinking content (#90132)
Summary: - Adds QQBot outbound `sanitizeText` wired to `sanitizeAssistantVisibleText` plus a regression test for stripping `<thinking>` and `<think>` blocks. - PR surface: Source +2, Tests +19. Total +21 across 2 files. - Reproducibility: yes. source-reproducible: current main QQBot outbound lacks `sanitizeText`, and shared deli ... nnel text sanitization when that hook exists. I did not run a live Tencent QQBot plus MiniMax reproduction. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(qqbot): add curly braces for eslint(curly) compliance Validation: - ClawSweeper review passed for head17cf140183. - Required merge gates passed before the squash merge. Prepared head SHA:17cf140183Review: https://github.com/openclaw/openclaw/pull/90132#issuecomment-4618527026 Co-authored-by: openperf <16864032@qq.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
This commit is contained in:
@@ -4,6 +4,25 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { qqbotPlugin } from "./channel.js";
|
||||
|
||||
describe("qqbot outbound sanitizeText", () => {
|
||||
it("strips reasoning/thinking tags before delivery", () => {
|
||||
const sanitize = qqbotPlugin.outbound?.sanitizeText;
|
||||
expect(sanitize).toBeDefined();
|
||||
if (!sanitize) {
|
||||
return;
|
||||
}
|
||||
|
||||
const input1 = "<thinking>internal reasoning</thinking>final answer";
|
||||
expect(sanitize({ text: input1, payload: { text: input1 } })).toBe("final answer");
|
||||
|
||||
const input2 = "<think>step by step</think>result";
|
||||
expect(sanitize({ text: input2, payload: { text: input2 } })).toBe("result");
|
||||
|
||||
const input3 = "plain text without tags";
|
||||
expect(sanitize({ text: input3, payload: { text: input3 } })).toBe("plain text without tags");
|
||||
});
|
||||
});
|
||||
|
||||
const sendTextMock = vi.hoisted(() => vi.fn());
|
||||
const sendMediaMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from "openclaw/plugin-sdk/channel-outbound";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
import type { ChannelPlugin } from "openclaw/plugin-sdk/core";
|
||||
import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
|
||||
// Register the PlatformAdapter before any core/ module is used.
|
||||
import "./bridge/bootstrap.js";
|
||||
import { getQQBotApprovalCapability } from "./bridge/approval/capability.js";
|
||||
@@ -254,6 +255,7 @@ export const qqbotPlugin: ChannelPlugin<ResolvedQQBotAccount> = {
|
||||
chunker: (text, limit) => getQQBotRuntime().channel.text.chunkMarkdownText(text, limit),
|
||||
chunkerMode: "markdown",
|
||||
textChunkLimit: 5000,
|
||||
sanitizeText: ({ text }) => sanitizeAssistantVisibleText(text),
|
||||
shouldSuppressLocalPayloadPrompt: ({ cfg, accountId, payload, hint }) =>
|
||||
shouldSuppressLocalQQBotApprovalPrompt({
|
||||
cfg,
|
||||
|
||||
Reference in New Issue
Block a user