Quick Start
With Direct Prompt (No YAML needed)
With agents.yaml
Installation
Deliver Scheduled Results to a Chat Channel
Route each successful scheduled run to Telegram, Discord, Slack, or WhatsApp — no gateway required. Set adeliver token from Python, YAML, or the CLI:
- Python
- YAML
- CLI
Token Grammar
Thedeliver token uses DeliveryTarget.parse. Whitespace is stripped and origin/all are case-insensitive.
Optional Dependency
Delivery goes through thepraisonai-bot package.
A CLI
--deliver token overrides any target resolved from YAML or a recipe.Async Delivery
AsyncAgentScheduler accepts the same deliver= parameter and dispatches delivery through asyncio.to_thread because the shared helper uses the sync bridge — it never raises and never blocks the event loop.
Delivery Best Practices
Prefer platform:channel_id for reliable routing
Prefer platform:channel_id for reliable routing
A bare
platform token depends on the router resolving the platform’s home channel. Use telegram:123456 to target an explicit chat and avoid ambiguity.Keep the token in YAML for reproducibility
Keep the token in YAML for reproducibility
Store
schedule.deliver in YAML so scheduled jobs are reproducible. Override with -d only for one-off runs.Don't use origin / all on the lightweight path
Don't use origin / all on the lightweight path
origin and all require the full BotOS gateway. Setting them on the lightweight scheduler path logs a warning and skips delivery.PM2-Style Daemon Commands
Start Scheduler
With a Task Prompt
With a Recipe
List Schedulers
View Logs
Stop Scheduler
Restart Scheduler
Delete Scheduler
Describe Scheduler
Legacy Foreground Mode
For quick testing or one-off runs, use foreground mode:Ctrl+C to stop. Shows final statistics:
Storage Locations
- Schedule data:
~/.praisonai/config.yaml(under thescheduleskey) - Log files:
~/.praisonai/logs/*.log
Schedules are stored in the same
config.yaml used by agents and server configuration. Legacy jobs.json data is auto-migrated on first use.Features
✅ PM2-style daemon management - No nohup needed✅ Process persistence - State saved to disk
✅ Easy lifecycle control - start/stop/restart/list
✅ Centralized logging - Auto-rotation, follow mode
✅ Graceful shutdown - SIGTERM with SIGKILL fallback
✅ Cost monitoring - Budget limits with $1.00 default
✅ Timeout protection - Prevent runaway executions
✅ Auto cleanup - Dead processes removed automatically
Schedule Intervals
Examples
Example 1: Simple Prompt Scheduling
Quick news check every hour:Save Configuration
Command Reference
Daemon Commands
Options
Notes:
- Default budget is $1.00 for safety. Set to higher value or
nullin YAML to disable. - Use
--verboseto see detailed logs. Without it, output is clean for background running.
Example 2: News Monitoring with YAML (Advanced)
agents.yaml:Example 2: Data Collection (Every 30 Minutes)
agents.yaml:Example 3: With Budget and Timeout Limits
agents.yaml:Example 4: Testing with Short Interval
Python API
For programmatic control, use the async-native Python API:Async Agent Scheduler (Recommended)
Import paths (PR #1552):
- Canonical:
from praisonai.scheduler import AgentScheduler - Deprecated (still works, emits
DeprecationWarning):from praisonai.agent_scheduler import AgentScheduler - Pending deprecation (still works, emits
PendingDeprecationWarning— will move topraisonai.scheduler.async_agent_schedulerin a future release):from praisonai.async_agent_scheduler import AsyncAgentScheduler
AgentScheduler from praisonai.scheduler exposes from_yaml, start_from_yaml_config, and from_recipe. For new applications, prefer AsyncAgentScheduler which provides better cancellation and fits naturally into async codebases.Budget & timeout (PR #1771): AsyncAgentScheduler now accepts timeout (per-run seconds) and max_cost (total USD cap) in its constructor — see Async Agent Scheduler for the full pattern.MCP scheduling note: The MCP server’s praisonai.schedule.list / .add / .remove tools are now backed by praisonaiagents.tools.schedule_tools, so YAML/recipe scheduling works through MCP without needing to choose an import path.Async-only agents (PR #2147): The sync AgentScheduler now accepts agents that expose only astart() (not start()). Dispatch logic is shared between sync and async schedulers via praisonai.scheduler._dispatch.adispatch_agent. Both schedulers prefer astart() when present and fall back to start() in a worker thread.Features
Core Features
- Interval-based scheduling: Run agents at regular intervals
- Background execution: Runs in daemon thread, won’t block terminal
- Automatic retry: Exponential backoff + jitter, capped at 300s, shared between sync & async
- Graceful shutdown: Clean stop with Ctrl+C
- YAML configuration: Simple configuration in agents.yaml
- CLI overrides: Override any setting from command line
Safety Features
- ⏱️ Timeout Protection: Prevent runaway executions
- 💰 Cost Monitoring: Real-time cost tracking with budget limits
- 📊 Statistics Tracking: Monitor execution success rates, costs, and runtime
- 🛡️ Budget Protection: Auto-stops when cost limit reached
- 🔄 Retry Logic: Exponential backoff prevents rapid failures
Real cost tracking (PR #2171):
--max-cost is now enforced against the real per-token spend pulled from each agent response. Previously the scheduler added a fixed $0.0001 per run, so the default $1.00 brake required ~10,000 executions to trip. Set --max-cost to your actual budget, and ensure your model is in DEFAULT_PRICING (or register it — see Cost Tracking) so runs aren’t silently priced at $0.Output
The scheduler provides detailed logging with cost tracking:Callbacks
Both schedulers accepton_success and on_failure callbacks in the constructor.
Callbacks may be sync or async functions; a raising callback is logged and swallowed
— it will not stop the scheduler.
on_success(result)— called with the agent’s return value after a successful run.on_failure(exc)— called with the finalExceptionafter all retries are exhausted. (Previously sync passed a formatted string; as of PR #1474 both sync and async pass the exception object.)
Statistics
CLI Daemon: Usepraisonai schedule describe <name> for detailed stats
Python API (AsyncAgentScheduler):
Stats parity (PR #1857): Both
AgentScheduler and AsyncAgentScheduler now return the same stats shape via a shared _BaseAgentScheduler._build_stats() helper. Keys: is_running, total_executions, successful_executions, failed_executions, success_rate, total_cost_usd, remaining_budget, runtime_seconds, cost_per_execution. Use await scheduler.get_stats_async() in async code, scheduler.get_stats() in sync code.On stop (Ctrl+C)
🛑 Stopping scheduler… 📊 Final Statistics: Total Executions: 5 Successful: 5 Failed: 0 Success Rate: 100.0% ✅ Agent stopped successfullyCLI Commands
Use the daemon management commands:Python API
Foreground Mode
PressCtrl+C to stop gracefully. The scheduler will:
- Set stop event
- Wait for current execution to complete
- Log final statistics
- Exit cleanly
See Also
- Async Agent Scheduler - Python async-native scheduler API
- Delivery Config - The
DeliveryRoutermachinery scheduled results reuse (origin/allneed the full gateway) - Scheduled Run Policy - Programmatic tool scoping, prompt scanning, and output auditing for unattended runs (no CLI flag — configure via
RunPolicyin Python) - Planning Mode - Add planning to scheduled agents
- Memory - Enable memory for scheduled agents
- Tools - Add custom tools to agents
- Examples - Working examples

