Status (May 2026): Active. Part of the HiringFunnel open-source stack. See also coldflow and foxyapply.
The Pypes Project is a fast and lightweight tool for defining autonomous AI agents that perceive (JSON inputs streamed in over an HTTP API) and act (named actions you wire up).
It ships as a single Rust binary — a CLI plus a daemonized HTTP server backed by an embedded JSON store.
- Stream perception into agents — every input is just JSON.
- Persist agents and their inputs to disk via embedded pickledb — no external database to run.
- HTTP API (
axum) for creating and listing agents from any language. - Optional Qdrant vector-db resource pulled via Docker for embeddings work.
- Single static binary —
cargo build --releaseproduces one artifact.
curl -sSL https://github.com/pypesdev/agents/raw/main/install.sh | shOr build from source:
git clone https://github.com/pypesdev/agents.git
cd agents
cargo build --release
./target/release/pypes --helpThe smallest end-to-end loop — create an agent, feed it a JSON input, list it back. State is persisted under ~/.agents/db/.
# 1. Create a named agent
pypes add agent echo
# 2. Stream a JSON input into it
pypes agent echo add '{"event":"hello","payload":"world"}'
# 3. List agents
pypes ls
# => Agent echoPrefer HTTP? Start the server attached to your terminal and POST agent definitions directly:
pypes start --attatch -p 7979
# In another shell:
curl -X POST http://localhost:7979/agents \
-H 'Content-Type: application/json' \
-d @examples/echo.json
curl http://localhost:7979/agents
# => [{"name":"echo","inputs":[{"event":"hello","payload":"world"}],"actions":[]}]See examples/ for ready-to-POST agent definitions.
| File | What it does |
|---|---|
examples/echo.json |
Minimal hello-world agent — one JSON input, no actions. |
examples/web-summarize.json |
Illustrative URL-fetch + summarize agent shape. Action wiring is intentionally a no-op until those executors land — see the integration table below. |
examples/webhook.json |
Agent with a single webhook action; pair with pypes agent webhook-demo run to fire it. |
examples/webhook_executor.rs |
End-to-end Rust example: spins up a local mock receiver, dispatches a webhook action, and prints the captured request. Run with cargo run --example webhook_executor. |
examples/cron_executor.rs |
End-to-end Rust example: schedules a webhook to fire on the next per-second tick via the in-process scheduler, then exits. Run with cargo run --example cron_executor. |
Honest status as of May 2026. Anything marked planned has a target release; anything else is fiction we are not shipping yet.
| Integration | Status | Notes |
|---|---|---|
| HTTP / JSON inputs | ✔️ Shipped | POST /agents, GET /agents, CLI agent <name> add. Backed by pickledb on disk. |
| Qdrant vector-db | ✔️ Shipped | pypes add vector-db pulls qdrant/qdrant via the local Docker socket. |
| Daemonized server | ✔️ Shipped | pypes start forks; pypes start --attatch runs in the foreground. |
| Action executors → webhook (HTTP POST) | ✔️ Shipped | First concrete executor. Each Agent.actions entry is a JSON spec like {"type":"webhook", ...}; see Action Executors → Webhook. |
| Action executors → cron (scheduled) | ✔️ Shipped | Wraps another action with a 5-, 6-, or 7-field cron expression and fires it on schedule via an in-process scheduler. See Action Executors → Cron. |
| Action executors → LLM | 📆 Planned | Same {"type": "..."} discriminator as webhook/cron. |
| Gmail | 📆 Planned for v0.1.0 | Not implemented. Earlier README claimed "in progress" — that was stale; no module exists in src/. |
| SMS (Twilio) | 📆 Planned for v0.1.0 | Not implemented. |
| Vision / image inputs | 📆 Planned for v0.2.0 | Not implemented. JSON-only inputs today. |
| Web UI | 🛠️ Experimental | src/server/templates/ ships layout/index stubs; no routes mount them yet. |
Legend: ✔️ shipped • 🛠️ experimental • 📆 planned.
Agents can now act, not just store. Each entry in Agent.actions is a
JSON-encoded spec; the executor dispatches by the type discriminator.
The first shipped executor is webhook — a single HTTP POST to a target
URL with a JSON payload and optional headers.
Run every action stored on an agent through the executor pipeline:
pypes agent <NAME> run
# [0] webhook → 200 (11 bytes)A 2xx response counts as success; anything else surfaces as a NonSuccessStatus
error so the caller can decide whether to retry. headers and payload are
optional (payload defaults to {}).
cargo run --example webhook_executorThe example boots a tiny in-process axum receiver on an ephemeral port,
constructs an in-memory Agent with one webhook action pointed at it, and
prints both the executor outcome and the body the receiver got:
→ stored action: {"headers":{"Authorization":"Bearer demo-token"},"payload":{"event":"agent.acted","n":1},"type":"webhook","url":"http://127.0.0.1:49207/hook"}
← webhook[0] status=200 body={"ok":true}
✓ mock receiver got 1 request(s):
{"event":"agent.acted","n":1}
No external services needed. Tests use wiremock
to assert on the exact request the executor sends — see
src/executors/webhook.rs.
Cron lets agents act on a schedule — required for any "check inbox every 10
minutes" or "run nightly summary" pattern. A cron action wraps another action
with a cron expression; an in-process scheduler fires the wrapped action on
each tick.
// One entry inside Agent.actions
{
"type": "cron",
"expression": "*/5 * * * *",
"action": {
"type": "webhook",
"url": "https://example.com/tick",
"payload": { "tick": true }
}
}The expression field accepts:
- 5-field standard cron —
min hour day-of-month month day-of-week(e.g.*/5 * * * *for every five minutes).secis padded to0andyearto*. - 6-field cron with seconds —
sec min hour dom mon dow(e.g.* * * * * *for every second). - 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 automatically once the
server is running:
pypes agent scheduled-pinger run
# [0] cron `*/5 * * * *` → next fire 2026-05-03 12:05:00 UTCpypes 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 daemon restarts (the loop starts fresh from Utc::now() on boot),
and per-tenant isolation.
cargo run --example cron_executorThe example boots a tiny in-process axum receiver on an ephemeral port, builds
a CronAction whose target is a webhook pointed at the receiver, advances the
Scheduler by one real tick, and prints both the
fired outcome and the body the receiver got:
→ stored action: {"type":"cron","expression":"* * * * * *","action":{"type":"webhook","url":"http://127.0.0.1:51636/hook","headers":{},"payload":{"event":"cron.tick","n":1}}}
⏲ next fire scheduled at 2026-05-03 09:10:56 UTC (in 253 ms)
← cron[0] fired webhook → status=200 body={"ok":true}
✓ mock receiver got 1 request(s):
{"event":"cron.tick","n":1}
The example terminates within ~1 second because the cron expression fires on
the next per-second boundary. Tests drive the scheduler with a fixed mock
clock and a tight real-time clock — see src/executors/cron.rs.
pypes start [--attatch] [-p PORT] # start the HTTP server (port 7979 by default)
pypes stop # kill a daemonized server
pypes status # check whether the server is reachable
pypes add agent <NAME> # create an empty agent
pypes add vector-db # pull qdrant/qdrant via Docker
pypes rm agent <NAME> # remove a single agent
pypes rm db # wipe the agents database
pypes ls # list known agents
pypes agent <NAME> add '<JSON>' # append a JSON input (or action spec) to an agent
pypes agent <NAME> run # execute every stored action through the executor pipeline
| Method | Path | Body | Response |
|---|---|---|---|
GET |
/agents |
— | Agent[] |
POST |
/agents |
{name, inputs: any[], actions: string[]} |
{records_created: number} |
cargo build # debug build
cargo test # run the test suite (matches the PR-check workflow)
cargo build --release # production binary at target/release/pypesPRs run cargo test via .github/workflows/pr-check.yaml. Releases are cut by pushing a vX.Y.Z tag — see .github/workflows/release.yaml.
Maintained by Pypes LLC under the HiringFunnel brand.





