Hayhooks 2.0 introduces durable execution: Haystack Pipelines and Agents that keep running after the HTTP request returns, survive restarts and deploys, and can pause for a human. State is checkpointed in Redis, and any replica can pick the work back up.
pip install "hayhooks[durable]"Durable execution requires Haystack 3.1+ and Redis 6.2+ (or Valkey 7.2+). Without it, Hayhooks works as before.
⏳ Durable Execution
- Detached runs. Submitting returns
202with an execution ID while workers carry on in the background. - Restart recovery. If a worker dies, its run is picked up again once the lease expires, and fencing stops a stale worker from writing results.
- Pipeline and Agent checkpoints. Pipelines resume from a chosen component boundary or a Haystack failure snapshot. Agents restore their state between LLM and tool steps, so finished work isn't repeated.
- Human-in-the-loop. A run can suspend with a public wait reason and continue later with typed resume input.
- Retries and cancellation. Crash recovery and application-requested retries have separate budgets, and cancellation is cooperative with a durable terminal result.
- Idempotent submissions. A caller-supplied idempotency key lets clients retry a submission safely and rejects conflicting reuse.
- Live streaming. SSE streams can be reattached with
Last-Event-ID. They deliver chunks as workers flush them and end with the authoritative result.
🧭 Durable Mode for the Hayhooks Server
- Set
HAYHOOKS_DURABLE_MODE=trueto serve wrappers that implementrun_durable/run_durable_async. Each one gets submit, inspect, cancel, resume and stream routes. - Durable mode loads a fixed set of pipelines at startup. Live deploy/undeploy routes and MCP tools are not available in this mode, and any startup failure stops the server.
- Optional owner scoping restricts each execution to the caller that submitted it.
GET /statusreportsdurable_modeand durable store health for readiness checks.HAYHOOKS_DURABLE_*settings control Redis, capacity, payload and stream limits, leases, retries and shutdown handoff.
🧩 Portable Engine
- Use the engine in any asyncio or FastAPI app without the Hayhooks server:
DurableDeployment,DurableRuntime,RedisExecutionStore/MemoryExecutionStore, andcreate_durable_router. hayhooks.durableonly needs Pydantic and Loguru. FastAPI, Haystack and Redis are loaded only when you use them.
⚠️ Upgrade Notes
- Default (live) mode now rejects durable wrappers. Serve them with
HAYHOOKS_DURABLE_MODE=true. - In durable mode,
hayhooks run --workersmust be1. Scale out with replicas instead. - Several internal server helpers in
hayhooks.server.utils(MCP, A2A and module loading) now take an explicit pipeline registry.
📚 Documentation
- New guides: Durable Execution, Durable Operations, and Embed Durable Execution in FastAPI.
- The README has been redesigned around durable execution.
What's Changed
- feat(durable): portable durable execution engine with Lua-guarded Redis protocol by @mpangrazzi in #267
- feat(durable): fixed runtime lifecycle, drained shutdown, and portable imports by @mpangrazzi in #268
- feat(durable): durable mode with a fixed pipeline registry and managed durable hosting by @mpangrazzi in #270
- fix(durable): harden recovery, streaming, and owner access by @mpangrazzi in #271
Full Changelog: v1.25.0...v2.0.0