Skip to content

ixchio/agent-vcr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

59 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“Ό 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.
# Pre-existing ignored files like .env are preserved.

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()
identity = GoldenRunCache.build_identity(
    model="gpt-4o",
    prompt_hash="prompt:v3",
    code_commit="abc123",
    tool_schema_hash="tools:v1",
)
cache.save_golden_run("Build a REST API with JWT auth", recorder, identity=identity)

# Every future run of the same task:
outputs, ledger = cache.replay("Build a REST API with JWT auth", identity=identity)
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
sentinel watch ./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

pip install "ai-agent-vcr[dashboard]"
vcr-server --vcr-dir .vcr --auth-token local-secret
# http://127.0.0.1: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")
identity = GoldenRunCache.build_identity(model="gpt-4o", code_commit="abc123")
cache.save_golden_run(task_description, recorder, identity=identity)
outputs, ledger = cache.replay(task_description, identity=identity)
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]"
make verify

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

About

Undo button for AI coding agents: ACID repo rollback, time-travel debugging, and zero-token Ghost Replay.

Topics

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages