mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 20:05:46 -06:00
fix(cli): avoid duplicate commentary delivery (#115596)
This commit is contained in:
committed by
GitHub
parent
520e9fe1dd
commit
a3a969be5d
@@ -209,6 +209,7 @@ export type GetReplyOptions = {
|
||||
meta?: string;
|
||||
approvalId?: string;
|
||||
approvalSlug?: string;
|
||||
suppressDurableProgress?: true;
|
||||
}) => Promise<ProgressCallbackResult> | ProgressCallbackResult;
|
||||
/**
|
||||
* Called when the utility-model narration of the in-progress turn changes.
|
||||
|
||||
@@ -257,6 +257,8 @@ export async function runCliFallbackCandidate(params: {
|
||||
itemId: payload.itemId,
|
||||
kind: "preamble",
|
||||
progressText: payload.text,
|
||||
// The block bridge owns durability; this event remains a progress preview.
|
||||
...(bridgeCliDurableCommentary ? { suppressDurableProgress: true } : {}),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -188,6 +188,7 @@ describe("executeAgentTurn: CLI durable commentary", () => {
|
||||
itemId: "commentary-durable-1",
|
||||
kind: "preamble",
|
||||
progressText: "The durable findings live here.",
|
||||
suppressDurableProgress: true,
|
||||
});
|
||||
});
|
||||
expect(result.kind).toBe("success");
|
||||
|
||||
@@ -422,14 +422,18 @@ export async function prepareDispatchExecution(state: ChooseDispatchRouteReadySt
|
||||
suppressAutomaticSourceDelivery &&
|
||||
allowSuppressedSourceProgressCallbacks &&
|
||||
canForwardItemEvents;
|
||||
const shouldDeliverDurableCommentaryProgress = (
|
||||
payload: Parameters<NonNullable<GetReplyOptions["onItemEvent"]>>[0],
|
||||
) =>
|
||||
deliverStandaloneCommentaryProgress &&
|
||||
payload.kind === "preamble" &&
|
||||
payload.suppressDurableProgress !== true;
|
||||
const forwardItemEvent = canForwardItemEvents
|
||||
? wrapProgressCallback(params.replyOptions?.onItemEvent, {
|
||||
...itemEventForwardingOptions,
|
||||
waitForDirectBlockReplyDelivery: true,
|
||||
onForward: (payload) =>
|
||||
preserveProgressCallbackStartOrder &&
|
||||
deliverStandaloneCommentaryProgress &&
|
||||
payload.kind === "preamble"
|
||||
preserveProgressCallbackStartOrder && shouldDeliverDurableCommentaryProgress(payload)
|
||||
? noteCommentaryProgress(payload)
|
||||
: undefined,
|
||||
onVisible: (payload) => {
|
||||
@@ -453,8 +457,7 @@ export async function prepareDispatchExecution(state: ChooseDispatchRouteReadySt
|
||||
}
|
||||
if (
|
||||
(!forwardItemEvent || !preserveProgressCallbackStartOrder) &&
|
||||
deliverStandaloneCommentaryProgress &&
|
||||
payload.kind === "preamble"
|
||||
shouldDeliverDurableCommentaryProgress(payload)
|
||||
) {
|
||||
await noteCommentaryProgress(payload);
|
||||
}
|
||||
|
||||
@@ -92,6 +92,61 @@ describe("dispatchReplyFromConfig", () => {
|
||||
expect(activeDuringOffRun).toBe(false);
|
||||
});
|
||||
|
||||
it("keeps block-owned commentary out of the standalone durable progress lane", async () => {
|
||||
setNoAbort();
|
||||
sessionStoreMocks.currentEntry = {
|
||||
verboseLevel: "on",
|
||||
};
|
||||
const dispatcher = createDispatcher();
|
||||
const ctx = buildTestCtx({
|
||||
Provider: "discord",
|
||||
Surface: "discord",
|
||||
ChatType: "direct",
|
||||
});
|
||||
const onItemEvent = vi.fn();
|
||||
|
||||
const replyResolver = async (
|
||||
_ctx: MsgContext,
|
||||
opts?: GetReplyOptions,
|
||||
_cfg?: OpenClawConfig,
|
||||
) => {
|
||||
await opts?.onItemEvent?.({
|
||||
itemId: "commentary-1",
|
||||
kind: "preamble",
|
||||
progressText: "Inspecting the dispatch path.",
|
||||
suppressDurableProgress: true,
|
||||
});
|
||||
await opts?.onBlockReply?.({ text: "Inspecting the dispatch path." });
|
||||
return { text: "Done." } satisfies ReplyPayload;
|
||||
};
|
||||
|
||||
await dispatchReplyFromConfig({
|
||||
ctx,
|
||||
cfg: emptyConfig,
|
||||
dispatcher,
|
||||
replyResolver,
|
||||
replyOptions: {
|
||||
suppressDefaultToolProgressMessages: true,
|
||||
commentaryProgressEnabled: true,
|
||||
progressPreambleEnabled: true,
|
||||
commentaryPayloadsEnabled: true,
|
||||
onItemEvent,
|
||||
},
|
||||
});
|
||||
|
||||
expect(onItemEvent).toHaveBeenCalledExactlyOnceWith({
|
||||
itemId: "commentary-1",
|
||||
kind: "preamble",
|
||||
progressText: "Inspecting the dispatch path.",
|
||||
suppressDurableProgress: true,
|
||||
});
|
||||
expect(dispatcher.sendToolResult).not.toHaveBeenCalled();
|
||||
expect(dispatcher.sendBlockReply).toHaveBeenCalledExactlyOnceWith({
|
||||
text: "Inspecting the dispatch path.",
|
||||
});
|
||||
expect(dispatcher.sendFinalReply).toHaveBeenCalledExactlyOnceWith({ text: "Done." });
|
||||
});
|
||||
|
||||
it("forwards channel-owned group progress callbacks while source delivery is suppressed", async () => {
|
||||
setNoAbort();
|
||||
sessionStoreMocks.currentEntry = {
|
||||
|
||||
Reference in New Issue
Block a user