Skip to content

Commit 372e270

Browse files
committed
fix(delivery): require outbound send result for success
1 parent b6ae0b8 commit 372e270

3 files changed

Lines changed: 20 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ Docs: https://docs.openclaw.ai
127127
- CLI/completion: guard the shell-profile source line written by `openclaw completion --install` with a file existence check (`[ -f ... ] && source ...` for bash/zsh, `test -f ...; and source ...` for fish) so uninstalling OpenClaw no longer makes new login shells error on a missing completion cache. (#78659) Thanks @sjf.
128128
- Cron/doctor: repair persisted cron jobs whose `payload.model` was stored as `"default"`, `"null"`, blank, or JSON `null` by removing the bad override during `openclaw doctor --fix` while keeping cron runtime model validation strict. Fixes #78549. Thanks @bizzle12368239.
129129
- Telegram: honor `accessGroup:*` sender allowlists for DMs, groups, native commands, and callback authorization before applying Telegram's numeric sender-ID checks. Fixes #78660. Thanks @manugc.
130+
- Agent delivery: report `deliverySucceeded=false` when outbound delivery returns no adapter result, so claimed/empty delivery paths no longer masquerade as successful sends. Fixes #78532. Thanks @joeyfrasier.
130131
- Doctor/OpenAI Codex: revert the 2026.5.5 `doctor --fix` repair that rewrote valid `openai-codex/*` ChatGPT/Codex OAuth routes to `openai/*`, which could break OAuth-only GPT-5.5 setups or accidentally move users onto the OpenAI API-key route. If 2026.5.5 already changed your default model, run `openclaw models set openai-codex/gpt-5.5 && openclaw config validate` to switch the default agent back to the Codex OAuth PI route. Fixes #78407.
131132
- Discord/groups: instruct group-chat agents to stay silent when a message is addressed to someone else, replying only when invited or correcting key facts. (#78615)
132133
- Discord/groups: tell Discord-channel agents to wrap bare URLs as `<https://example.com>` so link previews do not expand into uninvited embeds. (#78614)

src/agents/command/delivery.test.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,12 @@ describe("normalizeAgentCommandReplyPayloads", () => {
216216
});
217217

218218
it("reports successful requested delivery", async () => {
219-
deliverOutboundPayloadsMock.mockResolvedValue([]);
219+
deliverOutboundPayloadsMock.mockResolvedValue([
220+
{
221+
channel: "slack",
222+
messageId: "m1",
223+
},
224+
]);
220225

221226
const delivered = await deliverMediaReplyForTest({
222227
key: "agent:tester:slack:direct:alice",
@@ -226,6 +231,17 @@ describe("normalizeAgentCommandReplyPayloads", () => {
226231
expect(delivered.deliverySucceeded).toBe(true);
227232
});
228233

234+
it("does not report success when delivery claims no adapter result", async () => {
235+
deliverOutboundPayloadsMock.mockResolvedValue([]);
236+
237+
const delivered = await deliverMediaReplyForTest({
238+
key: "agent:tester:slack:direct:alice",
239+
agentId: "tester",
240+
} as never);
241+
242+
expect(delivered.deliverySucceeded).toBe(false);
243+
});
244+
229245
it("does not report success when best-effort delivery records an error", async () => {
230246
deliverOutboundPayloadsMock.mockImplementationOnce(async (params: unknown) => {
231247
(params as { onError?: (err: unknown) => void }).onError?.(new Error("send failed"));

src/agents/command/delivery.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ export async function deliverAgentCommandResult(params: {
381381
}
382382
if (deliver && deliveryChannel && !isInternalMessageChannel(deliveryChannel)) {
383383
if (deliveryTarget) {
384-
await deliverOutboundPayloads({
384+
const deliveryResults = await deliverOutboundPayloads({
385385
cfg,
386386
channel: deliveryChannel,
387387
to: deliveryTarget,
@@ -395,7 +395,7 @@ export async function deliverAgentCommandResult(params: {
395395
onPayload: logPayload,
396396
deps: createOutboundSendDeps(deps),
397397
});
398-
deliverySucceeded = !deliveryHadError;
398+
deliverySucceeded = deliveryResults.length > 0 && !deliveryHadError;
399399
}
400400
}
401401

0 commit comments

Comments
 (0)