Skip to main content
Set deliver= on a scheduled agent and each result is pushed to a chat target — no gateway required.
from praisonaiagents import Agent
from praisonai.scheduler import AgentScheduler

agent = Agent(name="Brief", instructions="Summarise the morning news")
AgentScheduler(agent, task="Morning brief", deliver="telegram:123456").start("hourly")
“Run this agent every hour and text me the result on Telegram.” That used to mean wiring up the scheduler and the full BotOS gateway. Now it’s one parameter — the scheduler talks to the shared DeliveryRouter directly.
If praisonai-bot isn’t installed, delivery logs a single warning and no-ops. The scheduled run itself never fails because delivery failed.

Quick Start

1

Deliver to a specific chat

from praisonaiagents import Agent
from praisonai.scheduler import AgentScheduler

agent = Agent(name="Brief", instructions="Summarise the morning news")

scheduler = AgentScheduler(agent, task="Morning brief", deliver="telegram:123456")
scheduler.start("hourly")
2

Deliver to the platform home channel

from praisonaiagents import Agent
from praisonai.scheduler import AgentScheduler

agent = Agent(name="Brief", instructions="Summarise the morning news")

# Bare platform token → router resolves the platform's home channel
scheduler = AgentScheduler(agent, task="Morning brief", deliver="telegram")
scheduler.start("daily")
3

Async scheduler

import asyncio
from praisonaiagents import Agent
from praisonai.scheduler import AsyncAgentScheduler

async def main():
    agent = Agent(name="Brief", instructions="Summarise the morning news")
    scheduler = AsyncAgentScheduler(agent, task="Morning brief", deliver="telegram:123456")
    await scheduler.start("hourly")

asyncio.run(main())

Three Ways to Set the Target

The same delivery token works from Python, YAML, and the CLI.
from praisonaiagents import Agent
from praisonai.scheduler import AgentScheduler

agent = Agent(name="Brief", instructions="Summarise the morning news")
AgentScheduler(agent, task="Morning brief", deliver="telegram:123456").start("hourly")
every: is a new alias for interval: in the YAML schedule: block — both accept hourly, daily, weekly, */30m, or raw seconds.

Which surface fits which scenario?


Delivery Target Tokens

The deliver value is parsed by DeliveryTarget.parse() — the same serialisable model reused from the existing delivery machinery.
TokenMeaning
"telegram"Default (home) channel of that platform
"telegram:123456"Specific channel / chat ID
"telegram:123456:789"Channel 123456 with thread 789
"origin"Reply to the same channel the schedule was created from
origin (and all) need request/session context from the full BotOS gateway. The lightweight scheduler path logs a warning and skips them — use an explicit platform or platform:chat_id token instead, or run under the gateway.
Swap telegram for discord, slack, or whatsapp — the grammar is identical.

How It Works

The scheduler runs the agent, then hands the result to SchedulerDelivery, which resolves the token and sends through the shared DeliveryRouter. SchedulerDelivery is built once per scheduler and reused across runs, so the router’s idempotency cache and rate limiters persist between ticks.

Reliability Guarantees

Delivery reuses the existing DeliveryRouter, so scheduled sends inherit the gateway’s guarantees.
GuaranteeWhat it means
Rate limitingInherits the router’s per-platform token-bucket limits
Idempotency dedupEach success carries a stable idempotency key; a re-fired job delivering the same result to the same target is deduplicated in-process
Dead-target self-healThe router retries and skips/marks dead targets
Graceful degradationWhen praisonai-bot is not installed, a single warning is logged and delivery no-ops — the scheduled run itself never fails

Common Patterns

Deliver from a blueprint

from praisonai.scheduler import AgentScheduler

scheduler = AgentScheduler.from_blueprint(
    "morning-brief",
    slots={"hour": 8, "weekdays": "mon-fri"},
    deliver="telegram",
)
scheduler.start(scheduler._yaml_schedule_config["interval"])
deliver= on from_blueprint overrides the blueprint’s default delivery target.

Deliver to a thread

from praisonaiagents import Agent
from praisonai.scheduler import AgentScheduler

agent = Agent(name="Standup", instructions="Post the daily standup summary")
AgentScheduler(agent, task="Standup", deliver="discord:555:thread-42").start("daily")

Best Practices

telegram:123456 targets a fixed chat and works without any request context. Reserve origin for interactive flows running under the full gateway — the lightweight scheduler path cannot resolve it.
Delivery needs the praisonai-bot package. Without it, the scheduled run still executes — only the push is skipped, with one warning. Install the bot extra to turn delivery on.
The router’s idempotency cache and rate limiters live on the scheduler’s delivery helper. Keep a single scheduler running so repeated identical results to the same target are deduplicated instead of re-sent.
Use Python inside an app, YAML for a config-file deploy, and the CLI for one-off terminal jobs — all three accept the same deliver token grammar.

Async Agent Scheduler

Run agents on a recurring schedule with async execution

Pre-Run Gate

Skip ticks when a cheap check says nothing to do

Schedule CLI

The --deliver / -d flag and other schedule commands

Gateway Inbound Hooks

Shares the same delivery target format