Skip to main content
Save and rewind workspace snapshots before agents change files — powered by a shadow git repository.
from praisonaiagents import Agent

agent = Agent(name="coder", instructions="Edit project files safely.")
agent.start("Refactor the auth module.")
The user runs an agent that edits files; checkpoints snapshot the workspace so you can diff or restore before bad changes land.

Quick Start

1

Attach checkpoints to an agent

from praisonaiagents import Agent
from praisonaiagents.checkpoints import CheckpointService

checkpoints = CheckpointService(workspace_dir="./my_project")
agent = Agent(
    name="RefactorBot",
    instructions="You are a code refactoring assistant.",
    checkpoints=checkpoints,
)
agent.start("Refactor the codebase to improve readability")
2

Save and restore from CLI

praisonai checkpoint save "Before major changes"
praisonai checkpoint list
praisonai checkpoint restore last
3

One-liner undo after a run

praisonai run agents.yaml
praisonai run --restore last

Overview

Checkpoints allow you to:
  • Save snapshots of your workspace before changes
  • Restore files to any previous checkpoint
  • Diff between checkpoints to see what changed
  • Track all file modifications made by agents

In-session /undo and /revert

When praisonai code --checkpoints is active, the coding REPL gains turn-aware undo and revert commands. /undo mode comparison:
ModeWhat /undo does
Checkpointing off (default)Removes the last assistant + user message pair from history only. Workspace files are untouched.
Checkpointing on, session store not wiredRestores workspace files to the previous turn’s snapshot. Conversation history is left intact. (Legacy / file-only fallback.)
Checkpointing on, session store wired (default in praisonai code)Restores workspace files and rewinds chat_history to the message count captured at checkpoint_turn(), so the agent’s memory matches the workspace. Diff preview shown first.
Revert is best-effort. A file restore failure skips the conversation rewind. A conversation-revert failure leaves the already-restored files intact — you can retry from a clean workspace state.
Preview reports dropped-message count. preview(n) now returns dropped_message_count alongside the file diff, so the CLI can show how many chat turns would be discarded before you confirm. If the session store is not wired in, dropped_message_count is None.
preview = manager.preview(1)
print(preview.dropped_message_count)   # 3 → messages that would be truncated
/revert [n] rolls back n turns (default 1). After revert, the timeline drops the restored turns so the next /undo walks further back. Project config:
# agents.yaml
checkpoints:
  auto: true
  storage_dir: ./.praisonai/checkpoints   # optional
Env override: PRAISONAI_CHECKPOINTS=on (or off). Precedence: PRAISONAI_CHECKPOINTS (env) > checkpoints.auto (config) > default (off).

CLI Commands

# Save a checkpoint (--allow-empty to snapshot even with no changes)
praisonai checkpoint save "Before major changes"
praisonai checkpoint save "Before major changes" --allow-empty

# List checkpoints (newest first; -n to limit)
praisonai checkpoint list
praisonai checkpoint list -n 10

# Show diff — accepts last/latest, full id, short id, or unique prefix
praisonai checkpoint diff
praisonai checkpoint diff last
praisonai checkpoint diff abc12345 def67890

# Restore to a checkpoint
praisonai checkpoint restore last
praisonai checkpoint restore abc12345

# Delete all checkpoints (-y to skip confirm prompt)
praisonai checkpoint delete
praisonai checkpoint delete --yes

# All subcommands accept -w to target a specific workspace directory
praisonai checkpoint list -w /path/to/project
praisonai checkpoint restore last -w /path/to/project
One-liner undo after a bad praisonai run: praisonai run --restore last. See Run — Checkpoint & Rewind for details.

Automatic Checkpoints with praisonai run

praisonai run snapshots your workspace automatically before every YAML-file run.
# Project config — opt out per project
checkpoints:
  auto: false
  • Default: true — automatic checkpoints are on for all YAML-file runs.
  • Scoped to YAML runs: plain-prompt runs (praisonai run "…") are skipped.
  • Workspace: the directory of the target YAML file, not the cwd.
  • Label: run:<run_id> (or "auto checkpoint before run" as a fallback).
  • Best-effort: failures are swallowed and never block the run.
  • Per-run override: praisonai run agents.yaml --no-checkpoint.
praisonai run agents.yaml            # auto-checkpoint, then run
praisonai run --restore last         # rewind workspace, exit
praisonai run agents.yaml --no-checkpoint   # skip auto-checkpoint

