Workflows and agents that don't lose their place.
Pyrula runs durable workflows, pipelines, and LLM agents on a fast Rust-backed functional core. They survive crashes and pick up where they stopped.
pip install pyrula | 0001 | 09:42:10 | RUN.START | run_01K9F8 | ok |
| 0002 | 09:42:10 | STEP.PENDING | fetch_invoices | queued |
| 0003 | 09:42:11 | STEP.DONE | fetch_invoices | 128 rows |
| 0004 | 09:42:11 | STEP.PENDING | score_risk | running |
| 0005 | 09:42:13 | AGENT.TOKEN | score_risk | streaming… |
| 0006 | 09:42:14 | STEP.ERROR | score_risk | TimeoutError |
| — worker lost · run resumes on another worker — | ||||
| 0007 | 09:42:20 | RUN.REPLAY | run_01K9F8 | from event 0004 |
| 0008 | 09:42:20 | STEP.CACHED | fetch_invoices | replayed |
| 0009 | 09:42:21 | STEP.DONE | score_risk | ok |
| 0010 | 09:42:22 | KAFKA.COMMIT | offset + output | 1 txn |
| 0011 | 09:42:22 | RUN.DONE | run_01K9F8 | ok |
Install only what you need.
Each piece ships as its own package built on the shared functional core.
Primitives
Rust-backed Either, Option, Try, immutable IList/IMap, and serde. They read like plain Python, and everything else builds on them.
Workflows
Append-only run streams. After a crash, a run replays and resumes at the point it stopped, so you keep the work already done.
Agents
Write agents with @agent and @tool. Stream turns over SSE and serve them over plain HTTP in production.
Kafka
A pure-Rust client (no librdkafka) that tracks the confluent-kafka API, with explicit timeouts and exactly-once (EOS) transactions.
Pipelines
Exactly-once Kafka, Delta, and Postgres connectors. Batches are Arrow, and the decode hot path runs in Rust.
Built for jobs that have to finish.
Survives crashes
Every run is an append-only event stream. Status comes from the stream, so a restart picks up where it stopped instead of running again from the top.
Exactly-once over Kafka
An agent's output and its offset commit land in the same transaction. Read-process-write pipelines with no duplicates and nothing dropped.
Rust-backed core
A fast, typed functional core sits under every package: Either, Option, Try, immutable collections, and Rust serde.
Install what you need
Each piece ships as its own package built on the core. Start with the primitives and add workflows, agents, or Kafka when you need them.
Ship durable agents.
Read the quickstart, or open the cloud console to run and watch your agents.