cron: suppress NO_REPLY for threaded announce targets

This commit is contained in:
ShionElia 2026-03-21 03:06:49 +00:00
parent ec1d653620
commit ff613f4c65
2 changed files with 72 additions and 0 deletions

View File

@ -61,4 +61,46 @@ describe("runCronIsolatedAgentTurn forum topic delivery", () => {
});
});
});
it('suppresses exact "NO_REPLY" for plain announce delivery', async () => {
await withTempCronHome(async (home) => {
const storePath = await writeSessionStore(home, { lastProvider: "webchat", lastTo: "" });
const deps = createCliDeps();
mockAgentPayloads([{ text: "NO_REPLY" }]);
const res = await runTelegramAnnounceTurn({
home,
storePath,
deps,
delivery: { mode: "announce", channel: "telegram", to: "123" },
});
expect(res.status).toBe("ok");
expect(res.delivered).toBe(false);
expect(res.deliveryAttempted).toBe(true);
expect(runSubagentAnnounceFlow).not.toHaveBeenCalled();
expect(deps.sendMessageTelegram).not.toHaveBeenCalled();
});
});
it('suppresses exact "NO_REPLY" for forum-topic announce delivery', async () => {
await withTempCronHome(async (home) => {
const storePath = await writeSessionStore(home, { lastProvider: "webchat", lastTo: "" });
const deps = createCliDeps();
mockAgentPayloads([{ text: "NO_REPLY" }]);
const res = await runTelegramAnnounceTurn({
home,
storePath,
deps,
delivery: { mode: "announce", channel: "telegram", to: "123:topic:42" },
});
expect(res.status).toBe("ok");
expect(res.delivered).toBe(false);
expect(res.deliveryAttempted).toBe(true);
expect(runSubagentAnnounceFlow).not.toHaveBeenCalled();
expect(deps.sendMessageTelegram).not.toHaveBeenCalled();
});
});
});

View File

@ -112,6 +112,24 @@ export type DispatchCronDeliveryState = {
deliveryPayloads: ReplyPayload[];
};
function isDirectSilentReplyOnly(payloads: readonly ReplyPayload[]): boolean {
if (payloads.length !== 1) {
return false;
}
const [payload] = payloads;
if (!payload || !isSilentReplyText(payload.text, SILENT_REPLY_TOKEN)) {
return false;
}
return !(
payload.mediaUrl ||
(payload.mediaUrls?.length ?? 0) > 0 ||
payload.interactive ||
payload.btw ||
payload.audioAsVoice === true ||
Object.keys(payload.channelData ?? {}).length > 0
);
}
const TRANSIENT_DIRECT_CRON_DELIVERY_ERROR_PATTERNS: readonly RegExp[] = [
/\berrorcode=unavailable\b/i,
/\bstatus\s*[:=]\s*"?unavailable\b/i,
@ -340,6 +358,18 @@ export async function dispatchCronDelivery(
if (payloadsForDelivery.length === 0) {
return null;
}
if (isDirectSilentReplyOnly(payloadsForDelivery)) {
deliveryAttempted = true;
delivered = false;
return params.withRunSession({
status: "ok",
summary,
outputText,
delivered: false,
deliveryAttempted: true,
...params.telemetry,
});
}
if (params.isAborted()) {
return params.withRunSession({
status: "error",