Skip to main content

ACID transactions, time-travel debugging, and zero-cost Ghost Replay for AI agents. Rollback filesystem + state. Works with LangGraph, CrewAI, or raw Python.

Project description

๐Ÿ“ผ Agent VCR

Your AI agent corrupted the codebase. Now what?

The only tool that physically deletes hallucinated files โ€” git reset --hard, not just state rollback.


PyPI CI Coverage License Python

pip install ai-agent-vcr

No API keys. No cloud. No vendor lock-in. Works with TERX โ€” memory layer for browser agents.



The Problem Every AI Agent Developer Has Hit

You ran Claude Code, OpenHands, or a LangGraph agent autonomously.

It wrote 40 files. It failed at step 8. Now you have:

  • 23 files that shouldn't exist
  • A broken import chain
  • State that says "success" on steps that half-ran
  • No way to know what the repo looked like before step 6
Your repo after a bad autonomous run:

/src/handlers.py          โ† hallucinated, breaks import
/src/auth_v2.py           โ† duplicate of auth.py, never needed
/src/models_refactor.py   โ† partial rewrite, syntax error
/tests/test_fake.py       โ† tests for code that doesn't exist
/config/settings_new.py   โ† overwrote working config

Every other tool shows you logs. Agent VCR runs git reset --hard and deletes every one of those files.


ACID Rollback โ€” The Feature Nobody Else Has

from agent_vcr import VCRRecorder
from agent_vcr.integrations.openhands import ACIDWorkspace

recorder = VCRRecorder()
acid = ACIDWorkspace("/my/workspace", recorder=recorder)

acid.begin(session_id="task-001")        # isolated git branch
acid.savepoint(state, node_name="coder") # checkpoint state + filesystem
acid.savepoint(state, node_name="tester")

# Agent writes 47 files. 23 are hallucinated garbage. Step 6 failed.
acid.rollback(to_frame_index=1)
# git reset --hard
# All 23 files: physically deleted from disk. Not hidden. Gone.

acid.commit()                            # merge only the clean branch
Before rollback:          After rollback:
/src/handlers.py    โœ—     DELETED
/src/auth_v2.py     โœ—     DELETED
/tests/fake_test.py โœ—     DELETED
/src/utils.py       โœ“     kept
/src/models.py      โœ“     kept

LangSmith shows you what happened. LangFuse shows you what happened. Arize shows you what happened.

Agent VCR changes what happened.


Ghost Replay โ€” Never Pay for the Same Task Twice

Agent succeeds? Save it. Run it again for free forever.

from agent_vcr.golden_cache import GoldenRunCache

cache = GoldenRunCache()
cache.save_golden_run("Build a REST API with JWT auth", recorder)

# Every future run of the same task:
outputs, ledger = cache.replay("Build a REST API with JWT auth")
print(ledger)
RUN 1 (original)      RUN 2 (Ghost Replay)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€     โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
Tokens:   4,100       Tokens:      0
Cost:   $0.0123       Cost:    $0.00
Time:  2,350ms        Time:      1ms

๐Ÿ’ฐ 100% savings ยท $0.0123 saved ยท 4,100 tokens ยท 2,349ms faster

Time-Travel Debugging

Agent fails at step 8 of 10? Don't re-run from zero.

from agent_vcr import VCRPlayer
from agent_vcr.models import ResumeConfig

player = VCRPlayer.load(".vcr/my_run.vcr")

# See exact state at every step
print(player.goto_frame(6))   # {'files_written': [...], 'plan': '...'}
print(player.get_errors())    # what broke and where

# Fix the prompt. Resume from step 6. Skip steps 0-5.
player.resume(
    agent_callable=coder,
    config=ResumeConfig(
        from_frame=6,
        state_overrides={"plan": "use SQLAlchemy instead of raw SQL"}
    )
)
Without Agent VCR          With Agent VCR
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€         โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
Agent fails step 8         Agent fails step 8
Patch the code             player.goto_frame(7)
Re-run ALL 10 steps        Fix the state
$0.04 + 2 min wasted       Resume from step 7
Repeat for every bug       Done. $0.00 extra.

Who This Is For

You need this if you're running:

  • Claude Code / Cursor autonomous mode
  • OpenHands on real codebases
  • LangGraph agents that write files
  • CrewAI pipelines with filesystem access
  • Any autonomous coding agent on a repo you care about

You don't need this if you're only:

  • Doing RAG / chatbots (no filesystem risk)
  • Already happy with LangSmith for tracing

