Skip to main content
Automation Suggestions turn recurring requests into scheduled jobs — but only when you tap Accept.

Quick Start

1

See pending suggestions

Type /automations in chat. The bot lists each pending suggestion with its own Accept/Dismiss buttons.
2

Accept from chat

Tap the ✓ Accept button on a suggestion. Exactly one scheduled job is created — nothing runs until you accept.
3

Or create from a template

Skip suggestions and build a job straight from a blueprint:

How It Works

Two paths lead to the same result — a scheduled job — but only ever on an explicit accept.
Button taps travel through the shared callback contract: sug:accept:<id> accepts a suggestion, sug:dismiss:<id> dismisses it. The interactive registry decodes sug:accept:<id> as namespace sug with the remainder as the payload — a Telegram-side detail you never type by hand.

Built-in Blueprints

Three blueprints ship ready to use, straight from blueprint_catalogue.py.
If your app already registers a custom /automations or /blueprint handler via @bot.on_command, that handler wins — the built-ins step aside for those two names only. All other built-in commands still take precedence.

Custom Blueprints (YAML)

Author your own blueprints under ~/.praisonai/blueprints/<name>/blueprint.yaml; a custom blueprint overrides a built-in of the same name.
Discovery scans each <name>/blueprint.yaml subdirectory — see BlueprintCatalogue._load_from_directory for the exact rule.

Chat Commands

/automations

List pending suggestions with inline ✓ Accept / ✕ Dismiss buttons. Telegram only today. Full detail in Bot Chat Commands.

/blueprint

Create an automation from a template: /blueprint <name> [slot=value ...]. Telegram only today. Full detail in Bot Chat Commands.

CLI Commands

Drive the same engine from the shell — full flags in Schedule CLI.

Python Usage

Propose and accept a suggestion programmatically.
propose() returns None when the pending cap (20) is reached or the same blueprint + slots was suggested within the 24-hour dedup window.

User Interaction Flows

Flow A — Accept an existing suggestion in chat:
Flow B — Create directly from a blueprint:
Flow C — Two users, one bot, no cross-talk (multi-tenant):
Before per-principal scoping, Bob’s identical proposal was silently blocked by Alice’s dedup entry, and either user could accept or dismiss the other’s suggestion.

Multi-tenant isolation

Each end-user sees only their own suggestions once the gateway passes their resolved identity as principal=. Alice and Bob can share one gateway yet never see or mutate each other’s pending queue; a single-user deployment leaves principal=None and keeps the global pool. principal is any stable, opaque string that names the caller — a user id, an email hash, a tenant id. The store never parses or validates it; it only compares it. Leave it unset (None) for the global, single-tenant behaviour used by the CLI and single-user deployments. A gateway handler that already knows who’s calling threads that identity through as principal:
Cross-owner access is rejected, not silently merged:
  • list_pending(principal="alice") never returns Bob’s suggestions.
  • accept(sug_id, principal="alice") returns False if the suggestion is Bob’s.
  • dismiss(sug_id, principal="alice") returns False if the suggestion is Bob’s.
  • The pending cap (MAX_PENDING_CAP, 20) and 24-hour dedup window are measured per principal, so one tenant can neither exhaust another’s slots nor block their identical proposal.
There is no admin bypass — a call passing principal="bob" cannot see Alice’s items even when the process runs as root. Scoping is enforced only by the principal the caller passes.

Safe by Default

The suggestion store’s isolation is opt-in: pass the resolved user identity as principal= on every read/write call. If the caller passes principal=None (the default), suggestions live in a global pool that every caller can see and mutate — see the Multi-tenant isolation section above.
Since PR #3507, Suggestion carries an optional principal owner and the store isolates list_pending / accept / dismiss per owner. See Per-User Scheduler Isolation for the full multi-tenant model. Access is still gated by CommandAccessPolicy (the automations permission is re-checked on every accept/dismiss tap). Nothing is ever auto-created — the engine only materialises a job on an explicit accept. MAX_PENDING_CAP (20), the 24-hour dedup window, and the 3-day TTL are enforced within each principal, so one tenant cannot exhaust the cap or shadow another’s suggestion. Leaving principal=None measures them against the global pool.

Platform Coverage

Telegram-only today. Discord, Slack, and WhatsApp adapters do not register /automations or /blueprint yet — parity is tracked in future PRs. The shared helper module keeps the accept/dismiss/blueprint glue in one place so those adapters can wire it later.
The commands also degrade gracefully: if the scheduler extra isn’t installed, they reply ❌ Automations are not available (scheduler not installed).

Best Practices

For multi-user gateways, pass the resolved end-user identity as principal= when reading or mutating suggestions — one user’s pending queue is then invisible and non-mutable to another’s. See Per-User Scheduler Isolation for the full multi-tenant model.
Store-level enforcement (per-principal pending cap + dedup window) means one tenant cannot exhaust the queue or shadow another’s suggestion. Leaving principal=None preserves the pre-scoping global pool for single-user deployments.
If the gateway is not yet threading a resolved identity into the store (i.e. principal is still None when calling add/list_pending), the store falls back to the shared global pool. Restrict the automations and blueprint permissions in CommandAccessPolicy to admin users until the identity wiring lands. See Command Access Control and Per-User Scheduler Isolation.
When a suggestion already exists for a pattern, accept it rather than running /blueprint — the dedup key latches on accept and avoids duplicate jobs.
Drop a blueprint.yaml in ~/.praisonai/blueprints/<name>/ to codify team-specific automations. A custom blueprint overrides a built-in of the same name.
For monitoring blueprints like important-mail, add a --pre-run gate to the resulting job so ticks with no new work spend no tokens. See the pre-run gate in the Schedule CLI.

Bot Chat Commands

Full /automations and /blueprint command details.

Schedule CLI

Blueprint and suggestion subcommands with every flag.

Async Scheduler

Recurring jobs with the same per-owner principal isolation.

Proactive Delivery

Home channels and delivery tokens for scheduled jobs.

Scheduled Run Policy

Guardrails and the pre-run gate for unattended runs.