Caravanserai
Your AI agent just spent 3 hours on a task. It crashed. Everything's gone.
Caravanserai fixes that: your agent checkpoints itself at natural waypoints — like a Silk Road caravan resting at a waystation — saving both its exact state and a plain-English note of what happened and what's next. Crash, and the next run picks up from the last waystation instead of starting over.
from caravanserai import checkpoint, resumable
@resumable
def do_the_task(run_id, state):
step = state.get("step", 0)
while step < 5:
step += 1
# ... do the actual work ...
checkpoint(run_id, {"step": step}, f"finished step {step}, next is step {step+1}")
do_the_task("my-run", {"step": 0})
Kill it mid-run. Run it again with the same run_id — @resumable loads the
last saved state automatically instead of starting from scratch.
Why not just use LangGraph/Temporal checkpointing?
They solve the mechanical replay problem well, but they're framework-locked and the checkpoint is a raw state blob — nothing a human (or a different agent picking up the job) can read to understand what actually happened. Caravanserai's waypoint files are markdown, meant to be read:
.caravanserai/my-run/waypoint-3.md
# Waypoint 3 — 2026-08-20T22:41:03+00:00
finished step 3, next is step 4
Works with any Python agent loop you control — LangChain, LangGraph, the Claude Agent SDK, OpenAI Agents SDK, CrewAI, or plain scripts. No database, no server, just local JSON + Markdown files.
Not for the Claude Code CLI itself — it already has its own session
resume (--resume/--continue) and you don't write its agent loop. This is
for agents you build in Python that don't have that built in.
Install
pip install -e .
Try it
python demo.py
# ^C it partway through, then:
python demo.py
# picks up where it left off
caravanserai show demo
Real transcript (not staged)
$ python demo.py
[1/5] doing work...
[2/5] doing work...
[3/5] doing work...
^C
crashed/killed mid-task. run me again — I'll resume, not restart.
$ python demo.py
[4/5] doing work...
[5/5] doing work...
done.
$ caravanserai show demo
waypoint 5
finished step 5/5
state: {'step': 5}
Killed at step 3, resumed straight to step 4 — no restart, no redone work.
Status
v1 — explicit checkpoint calls only (no auto-detection), single-process local
files (no distributed state), inspect-only CLI (real resume path is
@resumable in your own code). See the design notes for what's deliberately
scoped out.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file caravanserai-0.1.0.tar.gz.
File metadata
- Download URL: caravanserai-0.1.0.tar.gz
- Upload date:
- Size: 4.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c6d25b5eac667c1fd62b77a90ec58ece37554eaccf2815c79e7d78d067e9dfd
|
|
| MD5 |
a9b3996d34eb0e6c1cbce21206095b7b
|
|
| BLAKE2b-256 |
db0d73f8bb4ae68981e6b67755f5ed45fc5cc9044d72d674afd5740c8d0ca69f
|
File details
Details for the file caravanserai-0.1.0-py3-none-any.whl.
File metadata
- Download URL: caravanserai-0.1.0-py3-none-any.whl
- Upload date:
- Size: 5.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b6fd0ef1297b46908f2dd80164ef7b4e7e31e859878b9e9b4f37b57eda6c03f
|
|
| MD5 |
f3237f08dd6ed049d3d8cea97eac7a27
|
|
| BLAKE2b-256 |
6abf8b5393e244f33a812cecac88e055093491fd6228594a962dcd8ae8acf039
|