Quick Start

Record

from agent_vcr import VCRRecorder

recorder = VCRRecorder()
recorder.start_session("my_run")

state = {"query": "build a REST API"}
state = planner(state)
recorder.record_step("planner", input_state, state)

state = coder(state)
recorder.record_step("coder", input_state, state)

recorder.save()  # โ†’ .vcr/my_run.vcr

Or use the context manager โ€” frames are saved even if the agent crashes:

with VCRRecorder() as recorder:
    recorder.start_session("my_run")
    # ... your agent code ...

Rewind & Fix

player = VCRPlayer.load(".vcr/my_run.vcr")

diff = player.compare_frames(5, 6)
# {'added': {'bad_file': '...'}, 'modified': {'plan': '...'}}

player.resume(
    agent_callable=coder,
    config=ResumeConfig(from_frame=5, state_overrides={"plan": "fixed"})
)

Integrations

LangGraph โ€” one line

from langgraph.graph import StateGraph
from agent_vcr import VCRRecorder
from agent_vcr.integrations.langgraph import VCRLangGraph

recorder = VCRRecorder()
graph = VCRLangGraph(recorder).wrap_graph(graph)  # โ† one line, that's it

result = graph.invoke({"query": "Build a todo app"})
recorder.save()

CrewAI

from agent_vcr.integrations.crewai import VCRCrewAI

recorder = VCRRecorder()
recorder.start_session("crew_run")
result = VCRCrewAI(recorder).kickoff(crew)
recorder.save()
pip install "ai-agent-vcr[crewai]"
pip install "ai-agent-vcr[langgraph]"

Raw Python (decorator)

from agent_vcr.integrations.langgraph import vcr_record

@vcr_record(recorder, node_name="research_step")
def research(state: dict) -> dict:
    return {"findings": search(state["query"])}

Sentinel โ€” Real-Time Code Guardian

Catches what the agent wrote before it moves to the next step.

from openhands_sentinel import Sentinel

sentinel = Sentinel(recorder=recorder)
sentinel.attach(runtime.event_stream)  # 3 lines. auto-intercepts every write.
STEP 2: Agent writes handlers.py
๐Ÿ›ก๏ธ SENTINEL: VIOLATIONS DETECTED
  CRITICAL  hash_password() already exists in auth/utils.py:8 โ€” reuse it
  CRITICAL  handle_auth_request() is 109 lines (limit: 40) โ€” break it up
  CRITICAL  Cyclomatic complexity: 32 (limit: 8)

STEP 3: Agent self-corrects
๐Ÿ›ก๏ธ SENTINEL: handlers.py โ€” CLEAN โœ“
Without Sentinel With Sentinel
Agent writes bad code โœ“ โœ“
Sentinel catches it โ€” < 10ms
Agent self-corrects โ€” done
Human reviews PR manual zero
Cost 2ร— LLM + human time 1 extra LLM call

Standalone scan:

sentinel scan ./my-ai-project

TUI Debugger

vcr .vcr/my_run.vcr
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ๐Ÿ“ผ Agent VCR                  Session: my_run ยท 8 frames โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ โ–ถ Frame 0  โ”‚ planner     โ”‚ 100ms  โ”‚ โ—                    โ”‚
โ”‚   Frame 1  โ”‚ researcher  โ”‚  250ms โ”‚ โ—                    โ”‚
โ”‚   Frame 2  โ”‚ coder       โ”‚  480ms โ”‚ โœ— ERROR              โ”‚
โ”‚   Frame 3  โ”‚ tester      โ”‚   80ms โ”‚ โ—                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  { "query": "build a todo app", "plan": null }           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ โ†/โ†’ navigate  โ”‚ e edit  โ”‚ d diff  โ”‚ r resume  โ”‚ q quit   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Keybindings: โ†‘/โ†“ or j/k navigate ยท e edit state ยท 1/2/3 input/output/diff ยท r resume ยท s search ยท q quit

Claude Code hooks:

vcr init --claude-code

DAG Visualization

vcr-server .vcr/
# localhost:8000
original_run โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ [done]
               โ”‚ frame 3
               โ•ฐโ”€โ”€โ–บ fork_v1 โ”€โ”€โ–บ [coder] โ”€โ”€โ–บ [tester] โ”€โ”€โ–บ [done]
               โ•ฐโ”€โ”€โ–บ fork_v2 โ”€โ”€โ–บ [coder] โ”€โ”€โ–บ [done]

