@elizaos/plugin-cron 2.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,561 @@
1
+ import { IAgentRuntime, TaskWorker, Service, Plugin } from '@elizaos/core';
2
+ import { C as CronJob, a as CronServiceConfig, b as CronExecutionResult, c as CronSchedule, d as CronJobCreate, e as CronJobPatch, f as CronJobFilter } from './index-CcftVpZH.js';
3
+ export { g as CronEventData, h as CronExecutionContext, i as CronJobState, j as CronJobStatus, k as CronPayload, l as CronPayloadAction, m as CronPayloadEvent, n as CronPayloadPrompt, o as CronScheduleAt, p as CronScheduleCron, q as CronScheduleEvery, D as DEFAULT_CRON_CONFIG, r as otto } from './index-CcftVpZH.js';
4
+
5
+ /**
6
+ * @module constants
7
+ * @description Constants for the cron plugin
8
+ */
9
+ declare const CRON_SERVICE_TYPE = "CRON";
10
+ declare const CRON_JOB_COMPONENT_PREFIX = "cron_job";
11
+ declare const CRON_JOB_INDEX_COMPONENT = "cron_job_index";
12
+ declare const CronEvents: {
13
+ readonly CRON_FIRED: "CRON_FIRED";
14
+ readonly CRON_CREATED: "CRON_CREATED";
15
+ readonly CRON_UPDATED: "CRON_UPDATED";
16
+ readonly CRON_DELETED: "CRON_DELETED";
17
+ readonly CRON_FAILED: "CRON_FAILED";
18
+ };
19
+ declare const CronActions: {
20
+ readonly CREATE_CRON: "CREATE_CRON";
21
+ readonly UPDATE_CRON: "UPDATE_CRON";
22
+ readonly DELETE_CRON: "DELETE_CRON";
23
+ readonly LIST_CRONS: "LIST_CRONS";
24
+ readonly RUN_CRON: "RUN_CRON";
25
+ };
26
+
27
+ /**
28
+ * @module job-executor
29
+ * @description Executes cron job payloads with timeout and error handling
30
+ *
31
+ * Execution strategies by payload type:
32
+ * - prompt: Uses runtime.useModel() to process the prompt
33
+ * - action: Finds and invokes the named action via runtime.processActions()
34
+ * - event: Emits an event via runtime.emitEvent()
35
+ */
36
+
37
+ /**
38
+ * Executes a cron job payload
39
+ * @param runtime The agent runtime
40
+ * @param job The cron job to execute
41
+ * @param config Service configuration
42
+ * @returns Execution result
43
+ */
44
+ declare function executeJob(runtime: IAgentRuntime, job: CronJob, config: CronServiceConfig): Promise<CronExecutionResult>;
45
+ /**
46
+ * Validates that a job can be executed
47
+ * @returns Error message if invalid, null if valid
48
+ */
49
+ declare function validateJobExecutability(runtime: IAgentRuntime, job: CronJob): string | null;
50
+
51
+ /**
52
+ * @module heartbeat/config
53
+ * @description Configuration for the heartbeat worker.
54
+ *
55
+ * Reads heartbeat settings from the agent's runtime settings,
56
+ * supporting the same config shape as the Otto docs:
57
+ * agents.defaults.heartbeat.every
58
+ * agents.defaults.heartbeat.activeHours
59
+ * agents.defaults.heartbeat.target
60
+ * agents.defaults.heartbeat.prompt
61
+ */
62
+
63
+ interface ActiveHours {
64
+ start: string;
65
+ end: string;
66
+ }
67
+ interface HeartbeatConfig {
68
+ /** Interval between heartbeats in milliseconds. */
69
+ everyMs: number;
70
+ /** Optional active hours window. Heartbeats outside this window are skipped. */
71
+ activeHours: ActiveHours | null;
72
+ /** Delivery target. "last" uses the agent's last delivery route. */
73
+ target: string;
74
+ /** Name of the workspace file to read as heartbeat instructions. */
75
+ promptFile: string;
76
+ /** If true the heartbeat worker is enabled. */
77
+ enabled: boolean;
78
+ }
79
+ /**
80
+ * Resolve heartbeat config from runtime settings.
81
+ *
82
+ * Looks for the `heartbeat` key in the character settings object,
83
+ * which matches the Otto config shape:
84
+ * heartbeat: { every: "30m", activeHours: { start, end }, target, prompt }
85
+ */
86
+ declare function resolveHeartbeatConfig(runtime: IAgentRuntime): HeartbeatConfig;
87
+ /**
88
+ * Check whether the current local time falls inside the active hours window.
89
+ * Returns true if no active hours are configured (always active).
90
+ */
91
+ declare function isWithinActiveHours(activeHours: ActiveHours | null): boolean;
92
+
93
+ /**
94
+ * @module heartbeat/queue
95
+ * @description In-memory queue for system events destined for the next heartbeat tick.
96
+ *
97
+ * Cron main-session jobs push text here via pushSystemEvent().
98
+ * The heartbeat worker drains the queue on each tick and includes
99
+ * the events in the heartbeat prompt so the agent can act on them.
100
+ */
101
+ interface SystemEvent {
102
+ text: string;
103
+ source: string;
104
+ ts: number;
105
+ }
106
+ /**
107
+ * Push a system event for delivery on the next heartbeat tick.
108
+ */
109
+ declare function pushSystemEvent(agentId: string, text: string, source: string): void;
110
+ /**
111
+ * Drain all pending system events for an agent.
112
+ * Returns the events and clears the queue.
113
+ */
114
+ declare function drainSystemEvents(agentId: string): SystemEvent[];
115
+ /**
116
+ * Peek at pending event count without draining.
117
+ */
118
+ declare function pendingEventCount(agentId: string): number;
119
+
120
+ /**
121
+ * @module heartbeat/worker
122
+ * @description Heartbeat TaskWorker for periodic agent wakeup.
123
+ *
124
+ * Registers as an Eliza TaskWorker named "heartbeat".
125
+ * On each tick the worker:
126
+ * 1. Checks active hours
127
+ * 2. Drains the system events queue
128
+ * 3. Reads HEARTBEAT.md from the workspace
129
+ * 4. Sends a message into a heartbeat room via messageService.handleMessage()
130
+ * 5. Captures the agent's response
131
+ * 6. Suppresses HEARTBEAT_OK; otherwise delivers via sendMessageToTarget()
132
+ */
133
+
134
+ declare const HEARTBEAT_WORKER_NAME = "heartbeat";
135
+ /**
136
+ * The heartbeat TaskWorker. Register this with the runtime and create
137
+ * a recurring task to drive periodic heartbeats.
138
+ */
139
+ declare const heartbeatWorker: TaskWorker;
140
+ /**
141
+ * Register the heartbeat worker and create the recurring task.
142
+ */
143
+ declare function startHeartbeat(runtime: IAgentRuntime): Promise<void>;
144
+ /**
145
+ * Trigger an immediate heartbeat. Creates a one-shot "immediate" task
146
+ * that the TaskService will pick up on the next 1-second tick.
147
+ */
148
+ declare function wakeHeartbeatNow(runtime: IAgentRuntime): Promise<void>;
149
+
150
+ /**
151
+ * @module schedule-utils
152
+ * @description Utility functions for computing next run times and validating schedules
153
+ *
154
+ * Uses the 'croner' library for cron expression parsing which supports:
155
+ * - Standard 5-field cron expressions (minute hour day month weekday)
156
+ * - Extended 6-field expressions with seconds
157
+ * - Timezone support via IANA timezone names
158
+ */
159
+
160
+ /**
161
+ * Validates a complete schedule
162
+ * @param schedule The schedule to validate
163
+ * @param config Service configuration
164
+ * @returns Error message if invalid, null if valid
165
+ */
166
+ declare function validateSchedule(schedule: CronSchedule, config: CronServiceConfig): string | null;
167
+ /**
168
+ * Computes the next run time for a schedule
169
+ * @param schedule The schedule configuration
170
+ * @param nowMs Current time in milliseconds since epoch
171
+ * @returns Next run time in ms, or undefined if the schedule has no more runs
172
+ */
173
+ declare function computeNextRunAtMs(schedule: CronSchedule, nowMs: number): number | undefined;
174
+ /**
175
+ * Formats a schedule for human-readable display
176
+ * @param schedule The schedule to format
177
+ * @returns Human-readable description
178
+ */
179
+ declare function formatSchedule(schedule: CronSchedule): string;
180
+ /**
181
+ * Parses a human-readable duration string to milliseconds
182
+ * Supports formats like "5m", "2h", "1d", "30s"
183
+ * @param duration Duration string
184
+ * @returns Milliseconds (always > 0), or null if invalid or zero
185
+ */
186
+ declare function parseDuration(duration: string): number | null;
187
+ /**
188
+ * Creates a schedule from a human-readable description
189
+ * Supports:
190
+ * - "in 5 minutes" / "in 2 hours" -> 'at' schedule
191
+ * - "every 5 minutes" / "every hour" -> 'every' schedule
192
+ * - "at 9am" / "at 2024-12-31" -> 'at' schedule
193
+ * - Cron expressions (detected by field count)
194
+ *
195
+ * @param description Human-readable schedule description
196
+ * @param nowMs Current time for relative calculations
197
+ * @returns CronSchedule or undefined if parsing failed
198
+ */
199
+ declare function parseScheduleDescription(description: string, nowMs?: number): CronSchedule | undefined;
200
+
201
+ /**
202
+ * @module timer-manager
203
+ * @description Manages timers for cron job scheduling
204
+ *
205
+ * Uses a periodic check interval that:
206
+ * 1. Identifies jobs that are due
207
+ * 2. Fires callbacks for due jobs
208
+ * 3. Recalculates next run times
209
+ *
210
+ * Croner is used for parsing cron expressions, but timing is managed
211
+ * internally via setInterval for consistent behavior across schedule types.
212
+ */
213
+
214
+ /**
215
+ * Callback invoked when a job is due for execution
216
+ */
217
+ type JobDueCallback = (jobId: string) => Promise<void>;
218
+ /**
219
+ * Timer manager for cron job scheduling
220
+ */
221
+ declare class TimerManager {
222
+ private readonly config;
223
+ private readonly onJobDue;
224
+ private readonly trackedJobs;
225
+ private checkInterval;
226
+ private running;
227
+ constructor(config: CronServiceConfig, onJobDue: JobDueCallback);
228
+ /**
229
+ * Starts the timer manager
230
+ */
231
+ start(): void;
232
+ /**
233
+ * Stops the timer manager and cleans up all timers
234
+ */
235
+ stop(): void;
236
+ /**
237
+ * Adds or updates a job in the timer manager
238
+ * @param job The job to track
239
+ */
240
+ trackJob(job: CronJob): void;
241
+ /**
242
+ * Removes a job from tracking
243
+ * @param jobId The job ID to remove
244
+ */
245
+ untrackJob(jobId: string): void;
246
+ /**
247
+ * Marks a job as currently executing (to prevent overlapping executions)
248
+ * @param jobId The job ID
249
+ */
250
+ markExecuting(jobId: string): void;
251
+ /**
252
+ * Marks a job as finished executing and recalculates next run
253
+ * @param jobId The job ID
254
+ * @param updatedJob The job with updated state (optional)
255
+ */
256
+ markFinished(jobId: string, updatedJob?: CronJob): void;
257
+ /**
258
+ * Gets the next scheduled run time for a job
259
+ * @param jobId The job ID
260
+ * @returns Next run time in ms, or undefined
261
+ */
262
+ getNextRunAtMs(jobId: string): number | undefined;
263
+ /**
264
+ * Gets all tracked job IDs
265
+ */
266
+ getTrackedJobIds(): string[];
267
+ /**
268
+ * Gets the count of tracked jobs
269
+ */
270
+ getTrackedJobCount(): number;
271
+ /**
272
+ * Checks if a specific job is currently executing
273
+ */
274
+ isJobExecuting(jobId: string): boolean;
275
+ /**
276
+ * Forces an immediate check for due jobs
277
+ */
278
+ checkNow(): void;
279
+ /**
280
+ * Starts the periodic check interval
281
+ */
282
+ private startCheckInterval;
283
+ /**
284
+ * Stops the periodic check interval
285
+ */
286
+ private stopCheckInterval;
287
+ /**
288
+ * Performs a check for all due jobs
289
+ */
290
+ private performCheck;
291
+ /**
292
+ * Clears all tracked jobs
293
+ */
294
+ private clearAllJobs;
295
+ }
296
+
297
+ /**
298
+ * @module cron-service
299
+ * @description Main service for cron job management
300
+ *
301
+ * The CronService handles:
302
+ * - Job CRUD operations
303
+ * - Timer management for scheduling
304
+ * - Job execution coordination
305
+ * - Event emission for job lifecycle
306
+ * - Persistence via component storage
307
+ */
308
+
309
+ /**
310
+ * Cron scheduling service for ElizaOS
311
+ *
312
+ * Provides the ability to schedule recurring or one-time jobs that
313
+ * execute prompts, actions, or emit events on a defined schedule.
314
+ */
315
+ declare class CronService extends Service {
316
+ static serviceType: string;
317
+ capabilityDescription: string;
318
+ private cronConfig;
319
+ private storage;
320
+ private timerManager;
321
+ private initialized;
322
+ constructor(runtime?: IAgentRuntime, config?: Partial<CronServiceConfig>);
323
+ /**
324
+ * Starts the cron service
325
+ */
326
+ static start(runtime: IAgentRuntime): Promise<Service>;
327
+ /**
328
+ * Initializes the service, loading existing jobs and starting timers
329
+ */
330
+ private initialize;
331
+ /**
332
+ * Stops the cron service
333
+ */
334
+ stop(): Promise<void>;
335
+ /**
336
+ * Gets the service configuration
337
+ */
338
+ getConfig(): CronServiceConfig;
339
+ /**
340
+ * Creates a new cron job
341
+ * @param input Job creation input
342
+ * @returns The created job
343
+ * @throws Error if validation fails or max jobs exceeded
344
+ */
345
+ createJob(input: CronJobCreate): Promise<CronJob>;
346
+ /**
347
+ * Updates an existing cron job
348
+ * @param jobId The job ID to update
349
+ * @param patch The fields to update
350
+ * @returns The updated job
351
+ * @throws Error if job not found or validation fails
352
+ */
353
+ updateJob(jobId: string, patch: CronJobPatch): Promise<CronJob>;
354
+ /**
355
+ * Deletes a cron job
356
+ * @param jobId The job ID to delete
357
+ * @returns true if deleted, false if not found
358
+ */
359
+ deleteJob(jobId: string): Promise<boolean>;
360
+ /**
361
+ * Gets a job by ID
362
+ * @param jobId The job ID
363
+ * @returns The job or null if not found
364
+ */
365
+ getJob(jobId: string): Promise<CronJob | null>;
366
+ /**
367
+ * Lists all jobs, optionally filtered
368
+ * @param filter Optional filter criteria
369
+ * @returns Array of matching jobs
370
+ */
371
+ listJobs(filter?: CronJobFilter): Promise<CronJob[]>;
372
+ /**
373
+ * Gets the count of jobs
374
+ */
375
+ getJobCount(): Promise<number>;
376
+ /**
377
+ * Manually runs a job immediately
378
+ * @param jobId The job ID to run
379
+ * @param mode 'force' to run even if disabled, 'due' to only run if due
380
+ * @returns Execution result
381
+ */
382
+ runJob(jobId: string, mode?: "force" | "due"): Promise<CronExecutionResult & {
383
+ ran: boolean;
384
+ }>;
385
+ /**
386
+ * Handles a job becoming due (called by timer manager)
387
+ */
388
+ private handleJobDue;
389
+ /**
390
+ * Internal job execution with state management
391
+ */
392
+ private executeJobInternal;
393
+ /**
394
+ * Handles catch-up for jobs that may have been missed while the service was stopped
395
+ */
396
+ private handleMissedJobs;
397
+ /**
398
+ * Emits a cron event
399
+ */
400
+ private emitCronEvent;
401
+ /**
402
+ * Gets the service status
403
+ */
404
+ getStatus(): Promise<{
405
+ initialized: boolean;
406
+ jobCount: number;
407
+ trackedJobCount: number;
408
+ config: CronServiceConfig;
409
+ }>;
410
+ /**
411
+ * Performs a health check
412
+ */
413
+ healthCheck(): Promise<{
414
+ healthy: boolean;
415
+ issues: string[];
416
+ }>;
417
+ }
418
+
419
+ /**
420
+ * @module cron-storage
421
+ * @description Component-based persistence for cron job data using ElizaOS Components
422
+ *
423
+ * Storage strategy:
424
+ * - Each job is stored as a separate component with type "cron_job:{jobId}"
425
+ * - An index component "cron_job_index" tracks all job IDs for efficient listing
426
+ * - All components are scoped to the agent (entityId = agentId)
427
+ * - Index operations are serialized using an async mutex to prevent race conditions
428
+ */
429
+
430
+ /**
431
+ * Storage interface for cron job operations
432
+ */
433
+ interface CronStorage {
434
+ /**
435
+ * Retrieves a job by ID
436
+ * @returns The job or null if not found
437
+ */
438
+ getJob(jobId: string): Promise<CronJob | null>;
439
+ /**
440
+ * Saves a job (creates or updates)
441
+ */
442
+ saveJob(job: CronJob): Promise<void>;
443
+ /**
444
+ * Deletes a job by ID
445
+ * @returns true if the job was deleted, false if it didn't exist
446
+ */
447
+ deleteJob(jobId: string): Promise<boolean>;
448
+ /**
449
+ * Lists all jobs, optionally filtered
450
+ * @param filter Optional filter criteria
451
+ * @returns Array of matching jobs, sorted by next run time
452
+ */
453
+ listJobs(filter?: CronJobFilter): Promise<CronJob[]>;
454
+ /**
455
+ * Gets the total count of jobs for the agent
456
+ */
457
+ getJobCount(): Promise<number>;
458
+ /**
459
+ * Checks if a job exists
460
+ */
461
+ hasJob(jobId: string): Promise<boolean>;
462
+ }
463
+ /**
464
+ * Creates a storage instance for cron job operations
465
+ * @param runtime The agent runtime to use for component storage
466
+ */
467
+ declare function getCronStorage(runtime: IAgentRuntime): CronStorage;
468
+
469
+ /**
470
+ * @module plugin-cron
471
+ * @description ElizaOS plugin for cron job scheduling
472
+ *
473
+ * This plugin provides:
474
+ * - Scheduled job execution (cron expressions, intervals, one-time)
475
+ * - CRUD operations for managing jobs
476
+ * - Multiple payload types: prompts, actions, events
477
+ * - Persistent storage via Eliza components
478
+ * - Natural language job creation
479
+ *
480
+ * Key features:
481
+ * - Standard cron expression support (via croner)
482
+ * - Timezone-aware scheduling
483
+ * - Automatic catch-up for missed jobs
484
+ * - Job lifecycle events
485
+ *
486
+ * @example
487
+ * ```typescript
488
+ * import { cronPlugin } from '@elizaos/plugin-cron';
489
+ *
490
+ * const character = createCharacter({
491
+ * name: 'Scheduler',
492
+ * plugins: [cronPlugin],
493
+ * });
494
+ * ```
495
+ */
496
+
497
+ /**
498
+ * Cron scheduling plugin for ElizaOS
499
+ *
500
+ * Provides the ability to schedule recurring or one-time jobs that
501
+ * execute prompts, actions, or emit events on a defined schedule.
502
+ *
503
+ * Usage:
504
+ * ```typescript
505
+ * import { cronPlugin } from '@elizaos/plugin-cron';
506
+ *
507
+ * const agent = {
508
+ * character: myCharacter,
509
+ * plugins: [cronPlugin],
510
+ * };
511
+ * ```
512
+ *
513
+ * Once loaded, the plugin provides:
514
+ * - `CronService` - Core service for job management
515
+ * - Actions: CREATE_CRON, UPDATE_CRON, DELETE_CRON, LIST_CRONS, RUN_CRON
516
+ * - Provider: cronContext for injecting job info into prompts
517
+ *
518
+ * Creating jobs programmatically:
519
+ * ```typescript
520
+ * const cronService = runtime.getService<CronService>('CRON');
521
+ *
522
+ * // Create an interval job
523
+ * await cronService.createJob({
524
+ * name: 'Hourly check',
525
+ * enabled: true,
526
+ * schedule: { kind: 'every', everyMs: 3600000 },
527
+ * payload: { kind: 'prompt', text: 'Check system status' },
528
+ * });
529
+ *
530
+ * // Create a cron expression job
531
+ * await cronService.createJob({
532
+ * name: 'Daily report',
533
+ * enabled: true,
534
+ * schedule: { kind: 'cron', expr: '0 9 * * *', tz: 'America/New_York' },
535
+ * payload: { kind: 'prompt', text: 'Generate daily report' },
536
+ * });
537
+ *
538
+ * // Create a one-shot job
539
+ * await cronService.createJob({
540
+ * name: 'Reminder',
541
+ * enabled: true,
542
+ * deleteAfterRun: true,
543
+ * schedule: { kind: 'at', at: '2024-12-31T23:59:00Z' },
544
+ * payload: { kind: 'prompt', text: 'Happy New Year!' },
545
+ * });
546
+ * ```
547
+ */
548
+ /**
549
+ * Custom event names for cross-plugin communication.
550
+ * Other plugins (e.g. plugin-webhooks) can emit these to trigger
551
+ * heartbeat behaviour without a direct import dependency.
552
+ */
553
+ declare const CronPluginEvents: {
554
+ /** Request an immediate heartbeat tick. Payload: { text?: string } */
555
+ readonly HEARTBEAT_WAKE: "HEARTBEAT_WAKE";
556
+ /** Enqueue a system event for the next heartbeat. Payload: { text: string } */
557
+ readonly HEARTBEAT_SYSTEM_EVENT: "HEARTBEAT_SYSTEM_EVENT";
558
+ };
559
+ declare const cronPlugin: Plugin;
560
+
561
+ export { type ActiveHours, CRON_JOB_COMPONENT_PREFIX, CRON_JOB_INDEX_COMPONENT, CRON_SERVICE_TYPE, CronActions, CronEvents, CronExecutionResult, CronJob, CronJobCreate, CronJobFilter, CronJobPatch, CronPluginEvents, CronSchedule, CronService, CronServiceConfig, type CronStorage, HEARTBEAT_WORKER_NAME, type HeartbeatConfig, type SystemEvent, TimerManager, computeNextRunAtMs, cronPlugin, cronPlugin as default, drainSystemEvents, executeJob, formatSchedule, getCronStorage, heartbeatWorker, isWithinActiveHours, parseDuration, parseScheduleDescription, pendingEventCount, pushSystemEvent, resolveHeartbeatConfig, startHeartbeat, validateJobExecutability, validateSchedule, wakeHeartbeatNow };