0
# Scheduled Jobs (Crons)
1
2
The CronsClient provides comprehensive cron job management for scheduling recurring LangGraph runs. It enables automated execution of assistants on defined schedules, supporting both thread-specific and standalone cron jobs with flexible scheduling configuration and management operations.
3
4
## Core Functionality
5
6
The CronsClient supports:
7
8
- **Job Creation**: Create cron jobs for assistants with flexible scheduling
9
- **Thread Integration**: Create cron jobs specific to individual threads
10
- **Schedule Management**: Configure complex schedules using cron expressions
11
- **Job Control**: Delete and search existing cron jobs
12
- **Payload Configuration**: Full run configuration support for scheduled executions
13
14
## CronsClient API
15
16
```typescript { .api }
17
class CronsClient extends BaseClient {
18
/**
19
* Create a standalone cron job for an assistant
20
* @param assistantId - Assistant ID to schedule
21
* @param payload - Cron job configuration including schedule and run parameters
22
* @returns Promise resolving to cron creation response with job details
23
*/
24
create(assistantId: string, payload?: CronsCreatePayload): Promise<CronCreateResponse>;
25
26
/**
27
* Create a cron job specific to a thread and assistant combination
28
* @param threadId - Thread ID for scoped execution
29
* @param assistantId - Assistant ID to schedule
30
* @param payload - Cron job configuration including schedule and run parameters
31
* @returns Promise resolving to thread-specific cron creation response
32
*/
33
createForThread(
34
threadId: string,
35
assistantId: string,
36
payload?: CronsCreatePayload
37
): Promise<CronCreateForThreadResponse>;
38
39
/**
40
* Delete an existing cron job permanently
41
* @param cronId - Unique cron job identifier to delete
42
* @returns Promise resolving when deletion completes
43
*/
44
delete(cronId: string): Promise<void>;
45
46
/**
47
* Search for cron jobs with flexible filtering criteria
48
* @param query - Search parameters including schedule and metadata filters
49
* @returns Promise resolving to array of matching cron jobs
50
*/
51
search(query?: CronSearchQuery): Promise<Cron[]>;
52
}
53
```
54
55
## Core Types
56
57
### Cron Job Interface
58
59
```typescript { .api }
60
interface Cron {
61
/** Unique cron job identifier */
62
cron_id: string;
63
/** Associated assistant ID */
64
assistant_id: string;
65
/** Associated thread ID (if thread-specific) */
66
thread_id?: string;
67
/** Cron schedule expression */
68
schedule: string;
69
/** Cron job creation timestamp */
70
created_at: string;
71
/** Cron job last update timestamp */
72
updated_at: string;
73
/** Next scheduled execution time */
74
next_run_time?: string;
75
/** Cron job metadata */
76
metadata: Metadata;
77
/** Run configuration for scheduled executions */
78
config: Config;
79
/** Run input payload */
80
payload: Record<string, any>;
81
/** Whether the cron is currently enabled */
82
enabled: boolean;
83
/** Timezone for schedule execution */
84
timezone?: string;
85
}
86
87
interface Metadata {
88
[key: string]: any;
89
}
90
```
91
92
### Response Types
93
94
```typescript { .api }
95
interface CronCreateResponse {
96
/** Created cron job details */
97
cron: Cron;
98
/** Creation success status */
99
success: boolean;
100
/** Optional creation message */
101
message?: string;
102
}
103
104
interface CronCreateForThreadResponse {
105
/** Created thread-specific cron job details */
106
cron: Cron;
107
/** Associated thread ID */
108
thread_id: string;
109
/** Creation success status */
110
success: boolean;
111
/** Optional creation message */
112
message?: string;
113
}
114
```
115
116
## Payload Types
117
118
### Creation Payload
119
120
```typescript { .api }
121
interface CronsCreatePayload {
122
/**
123
* Cron schedule expression in standard format
124
* Format: "minute hour day month day-of-week"
125
* Examples:
126
* - "0 9 * * *" - Daily at 9:00 AM
127
* - "0 9 * * 1-5" - Weekdays at 9:00 AM
128
* - "*/15 * * * *" - Every 15 minutes
129
* - "0 0 1 * *" - First day of every month
130
*/
131
schedule: string;
132
133
/** Input payload for scheduled run executions */
134
payload?: Record<string, any>;
135
136
/** Configuration for scheduled run executions */
137
config?: Config;
138
139
/** Metadata for the cron job */
140
metadata?: Metadata;
141
142
/** Timezone for schedule execution (defaults to UTC) */
143
timezone?: string;
144
145
/** Whether the cron job is enabled (defaults to true) */
146
enabled?: boolean;
147
148
/** Webhook URL to call on execution completion */
149
webhook?: string;
150
151
/** Maximum number of concurrent executions allowed */
152
maxConcurrency?: number;
153
154
/** Timeout for individual run executions in seconds */
155
timeout?: number;
156
157
/** Retry configuration for failed executions */
158
retryConfig?: {
159
maxRetries: number;
160
retryDelay: number;
161
backoffMultiplier?: number;
162
};
163
}
164
```
165
166
### Search Query
167
168
```typescript { .api }
169
interface CronSearchQuery {
170
/** Filter by assistant ID */
171
assistantId?: string;
172
173
/** Filter by thread ID (for thread-specific crons) */
174
threadId?: string;
175
176
/** Filter by enabled status */
177
enabled?: boolean;
178
179
/** Filter by schedule pattern (partial match) */
180
schedulePattern?: string;
181
182
/** Filter by metadata fields */
183
metadata?: Record<string, any>;
184
185
/** Filter by next run time after specified timestamp */
186
nextRunAfter?: string;
187
188
/** Filter by next run time before specified timestamp */
189
nextRunBefore?: string;
190
191
/** Filter by creation time after specified timestamp */
192
createdAfter?: string;
193
194
/** Filter by creation time before specified timestamp */
195
createdBefore?: string;
196
197
/** Maximum number of results to return */
198
limit?: number;
199
200
/** Pagination offset */
201
offset?: number;
202
203
/** Sort order for results */
204
sortBy?: "created_at" | "updated_at" | "next_run_time" | "schedule";
205
206
/** Sort direction */
207
sortOrder?: "asc" | "desc";
208
}
209
```
210
211
## Usage Examples
212
213
### Basic Cron Job Creation
214
215
```typescript
216
import { Client } from "@langchain/langgraph-sdk";
217
218
const client = new Client({
219
apiUrl: "https://api.langgraph.example.com",
220
apiKey: "your-api-key"
221
});
222
223
// Create a daily report generation cron
224
const dailyReportCron = await client.crons.create("assistant_reporter", {
225
schedule: "0 9 * * *", // Daily at 9:00 AM
226
payload: {
227
reportType: "daily_summary",
228
recipients: ["team@company.com"]
229
},
230
config: {
231
tags: ["reporting", "automated"],
232
recursion_limit: 10
233
},
234
metadata: {
235
description: "Daily team report generation",
236
owner: "admin@company.com",
237
category: "reporting"
238
},
239
timezone: "America/New_York",
240
timeout: 300 // 5 minutes timeout
241
});
242
243
console.log("Created cron job:", dailyReportCron.cron.cron_id);
244
console.log("Next run:", dailyReportCron.cron.next_run_time);
245
```
246
247
### Thread-Specific Cron Jobs
248
249
```typescript
250
// Create a cron job for a specific conversation thread
251
const threadCron = await client.crons.createForThread(
252
"thread_conversation_123",
253
"assistant_reminder",
254
{
255
schedule: "0 10,14,18 * * 1-5", // 10 AM, 2 PM, 6 PM on weekdays
256
payload: {
257
reminderType: "check_in",
258
message: "How are you doing today?"
259
},
260
config: {
261
configurable: {
262
temperature: 0.7,
263
personalization: true
264
}
265
},
266
metadata: {
267
user_id: "user_456",
268
reminder_category: "wellness_check",
269
frequency: "workday_reminders"
270
},
271
enabled: true
272
}
273
);
274
275
console.log("Thread cron created:", threadCron.cron.cron_id);
276
console.log("Associated thread:", threadCron.thread_id);
277
```
278
279
### Complex Scheduling Examples
280
281
```typescript
282
// Weekly data processing cron
283
const weeklyProcessor = await client.crons.create("assistant_data_processor", {
284
schedule: "0 2 * * 0", // Every Sunday at 2:00 AM
285
payload: {
286
operation: "weekly_analytics",
287
datasets: ["user_activity", "system_metrics", "performance_data"],
288
outputFormat: "json"
289
},
290
config: {
291
tags: ["analytics", "weekly"],
292
recursion_limit: 50
293
},
294
metadata: {
295
priority: "high",
296
department: "data_science",
297
estimated_duration: "2h"
298
},
299
retryConfig: {
300
maxRetries: 3,
301
retryDelay: 600, // 10 minutes
302
backoffMultiplier: 2
303
},
304
maxConcurrency: 1, // Ensure only one instance runs
305
timeout: 7200 // 2 hours timeout
306
});
307
308
// Monthly report cron with advanced configuration
309
const monthlyReportCron = await client.crons.create("assistant_monthly_reporter", {
310
schedule: "0 0 1 * *", // First day of every month at midnight
311
payload: {
312
reportType: "monthly_comprehensive",
313
includeMetrics: true,
314
includeCharts: true,
315
format: "pdf"
316
},
317
config: {
318
tags: ["monthly", "comprehensive", "executive"],
319
configurable: {
320
quality: "high",
321
detailed_analysis: true
322
}
323
},
324
metadata: {
325
recipients: ["exec@company.com", "manager@company.com"],
326
confidentiality: "internal",
327
auto_archive: true
328
},
329
webhook: "https://company.com/webhooks/report-complete",
330
timezone: "UTC"
331
});
332
333
// High-frequency monitoring cron
334
const monitoringCron = await client.crons.create("assistant_monitor", {
335
schedule: "*/5 * * * *", // Every 5 minutes
336
payload: {
337
checkType: "health_check",
338
systems: ["api", "database", "cache", "queue"],
339
alertThreshold: 0.9
340
},
341
config: {
342
tags: ["monitoring", "health_check"],
343
recursion_limit: 5
344
},
345
metadata: {
346
criticality: "high",
347
auto_escalate: true,
348
contact: "devops@company.com"
349
},
350
maxConcurrency: 2,
351
timeout: 30 // 30 seconds timeout for quick checks
352
});
353
```
354
355
### Cron Job Management
356
357
```typescript
358
// Search for cron jobs by various criteria
359
const reportingCrons = await client.crons.search({
360
metadata: { category: "reporting" },
361
enabled: true,
362
sortBy: "next_run_time",
363
sortOrder: "asc",
364
limit: 20
365
});
366
367
console.log("Found reporting crons:", reportingCrons.length);
368
reportingCrons.forEach(cron => {
369
console.log(`${cron.cron_id}: Next run at ${cron.next_run_time}`);
370
});
371
372
// Search for crons by assistant
373
const assistantCrons = await client.crons.search({
374
assistantId: "assistant_reporter",
375
createdAfter: "2024-01-01T00:00:00Z",
376
limit: 50
377
});
378
379
// Search for thread-specific crons
380
const threadSpecificCrons = await client.crons.search({
381
threadId: "thread_conversation_123",
382
enabled: true
383
});
384
385
// Search for crons scheduled to run soon
386
const upcomingCrons = await client.crons.search({
387
nextRunAfter: new Date().toISOString(),
388
nextRunBefore: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), // Next 24 hours
389
sortBy: "next_run_time",
390
sortOrder: "asc"
391
});
392
393
console.log("Crons running in next 24 hours:", upcomingCrons.length);
394
```
395
396
### Cron Job Lifecycle Management
397
398
```typescript
399
// Create, monitor, and manage cron lifecycle
400
async function manageCronLifecycle() {
401
// Create a temporary cron for a specific campaign
402
const campaignCron = await client.crons.create("assistant_campaign", {
403
schedule: "0 12 * * *", // Daily at noon
404
payload: {
405
campaignId: "summer_2024",
406
action: "send_daily_update"
407
},
408
config: {
409
tags: ["campaign", "summer_2024", "temporary"]
410
},
411
metadata: {
412
campaign: "summer_2024",
413
expiry: "2024-09-01T00:00:00Z",
414
auto_cleanup: true
415
}
416
});
417
418
console.log("Campaign cron created:", campaignCron.cron.cron_id);
419
420
// Monitor cron jobs and clean up expired ones
421
const expiredCrons = await client.crons.search({
422
metadata: { auto_cleanup: true },
423
createdBefore: "2024-09-01T00:00:00Z",
424
enabled: true
425
});
426
427
for (const expiredCron of expiredCrons) {
428
const expiryDate = new Date(expiredCron.metadata.expiry);
429
if (expiryDate < new Date()) {
430
await client.crons.delete(expiredCron.cron_id);
431
console.log(`Cleaned up expired cron: ${expiredCron.cron_id}`);
432
}
433
}
434
}
435
436
// Bulk operations
437
async function bulkCronManagement() {
438
// Find all crons for a specific project
439
const projectCrons = await client.crons.search({
440
metadata: { project: "data_migration" },
441
limit: 100
442
});
443
444
console.log(`Found ${projectCrons.length} project crons`);
445
446
// Disable all project crons (simulate project pause)
447
for (const cron of projectCrons) {
448
// Note: In real implementation, you'd need an update/disable method
449
// For now, we delete and recreate if needed
450
console.log(`Managing cron: ${cron.cron_id}`);
451
}
452
453
// Clean up completed project crons
454
const completedProjectCrons = projectCrons.filter(
455
cron => cron.metadata.status === "completed"
456
);
457
458
for (const completedCron of completedProjectCrons) {
459
await client.crons.delete(completedCron.cron_id);
460
console.log(`Deleted completed cron: ${completedCron.cron_id}`);
461
}
462
}
463
```
464
465
### Advanced Scheduling Patterns
466
467
```typescript
468
// Complex scheduling examples with different patterns
469
470
// Business hours only
471
const businessHoursCron = await client.crons.create("assistant_business_support", {
472
schedule: "0 9-17 * * 1-5", // Every hour from 9 AM to 5 PM, Monday to Friday
473
payload: {
474
supportType: "business_hours_monitoring",
475
priority: "normal"
476
},
477
timezone: "America/New_York"
478
});
479
480
// Quarterly reporting
481
const quarterlyCron = await client.crons.create("assistant_quarterly", {
482
schedule: "0 0 1 1,4,7,10 *", // First day of quarters (Jan, Apr, Jul, Oct)
483
payload: {
484
reportType: "quarterly_financial",
485
includeProjections: true
486
}
487
});
488
489
// End of month processing
490
const monthEndCron = await client.crons.create("assistant_month_end", {
491
schedule: "0 23 28-31 * *", // Last few days of month at 11 PM
492
payload: {
493
processType: "month_end_closing",
494
validateData: true
495
},
496
metadata: {
497
// Custom logic can determine if it's actually the last day
498
checkLastDay: true
499
}
500
});
501
502
// Holiday-aware scheduling (requires custom logic in assistant)
503
const holidayAwareCron = await client.crons.create("assistant_holiday_checker", {
504
schedule: "0 8 * * 1-5", // Weekdays at 8 AM
505
payload: {
506
checkHolidays: true,
507
skipOnHolidays: ["US_FEDERAL", "COMPANY_SPECIFIC"],
508
rescheduleLogic: "next_business_day"
509
},
510
config: {
511
configurable: {
512
holiday_calendar: "US",
513
company_holidays: true
514
}
515
}
516
});
517
```
518
519
### Error Handling and Monitoring
520
521
```typescript
522
async function robustCronManagement() {
523
try {
524
// Create cron with comprehensive error handling
525
const monitoredCron = await client.crons.create("assistant_monitored", {
526
schedule: "0 */2 * * *", // Every 2 hours
527
payload: {
528
task: "system_health_check",
529
alertOnFailure: true
530
},
531
config: {
532
tags: ["monitoring", "critical"]
533
},
534
metadata: {
535
alertEmail: "alerts@company.com",
536
escalationLevel: "high",
537
maxFailures: 3
538
},
539
retryConfig: {
540
maxRetries: 2,
541
retryDelay: 300,
542
backoffMultiplier: 1.5
543
},
544
webhook: "https://company.com/webhooks/cron-status"
545
});
546
547
console.log("Monitored cron created successfully");
548
549
// Verify cron creation
550
const verifySearch = await client.crons.search({
551
assistantId: "assistant_monitored",
552
limit: 1
553
});
554
555
if (verifySearch.length === 0) {
556
throw new Error("Cron creation verification failed");
557
}
558
559
} catch (error) {
560
console.error("Cron creation failed:", error);
561
562
// Attempt cleanup if partial creation occurred
563
try {
564
const cleanupCrons = await client.crons.search({
565
assistantId: "assistant_monitored",
566
createdAfter: new Date(Date.now() - 60000).toISOString() // Last minute
567
});
568
569
for (const cleanupCron of cleanupCrons) {
570
await client.crons.delete(cleanupCron.cron_id);
571
console.log(`Cleaned up partial cron: ${cleanupCron.cron_id}`);
572
}
573
} catch (cleanupError) {
574
console.error("Cleanup failed:", cleanupError);
575
}
576
577
throw error;
578
}
579
}
580
581
// Monitoring and alerting
582
async function monitorCronHealth() {
583
// Check for crons that should have run but might be stuck
584
const recentCrons = await client.crons.search({
585
nextRunBefore: new Date(Date.now() - 60 * 60 * 1000).toISOString(), // Should have run in last hour
586
enabled: true,
587
sortBy: "next_run_time",
588
limit: 50
589
});
590
591
const potentiallyStuck = recentCrons.filter(cron => {
592
const nextRun = new Date(cron.next_run_time || 0);
593
const now = new Date();
594
return nextRun < now;
595
});
596
597
if (potentiallyStuck.length > 0) {
598
console.warn(`Found ${potentiallyStuck.length} potentially stuck crons:`);
599
potentiallyStuck.forEach(cron => {
600
console.warn(`- ${cron.cron_id}: Should have run at ${cron.next_run_time}`);
601
});
602
}
603
}
604
```
605
606
The CronsClient provides comprehensive cron job management with flexible scheduling, advanced configuration options, and robust lifecycle management, enabling reliable automation of LangGraph assistant executions on defined schedules.