mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-12 13:10:43 +00:00
178 lines
4.9 KiB
TypeScript
178 lines
4.9 KiB
TypeScript
import type { CliDeps } from "../cli/deps.types.js";
|
|
import { createOutboundSendDeps } from "../cli/outbound-send-deps.js";
|
|
import type { OpenClawConfig } from "../config/types.js";
|
|
import { formatErrorMessage } from "../infra/errors.js";
|
|
import { deliverOutboundPayloads } from "../infra/outbound/deliver.js";
|
|
import { resolveAgentOutboundIdentity } from "../infra/outbound/identity.js";
|
|
import { buildOutboundSessionContext } from "../infra/outbound/session-context.js";
|
|
import { getChildLogger } from "../logging.js";
|
|
import {
|
|
resolveFailureDestination,
|
|
type CronFailureDeliveryPlan,
|
|
type CronFailureDestinationInput,
|
|
type CronDeliveryPlan,
|
|
resolveCronDeliveryPlan,
|
|
} from "./delivery-plan.js";
|
|
import {
|
|
resolveDeliveryTarget,
|
|
type DeliveryTargetResolution,
|
|
} from "./isolated-agent/delivery-target.js";
|
|
import { resolveCronNotificationSessionKey } from "./session-target.js";
|
|
import type { CronMessageChannel } from "./types.js";
|
|
|
|
export {
|
|
resolveCronDeliveryPlan,
|
|
resolveFailureDestination,
|
|
type CronDeliveryPlan,
|
|
type CronFailureDeliveryPlan,
|
|
type CronFailureDestinationInput,
|
|
};
|
|
|
|
const FAILURE_NOTIFICATION_TIMEOUT_MS = 30_000;
|
|
const cronDeliveryLogger = getChildLogger({ subsystem: "cron-delivery" });
|
|
|
|
export type CronAnnounceTarget = {
|
|
channel?: string;
|
|
to?: string;
|
|
accountId?: string;
|
|
sessionKey?: string;
|
|
};
|
|
|
|
type SuccessfulDeliveryTarget = Extract<DeliveryTargetResolution, { ok: true }>;
|
|
|
|
async function resolveCronAnnounceDelivery(params: {
|
|
cfg: OpenClawConfig;
|
|
agentId: string;
|
|
jobId: string;
|
|
target: CronAnnounceTarget;
|
|
}): Promise<
|
|
| {
|
|
ok: true;
|
|
resolvedTarget: SuccessfulDeliveryTarget;
|
|
session: ReturnType<typeof buildOutboundSessionContext>;
|
|
identity: ReturnType<typeof resolveAgentOutboundIdentity>;
|
|
}
|
|
| { ok: false; error: Error }
|
|
> {
|
|
const resolvedTarget = await resolveDeliveryTarget(params.cfg, params.agentId, {
|
|
channel: params.target.channel as CronMessageChannel | undefined,
|
|
to: params.target.to,
|
|
accountId: params.target.accountId,
|
|
sessionKey: params.target.sessionKey,
|
|
});
|
|
|
|
if (!resolvedTarget.ok) {
|
|
return { ok: false, error: resolvedTarget.error };
|
|
}
|
|
|
|
const identity = resolveAgentOutboundIdentity(params.cfg, params.agentId);
|
|
const session = buildOutboundSessionContext({
|
|
cfg: params.cfg,
|
|
agentId: params.agentId,
|
|
sessionKey: resolveCronNotificationSessionKey({
|
|
jobId: params.jobId,
|
|
sessionKey: params.target.sessionKey,
|
|
}),
|
|
});
|
|
|
|
return {
|
|
ok: true,
|
|
resolvedTarget,
|
|
session,
|
|
identity,
|
|
};
|
|
}
|
|
|
|
async function deliverCronAnnouncePayload(params: {
|
|
deps: CliDeps;
|
|
cfg: OpenClawConfig;
|
|
delivery: {
|
|
resolvedTarget: SuccessfulDeliveryTarget;
|
|
session: ReturnType<typeof buildOutboundSessionContext>;
|
|
identity: ReturnType<typeof resolveAgentOutboundIdentity>;
|
|
};
|
|
message: string;
|
|
abortSignal: AbortSignal;
|
|
}): Promise<void> {
|
|
await deliverOutboundPayloads({
|
|
cfg: params.cfg,
|
|
channel: params.delivery.resolvedTarget.channel,
|
|
to: params.delivery.resolvedTarget.to,
|
|
accountId: params.delivery.resolvedTarget.accountId,
|
|
threadId: params.delivery.resolvedTarget.threadId,
|
|
payloads: [{ text: params.message }],
|
|
session: params.delivery.session,
|
|
identity: params.delivery.identity,
|
|
bestEffort: false,
|
|
deps: createOutboundSendDeps(params.deps),
|
|
abortSignal: params.abortSignal,
|
|
});
|
|
}
|
|
|
|
export async function sendCronAnnouncePayloadStrict(params: {
|
|
deps: CliDeps;
|
|
cfg: OpenClawConfig;
|
|
agentId: string;
|
|
jobId: string;
|
|
target: CronAnnounceTarget;
|
|
message: string;
|
|
abortSignal: AbortSignal;
|
|
}): Promise<void> {
|
|
const delivery = await resolveCronAnnounceDelivery(params);
|
|
if (!delivery.ok) {
|
|
throw delivery.error;
|
|
}
|
|
await deliverCronAnnouncePayload({
|
|
deps: params.deps,
|
|
cfg: params.cfg,
|
|
delivery,
|
|
message: params.message,
|
|
abortSignal: params.abortSignal,
|
|
});
|
|
}
|
|
|
|
export async function sendFailureNotificationAnnounce(
|
|
deps: CliDeps,
|
|
cfg: OpenClawConfig,
|
|
agentId: string,
|
|
jobId: string,
|
|
target: CronAnnounceTarget,
|
|
message: string,
|
|
): Promise<void> {
|
|
const delivery = await resolveCronAnnounceDelivery({ cfg, agentId, jobId, target });
|
|
|
|
if (!delivery.ok) {
|
|
cronDeliveryLogger.warn(
|
|
{ error: delivery.error.message },
|
|
"cron: failed to resolve failure destination target",
|
|
);
|
|
return;
|
|
}
|
|
|
|
const abortController = new AbortController();
|
|
const timeout = setTimeout(() => {
|
|
abortController.abort();
|
|
}, FAILURE_NOTIFICATION_TIMEOUT_MS);
|
|
|
|
try {
|
|
await deliverCronAnnouncePayload({
|
|
deps,
|
|
cfg,
|
|
delivery,
|
|
message,
|
|
abortSignal: abortController.signal,
|
|
});
|
|
} catch (err) {
|
|
cronDeliveryLogger.warn(
|
|
{
|
|
err: formatErrorMessage(err),
|
|
channel: delivery.resolvedTarget.channel,
|
|
to: delivery.resolvedTarget.to,
|
|
},
|
|
"cron: failure destination announce failed",
|
|
);
|
|
} finally {
|
|
clearTimeout(timeout);
|
|
}
|
|
}
|