

























11/** Dispatches isolated cron output to direct delivery, mirrors, and follow-up queues. */
22import { isAudioFileName } from "@openclaw/media-core/mime";
33import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
4-import { retireSessionMcpRuntime } from "../../agents/agent-bundle-mcp-tools.js";
54import type { ReplyPayload } from "../../auto-reply/reply-payload.js";
65import {
76isSilentReplyText,
@@ -39,7 +38,6 @@ import { normalizeTargetForProvider } from "../../infra/outbound/target-normaliz
3938import { hasReplyPayloadContent } from "../../interactive/payload.js";
4039import { stringifyRouteThreadId } from "../../plugin-sdk/channel-route.js";
4140import {
42-isCronSessionKey,
4341parseThreadSessionSuffix,
4442resolveAgentIdFromSessionKey,
4543} from "../../routing/session-key.js";
@@ -51,6 +49,7 @@ import type { CronJob, CronRunTelemetry } from "../types.js";
5149import type { DeliveryTargetResolution } from "./delivery-target.js";
5250import { pickLastNonEmptyTextFromPayloads, pickSummaryFromOutput } from "./helpers.js";
5351import type { RunCronAgentTurnResult } from "./run.types.js";
52+import { cleanupCronRunSessionAfterRun } from "./session-cleanup.js";
5453import { expectsSubagentFollowup, isLikelyInterimCronMessage } from "./subagent-followup-hints.js";
55545655function normalizeDeliveryTarget(channel: string, to: string): string {
@@ -136,6 +135,7 @@ export type DispatchCronDeliveryState = {
136135result?: RunCronAgentTurnResult;
137136delivered: boolean;
138137deliveryAttempted: boolean;
138+cronRunSessionCleanupAttempted: boolean;
139139summary?: string;
140140outputText?: string;
141141synthesizedText?: string;
@@ -172,9 +172,6 @@ type CompletedDirectCronDelivery = {
172172results: OutboundDeliveryResult[];
173173};
174174175-const gatewayCallRuntimeLoader = createLazyImportLoader(
176-() => import("../../gateway/call.runtime.js"),
177-);
178175const deliveryOutboundRuntimeLoader = createLazyImportLoader(
179176() => import("./delivery-outbound.runtime.js"),
180177);
@@ -197,10 +194,6 @@ const ttsRuntimeLoader = createLazyImportLoader(() => import("../../tts/tts.runt
197194198195const COMPLETED_DIRECT_CRON_DELIVERIES = new Map<string, CompletedDirectCronDelivery>();
199196200-async function loadGatewayCallRuntime(): Promise<typeof import("../../gateway/call.runtime.js")> {
201-return await gatewayCallRuntimeLoader.load();
202-}
203-204197async function loadDeliveryOutboundRuntime(): Promise<
205198typeof import("./delivery-outbound.runtime.js")
206199> {
@@ -256,29 +249,12 @@ export async function cleanupDirectCronSession(params: {
256249sessionId: string;
257250retireReason: string;
258251}): Promise<void> {
259-if (!params.job.deleteAfterRun) {
260-return;
261-}
262-if (!isCronSessionKey(params.agentSessionKey)) {
263-return;
264-}
265-try {
266-const { callGateway } = await loadGatewayCallRuntime();
267-await callGateway({
268-method: "sessions.delete",
269-params: {
270-key: params.agentSessionKey,
271-deleteTranscript: true,
272-emitLifecycleHooks: false,
273-},
274-timeoutMs: 10_000,
275-});
276-} catch {
277-await retireSessionMcpRuntime({
278-sessionId: params.sessionId,
279-reason: params.retireReason,
280-});
281-}
252+await cleanupCronRunSessionAfterRun({
253+job: params.job,
254+agentSessionKey: params.agentSessionKey,
255+sessionId: params.sessionId,
256+reason: params.retireReason,
257+});
282258}
283259284260function logCronDeliveryErrorDeferred(message: string): void {
@@ -940,7 +916,17 @@ export async function dispatchCronDelivery(
940916941917let delivered = verifiedMessageToolDelivery;
942918let deliveryAttempted = verifiedMessageToolDelivery;
943-let directCronSessionDeleted = false;
919+let directCronSessionCleanupAttempted = false;
920+const buildDeliveryState = (result?: RunCronAgentTurnResult): DispatchCronDeliveryState => ({
921+ ...(result ? { result } : {}),
922+ delivered,
923+ deliveryAttempted,
924+cronRunSessionCleanupAttempted: directCronSessionCleanupAttempted,
925+ summary,
926+ outputText,
927+ synthesizedText,
928+ deliveryPayloads,
929+});
944930const formatDeliveryTargetError = (error: string) =>
945931params.sourceDeliveryOutcome.unverifiedMessageToolDelivery
946932 ? `${error}; the agent used the message tool, but OpenClaw could not verify that message matched the cron delivery target`
@@ -956,16 +942,18 @@ export async function dispatchCronDelivery(
956942 ...params.telemetry,
957943});
958944const cleanupDirectCronSessionIfNeeded = async (): Promise<void> => {
959-if (directCronSessionDeleted) {
945+if (directCronSessionCleanupAttempted) {
960946return;
961947}
962-directCronSessionDeleted = true;
963-await cleanupDirectCronSession({
948+const cleanupAttempted = await cleanupCronRunSessionAfterRun({
964949job: params.job,
965950agentSessionKey: params.agentSessionKey,
966951sessionId: params.sessionId,
967-retireReason: "cron-delete-after-run-fallback",
952+reason: "cron-delete-after-run-fallback",
968953});
954+if (cleanupAttempted) {
955+directCronSessionCleanupAttempted = true;
956+}
969957};
970958const finishSilentReplyDelivery = async (): Promise<RunCronAgentTurnResult> => {
971959deliveryAttempted = true;
@@ -1417,32 +1405,18 @@ export async function dispatchCronDelivery(
14171405// non-deleteAfterRun / non-cron sessions (see cleanupDirectCronSession).
14181406await cleanupDirectCronSessionIfNeeded();
14191407if (!params.deliveryBestEffort) {
1420-return {
1421-result: failDeliveryTarget(params.resolvedDelivery.error.message),
1422- delivered,
1423- deliveryAttempted,
1424- summary,
1425- outputText,
1426- synthesizedText,
1427- deliveryPayloads,
1428-};
1408+return buildDeliveryState(failDeliveryTarget(params.resolvedDelivery.error.message));
14291409}
14301410await logCronDeliveryWarn(`[cron:${params.job.id}] ${params.resolvedDelivery.error.message}`);
1431-return {
1432-result: params.withRunSession({
1411+return buildDeliveryState(
1412+params.withRunSession({
14331413status: "ok",
14341414 summary,
14351415 outputText,
14361416 deliveryAttempted,
14371417 ...params.telemetry,
14381418}),
1439- delivered,
1440- deliveryAttempted,
1441- summary,
1442- outputText,
1443- synthesizedText,
1444- deliveryPayloads,
1445-};
1419+);
14461420}
1447142114481422// Finalize descendant/subagent output first for text-only cron runs, then
@@ -1453,38 +1427,15 @@ export async function dispatchCronDelivery(
14531427if (useDirectDelivery) {
14541428const directResult = await deliverViaDirectAndCleanup(params.resolvedDelivery);
14551429if (directResult) {
1456-return {
1457-result: directResult,
1458- delivered,
1459- deliveryAttempted,
1460- summary,
1461- outputText,
1462- synthesizedText,
1463- deliveryPayloads,
1464-};
1430+return buildDeliveryState(directResult);
14651431}
14661432} else {
14671433const finalizedTextResult = await finalizeTextDelivery(params.resolvedDelivery);
14681434if (finalizedTextResult) {
1469-return {
1470-result: finalizedTextResult,
1471- delivered,
1472- deliveryAttempted,
1473- summary,
1474- outputText,
1475- synthesizedText,
1476- deliveryPayloads,
1477-};
1435+return buildDeliveryState(finalizedTextResult);
14781436}
14791437}
14801438}
148114391482-return {
1483- delivered,
1484- deliveryAttempted,
1485- summary,
1486- outputText,
1487- synthesizedText,
1488- deliveryPayloads,
1489-};
1440+return buildDeliveryState();
14901441}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。