Skip to main content
The user describes a recurring reminder; the agent registers a schedule job via schedule tools.
Built-in — no extra dependencies required. Schedule tools are included in the core praisonaiagents package.
Schedule tools let your agents self-schedule reminders, recurring tasks, and one-shot jobs — all via simple tool calls. Optionally gate each tick with a cheap shell check via pre_run so expensive model turns only happen when there’s real work to do. No changes to the Agent class are needed.

Quick Start

1

Simple Usage

2

With Configuration

The agent will call schedule_add with the appropriate schedule expression, and the job will be persisted to disk.

Available Tools

schedule_add

Add a new scheduled job. Returns: Confirmation string with the job id.

schedule_list

List all scheduled jobs. Takes no parameters. Returns: Formatted string listing every job with id, name, schedule, status, and message.

schedule_remove

Remove a scheduled job by name. Returns: Confirmation or not-found message.

Schedule Expressions

Pick the format that matches how the job should recur.

Examples

Recurring Schedule

One-Shot Reminder

Fire-and-forget vs. continuable

A delivered brief is continuable by default — a reply in the same chat resumes the job’s conversation. For pure alerts, set continuable=False so a reply stays a fresh turn.
See Scheduler Delivery → Continuable Delivery for the full seed contract.

List and Manage

Using String Tool Names

Storage

Jobs are persisted to ~/.praisonai/config.yaml under the schedules key by default via ConfigYamlScheduleStore. The store is:
  • Thread-safe for multi-agent scenarios
  • Atomic writes (tmp + rename) to prevent corruption
  • Auto-created on first use
  • Auto-migrates legacy jobs.json data on first load
This exact store instance is shared by the gateway scheduler tick and the wrapper’s schedules bridge. Jobs authored by an agent tool are polled by every runtime — you no longer see “scheduled ✓” silently drop.

Shared Default Store

Every runtime shares one process-wide store via get_default_store() so a job authored by an agent is claimed by the gateway ticker, not silently dropped.
praisonaiagents.tools.schedule_tools.set_store(my_store) continues to work and now also repoints the canonical default under the hood.

Custom Store (ScheduleStoreProtocol)

Swap the default file store for any backend that implements ScheduleStoreProtocol:
Inject it at startup so all agent schedule_add/list/remove calls use your store:
set_store() now also repoints the process-wide scheduler.get_default_store() so the gateway tick and host bridge pick up the same backend. This is best-effort and logs a warning if the repoint fails; the tool store you passed is always authoritative for the agent tools.
PraisonAIUI and BotOS use the same config.yaml store. You can also call set_store() to inject any custom backend.

Custom Provider (SchedulerProviderProtocol)

Swap the default in-process poll thread for any backend that decides when to fire:
See Scheduler Providers for full patterns.

Schedule Runner

The ScheduleRunner checks which jobs are due for execution:
Constructing ConfigYamlScheduleStore() directly still works — the process-wide get_default_store() returns the same class by default and is the recommended way to share one instance with the gateway tick and host bridge.

Hook Events

Schedule lifecycle events are available via the hook system:

Execution History

Every scheduled job execution is logged as a RunRecord for auditing:

Executing Scheduled Jobs

Schedule tools create and persist jobs, but to actually execute them when they’re due, use ScheduleLoop:
See Background Tasks — ScheduleLoop for the full API and combined examples with BackgroundRunner.
ScheduleLoop is the default provider. For event-driven firing (cloud webhook, systemd timer, K8s CronJob) see Scheduler Providers.

Pre-Run Condition Gate

Gate a scheduled tick on a cheap shell check so no model tokens are spent when there’s nothing to do.
1

Add pre_run to a schedule in bot.yaml

2

Every tick, PraisonAI evaluates pre_run before spending tokens

pre_run is a cost gate (decides whether to run). It is not a safety gate (RunPolicy, which decides what a run may do). Use both when you need both.

Real-World Examples

Only triage when new issues exist:
Only summarise inbox when there’s unread mail:
Guard against off-hours runs (Monday–Friday, 09:00–18:00):

Custom Condition Gate

Any object implementing JobConditionProtocol can replace the default shell gate — a Python callable, an MCP probe, a database check.
Pass condition_resolver=False to disable gating entirely. The default resolver automatically activates ShellConditionGate for any job that has a pre_run value.

BotOS Integration

When using BotOS (multi-platform bot orchestrator), scheduled jobs execute automatically — no ScheduleLoop needed. BotOS runs its own 30-second schedule tick alongside all bots:
  • Agents create jobs via schedule_add during conversations
  • BotOS detects due jobs every 30 seconds
  • The originating agent processes the job message
  • Results are delivered back to the originating platform (Telegram, Discord, etc.)

Architecture

Schedule tools follow PraisonAI’s core principles:
  • Agent-centric — tools, not Agent parameters
  • Lazy-loaded — zero import cost until used
  • Protocol-drivenScheduleStoreProtocol makes stores swappable
  • No Agent bloat — the Agent class is unchanged
  • Thread-safe — safe for multi-agent workflows
  • Pluggableset_store() lets any backend replace the default file store

See Also

Background Tasks

Sync wrappers, ScheduleLoop, and combined recipes

Scheduler CLI

24/7 autonomous agent scheduling via CLI

Best Practices

Cron expressions give exact control over scheduling - prefer them for production use.
Add logging to scheduled agent tasks so you can verify they ran and diagnose failures.
Use 1-minute intervals during testing, then switch to production schedules before deployment.
Scheduled jobs should catch exceptions and report errors rather than silently failing.
If a schedule only has work when some external state changes (new emails, new PRs, a queue with pending rows), put the cheap check in pre_run. Model tokens are spent only for ticks that actually have work to do.

Custom Tools

Build your own agent tools

Tools Overview

Browse PraisonAI tool documentation