# Cron Jobs in Poimen Workflows ## Quick Summary **llm-router** detects if user is asking for scheduled/recurring work and generates either: - **WorkflowSpec** (one-time execution) - **CronWorkflowSpec** (scheduled execution) --- ## CRON EXAMPLES ### Example 1: Daily Security Scan **User says**: "Run security scan on all repos every day at 2 AM" **llm-router detects**: - is_scheduled: true - schedule: "0 2 * * *" (2 AM every day) - activities_needed: [Clone, SecurityScan, SendAlert] **llm-router generates**: ```json { "type": "CronWorkflow", "name": "daily-security-scan", "schedule": "0 2 * * *", "timezone": "UTC", "input": {"repos": [...]}, "states": [ {"name": "Clone", "type": "Task", "resource": "CloneRepoActivity", ...}, {"name": "SecurityScan", "type": "Task", "resource": "SecurityScanActivity", ...}, {"name": "SendAlert", "type": "Task", "resource": "SendNotificationActivity", ...} ] } ``` **Temporal** executes this: - At 2 AM UTC every day - Runs RoutingWorkflow with this spec - Each run is independent (tracks execution history) --- ### Example 2: Hourly Health Check **User says**: "Check API health every hour" **llm-router generates**: ```json { "type": "CronWorkflow", "schedule": "0 * * * *", "timezone": "UTC", "states": [ {"name": "HealthCheck", "type": "Task", "resource": "HealthCheckActivity", ...}, {"name": "RecordMetrics", "type": "Task", "resource": "RecordMetricsActivity", ...} ] } ``` **Execution**: Every hour, automatically --- ### Example 3: Weekly Performance Baseline **User says**: "Compare performance with baseline every Sunday at 3 AM" **llm-router generates**: ```json { "type": "CronWorkflow", "schedule": "0 3 * * 0", "timezone": "America/New_York", "states": [...] } ``` **Execution**: Every Sunday at 3 AM in New York timezone --- ## CRON SCHEDULE SYNTAX ``` ┌───────────── minute (0 - 59) │ ┌───────────── hour (0 - 23) │ │ ┌───────────── day of month (1 - 31) │ │ │ ┌───────────── month (1 - 12) │ │ │ │ ┌───────────── day of week (0 - 6, 0 = Sunday) │ │ │ │ │ │ │ │ │ │ * * * * * Common Examples: 0 2 * * * → Every day at 2:00 AM 0 */6 * * * → Every 6 hours 0 9 * * 1-5 → Weekdays at 9 AM (Mon-Fri) 0 0 1 * * → First day of month at midnight 0 0 * * 0 → Every Sunday at midnight */15 * * * * → Every 15 minutes 30 2 * * 0 → Every Sunday at 2:30 AM ``` --- ## EXECUTION TRACKING Temporal automatically tracks all cron executions: ``` Workflow: daily-security-scan Run 1: 2025-02-01 02:00:00 UTC → COMPLETED (5m 32s) Run 2: 2025-02-02 02:00:00 UTC → COMPLETED (4m 58s) Run 3: 2025-02-03 02:00:00 UTC → FAILED (timeout in SecurityScan) Run 4: 2025-02-04 02:00:00 UTC → COMPLETED (6m 15s) Run 5: 2025-02-05 02:00:00 UTC → COMPLETED (5m 01s) ``` Retrieve with: ```bash temporal workflow list --query "ExecutionStatus='Completed' AND WorkflowType='RoutingWorkflow'" temporal workflow describe --workflow-id daily-security-scan ``` --- ## HOW llm-router DETECTS CRON LLM looks for keywords in user message: ``` "every day at 2 AM" → "0 2 * * *" "every 6 hours" → "0 */6 * * *" "daily" → "0 0 * * *" "weekly" → "0 0 * * 0" (Sunday) "every Monday" → "0 0 * * 1" "every 15 minutes" → "*/15 * * * *" "weekdays at 9 AM" → "0 9 * * 1-5" "first of month" → "0 0 1 * *" "midnight" → "0 0" ``` --- ## DIFFERENCES: One-Time vs Cron | Aspect | One-Time | Cron | |--------|----------|------| | **Type** | WorkflowSpec | CronWorkflowSpec | | **Triggered by** | API call, CLI | Schedule | | **Execution** | Runs once, returns immediately | Runs on schedule, indefinitely | | **Input** | Varies per call | Fixed for all runs | | **History** | Single execution | Multiple executions tracked | | **Cancellation** | Can't cancel | Can stop/restart cron | | **Use Case** | Ad-hoc analysis | Background monitoring | --- ## API ENDPOINTS (Proposed) ### Submit Cron Workflow ```bash POST /api/v1/cron/workflows { "type": "CronWorkflow", "schedule": "0 2 * * *", "timezone": "UTC", "states": [...] } Response: { "workflow_id": "daily-security-scan", "schedule": "0 2 * * *", "next_run": "2025-02-02 02:00:00 UTC", "created": "2025-02-01 15:30:00 UTC" } ``` ### Get Cron Status ```bash GET /api/v1/cron/workflows/daily-security-scan/status Response: { "workflow_id": "daily-security-scan", "schedule": "0 2 * * *", "is_active": true, "last_run": { "time": "2025-02-01 02:00:00 UTC", "status": "COMPLETED", "duration": "5m 32s" }, "next_run": "2025-02-02 02:00:00 UTC", "execution_history": [...] } ``` ### List Cron Workflows ```bash GET /api/v1/cron/workflows Response: { "workflows": [ { "workflow_id": "daily-security-scan", "schedule": "0 2 * * *", "is_active": true, "created": "2025-02-01 15:30:00 UTC" }, { "workflow_id": "hourly-health-check", "schedule": "0 * * * *", "is_active": true, "created": "2025-02-01 16:00:00 UTC" } ] } ``` ### Cancel Cron Workflow ```bash DELETE /api/v1/cron/workflows/daily-security-scan Response: { "status": "cancelled", "workflow_id": "daily-security-scan", "cancelled_at": "2025-02-01 16:30:00 UTC" } ``` --- ## SUMMARY ✅ **llm-router handles both**: - One-time workflows (instant execution) - Cron workflows (scheduled, recurring) ✅ **Same RoutingWorkflow executor** for both ✅ **Temporal manages scheduling** (native support) ✅ **Full execution history** tracked This completes the architecture! 🎉