惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
Microsoft Azure Blog
Microsoft Azure Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
B
Blog
Y
Y Combinator Blog
博客园_首页
有赞技术团队
有赞技术团队
博客园 - Franky
腾讯CDC
G
Google Developers Blog
Recent Announcements
Recent Announcements
博客园 - 【当耐特】
D
Docker
The GitHub Blog
The GitHub Blog
MyScale Blog
MyScale Blog
H
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
A
About on SuperTechFans
D
DataBreaches.Net
T
The Blog of Author Tim Ferriss
V
V2EX
U
Unit 42
aimingoo的专栏
aimingoo的专栏
WordPress大学
WordPress大学

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
I built a tiny runtime for resumable agent workers
Mariusz Czaj · 2026-05-26 · via DEV Community

A while ago I needed a resumable agent runtime.

I did not want something as large as Temporal, and I did not want another agent framework like LangChain. I wanted something small enough to understand, but solid enough to adapt across the different verticals I was building.

It started with a few bare-bones questions.

The moment an agent leaves a notebook, script, or chat session, the hard problems change:

  • What work exists?
  • Which worker owns it right now?
  • What was the last durable step?
  • Can another worker resume after a crash?
  • Which resources are locked?
  • What did the agent produce?
  • Can operators inspect what happened?

The effect of it is Roost as a small runtime layer for that problem.

GitHub: https://github.com/mczaykowski/Roost

The basic idea

Roost treats an agent as a durable step machine.

An engine implements two methods:

class Engine:
    engine_id: str

    async def init_snapshot(self, item: WorkItem) -> Snapshot: ...
    async def step(self, snapshot: Snapshot, item: WorkItem) -> Snapshot: ...

Enter fullscreen mode Exit fullscreen mode

The engine owns the domain-specific transition.

Roost owns the operational substrate:

Queue
  -> acquire lease
  -> load latest Snapshot
  -> Engine.step(snapshot, item)
  -> compare-and-swap save Snapshot
  -> re-enqueue or mark done

Enter fullscreen mode Exit fullscreen mode

That gives you:

  • durable snapshots
  • per-work leases
  • at-least-once execution
  • retry-safe progress
  • delayed continuation
  • resource claims
  • event history
  • content-addressed artifacts
  • failed-work inspection

It is intentionally small. It is not trying to be a prompt framework, model router, workflow DSL, or hosted agent platform.

Roost does not help an agent think.

Roost helps an agent keep going.

Why I built it

A lot of agent tooling focuses on the thinking loop: prompts, tools, retrieval, planning, memory, model routing.

That is useful, but once agents run as workers for minutes, hours, or days, the bottleneck becomes more boring and more operational.

For example:

  • a worker dies halfway through a task
  • the same job is delivered twice
  • a long-running task needs to wait before its next step
  • two workers should not touch the same resource at the same time
  • an operator needs to know what happened
  • the output needs to be inspectable later

You can solve this with a workflow engine, a custom queue, a database table, or a pile of scripts.

Roost is my attempt at a small, agent-shaped version of that layer.

A simple demo: crash-safe URL watchlist

The demo engine is a URL watchlist worker.

It fetches a URL over multiple steps, saves each observation into a snapshot, waits between checks, and writes a final JSON artifact.

You can kill the worker halfway through, restart it, and Roost resumes from the latest saved snapshot.

uv sync --extra redis --extra dev
docker run --rm -p 6379:6379 redis:7

Enter fullscreen mode Exit fullscreen mode

In one terminal:

uv run roost worker --engines watchlist

Enter fullscreen mode Exit fullscreen mode

In another:

WORK_ID=$(uv run roost enqueue \
  --engine watchlist \
  --resource domain:example.com \
  --payload '{"url":"https://example.com","claim":"Example Domain is reachable","checks_required":3,"delay_seconds":5}')

uv run roost status "$WORK_ID"

Enter fullscreen mode Exit fullscreen mode

Then kill the worker with Ctrl-C, start it again, and inspect the same work item.

uv run roost worker --engines watchlist
uv run roost status "$WORK_ID"

Enter fullscreen mode Exit fullscreen mode

There is also a local end-to-end script:

scripts/e2e_watchlist.sh

Enter fullscreen mode Exit fullscreen mode

No LLM key is required. The demo is about runtime behavior, not model behavior.

Local console

Roost includes a small local console:

uv run roost ui

Enter fullscreen mode Exit fullscreen mode

It shows live work, saved state, events, failed work, and artifacts.

Roost Console Work View

The detail view lets you inspect payloads, snapshots, and outputs:

Roost Console Detail

Where this fits

Roost is not a replacement for LangChain, LlamaIndex, CrewAI, AutoGen, Temporal, Celery, or your own agent loop.

It sits at a different layer.

LangChain helps decide what an agent should do.
Temporal helps coordinate workflows.
Celery runs jobs.
Roost keeps long-running agent workers alive, inspectable, and resumable.

Enter fullscreen mode Exit fullscreen mode

The current backend is Redis + SAQ. Execution is at-least-once, so engines need to make step() retry-safe from the same snapshot.

That tradeoff is intentional. I would rather expose the semantics clearly than pretend exactly-once execution exists.

What I’m looking for feedback on

I’m especially interested in feedback on the abstraction boundary.

Is this useful as a small runtime under agent loops?

Would you rather reach for Temporal, Celery, or a custom queue?

Does the init_snapshot() / step() model feel too small, or exactly small enough?

GitHub: https://github.com/mczaykowski/Roost