Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/
- `examples/cron_executor.rs` — end-to-end example: schedules a webhook to fire on the next per-second tick and exits within ~1 second.
- README section: **Action Executors → Cron**.
- `cron` and `chrono` dependencies (chrono with `clock` + `serde` features).
- `src/scheduler_loop.rs` — long-running tokio task spawned by `pypes start` that loads every cron action across all agents on boot, fires due entries through the existing webhook executor, advances the scheduler, and logs each fire to the daemon's stderr (`~/.agents/tmp/daemon.err`). `POST /agents` now triggers an in-process reload so newly stored cron actions go live without restarting the daemon.

### Changed
- `Agent.actions` storage is unchanged on disk (`Vec<String>`), but each entry is now interpreted as a typed `Action` enum at execution time. Strings that don't parse fall through as `Unrecognized` rather than blocking the pipeline.
Expand Down
50 changes: 49 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ chrono = { version = "0.4", default-features = false, features = ["clock", "serd

[dev-dependencies]
wiremock = "0.5"
tempfile = "3"
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,16 +204,25 @@ The `expression` field accepts:
- **7-field cron with year** — passed through to the underlying parser.

`pypes agent <NAME> run` reports the next computed fire time for each cron
action without firing it; the actual firing happens via the scheduler:
action without firing it; the actual firing happens automatically once the
server is running:

```bash
pypes agent scheduled-pinger run
# [0] cron `*/5 * * * *` → next fire 2026-05-03 12:05:00 UTC
```

`pypes start` (daemonized or `--attatch`) launches a background scheduler
loop that loads every cron action across all agents on boot, sleeps until
the next due tick, fires the wrapped action (currently `webhook`), and
advances. Each fire is logged to the daemon stderr at
`~/.agents/tmp/daemon.err`. Creating a new agent via `POST /agents`
triggers an in-process reload so newly stored cron actions become live
without restarting the daemon.

Out of scope for v1: distributed scheduling, persistent missed-fire catchup
across restarts. The scheduler is single-process and fires only while it's
running.
across daemon restarts (the loop starts fresh from `Utc::now()` on boot),
and per-tenant isolation.

### Worked example

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pub mod daemon;
pub mod db;
pub mod executors;
pub mod resource;
pub mod scheduler_loop;
pub mod server;
Loading
Loading