cron: skip delivery for HEARTBEAT_OK responses (#238)
When an isolated cron job has deliver:true, skip message delivery if the response is just HEARTBEAT_OK (or contains HEARTBEAT_OK at edges with short remaining content <= 30 chars). This allows cron jobs to silently ack when nothing to report but still deliver actual content when there is something meaningful to say. Media is still delivered even if text is HEARTBEAT_OK, since the presence of media indicates there's something to share.
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
ensureAgentWorkspace,
|
||||
} from "../agents/workspace.js";
|
||||
import { chunkText, resolveTextChunkLimit } from "../auto-reply/chunk.js";
|
||||
import { stripHeartbeatToken } from "../auto-reply/heartbeat.js";
|
||||
import { normalizeThinkLevel } from "../auto-reply/thinking.js";
|
||||
import type { CliDeps } from "../cli/deps.js";
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
@@ -57,6 +58,25 @@ function pickSummaryFromPayloads(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all payloads are just heartbeat ack responses (HEARTBEAT_OK).
|
||||
* Returns true if delivery should be skipped because there's no real content.
|
||||
*/
|
||||
function isHeartbeatOnlyResponse(
|
||||
payloads: Array<{ text?: string; mediaUrl?: string; mediaUrls?: string[] }>,
|
||||
) {
|
||||
if (payloads.length === 0) return true;
|
||||
return payloads.every((payload) => {
|
||||
// If there's media, we should deliver regardless of text content.
|
||||
const hasMedia =
|
||||
(payload.mediaUrls?.length ?? 0) > 0 || Boolean(payload.mediaUrl);
|
||||
if (hasMedia) return false;
|
||||
// Use heartbeat mode to check if text is just HEARTBEAT_OK or short ack.
|
||||
const result = stripHeartbeatToken(payload.text, { mode: "heartbeat" });
|
||||
return result.shouldSkip;
|
||||
});
|
||||
}
|
||||
|
||||
function resolveDeliveryTarget(
|
||||
cfg: ClawdbotConfig,
|
||||
jobPayload: {
|
||||
@@ -343,7 +363,12 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
const summary =
|
||||
pickSummaryFromPayloads(payloads) ?? pickSummaryFromOutput(firstText);
|
||||
|
||||
if (delivery) {
|
||||
// Skip delivery for heartbeat-only responses (HEARTBEAT_OK with no real content).
|
||||
// This allows cron jobs to silently ack when nothing to report but still deliver
|
||||
// actual content when there is something to say.
|
||||
const skipHeartbeatDelivery = delivery && isHeartbeatOnlyResponse(payloads);
|
||||
|
||||
if (delivery && !skipHeartbeatDelivery) {
|
||||
if (resolvedDelivery.channel === "whatsapp") {
|
||||
if (!resolvedDelivery.to) {
|
||||
if (!bestEffortDeliver)
|
||||
|
||||
Reference in New Issue
Block a user