import type { FailoverReason } from "../agents/pi-embedded-helpers/types.js"; import type { ChannelId } from "../channels/plugins/types.public.js"; import type { HookExternalContentSource } from "../security/external-content.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" | "current" | `session:${string}`; export type CronWakeMode = "next-heartbeat" | "now"; export type CronMessageChannel = ChannelId; export type CronDeliveryMode = "none" | "announce" | "webhook"; export type CronDelivery = { mode: CronDeliveryMode; channel?: CronMessageChannel; to?: string; /** Explicit thread/topic id for channels that support threaded delivery. */ threadId?: string | number; /** 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 CronDeliveryTraceTarget = { channel?: string; to?: string | null; accountId?: string; threadId?: string | number; source?: "explicit" | "last"; }; export type CronDeliveryTraceMessageTarget = { channel: string; to?: string; accountId?: string; threadId?: string; }; export type CronDeliveryTrace = { intended?: CronDeliveryTraceTarget; resolved?: CronDeliveryTraceTarget & { ok: boolean; error?: string }; messageToolSentTo?: CronDeliveryTraceMessageTarget[]; fallbackUsed?: boolean; delivered?: boolean; }; export type CronDeliveryPreview = { label: string; detail: string; }; 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 CronRunDiagnosticSeverity = "info" | "warn" | "error"; export type CronRunDiagnosticSource = | "cron-preflight" | "cron-setup" | "model-preflight" | "agent-run" | "tool" | "exec" | "delivery"; export type CronRunDiagnostic = { ts: number; source: CronRunDiagnosticSource; severity: CronRunDiagnosticSeverity; message: string; toolName?: string; exitCode?: number | null; truncated?: boolean; }; export type CronRunDiagnostics = { summary?: string; entries: CronRunDiagnostic[]; }; 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; diagnostics?: CronRunDiagnostics; }; export type CronAgentExecutionStarted = { jobId: string; agentId?: string; sessionId?: string; sessionKey?: string; }; export type CronFailureAlert = { after?: number; channel?: CronMessageChannel; to?: string; cooldownMs?: number; /** When true, consecutive skipped runs count toward the alert threshold. */ includeSkipped?: boolean; /** 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; /** Immutable external hook provenance for async dispatch. */ externalContentSource?: HookExternalContentSource; /** If true, run with lightweight bootstrap context. */ lightContext?: boolean; /** Optional tool allow-list; when set, only these tools are sent to the model. */ toolsAllow?: string[]; }; type CronAgentTurnPayload = { kind: "agentTurn"; } & CronAgentTurnPayloadFields; type CronAgentTurnPayloadPatch = { kind: "agentTurn"; } & Partial> & { toolsAllow?: string[] | null; }; export type CronJobState = { nextRunAtMs?: number; runningAtMs?: number; lastRunAtMs?: number; /** Preferred execution outcome field. */ lastRunStatus?: CronRunStatus; /** @deprecated Use lastRunStatus. */ lastStatus?: "ok" | "error" | "skipped"; lastError?: string; lastDiagnostics?: CronRunDiagnostics; lastDiagnosticSummary?: 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; /** Number of consecutive skipped executions (reset on success or error). */ consecutiveSkipped?: 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; };