Live WebSocket streaming. Every fork is a branch. Errors in red.


vs Everything Else

Honest take: LangSmith, Langfuse, Arize Phoenix, and AgentOps are serious platforms with large teams. They are observability tools โ€” they show you what happened. Agent VCR is an intervention tool โ€” it lets you change what happened. Different category. The overlap is tracing. Everything else diverges.

Capability ๐Ÿ“ผ Agent VCR LangSmith LangFuse AgentOps Arize Phoenix
Record execution traces โœ… โœ… โœ… โœ… โœ…
Production dashboards Local โœ… best-in-class โœ… โœ… โœ…
Eval / scoring pipelines โŒ โœ… โœ… โœ… โœ…
Time-travel / session replay โœ… โŒ โŒ โœ… (view only) โŒ
Edit state & resume mid-chain โœ… โŒ โŒ โŒ โŒ
ACID filesystem rollback โœ… โŒ โŒ โŒ โŒ
Ghost Replay (zero tokens) โœ… โŒ โŒ โŒ โŒ
Sentinel (real-time code guard) โœ… โŒ โŒ โŒ โŒ
Fork from any frame โœ… โŒ โŒ โŒ โŒ
TUI debugger โœ… โŒ โŒ โŒ โŒ
Fully local / self-hosted โœ… โŒ Cloud โœ… โŒ Cloud โœ…
Framework-agnostic โœ… โš ๏ธ LangChain โœ… โœ… โœ…

AgentOps โ€” closest competitor on time-travel. It lets you view past sessions. It does not let you edit state and resume, fork a session, rollback the filesystem, or replay for zero tokens. If you need view-only replay, AgentOps is mature. If you need to actually intervene, you need Agent VCR.

Use LangSmith/Langfuse/Phoenix/AgentOps for production tracing and evals. Use Agent VCR when you need to actually fix a broken run without re-running it, rollback filesystem damage, or replay a successful run for free.


vs LangGraph's Built-In Checkpointer

LangGraph's checkpointer is solid if you're 100% LangGraph and only need state inspection.

The gap: when your agent writes files to disk and fails, the checkpointer rolls back the state object. The files stay. Agent VCR runs git reset --hard. The files are gone.

LangGraph Checkpointer Agent VCR
Checkpoint in-memory state โœ… โœ…
Rollback files from disk โŒ โœ…
Ghost Replay (zero tokens) โŒ โœ…
Sentinel (code guardian) โŒ โœ…
Works with CrewAI, raw Python โŒ โœ…
JSONL format (git-diffable) โŒ โœ…
Session forking โŒ โœ…

Performance

Every benchmark is enforced in CI. If it regresses, CI fails.

pip install -e ".[dev]"
pytest tests/benchmarks/ -v --benchmark-only
Benchmark Limit What it measures
test_benchmark_recorder_overhead < 5ms mean Serialize + buffer one state snapshot
test_benchmark_file_write_speed > 1,000 frames/sec Sustained write throughput (10K frames)
test_benchmark_load_speed < 500ms Load a 10,000-frame session from disk
test_benchmark_goto_frame < 1ms Random-access time-travel to any frame

Historical results: ixchio.github.io/agent-vcr/dev/bench/


Storage Format

Plain JSONL. One object per line.

{"type": "session", "data": {"session_id": "my_run", "created_at": "..."}}
{"type": "frame", "data": {"node_name": "planner", "input_state": {...}, "output_state": {...}}}
{"type": "frame", "data": {"node_name": "coder", ...}}
  • Human-readable โ€” open in any text editor
  • Git-diffable โ€” review agent state in PRs
  • Append-only โ€” safe for concurrent agents, no full-file rewrites
  • Streamable โ€” parse line-by-line without loading the full file

API Reference

VCRRecorder

recorder = VCRRecorder(
    output_dir=".vcr",
    auto_save=True,
    diff_mode=False,
)

recorder.start_session(session_id="my_run", tags=["prod"])
recorder.record_step(node_name, input_state, output_state, metadata)
recorder.record_llm_call(model, messages, response, tokens_input, tokens_output, latency_ms)
recorder.record_tool_call(tool_name, tool_input, tool_output, latency_ms)
recorder.record_error(node_name, input_state, error)
recorder.save() -> Path
recorder.fork(from_frame=3) -> VCRRecorder

VCRPlayer

player = VCRPlayer.load(".vcr/my_run.vcr")

