Task 1.1 COMPLETE ✅ Core type definitions for routing workflows: - WorkflowSpec: One-time workflow specification - CronWorkflowSpec: Scheduled workflow specification - State: Individual step in workflow (Task/Pass/Fail) - RetryPolicy: Retry configuration with backoff - CatchClause: Error handling - ExecutionContext: Tracks state during execution - ActivityMetadata: Describes activity capabilities - Supporting types: PollParams, Heartbeat, Result All types support JSON marshaling/unmarshaling. 8 unit tests covering complex scenarios (9/9 PASS). Acceptance criteria met: ✅ All types compile without errors ✅ JSON marshaling/unmarshaling works correctly ✅ Unit tests pass (complex workflow examples) ✅ Ready for next phase (Knowledge Base) Effort: 2 hours Files: internal/routing/types.go (159 lines) internal/routing/types_test.go (286 lines)
253 lines
5.7 KiB
Markdown
253 lines
5.7 KiB
Markdown
# 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! 🎉
|
|
|