# How Prime Agent's Scheduling Architecture Manages Delayed and Recurring Prompts

> Discover how Prime Agent's scheduling architecture efficiently manages delayed and recurring prompts using its cron-style subsystem with AgentCronJobStore and AgentCronScheduler for reliable execution.

- Repository: [Prime Intellect/prime-agent](https://github.com/PrimeIntellect-ai/prime-agent)
- Tags: architecture
- Published: 2026-08-18

---

**Prime Agent employs a dedicated cron-style subsystem utilizing `AgentCronJobStore` for persistence and `AgentCronScheduler` for execution to handle both delayed (one-time) and recurring prompts through interval and cron expression support.**

The PrimeIntellect-ai/prime-agent repository implements a deterministic scheduling architecture that cleanly separates job definition from execution logic. This system enables AI agents to schedule future tasks using human-readable strings like `"in 10m"` or `"every 5m"`, persisting state across daemon restarts in [`scheduled-jobs.json`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/scheduled-jobs.json) while respecting Node.js timer limitations.

## Core Components of the Scheduling Architecture

### AgentCronJobStore and Persistent State

The **`AgentCronJobStore`** class in [`packages/coding-agent/src/core/cron-jobs.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/cron-jobs.ts) handles persistence of scheduled jobs to a JSON file (typically [`scheduled-jobs.json`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/scheduled-jobs.json)). It provides CRUD operations for managing job lifecycles, storing critical metadata including `nextRunAt` timestamps, schedule configurations, and current status. The job record structure (lines 35‑53) defines fields such as `activeSessionId`, `sessionFile`, `prompt`, and `status`, ensuring scheduled prompts survive process restarts.

### AgentCronScheduler and Execution Logic

The **`AgentCronScheduler`** drives the actual execution loop. It polls the store, calculates next run times, and invokes the supplied **`runJob`** hook when deadlines are reached. The scheduler's `runDue` method updates `nextRunAt` after each execution for recurring jobs, while one-time jobs transition to `"completed"` or `"cancelled"` status. This implementation handles the timer orchestration, including fallback logic when delays exceed Node.js's maximum timeout value.

### Schedule Types and Parsing

The system supports three distinct schedule kinds via `AgentCronScheduleKind`:

- **`"once"`** — Single delayed execution at a specific future time
- **`"interval"`** — Recurring execution based on fixed millisecond intervals  
- **`"cron"`** — Full cron-expression support for complex scheduling patterns

The **`parseAgentCronSchedule`** function converts human-readable strings (e.g., `"in 1m"`, `"every 5m"`) into structured `AgentCronSchedule` objects with calculated `nextRunAt` timestamps. Schedule definitions (lines 29‑33) specify the shape including `kind`, `intervalMs`, and cron expressions.

## Handling Delayed (One-Time) Prompts

When users supply schedules like **`"in 1m"`**, the parser returns a `kind: "once"` schedule with `nextRunAt` set to the current time plus the specified duration. The `create` method (lines 23‑46) persists this job with `status: "active"`.

The scheduler monitors active jobs and fires when `nextRunAt` is reached. Upon execution completion, the job status updates to **`"completed"`** (or `"cancelled"` on error), preventing further invocations.

```typescript
import { AgentCronJobStore } from "./core/cron-jobs.js";

const store = new AgentCronJobStore("my-session/scheduled-jobs.json");

// Schedule a one-time delayed prompt
store.create({
  activeSessionId: "sess-1",
  sessionId: "sess-1",
  sessionFile: "session.json",
  cwd: "/home/user",
  label: "reminder",
  prompt: "Check inbox",
  scheduleText: "in 10m",  // Executes once after 10 minutes
});

```

## Managing Recurring Prompts

### Interval-Based Recurrence

For schedules such as **`"every 5m"`**, `parseAgentCronSchedule` produces `kind: "interval"` with `intervalMs` set to 300,000 milliseconds. The `create` method initializes `nextRunAt` to the current time plus the interval duration.

After each successful execution, the scheduler's `runDue` implementation updates `nextRunAt` by adding `intervalMs` to the previous value. The job maintains `status: "active"` indefinitely, enabling continuous execution until explicitly paused, cancelled, or until the session terminates.

### Cron Expression Support

The architecture also supports standard cron expressions through the `"cron"` schedule kind, allowing complex patterns like `"0 9 * * 1"` for weekly Monday morning executions. The scheduler evaluates these expressions to determine the next valid `nextRunAt` timestamp using standard cron parsing logic.

```typescript
// Schedule a recurring heartbeat prompt
store.create({
  activeSessionId: "sess-1",
  sessionId: "sess-1",
  sessionFile: "session.json",
  cwd: "/home/user",
  label: "heartbeat",
  prompt: "Send keep-alive",
  scheduleText: "every 5m",  // Recurring every 5 minutes
});

```

## Daemon Integration and Heartbeat Defaults

The daemon mode in [`packages/coding-agent/src/modes/daemon/daemon-mode.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/daemon-mode.ts) instantiates `AgentCronScheduler` and wires the `runJob` hook to the agent's execution pipeline. It leverages the **`createHeartbeat`** method (lines 13‑50) to establish default recurring schedules.

The system supplies a default heartbeat schedule of **`every 5m`** (defined in lines 17‑18) and a default delivery mode of `steer`. This ensures continuous agent activity through persistent, automatically managed heartbeat prompts that keep the session alive between user interactions.

## Edge Cases and Timer Limitations

The scheduler respects Node.js's maximum timer value (**`MAX_TIMEOUT_MS`** ≈ 2.1 billion milliseconds). When `nextRunAt` exceeds this limit (roughly 24.8 days in the future), the implementation falls back to a poll-loop mechanism rather than using native `setTimeout`. This ensures reliable execution of long-delayed prompts without timer overflow issues.

Unit tests in [`packages/coding-agent/test/cron-jobs.test.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/test/cron-jobs.test.ts) verify correct state transitions for both delayed (`in 1m`) and recurring (`every 5m`) scenarios, ensuring the architecture handles edge cases deterministically.

## Summary

- **Prime Agent's scheduling architecture** separates persistence (`AgentCronJobStore`) from execution (`AgentCronScheduler`) to enable reliable delayed and recurring prompts.
- **Three schedule kinds**—`"once"`, `"interval"`, and `"cron"`—support everything from one-time delays to complex recurring patterns.
- **Human-readable parsing** via `parseAgentCronSchedule` converts strings like `"in 10m"` or `"every 5m"` into executable schedules with precise `nextRunAt` timestamps.
- **State management** tracks job status through `"active"`, `"completed"`, and `"cancelled"` states, persisting to [`scheduled-jobs.json`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/scheduled-jobs.json) for durability across restarts.
- **Timer safety** respects Node.js's `MAX_TIMEOUT_MS` limit through intelligent poll-loop fallbacks for long-dated schedules.

## Frequently Asked Questions

### How does Prime Agent parse human-readable schedule strings?

The **`parseAgentCronSchedule`** function in [`packages/coding-agent/src/core/cron-jobs.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/cron-jobs.ts) analyzes strings like `"in 1m"` or `"every 5m"` to determine the schedule kind, extract millisecond values, and calculate the initial `nextRunAt` timestamp. It supports relative time expressions for delayed execution and recurrence patterns, returning a structured `AgentCronSchedule` object that the job store can persist and the scheduler can execute.

### What happens when a scheduled prompt fails during execution?

When the `runJob` hook encounters an error, the scheduler catches the exception and updates the job's status to **`"cancelled"`** rather than `"completed"`. For recurring interval jobs, this typically prevents the next `nextRunAt` calculation, effectively halting the schedule. The persisted state in [`scheduled-jobs.json`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/scheduled-jobs.json) preserves the error status, allowing inspection and potential rescheduling by the user or daemon recovery logic.

### How does the scheduler handle very long delays beyond Node.js timer limits?

The architecture monitors whether `nextRunAt` exceeds **`MAX_TIMEOUT_MS`** (approximately 2.1 billion milliseconds or 24.8 days). When delays extend beyond this boundary, `AgentCronScheduler` abandons the standard `setTimeout` approach and switches to a **poll-loop mechanism** that periodically checks if the target time has been reached, ensuring reliable execution of long-dated prompts without timer overflow.

### Can recurring jobs be paused or cancelled mid-execution?

Yes. The `AgentCronJobStore` provides methods to update job status from `"active"` to `"paused"` or `"cancelled"`. While paused, the scheduler skips execution of that job's `runJob` hook even when `nextRunAt` is reached. Cancellation permanently stops the schedule regardless of kind, preventing both immediate execution and future next-run calculations for interval or cron-based prompts.