feat: agent state checkpointing (rollback, restore, session resume)#193
Open
EvilFreelancer wants to merge 9 commits into
Open
feat: agent state checkpointing (rollback, restore, session resume)#193EvilFreelancer wants to merge 9 commits into
EvilFreelancer wants to merge 9 commits into
Conversation
Add AgentContext.to_snapshot/from_snapshot (JSON-serializable, excludes the live clarification event and re-resolvable skills) and the AgentCheckpoint snapshot model. Foundation for agent state checkpointing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add BaseCheckpointStore with save/list/get/latest/delete/agent_ids/ find_by_session, an in-memory backend with optional ring-buffer history, and a JSON file backend that survives process restarts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add execution.checkpoint with enabled/backend/dir/max_history; defaults keep checkpointing off so existing behavior is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
BaseAgent gains checkpoint(), list_checkpoints(), rollback(step) and an optional checkpoint_store/session_id. When a store is attached the execution loop snapshots state at the start of every iteration; rollback restores the conversation and context (with a fresh clarification event). No store = prior behavior. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
create() now accepts checkpoint_store/session_id. restore() rebuilds a live agent from a checkpoint: resolves the definition (arg or GlobalConfig by def_name), rebinds the saved id (and streaming generator id), and re-applies conversation + context. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add GET /agents/{id}/checkpoints, POST /agents/{id}/rollback and
POST /agents/{id}/restore, a shared checkpoint_store built from
execution.checkpoint at startup, and thread it into agent creation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Advertise load_session=True, accept a checkpoint_store, tag per-prompt checkpoints with the ACP session id, and implement load_session to rebuild the session from its latest checkpoint. Wire the store from config in the ACP entry point. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add framework/checkpoints.md (en+ru) and nav entry, document the three REST endpoints in SGR-Description-API (en+ru), add examples/checkpoint_and_rollback.py, and a commented checkpoint block in config.yaml.example. Apply ruff/docformatter. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- models: serialize custom_context with serialize_as_any so a Pydantic
custom_context is not silently reduced to {} on snapshot
- base_agent: isolate auto-checkpoint failures (never abort a run) and capture
a checkpoint at the clarification pause so a restore observes the waiting state
- store: order find_by_session by created_at (correct 'latest turn' across
multi-agent sessions); delete via rmtree (tolerate stray files)
- server: cancel a running execute task before rollback to avoid the race
- acp: prompt() now resumes a restored agent instead of discarding it
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds agent state checkpointing so an agent can snapshot its execution state as it runs, then roll back to an earlier step, restore after a process restart, and resume a session (including over ACP). Checkpointing is opt-in — disabled by default, so existing behavior is unchanged.
Built bottom-up (base → services → config → agent → factory → server → acp), TDD, one layer per commit.
What's included
AgentContext.to_snapshot()/from_snapshot()+AgentCheckpoint(models.py) — JSON-serializable snapshot; excludes the liveasyncioclarification event and re-resolvable skills;serialize_as_anypreserves a Pydanticcustom_context.CheckpointStore(services/checkpoint_store.py) —InMemoryCheckpointStore(default) andFileCheckpointStore(JSON on disk, survives restarts), each with optionalmax_historyring buffer;build_checkpoint_store()helper.execution.checkpoint) —enabled/backend(memory|file) /dir/max_history; off by default.BaseAgent—checkpoint(),list_checkpoints(),rollback(step); automatic snapshot at the start of every iteration (crash-safe) and at the clarification pause. Auto-checkpoint failures are logged, never abort a run.AgentFactory—create(checkpoint_store=…, session_id=…)andrestore(checkpoint)(rebinds id + streaming generator, re-applies conversation/context).GET /agents/{id}/checkpoints,POST /agents/{id}/rollback(cancels a running task first),POST /agents/{id}/restore; store wired from config at startup.load_session=true, tags per-prompt checkpoints with the session id, andload_sessionrebuilds the session from its latest checkpoint; the nextpromptresumes the restored agent instead of discarding it.framework/checkpoints.md(en+ru) + nav, three endpoints in the API reference (en+ru),examples/checkpoint_and_rollback.py, and a commentedexecution.checkpointblock inconfig.yaml.example.Testing
.venv/bin/pytest); ~66 new tests across models, store, config, agent, factory, server, ACP.pre-commit run -aclean (ruff, ruff-format, docformatter, mdformat).Review
An adversarial review pass ran over the full diff; its findings were folded in as a dedicated fix commit:
custom_contextPydantic model was silently reduced to{}on snapshot → fixed withserialize_as_any.prompt()now continues the restored agent; a checkpoint is captured at the clarification pause.find_by_sessionordered by step across multi-agent sessions → ordered bycreated_at.FileCheckpointStore.delete()broke on stray non-JSON files → usesrmtree.Notes / scope
def_name) to be present in the current configuration.🤖 Generated with Claude Code