mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-29 10:02:04 +00:00
fix: prevent delivery-mirror re-delivery and raise Slack chunk limit (#45489)
Merged via squash.
Prepared head SHA: c7664c7b6e
Co-authored-by: theo674 <261068216+theo674@users.noreply.github.com>
Co-authored-by: altaywtf <9790196+altaywtf@users.noreply.github.com>
Reviewed-by: @altaywtf
This commit is contained in:
@@ -38,6 +38,15 @@ const stripTrailingDirective = (text: string): string => {
|
||||
return text.slice(0, openIndex);
|
||||
};
|
||||
|
||||
function isTranscriptOnlyOpenClawAssistantMessage(message: AgentMessage | undefined): boolean {
|
||||
if (!message || message.role !== "assistant") {
|
||||
return false;
|
||||
}
|
||||
const provider = typeof message.provider === "string" ? message.provider.trim() : "";
|
||||
const model = typeof message.model === "string" ? message.model.trim() : "";
|
||||
return provider === "openclaw" && (model === "delivery-mirror" || model === "gateway-injected");
|
||||
}
|
||||
|
||||
function emitReasoningEnd(ctx: EmbeddedPiSubscribeContext) {
|
||||
if (!ctx.state.reasoningStreamOpen) {
|
||||
return;
|
||||
@@ -134,7 +143,7 @@ export function handleMessageStart(
|
||||
evt: AgentEvent & { message: AgentMessage },
|
||||
) {
|
||||
const msg = evt.message;
|
||||
if (msg?.role !== "assistant") {
|
||||
if (msg?.role !== "assistant" || isTranscriptOnlyOpenClawAssistantMessage(msg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -153,7 +162,7 @@ export function handleMessageUpdate(
|
||||
evt: AgentEvent & { message: AgentMessage; assistantMessageEvent?: unknown },
|
||||
) {
|
||||
const msg = evt.message;
|
||||
if (msg?.role !== "assistant") {
|
||||
if (msg?.role !== "assistant" || isTranscriptOnlyOpenClawAssistantMessage(msg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -323,7 +332,7 @@ export function handleMessageEnd(
|
||||
evt: AgentEvent & { message: AgentMessage },
|
||||
) {
|
||||
const msg = evt.message;
|
||||
if (msg?.role !== "assistant") {
|
||||
if (msg?.role !== "assistant" || isTranscriptOnlyOpenClawAssistantMessage(msg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,10 +42,15 @@ async function emitMessageToolLifecycle(params: {
|
||||
});
|
||||
}
|
||||
|
||||
function emitAssistantMessageEnd(emit: (evt: unknown) => void, text: string) {
|
||||
function emitAssistantMessageEnd(
|
||||
emit: (evt: unknown) => void,
|
||||
text: string,
|
||||
overrides?: Partial<AssistantMessage>,
|
||||
) {
|
||||
const assistantMessage = {
|
||||
role: "assistant",
|
||||
content: [{ type: "text", text }],
|
||||
...overrides,
|
||||
} as AssistantMessage;
|
||||
emit({ type: "message_end", message: assistantMessage });
|
||||
}
|
||||
@@ -68,6 +73,7 @@ describe("subscribeEmbeddedPiSession", () => {
|
||||
result: "ok",
|
||||
});
|
||||
emitAssistantMessageEnd(emit, messageText);
|
||||
await Promise.resolve();
|
||||
|
||||
expect(onBlockReply).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -82,16 +88,44 @@ describe("subscribeEmbeddedPiSession", () => {
|
||||
result: { details: { status: "error" } },
|
||||
});
|
||||
emitAssistantMessageEnd(emit, messageText);
|
||||
await Promise.resolve();
|
||||
|
||||
expect(onBlockReply).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
it("clears block reply state on message_start", () => {
|
||||
|
||||
it("ignores delivery-mirror assistant messages", async () => {
|
||||
const { emit, onBlockReply } = createBlockReplyHarness("message_end");
|
||||
|
||||
emitAssistantMessageEnd(emit, "Mirrored transcript text", {
|
||||
provider: "openclaw",
|
||||
model: "delivery-mirror",
|
||||
});
|
||||
await Promise.resolve();
|
||||
|
||||
expect(onBlockReply).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("ignores gateway-injected assistant messages", async () => {
|
||||
const { emit, onBlockReply } = createBlockReplyHarness("message_end");
|
||||
|
||||
emitAssistantMessageEnd(emit, "Injected transcript text", {
|
||||
provider: "openclaw",
|
||||
model: "gateway-injected",
|
||||
});
|
||||
await Promise.resolve();
|
||||
|
||||
expect(onBlockReply).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("clears block reply state on message_start", async () => {
|
||||
const { emit, onBlockReply } = createBlockReplyHarness("text_end");
|
||||
emitAssistantTextEndBlock(emit, "OK");
|
||||
await Promise.resolve();
|
||||
expect(onBlockReply).toHaveBeenCalledTimes(1);
|
||||
|
||||
// New assistant message with identical output should still emit.
|
||||
emitAssistantTextEndBlock(emit, "OK");
|
||||
await Promise.resolve();
|
||||
expect(onBlockReply).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user