From 085bf9ffb66ef3bf08d6ffe984aa25a61c9be973 Mon Sep 17 00:00:00 2001 From: Harjoth Khara Date: Thu, 27 Aug 2026 07:16:56 -0700 Subject: [PATCH] fix(cron): report verified mode-none delivery (#118260) Report a verified agent message-tool send as delivered for mode-none cron jobs while keeping no-send runs not-requested. Co-authored-by: Harjoth Khara Co-authored-by: Ayaan Zaidi --- .../service.persists-delivered-status.test.ts | 40 ++++++++--------- src/cron/service/timer-trigger.ts | 45 ++++++++----------- 2 files changed, 37 insertions(+), 48 deletions(-) diff --git a/src/cron/service.persists-delivered-status.test.ts b/src/cron/service.persists-delivered-status.test.ts index 51d257b054e2..f3d51afa2a66 100644 --- a/src/cron/service.persists-delivered-status.test.ts +++ b/src/cron/service.persists-delivered-status.test.ts @@ -732,17 +732,29 @@ describe("CronService persists delivered status", () => { } }); - it("persists lastDelivered=true when isolated job reports delivered", async () => { + it("persists and emits verified mode-none message-tool delivery", async () => { + let finishedEvent: { delivered?: boolean; deliveryStatus?: string } | undefined; const updated = await runIsolatedJobAndReadState({ - job: buildAnnounceIsolatedAgentTurnJob("delivered-true"), + job: { + ...buildIsolatedAgentTurnJob("mode-none-verified-delivery"), + delivery: { mode: "none", channel: "forum", to: "123" }, + }, delivered: true, + delivery: { + delivered: true, + resolved: { ok: true, channel: "forum", to: "123" }, + messageToolSentTo: [{ channel: "forum", to: "123" }], + }, + onFinished: (event) => (finishedEvent = event), }); + expectSuccessfulCronRun(updated); - expect(updated?.state.lastDelivered).toBe(true); - expect(updated?.state.lastDeliveryStatus).toBe("delivered"); - expect(updated?.state.lastDeliveryError).toBeUndefined(); - expect(updated?.state.lastFailureNotificationDelivered).toBeUndefined(); - expect(updated?.state.lastFailureNotificationDeliveryStatus).toBe("not-requested"); + expect(updated?.state).toMatchObject({ + lastDelivered: true, + lastDeliveryStatus: "delivered", + lastFailureNotificationDeliveryStatus: "not-requested", + }); + expect(finishedEvent).toMatchObject({ delivered: true, deliveryStatus: "delivered" }); }); it("persists lastDelivered=false when isolated job explicitly reports not delivered", async () => { @@ -926,20 +938,6 @@ describe("CronService persists delivered status", () => { cron.stop(); }); - it("emits delivered in the finished event", async () => { - let capturedEvent: { jobId: string; delivered?: boolean; deliveryStatus?: string } | undefined; - await runIsolatedJobAndReadState({ - job: buildAnnounceIsolatedAgentTurnJob("event-test"), - delivered: true, - onFinished: (evt) => { - capturedEvent = evt; - }, - }); - - expect(capturedEvent?.delivered).toBe(true); - expect(capturedEvent?.deliveryStatus).toBe("delivered"); - }); - it("surfaces a successful run's delivery error on the finished event", async () => { // Regression for https://github.com/openclaw/openclaw/issues/95419: // when an isolated turn succeeds but post-run delivery fails, the run keeps diff --git a/src/cron/service/timer-trigger.ts b/src/cron/service/timer-trigger.ts index 60cf61fa6365..c927af353b6a 100644 --- a/src/cron/service/timer-trigger.ts +++ b/src/cron/service/timer-trigger.ts @@ -301,33 +301,31 @@ export function resolveDeliveryState(params: { const primaryDeliveryPlan = resolveCronDeliveryPlan(params.job); const primaryDeliveryRequested = primaryDeliveryPlan.requested; const noFailureNotification = { status: "not-requested" as const }; + const verifiedDelivery = + params.delivered === true && + (params.runStatus !== "error" || params.delivery?.delivered === true); + if (verifiedDelivery) { + return { + delivered: true, + status: "delivered", + failureNotification: noFailureNotification, + }; + } if (!primaryDeliveryRequested) { - if (primaryDeliveryPlan.mode === "webhook") { - if (params.delivered === true) { - return { - delivered: true, - status: "delivered", - failureNotification: noFailureNotification, - }; - } - if (params.deliveryAttempted === true) { - return { - delivered: false, - status: "not-delivered", - error: params.error, - failureNotification: noFailureNotification, - }; - } + if (primaryDeliveryPlan.mode === "webhook" && params.deliveryAttempted === true) { + return { + delivered: false, + status: "not-delivered", + error: params.error, + failureNotification: noFailureNotification, + }; } return { status: "not-requested", failureNotification: noFailureNotification, }; } - if ( - params.runStatus === "error" && - !(params.delivered === true && params.delivery?.delivered === true) - ) { + if (params.runStatus === "error") { if (params.delivered !== undefined) { return { delivered: false, @@ -343,13 +341,6 @@ export function resolveDeliveryState(params: { failureNotification: noFailureNotification, }; } - if (params.delivered === true) { - return { - delivered: true, - status: "delivered", - failureNotification: { status: "not-requested" }, - }; - } if (params.delivered === false) { return { delivered: false,