TypeScript/JavaScript SDK for interacting with the LangGraph REST API server
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.
The CronsClient supports:
class CronsClient extends BaseClient {
/**
* Create a standalone cron job for an assistant
* @param assistantId - Assistant ID to schedule
* @param payload - Cron job configuration including schedule and run parameters
* @returns Promise resolving to cron creation response with job details
*/
create(assistantId: string, payload?: CronsCreatePayload): Promise<CronCreateResponse>;
/**
* Create a cron job specific to a thread and assistant combination
* @param threadId - Thread ID for scoped execution
* @param assistantId - Assistant ID to schedule
* @param payload - Cron job configuration including schedule and run parameters
* @returns Promise resolving to thread-specific cron creation response
*/
createForThread(
threadId: string,
assistantId: string,
payload?: CronsCreatePayload
): Promise<CronCreateForThreadResponse>;
/**
* Delete an existing cron job permanently
* @param cronId - Unique cron job identifier to delete
* @returns Promise resolving when deletion completes
*/
delete(cronId: string): Promise<void>;
/**
* Search for cron jobs with flexible filtering criteria
* @param query - Search parameters including schedule and metadata filters
* @returns Promise resolving to array of matching cron jobs
*/
search(query?: CronSearchQuery): Promise<Cron[]>;
}interface Cron {
/** Unique cron job identifier */
cron_id: string;
/** Associated assistant ID */
assistant_id: string;
/** Associated thread ID (if thread-specific) */
thread_id?: string;
/** Cron schedule expression */
schedule: string;
/** Cron job creation timestamp */
created_at: string;
/** Cron job last update timestamp */
updated_at: string;
/** Next scheduled execution time */
next_run_time?: string;
/** Cron job metadata */
metadata: Metadata;
/** Run configuration for scheduled executions */
config: Config;
/** Run input payload */
payload: Record<string, any>;
/** Whether the cron is currently enabled */
enabled: boolean;
/** Timezone for schedule execution */
timezone?: string;
}
interface Metadata {
[key: string]: any;
}interface CronCreateResponse {
/** Created cron job details */
cron: Cron;
/** Creation success status */
success: boolean;
/** Optional creation message */
message?: string;
}
interface CronCreateForThreadResponse {
/** Created thread-specific cron job details */
cron: Cron;
/** Associated thread ID */
thread_id: string;
/** Creation success status */
success: boolean;
/** Optional creation message */
message?: string;
}interface CronsCreatePayload {
/**
* Cron schedule expression in standard format
* Format: "minute hour day month day-of-week"
* Examples:
* - "0 9 * * *" - Daily at 9:00 AM
* - "0 9 * * 1-5" - Weekdays at 9:00 AM
* - "*/15 * * * *" - Every 15 minutes
* - "0 0 1 * *" - First day of every month
*/
schedule: string;
/** Input payload for scheduled run executions */
payload?: Record<string, any>;
/** Configuration for scheduled run executions */
config?: Config;
/** Metadata for the cron job */
metadata?: Metadata;
/** Timezone for schedule execution (defaults to UTC) */
timezone?: string;
/** Whether the cron job is enabled (defaults to true) */
enabled?: boolean;
/** Webhook URL to call on execution completion */
webhook?: string;
/** Maximum number of concurrent executions allowed */
maxConcurrency?: number;
/** Timeout for individual run executions in seconds */
timeout?: number;
/** Retry configuration for failed executions */
retryConfig?: {
maxRetries: number;
retryDelay: number;
backoffMultiplier?: number;
};
}interface CronSearchQuery {
/** Filter by assistant ID */
assistantId?: string;
/** Filter by thread ID (for thread-specific crons) */
threadId?: string;
/** Filter by enabled status */
enabled?: boolean;
/** Filter by schedule pattern (partial match) */
schedulePattern?: string;
/** Filter by metadata fields */
metadata?: Record<string, any>;
/** Filter by next run time after specified timestamp */
nextRunAfter?: string;
/** Filter by next run time before specified timestamp */
nextRunBefore?: string;
/** Filter by creation time after specified timestamp */
createdAfter?: string;
/** Filter by creation time before specified timestamp */
createdBefore?: string;
/** Maximum number of results to return */
limit?: number;
/** Pagination offset */
offset?: number;
/** Sort order for results */
sortBy?: "created_at" | "updated_at" | "next_run_time" | "schedule";
/** Sort direction */
sortOrder?: "asc" | "desc";
}import { Client } from "@langchain/langgraph-sdk";
const client = new Client({
apiUrl: "https://api.langgraph.example.com",
apiKey: "your-api-key"
});
// Create a daily report generation cron
const dailyReportCron = await client.crons.create("assistant_reporter", {
schedule: "0 9 * * *", // Daily at 9:00 AM
payload: {
reportType: "daily_summary",
recipients: ["team@company.com"]
},
config: {
tags: ["reporting", "automated"],
recursion_limit: 10
},
metadata: {
description: "Daily team report generation",
owner: "admin@company.com",
category: "reporting"
},
timezone: "America/New_York",
timeout: 300 // 5 minutes timeout
});
console.log("Created cron job:", dailyReportCron.cron.cron_id);
console.log("Next run:", dailyReportCron.cron.next_run_time);// Create a cron job for a specific conversation thread
const threadCron = await client.crons.createForThread(
"thread_conversation_123",
"assistant_reminder",
{
schedule: "0 10,14,18 * * 1-5", // 10 AM, 2 PM, 6 PM on weekdays
payload: {
reminderType: "check_in",
message: "How are you doing today?"
},
config: {
configurable: {
temperature: 0.7,
personalization: true
}
},
metadata: {
user_id: "user_456",
reminder_category: "wellness_check",
frequency: "workday_reminders"
},
enabled: true
}
);
console.log("Thread cron created:", threadCron.cron.cron_id);
console.log("Associated thread:", threadCron.thread_id);// Weekly data processing cron
const weeklyProcessor = await client.crons.create("assistant_data_processor", {
schedule: "0 2 * * 0", // Every Sunday at 2:00 AM
payload: {
operation: "weekly_analytics",
datasets: ["user_activity", "system_metrics", "performance_data"],
outputFormat: "json"
},
config: {
tags: ["analytics", "weekly"],
recursion_limit: 50
},
metadata: {
priority: "high",
department: "data_science",
estimated_duration: "2h"
},
retryConfig: {
maxRetries: 3,
retryDelay: 600, // 10 minutes
backoffMultiplier: 2
},
maxConcurrency: 1, // Ensure only one instance runs
timeout: 7200 // 2 hours timeout
});
// Monthly report cron with advanced configuration
const monthlyReportCron = await client.crons.create("assistant_monthly_reporter", {
schedule: "0 0 1 * *", // First day of every month at midnight
payload: {
reportType: "monthly_comprehensive",
includeMetrics: true,
includeCharts: true,
format: "pdf"
},
config: {
tags: ["monthly", "comprehensive", "executive"],
configurable: {
quality: "high",
detailed_analysis: true
}
},
metadata: {
recipients: ["exec@company.com", "manager@company.com"],
confidentiality: "internal",
auto_archive: true
},
webhook: "https://company.com/webhooks/report-complete",
timezone: "UTC"
});
// High-frequency monitoring cron
const monitoringCron = await client.crons.create("assistant_monitor", {
schedule: "*/5 * * * *", // Every 5 minutes
payload: {
checkType: "health_check",
systems: ["api", "database", "cache", "queue"],
alertThreshold: 0.9
},
config: {
tags: ["monitoring", "health_check"],
recursion_limit: 5
},
metadata: {
criticality: "high",
auto_escalate: true,
contact: "devops@company.com"
},
maxConcurrency: 2,
timeout: 30 // 30 seconds timeout for quick checks
});// Search for cron jobs by various criteria
const reportingCrons = await client.crons.search({
metadata: { category: "reporting" },
enabled: true,
sortBy: "next_run_time",
sortOrder: "asc",
limit: 20
});
console.log("Found reporting crons:", reportingCrons.length);
reportingCrons.forEach(cron => {
console.log(`${cron.cron_id}: Next run at ${cron.next_run_time}`);
});
// Search for crons by assistant
const assistantCrons = await client.crons.search({
assistantId: "assistant_reporter",
createdAfter: "2024-01-01T00:00:00Z",
limit: 50
});
// Search for thread-specific crons
const threadSpecificCrons = await client.crons.search({
threadId: "thread_conversation_123",
enabled: true
});
// Search for crons scheduled to run soon
const upcomingCrons = await client.crons.search({
nextRunAfter: new Date().toISOString(),
nextRunBefore: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), // Next 24 hours
sortBy: "next_run_time",
sortOrder: "asc"
});
console.log("Crons running in next 24 hours:", upcomingCrons.length);// Create, monitor, and manage cron lifecycle
async function manageCronLifecycle() {
// Create a temporary cron for a specific campaign
const campaignCron = await client.crons.create("assistant_campaign", {
schedule: "0 12 * * *", // Daily at noon
payload: {
campaignId: "summer_2024",
action: "send_daily_update"
},
config: {
tags: ["campaign", "summer_2024", "temporary"]
},
metadata: {
campaign: "summer_2024",
expiry: "2024-09-01T00:00:00Z",
auto_cleanup: true
}
});
console.log("Campaign cron created:", campaignCron.cron.cron_id);
// Monitor cron jobs and clean up expired ones
const expiredCrons = await client.crons.search({
metadata: { auto_cleanup: true },
createdBefore: "2024-09-01T00:00:00Z",
enabled: true
});
for (const expiredCron of expiredCrons) {
const expiryDate = new Date(expiredCron.metadata.expiry);
if (expiryDate < new Date()) {
await client.crons.delete(expiredCron.cron_id);
console.log(`Cleaned up expired cron: ${expiredCron.cron_id}`);
}
}
}
// Bulk operations
async function bulkCronManagement() {
// Find all crons for a specific project
const projectCrons = await client.crons.search({
metadata: { project: "data_migration" },
limit: 100
});
console.log(`Found ${projectCrons.length} project crons`);
// Disable all project crons (simulate project pause)
for (const cron of projectCrons) {
// Note: In real implementation, you'd need an update/disable method
// For now, we delete and recreate if needed
console.log(`Managing cron: ${cron.cron_id}`);
}
// Clean up completed project crons
const completedProjectCrons = projectCrons.filter(
cron => cron.metadata.status === "completed"
);
for (const completedCron of completedProjectCrons) {
await client.crons.delete(completedCron.cron_id);
console.log(`Deleted completed cron: ${completedCron.cron_id}`);
}
}// Complex scheduling examples with different patterns
// Business hours only
const businessHoursCron = await client.crons.create("assistant_business_support", {
schedule: "0 9-17 * * 1-5", // Every hour from 9 AM to 5 PM, Monday to Friday
payload: {
supportType: "business_hours_monitoring",
priority: "normal"
},
timezone: "America/New_York"
});
// Quarterly reporting
const quarterlyCron = await client.crons.create("assistant_quarterly", {
schedule: "0 0 1 1,4,7,10 *", // First day of quarters (Jan, Apr, Jul, Oct)
payload: {
reportType: "quarterly_financial",
includeProjections: true
}
});
// End of month processing
const monthEndCron = await client.crons.create("assistant_month_end", {
schedule: "0 23 28-31 * *", // Last few days of month at 11 PM
payload: {
processType: "month_end_closing",
validateData: true
},
metadata: {
// Custom logic can determine if it's actually the last day
checkLastDay: true
}
});
// Holiday-aware scheduling (requires custom logic in assistant)
const holidayAwareCron = await client.crons.create("assistant_holiday_checker", {
schedule: "0 8 * * 1-5", // Weekdays at 8 AM
payload: {
checkHolidays: true,
skipOnHolidays: ["US_FEDERAL", "COMPANY_SPECIFIC"],
rescheduleLogic: "next_business_day"
},
config: {
configurable: {
holiday_calendar: "US",
company_holidays: true
}
}
});async function robustCronManagement() {
try {
// Create cron with comprehensive error handling
const monitoredCron = await client.crons.create("assistant_monitored", {
schedule: "0 */2 * * *", // Every 2 hours
payload: {
task: "system_health_check",
alertOnFailure: true
},
config: {
tags: ["monitoring", "critical"]
},
metadata: {
alertEmail: "alerts@company.com",
escalationLevel: "high",
maxFailures: 3
},
retryConfig: {
maxRetries: 2,
retryDelay: 300,
backoffMultiplier: 1.5
},
webhook: "https://company.com/webhooks/cron-status"
});
console.log("Monitored cron created successfully");
// Verify cron creation
const verifySearch = await client.crons.search({
assistantId: "assistant_monitored",
limit: 1
});
if (verifySearch.length === 0) {
throw new Error("Cron creation verification failed");
}
} catch (error) {
console.error("Cron creation failed:", error);
// Attempt cleanup if partial creation occurred
try {
const cleanupCrons = await client.crons.search({
assistantId: "assistant_monitored",
createdAfter: new Date(Date.now() - 60000).toISOString() // Last minute
});
for (const cleanupCron of cleanupCrons) {
await client.crons.delete(cleanupCron.cron_id);
console.log(`Cleaned up partial cron: ${cleanupCron.cron_id}`);
}
} catch (cleanupError) {
console.error("Cleanup failed:", cleanupError);
}
throw error;
}
}
// Monitoring and alerting
async function monitorCronHealth() {
// Check for crons that should have run but might be stuck
const recentCrons = await client.crons.search({
nextRunBefore: new Date(Date.now() - 60 * 60 * 1000).toISOString(), // Should have run in last hour
enabled: true,
sortBy: "next_run_time",
limit: 50
});
const potentiallyStuck = recentCrons.filter(cron => {
const nextRun = new Date(cron.next_run_time || 0);
const now = new Date();
return nextRun < now;
});
if (potentiallyStuck.length > 0) {
console.warn(`Found ${potentiallyStuck.length} potentially stuck crons:`);
potentiallyStuck.forEach(cron => {
console.warn(`- ${cron.cron_id}: Should have run at ${cron.next_run_time}`);
});
}
}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.
Install with Tessl CLI
npx tessl i tessl/npm-langchain--langgraph-sdk