The
monitor field is a declarable spec the core round-trips through storage. The probe, hashing, bounded diff, state persistence, and the no_change record live in the praisonai-bot / wrapper layer — the core owns only the contract.Quick Start
1
Turn an agent into a monitor
Add
monitor to a ScheduleJob. The agent runs only when the watched URL changes.2
Watch a shell source instead
Use
command inside monitor to watch any cheap shell output — a file, a database count, a health probe.What The User Sees
Silence is the feature — an unchanged source produces no ping and spends no tokens.How It Works
Each tick probes the source, hashes the output, and compares it to the last-seen hash held in per-job state.no_change is a distinct status from skipped. skipped means “a gate said don’t run”; no_change means “a watched source was unchanged” — so operators can tell the two apart in run history.Configuration Options
monitor spec
monitor is a small mapping naming one cheap source to probe each tick.
ScheduleJob field
GateResult — monitor outcome
The wrapper’s monitor gate returns a GateResult carrying the monitor-mode outcome.
RunRecord.status
Monitor vs Pre-Run vs Command
Three scheduler features feel similar but solve different problems.From the SDK docstring: “monitor is distinct frompre_run(a stateless go/no-go gate) andcommand(a model-free delivery action).”
On the scheduled delivery path, a
no_change outcome is silently suppressed — no ping, no tokens. See Scheduler Delivery and Bot Intentional Silence for how unattended-monitor silence is enforced unconditionally.Per-Job State
A monitor needs memory across wake-ups — the last-seen hash or a watermark. The core defines theJobStateStoreProtocol contract; a concrete store lives in the wrapper alongside the heavy monitor gate.
Best Practices
Bound your source so a large fetch can't stall the tick
Bound your source so a large fetch can't stall the tick
The probe runs on every tick. Watch a small, cheap source — a status endpoint, a row count, a file’s modification marker — not a multi-megabyte page. A bounded source keeps the ticker responsive.
Use monitor when you want silence-when-unchanged
Use monitor when you want silence-when-unchanged
Reach for
monitor when the whole point is “only tell me when something changed” — a page, a feed, a metric. Unchanged ticks cost zero tokens and deliver nothing.Use pre_run when you want silence-when-nothing-to-do
Use pre_run when you want silence-when-nothing-to-do
If the decision is a stateless go/no-go (an inbox check, a queue depth), use
pre_run instead — it doesn’t need to remember a prior hash.Let first-run seed the baseline
Let first-run seed the baseline
The first tick has no prior state, so it always runs and stores the baseline hash. Expect one delivery when a monitor job is created, then silence until the source moves.
Related
Pre-Run Gate
Stateless go/no-go gate — skip when there’s nothing to do
Command Action
Model-free action — deliver a command’s stdout verbatim
Scheduler Delivery
Push scheduled results to Telegram/Discord/Slack/WhatsApp
Bot Intentional Silence
How unattended silence is enforced

