import type { FailoverReason } from "../agents/pi-embedded-helpers.js"; import type { ChannelId } from "../channels/plugins/types.js"; import type { CronJobBase } from "./types-shared.js"; export type CronSchedule = | { kind: "at"; at: string } | { kind: "every"; everyMs: number; anchorMs?: number } | { kind: "cron"; expr: string; tz?: string; /** Optional deterministic stagger window in milliseconds (0 keeps exact schedule). */ staggerMs?: number; }; export type CronSessionTarget = "main" | "isolated"; export type CronWakeMode = "next-heartbeat" | "now"; export type CronMessageChannel = ChannelId | "last"; export type CronDeliveryMode = "none" | "announce" | "webhook"; export type CronDelivery = { mode: CronDeliveryMode; channel?: CronMessageChannel; to?: string; /** Explicit channel account id for multi-account setups (e.g. multiple Telegram bots). */ accountId?: string; bestEffort?: boolean; /** Separate destination for failure notifications. */ failureDestination?: CronFailureDestination; }; export type CronFailureDestination = { channel?: CronMessageChannel; to?: string; accountId?: string; mode?: "announce" | "webhook"; }; export type CronDeliveryPatch = Partial; export type CronRunStatus = "ok" | "error" | "skipped"; export type CronDeliveryStatus = "delivered" | "not-delivered" | "unknown" | "not-requested"; export type CronUsageSummary = { input_tokens?: number; output_tokens?: number; total_tokens?: number; cache_read_tokens?: number; cache_write_tokens?: number; }; export type CronRunTelemetry = { model?: string; provider?: string; usage?: CronUsageSummary; }; export type CronRunOutcome = { status: CronRunStatus; error?: string; /** Optional classifier for execution errors to guide fallback behavior. */ errorKind?: "delivery-target"; summary?: string; sessionId?: string; sessionKey?: string; }; export type CronFailureAlert = { after?: number; channel?: CronMessageChannel; to?: string; cooldownMs?: number; /** Delivery mode: announce (via messaging channels) or webhook (HTTP POST). */ mode?: "announce" | "webhook"; /** Account ID for multi-account channel configurations. */ accountId?: string; }; export type CronPayload = { kind: "systemEvent"; text: string } | CronAgentTurnPayload; export type CronPayloadPatch = { kind: "systemEvent"; text?: string } | CronAgentTurnPayloadPatch; type CronAgentTurnPayloadFields = { message: string; /** Optional model override (provider/model or alias). */ model?: string; /** Optional per-job fallback models; overrides agent/global fallbacks when defined. */ fallbacks?: string[]; thinking?: string; timeoutSeconds?: number; allowUnsafeExternalContent?: boolean; /** If true, run with lightweight bootstrap context. */ lightContext?: boolean; deliver?: boolean; channel?: CronMessageChannel; to?: string; bestEffortDeliver?: boolean; }; type CronAgentTurnPayload = { kind: "agentTurn"; } & CronAgentTurnPayloadFields; type CronAgentTurnPayloadPatch = { kind: "agentTurn"; } & Partial; export type CronJobState = { nextRunAtMs?: number; runningAtMs?: number; lastRunAtMs?: number; /** Preferred execution outcome field. */ lastRunStatus?: CronRunStatus; /** Back-compat alias for lastRunStatus. */ lastStatus?: "ok" | "error" | "skipped"; lastError?: string; /** Classified reason for the last error (when available). */ lastErrorReason?: FailoverReason; lastDurationMs?: number; /** Number of consecutive execution errors (reset on success). Used for backoff. */ consecutiveErrors?: number; /** Last failure alert timestamp (ms since epoch) for cooldown gating. */ lastFailureAlertAtMs?: number; /** Number of consecutive schedule computation errors. Auto-disables job after threshold. */ scheduleErrorCount?: number; /** Explicit delivery outcome, separate from execution outcome. */ lastDeliveryStatus?: CronDeliveryStatus; /** Delivery-specific error text when available. */ lastDeliveryError?: string; /** Whether the last run's output was delivered to the target channel. */ lastDelivered?: boolean; }; export type CronJob = CronJobBase< CronSchedule, CronSessionTarget, CronWakeMode, CronPayload, CronDelivery, CronFailureAlert | false > & { state: CronJobState; }; export type CronStoreFile = { version: 1; jobs: CronJob[]; }; export type CronJobCreate = Omit & { state?: Partial; }; export type CronJobPatch = Partial> & { payload?: CronPayloadPatch; delivery?: CronDeliveryPatch; state?: Partial; };