




















@@ -13,6 +13,7 @@ import {
1313resolveMainSessionKey,
1414} from "../../config/sessions/main-session.js";
1515import type { OpenClawConfig } from "../../config/types.openclaw.js";
16+import type { TtsAutoMode } from "../../config/types.tts.js";
1617import { sleepWithAbort } from "../../infra/backoff.js";
1718import { formatErrorMessage } from "../../infra/errors.js";
1819import type { OutboundDeliveryResult } from "../../infra/outbound/deliver.js";
@@ -24,6 +25,7 @@ import {
2425normalizeOptionalLowercaseString,
2526normalizeOptionalString,
2627} from "../../shared/string-coerce.js";
28+import { shouldAttemptTtsPayload } from "../../tts/tts-config.js";
2729import { createCronExecutionId } from "../run-id.js";
2830import { hasScheduledNextRunAtMs } from "../service/jobs.js";
2931import type { CronJob, CronRunTelemetry } from "../types.js";
@@ -119,6 +121,7 @@ type DispatchCronDeliveryParams = {
119121deliveryPayloadHasStructuredContent: boolean;
120122deliveryPayloads: ReplyPayload[];
121123synthesizedText?: string;
124+ttsAuto?: TtsAutoMode;
122125summary?: string;
123126outputText?: string;
124127telemetry?: CronRunTelemetry;
@@ -183,6 +186,7 @@ let deliveryLoggerRuntimePromise:
183186let subagentFollowupRuntimePromise:
184187| Promise<typeof import("./subagent-followup.runtime.js")>
185188| undefined;
189+let ttsRuntimePromise: Promise<typeof import("../../tts/tts.runtime.js")> | undefined;
186190187191const COMPLETED_DIRECT_CRON_DELIVERIES = new Map<string, CompletedDirectCronDelivery>();
188192@@ -217,6 +221,11 @@ async function loadSubagentFollowupRuntime(): Promise<
217221return await subagentFollowupRuntimePromise;
218222}
219223224+async function loadTtsRuntime(): Promise<typeof import("../../tts/tts.runtime.js")> {
225+ttsRuntimePromise ??= import("../../tts/tts.runtime.js");
226+return await ttsRuntimePromise;
227+}
228+220229async function logCronDeliveryWarn(message: string): Promise<void> {
221230const { logWarn } = await loadDeliveryLoggerRuntime();
222231logWarn(message);
@@ -303,6 +312,40 @@ function getCompletedDirectCronDelivery(
303312return cloneDeliveryResults(cached.results);
304313}
305314315+async function maybeApplyTtsToCronPayloads(params: {
316+cfg: OpenClawConfig;
317+payloads: ReplyPayload[];
318+delivery: SuccessfulDeliveryTarget;
319+agentId: string;
320+ttsAuto?: TtsAutoMode;
321+}): Promise<ReplyPayload[]> {
322+if (
323+!shouldAttemptTtsPayload({
324+cfg: params.cfg,
325+ttsAuto: params.ttsAuto,
326+agentId: params.agentId,
327+channelId: params.delivery.channel,
328+accountId: params.delivery.accountId,
329+})
330+) {
331+return params.payloads;
332+}
333+const { maybeApplyTtsToPayload } = await loadTtsRuntime();
334+return await Promise.all(
335+params.payloads.map((payload) =>
336+maybeApplyTtsToPayload({
337+ payload,
338+cfg: params.cfg,
339+channel: params.delivery.channel,
340+kind: "final",
341+ttsAuto: params.ttsAuto,
342+agentId: params.agentId,
343+accountId: params.delivery.accountId,
344+}),
345+),
346+);
347+}
348+306349function buildDirectCronDeliveryIdempotencyKey(params: {
307350jobId: string;
308351runStartedAt: number;
@@ -524,7 +567,7 @@ export async function dispatchCronDelivery(
524567 : synthesizedText
525568 ? [{ text: synthesizedText }]
526569 : [];
527-const payloadsForDelivery = rawPayloads
570+const normalizedPayloads = rawPayloads
528571.map((p) => {
529572if (!p.text) {
530573return p;
@@ -535,7 +578,7 @@ export async function dispatchCronDelivery(
535578});
536579})
537580.filter((p) => hasReplyPayloadContent(p, { trimText: true }));
538-if (payloadsForDelivery.length === 0) {
581+if (normalizedPayloads.length === 0) {
539582return await finishSilentReplyDelivery();
540583}
541584if (params.isAborted()) {
@@ -575,6 +618,18 @@ export async function dispatchCronDelivery(
575618 ...params.telemetry,
576619});
577620}
621+const payloadsForDelivery = (
622+await maybeApplyTtsToCronPayloads({
623+cfg: params.cfgWithAgentDefaults,
624+payloads: normalizedPayloads,
625+ delivery,
626+agentId: params.agentId,
627+ttsAuto: params.ttsAuto,
628+})
629+).filter((p) => hasReplyPayloadContent(p, { trimText: true }));
630+if (payloadsForDelivery.length === 0) {
631+return await finishSilentReplyDelivery();
632+}
578633deliveryAttempted = true;
579634const cachedResults = getCompletedDirectCronDelivery(deliveryIdempotencyKey);
580635if (cachedResults) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。