player.goto_frame(index)           # โ†’ output state at frame N
player.get_input_state(index)      # โ†’ input state at frame N
player.get_errors()                # โ†’ [Frame, ...]
player.compare_frames(a, b)        # โ†’ {'added': {}, 'removed': {}, 'modified': {}}
player.get_total_cost()            # โ†’ float (USD)

player.resume(
    agent_callable,
    config=ResumeConfig(
        from_frame=7,
        state_overrides={"k": "v"},
        mode=ResumeMode.FORK,      # FORK | REPLAY | MOCK
    )
)

ACIDWorkspace

acid = ACIDWorkspace("/workspace", recorder=recorder)
acid.begin(session_id="task-001")
acid.savepoint(state, node_name="coder")
acid.rollback(to_frame_index=2)    # git reset --hard
acid.commit()

GoldenRunCache

cache = GoldenRunCache(cache_dir=".vcr/golden")
cache.save_golden_run(task_description, recorder)
outputs, ledger = cache.replay(task_description)
cache.invalidate(task_description)
cache.list_golden_runs()

Examples

# ACID rollback + Ghost Replay โ€” start here
python examples/acid_golden_run.py

# Time-travel: rewind, edit state, resume
python examples/time_travel_demo.py

# Sentinel: watch agent self-correct in real time
python examples/sentinel_demo.py

# LangGraph auto-instrumentation
python examples/langgraph_integration.py

# Basic recording and playback
python examples/basic_usage.py

Roadmap

  • Core recording and playback
  • Time-travel resume with state injection
  • LangGraph + CrewAI integrations
  • Async recorder and player
  • Terminal TUI debugger (vcr)
  • Claude Code hook scaffolding (vcr init --claude-code)
  • Live dashboard with DAG visualization
  • ACID Transactions (git-backed filesystem rollback)
  • Ghost Replay (zero-cost replay of successful runs)
  • Sentinel โ€” real-time code quality guardian
  • Context manager (with VCRRecorder() as r:)
  • Claude Code / Cursor integration
  • AutoGen integration
  • Replay regression tests (golden paths as CI assertions)
  • Collaborative debugging (share sessions)
  • Cloud storage backend (S3, GCS)

Community

If Agent VCR saved your repo from a bad autonomous run, share it:

  • OpenHands โ€” Discord #tools channel
  • LangGraph โ€” Discord #community channel
  • r/LocalLLaMA โ€” post your ACID rollback story
  • Hacker News โ€” Show HN posts with real before/after diffs get traction

The best growth comes from developers sharing the moment it saved them. If that's you, a post with your actual corrupted-repo story (even anonymized) is worth more than any ad.


Contributing

git clone https://github.com/ixchio/agent-vcr.git
cd agent-vcr
pip install -e ".[dev,tui]"
pytest tests/unit/ -v

See CONTRIBUTING.md for guidelines.


License

MIT โ€” see LICENSE.


๐Ÿ“ผ

Every AI agent developer has had a bad run trash their codebase. Agent VCR is the undo button.


pip install ai-agent-vcr

โญ Star on GitHub ยท ๐Ÿ“ฆ PyPI ยท ๐Ÿ“– Docs


Built by ixchio ยท MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ai_agent_vcr-0.7.1.tar.gz (920.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ai_agent_vcr-0.7.1-py3-none-any.whl (166.3 kB view details)

Uploaded Python 3

File details

Details for the file ai_agent_vcr-0.7.1.tar.gz.

File metadata

  • Download URL: ai_agent_vcr-0.7.1.tar.gz
  • Upload date:
  • Size: 920.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for ai_agent_vcr-0.7.1.tar.gz
Algorithm Hash digest
SHA256 2df4b229f5ca65483b4c22f8abcdbf98a40451223de1709b562a7b998b1e64d7
MD5 5a99d2c07c8a9f9df4d962769e591b8b
BLAKE2b-256 531f8d3d1b36b50d2c197b559192b59f89d978836353e07c6fd07f56cafd5f18

See more details on using hashes here.

File details

Details for the file ai_agent_vcr-0.7.1-py3-none-any.whl.

File metadata

  • Download URL: ai_agent_vcr-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 166.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for ai_agent_vcr-0.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2c5182d04a55bb48a39e27bc1591fdfc814b6b701857d3630c2eda5d915c844f
MD5 711d26c5c7a7f164d776aa0c067f568b
BLAKE2b-256 bbd2475ff8df2fe94b33ce02a3768bdea79f26dc21a70c9a0fa5bc534570ed46

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page