mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 17:00:50 +00:00
fix(slack): suppress reasoning in native streams
This commit is contained in:
@@ -14,6 +14,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Providers/GitHub Copilot: keep the plugin stream wrapper from claiming transport selection before OpenClaw picks a boundary-aware stream path, avoiding Pi's stale fallback Copilot headers on normal model turns. Thanks @steipete.
|
||||
- Discord/subagents: pass runtime config into thread-bound native subagent binding and require it at the helper boundary so Discord channel resolution keeps account-aware config. Fixes #71054. (#70945) Thanks @jai.
|
||||
- Slack/Assistant: accept Slack Assistant DM `message_changed` events when their metadata identifies the human sender, while continuing to drop self-authored bot edits. Fixes #55445. Thanks @AlfredPros.
|
||||
- Slack/native streaming: suppress reasoning-only payloads before `chat.startStream`/`appendStream`, so Claude extended-thinking blocks no longer appear as visible Slack messages. Fixes #59687. Thanks @vision-ifc.
|
||||
- Slack/block replies: keep multi-part block deliveries in the first Slack reply thread when `replyToMode` is `first`, matching text reply threading instead of leaking later blocks into the channel. Fixes #49341. Thanks @pholmstr and @xiwuqi.
|
||||
- Agents/failover: stop body-less HTTP 400/422 proxy failures from defaulting to `"format"` classification, so embedded retries surface the opaque provider failure instead of falling into a compaction loop. Fixes #66462. (#67024) Thanks @altaywtf and @HongzhuLiu.
|
||||
- Plugins/loader: use cached discovery-mode snapshot loads for read-only plugin capability lookups, keep snapshot caches isolated from active Gateway registries, and make same-plugin channel/HTTP route re-registration idempotent so repeated snapshot or hot-reload paths no longer rerun full plugin side effects or accumulate duplicate surfaces. Fixes #51781, #52031, #54181, and #57514. Thanks @livingghost, @okuyam2y, @ShionEria, and @bbshih.
|
||||
|
||||
@@ -34,7 +34,13 @@ let mockedReplyThreadTs: string | undefined = THREAD_TS;
|
||||
let mockedReplyThreadTsSequence: Array<string | undefined> | undefined;
|
||||
let mockedDispatchSequence: Array<{
|
||||
kind: "tool" | "block" | "final";
|
||||
payload: { text: string; isError?: boolean; mediaUrl?: string; mediaUrls?: string[] };
|
||||
payload: {
|
||||
text: string;
|
||||
isError?: boolean;
|
||||
isReasoning?: boolean;
|
||||
mediaUrl?: string;
|
||||
mediaUrls?: string[];
|
||||
};
|
||||
}> = [];
|
||||
|
||||
const noop = () => {};
|
||||
@@ -289,7 +295,13 @@ vi.mock("../reply.runtime.js", () => ({
|
||||
replyOptions?: { disableBlockStreaming?: boolean };
|
||||
dispatcher: {
|
||||
deliver: (
|
||||
payload: { text: string; isError?: boolean; mediaUrl?: string; mediaUrls?: string[] },
|
||||
payload: {
|
||||
text: string;
|
||||
isError?: boolean;
|
||||
isReasoning?: boolean;
|
||||
mediaUrl?: string;
|
||||
mediaUrls?: string[];
|
||||
},
|
||||
info: { kind: "tool" | "block" | "final" },
|
||||
) => Promise<void>;
|
||||
};
|
||||
@@ -389,6 +401,25 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
|
||||
expect(deliverRepliesMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("suppresses reasoning payloads before Slack native streaming delivery", async () => {
|
||||
mockedNativeStreaming = true;
|
||||
mockedDispatchSequence = [
|
||||
{ kind: "block", payload: { text: "Reasoning:\n_hidden_", isReasoning: true } },
|
||||
{ kind: "final", payload: { text: FINAL_REPLY_TEXT } },
|
||||
];
|
||||
|
||||
await dispatchPreparedSlackMessage(createPreparedSlackMessage());
|
||||
|
||||
expect(startSlackStreamMock).toHaveBeenCalledTimes(1);
|
||||
expect(startSlackStreamMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
text: FINAL_REPLY_TEXT,
|
||||
}),
|
||||
);
|
||||
expect(appendSlackStreamMock).not.toHaveBeenCalled();
|
||||
expect(deliverRepliesMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("keeps same-content tool and final payloads distinct after preview fallback", async () => {
|
||||
mockedDispatchSequence = [
|
||||
{ kind: "tool", payload: { text: SAME_TEXT } },
|
||||
|
||||
@@ -589,6 +589,9 @@ export async function dispatchPreparedSlackMessage(prepared: PreparedSlackMessag
|
||||
payload: ReplyPayload;
|
||||
kind: ReplyDispatchKind;
|
||||
}): Promise<void> => {
|
||||
if (params.payload.isReasoning === true) {
|
||||
return;
|
||||
}
|
||||
const reply = resolveSendableOutboundReplyParts(params.payload);
|
||||
if (
|
||||
streamFailed ||
|
||||
|
||||
Reference in New Issue
Block a user