Configuration

from praisonaiagents.checkpoints import CheckpointService

service = CheckpointService(
    workspace_dir="/path/to/project",
    storage_dir="~/.praisonai/checkpoints",
    enabled=True,
    auto_checkpoint=True,
    max_checkpoints=100
)
Parameters:
  • workspace_dir: Directory to track
  • storage_dir: Where to store checkpoint data (default: ~/.praisonai/checkpoints)
  • enabled: Enable/disable checkpoints
  • auto_checkpoint: Auto-checkpoint before file modifications
  • max_checkpoints: Maximum checkpoints to keep

Data Types

Checkpoint

@dataclass
class Checkpoint:
    id: str           # Full commit hash
    short_id: str     # Short hash (8 chars)
    message: str      # Checkpoint message
    timestamp: datetime
    files_changed: int
    insertions: int
    deletions: int

CheckpointDiff

@dataclass
class CheckpointDiff:
    from_checkpoint: str
    to_checkpoint: Optional[str]  # None = working directory
    files: List[FileDiff]
    total_additions: int
    total_deletions: int

Best Practices

Save with a descriptive message before large edits so restore targets are obvious in checkpoint list.
Run praisonai checkpoint diff last to confirm you are rewinding to the right snapshot.
Set max_checkpoints on CheckpointService to avoid unbounded shadow-git growth.
Skip auto-checkpoints on YAML runs when you know the workspace is disposable.
With the session store wired in, /undo rewinds files and chat history to the same turn boundary, so the agent’s memory stays consistent with the workspace. /clear only truncates history and leaves reverted edits invisible to the agent.

Low-level API Reference

CheckpointService Direct Usage

from praisonaiagents.checkpoints import CheckpointService

# Create checkpoint service
service = CheckpointService(
    workspace_dir="/path/to/project",
    storage_dir="~/.praisonai/checkpoints"
)

# Initialize
await service.initialize()

# Save a checkpoint
result = await service.save("Before refactoring")
print(f"Saved: {result.checkpoint.short_id}")

# Make changes...

# Restore if needed
await service.restore(result.checkpoint.id)

# View diff
diff = await service.diff()

Methods

initialize()

Initialize the checkpoint service:
success = await service.initialize()

save(message, allow_empty=False, quiet=False)

Save a checkpoint:
result = await service.save("Checkpoint message")

if result.success:
    print(f"Saved: {result.checkpoint.short_id}")
else:
    print(f"Error: {result.error}")
ParameterTypeDefaultDescription
messagestrCheckpoint message
allow_emptyboolFalseAllow saving even when no files changed
quietboolFalseSuppress output (used by machine-readable run modes)

restore(checkpoint_id)

Restore to a checkpoint:
result = await service.restore("abc123")

if result.success:
    print("Restored successfully")

diff(from_id=None, to_id=None)

Get diff between checkpoints:
# Diff from last checkpoint to current
diff = await service.diff()

# Diff between specific checkpoints
diff = await service.diff("abc123", "def456")

for file in diff.files:
    print(f"{file.status}: {file.path} (+{file.additions}/-{file.deletions})")

list_checkpoints(limit=50)

List all checkpoints:
checkpoints = await service.list_checkpoints(limit=20)

for cp in checkpoints:
    print(f"{cp.short_id} - {cp.message} ({cp.timestamp})")

Event Handlers

Subscribe to checkpoint events:
from praisonaiagents.checkpoints import CheckpointEvent

def on_checkpoint(checkpoint):
    print(f"Checkpoint created: {checkpoint.short_id}")

service.on(CheckpointEvent.CHECKPOINT_CREATED, on_checkpoint)
service.on(CheckpointEvent.CHECKPOINT_RESTORED, lambda cp: print(f"Restored: {cp.short_id}"))
service.on(CheckpointEvent.ERROR, lambda e: print(f"Error: {e['error']}"))

Zero Performance Impact

The checkpoint system is designed for minimal overhead:
  • Lazy loading: All imports via __getattr__
  • Async operations: Non-blocking git operations
  • Incremental commits: Only changed files are tracked
  • Configurable limits: Control max checkpoints to manage storage

CLI

praisonai checkpoint and praisonai run --restore commands.

Code Execution

Agents that edit files benefit most from automatic checkpoints.

Context Files

Pair workspace snapshots with project context files.

Self-Reflection

Rewind bad reflection loops with a saved checkpoint.