mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 16:40:49 +00:00
fix: suppress Mattermost quoted reasoning replies (#69927) (thanks @lawrence3699)
This commit is contained in:
@@ -257,7 +257,7 @@ describe("deliverMattermostReplyWithDraftPreview", () => {
|
||||
const deliverFinal = vi.fn(async () => {});
|
||||
|
||||
await deliverMattermostReplyWithDraftPreview({
|
||||
payload: { text: " \n Reasoning:\n_hidden_" } as never,
|
||||
payload: { text: " \n > Reasoning:\n> _hidden_" } as never,
|
||||
info: { kind: "final" },
|
||||
client: createMattermostClientMock(),
|
||||
draftStream,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { deliverFinalizableDraftPreview } from "openclaw/plugin-sdk/channel-lifecycle";
|
||||
import { createClaimableDedupe, type ClaimableDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
|
||||
import { isReasoningReplyPayload } from "openclaw/plugin-sdk/reply-payload";
|
||||
import { isPrivateNetworkOptInEnabled } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
@@ -55,10 +56,7 @@ import {
|
||||
type MattermostWebSocketFactory,
|
||||
} from "./monitor-websocket.js";
|
||||
import { runWithReconnect } from "./reconnect.js";
|
||||
import {
|
||||
deliverMattermostReplyPayload,
|
||||
shouldSuppressMattermostReasoningReply,
|
||||
} from "./reply-delivery.js";
|
||||
import { deliverMattermostReplyPayload } from "./reply-delivery.js";
|
||||
import type {
|
||||
ChannelAccountSnapshot,
|
||||
ChatType,
|
||||
@@ -292,7 +290,7 @@ type MattermostDraftPreviewDeliverParams = {
|
||||
export async function deliverMattermostReplyWithDraftPreview(
|
||||
params: MattermostDraftPreviewDeliverParams,
|
||||
): Promise<void> {
|
||||
if (shouldSuppressMattermostReasoningReply(params.payload)) {
|
||||
if (isReasoningReplyPayload(params.payload)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,27 @@ describe("deliverMattermostReplyPayload", () => {
|
||||
expect(sendMessage).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("suppresses reasoning payloads formatted as a Mattermost blockquote", async () => {
|
||||
const sendMessage = vi.fn(async () => undefined);
|
||||
const cfg = {} satisfies OpenClawConfig;
|
||||
const core = createReplyDeliveryCore();
|
||||
|
||||
await deliverMattermostReplyPayload({
|
||||
core,
|
||||
cfg,
|
||||
payload: { text: "> Reasoning:\n> _hidden_" },
|
||||
to: "channel:town-square",
|
||||
accountId: "default",
|
||||
agentId: "agent-1",
|
||||
replyToId: "root-post",
|
||||
textLimit: 4000,
|
||||
tableMode: "off",
|
||||
sendMessage,
|
||||
});
|
||||
|
||||
expect(sendMessage).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not suppress messages that mention Reasoning: mid-text", async () => {
|
||||
const sendMessage = vi.fn(async () => undefined);
|
||||
const cfg = {} satisfies OpenClawConfig;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {
|
||||
deliverTextOrMediaReply,
|
||||
isReasoningReplyPayload,
|
||||
resolveSendableOutboundReplyParts,
|
||||
} from "openclaw/plugin-sdk/reply-payload";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
getAgentScopedMediaLocalRoots,
|
||||
type OpenClawConfig,
|
||||
@@ -24,19 +24,6 @@ type SendMattermostMessage = (
|
||||
},
|
||||
) => Promise<unknown>;
|
||||
|
||||
const REASONING_PREFIX = "reasoning:";
|
||||
|
||||
export function shouldSuppressMattermostReasoningReply(payload: ReplyPayload): boolean {
|
||||
if (payload.isReasoning === true) {
|
||||
return true;
|
||||
}
|
||||
const text = payload.text;
|
||||
if (typeof text !== "string") {
|
||||
return false;
|
||||
}
|
||||
return normalizeLowercaseStringOrEmpty(text.trimStart()).startsWith(REASONING_PREFIX);
|
||||
}
|
||||
|
||||
export async function deliverMattermostReplyPayload(params: {
|
||||
core: PluginRuntime;
|
||||
cfg: OpenClawConfig;
|
||||
@@ -49,7 +36,7 @@ export async function deliverMattermostReplyPayload(params: {
|
||||
tableMode: MarkdownTableMode;
|
||||
sendMessage: SendMattermostMessage;
|
||||
}): Promise<void> {
|
||||
if (shouldSuppressMattermostReasoningReply(params.payload)) {
|
||||
if (isReasoningReplyPayload(params.payload)) {
|
||||
return;
|
||||
}
|
||||
const reply = resolveSendableOutboundReplyParts(params.payload, {
|
||||
|
||||
@@ -101,6 +101,10 @@ describe("deliverWebReply", () => {
|
||||
await expectReplySuppressed({ text: " \n Reasoning:\n_hidden_" });
|
||||
});
|
||||
|
||||
it("suppresses payloads that start with a quoted reasoning prefix", async () => {
|
||||
await expectReplySuppressed({ text: " > Reasoning:\n> _hidden_" });
|
||||
});
|
||||
|
||||
it("does not suppress messages that mention Reasoning: mid-text", async () => {
|
||||
const msg = makeMsg();
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@ import type { MarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { chunkMarkdownTextWithMode, type ChunkMode } from "openclaw/plugin-sdk/reply-chunking";
|
||||
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-chunking";
|
||||
import {
|
||||
isReasoningReplyPayload,
|
||||
resolveOutboundMediaUrls,
|
||||
sendMediaWithLeadingCaption,
|
||||
} from "openclaw/plugin-sdk/reply-payload";
|
||||
import { logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { loadWebMedia } from "../media.js";
|
||||
import { newConnectionId } from "../reconnect.js";
|
||||
import { formatError } from "../session.js";
|
||||
@@ -16,19 +16,6 @@ import { whatsappOutboundLog } from "./loggers.js";
|
||||
import type { WebInboundMsg } from "./types.js";
|
||||
import { elide } from "./util.js";
|
||||
|
||||
const REASONING_PREFIX = "reasoning:";
|
||||
|
||||
function shouldSuppressReasoningReply(payload: ReplyPayload): boolean {
|
||||
if (payload.isReasoning === true) {
|
||||
return true;
|
||||
}
|
||||
const text = payload.text;
|
||||
if (typeof text !== "string") {
|
||||
return false;
|
||||
}
|
||||
return normalizeLowercaseStringOrEmpty(text.trimStart()).startsWith(REASONING_PREFIX);
|
||||
}
|
||||
|
||||
export async function deliverWebReply(params: {
|
||||
replyResult: ReplyPayload;
|
||||
msg: WebInboundMsg;
|
||||
@@ -46,7 +33,7 @@ export async function deliverWebReply(params: {
|
||||
}) {
|
||||
const { replyResult, msg, maxMediaBytes, textLimit, replyLogger, connectionId, skipLog } = params;
|
||||
const replyStarted = Date.now();
|
||||
if (shouldSuppressReasoningReply(replyResult)) {
|
||||
if (isReasoningReplyPayload(replyResult)) {
|
||||
whatsappOutboundLog.debug(`Suppressed reasoning payload to ${msg.from}`);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user