Skip to main content

Deterministic record/replay of LLM and tool calls for AI agents, captured into human-readable cassettes.

Project description

AgentTape

Deterministic record and replay for AI agents. Capture every external interaction your agent makes — LLM calls and tool calls — into human-readable "cassettes", then replay them deterministically so your tests run offline, for free, with zero side effects.

CI PyPI Python License: MIT


Why

Agent tests today are slow, flaky, expensive, and dangerous: they hit real LLM APIs (cost + nondeterminism) and real tools (a tool that charges a card, writes a row, or posts to Slack actually does it). AgentTape records those interactions once and replays them deterministically afterwards. Your CI runs with no network access, no API keys, and no risk of a real side effect.

  • Local-first — no server, no telemetry, nothing leaves your machine.
  • Deterministic — same inputs produce the same recorded outputs, byte-for-byte.
  • Zero side effects in replay — a replayed tool never executes for real.
  • Almost-no-code — add a decorator or a with block.
  • Git-friendly — cassettes are YAML: diffable, reviewable, hand-editable.
  • Zero core dependencies — the engine is pure standard library.

Install

pip install agenttape            # core (stdlib only)
pip install "agenttape[openai]"  # + OpenAI adapter
pip install "agenttape[yaml]"    # + PyYAML for extra-robust YAML loading

30-second quickstart

Record once (real API call), then replay forever (no network):

import agenttape
from openai import OpenAI

def run_agent():
    client = OpenAI()
    resp = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": "Say hi in 3 words"}],
    )
    return resp.choices[0].message.content

# --- record (hits the real API once, writes cassettes/hello.yaml) ---
with agenttape.use_cassette("hello", mode="record"):
    print(run_agent())

# --- replay (zero network calls, milliseconds, free, deterministic) ---
with agenttape.use_cassette("hello", mode="none"):
    print(run_agent())   # identical output, served from the cassette

Or as a decorator:

@agenttape.replay("hello")          # mode="none": offline + deterministic
def test_agent():
    assert "hi" in run_agent().lower()

Mixed / partial replay — "freeze all but one"

Change one thing — a prompt, a model, a single tool — and re-run while every other expensive or dangerous boundary stays frozen from the recording:

# Only the LLM runs for real; every tool is served from the cassette.
# A *derived* cassette is written — the original is never mutated.
with agenttape.use_cassette("checkout", live={"llm"}):
    result = run_agent()   # new prompt → new LLM output, tools stay frozen

# See exactly what changed:
#   agenttape diff cassettes/checkout.yaml cassettes/checkout.derived.yaml

Any boundary that is not in live and has no recording raises UnmatchedInteractionError — AgentTape will never silently run a real side effect.

Hand-edit a response

Cassettes are just YAML. Open cassettes/hello.yaml, edit a recorded LLM response, save, and re-run in mode="none" — your agent behaves differently with no API call at all. Perfect for testing edge cases and failure paths.

pytest plugin

Ships in the box. Tests run offline and deterministically by default:

import pytest

@pytest.mark.agenttape("weather_agent")
def test_weather(agenttape_cassette):
    assert run_agent() == "It's sunny."
pytest                       # replay mode, offline, free (CI default)
pytest --agenttape-record    # (re)record cassettes against the real API

CLI

agenttape init                       # scaffold agenttape.toml + cassettes/
agenttape inspect cassettes/hello    # tokens, latency, cost, per-step I/O
agenttape timeline cassettes/hello   # ASCII waterfall of the run
agenttape diff a.yaml b.yaml         # prompt / model / tool / cost / output diff
agenttape validate cassettes/hello   # schema + determinism + leaked-secret lint
agenttape view cassettes/hello       # self-contained static HTML, no server
agenttape redact cassettes/hello     # re-run secret/PII redaction
agenttape export cassettes/hello --format otel

What this is — and what it isn't

It is:

  • A deterministic record/replay layer for agent I/O (LLM + tools + raw HTTP).
  • A way to make agent tests fast, free, offline and side-effect-free.
  • A diff/inspection toolkit for understanding and reviewing agent runs.

It isn't:

  • It is not a way to "replay with a different prompt/model and get a deterministic answer for free." Replay reconstructs recorded bytes. The moment you change an input to a boundary marked live, that boundary really executes (real API call, real cost) and produces a new recording. AgentTape is explicit about this everywhere — pure replay vs. re-execution are different verbs and we never blur them.
  • It is not an evaluation framework, a prompt optimizer, or a tracing SaaS.

See the determinism guide and the cassette format spec for details.

License

MIT — see 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

agenttape-0.1.0.tar.gz (59.8 kB view details)

Uploaded Source

Built Distribution

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

agenttape-0.1.0-py3-none-any.whl (72.2 kB view details)

Uploaded Python 3

File details

Details for the file agenttape-0.1.0.tar.gz.

File metadata

  • Download URL: agenttape-0.1.0.tar.gz
  • Upload date:
  • Size: 59.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for agenttape-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7bf8b530b5d1a9d832cd54337ac7a7965a70e66041bd9b73a70e66a1705a9af8
MD5 d9813c7748de945d107df2b728987884
BLAKE2b-256 c27084b9b23e622f9482a53acd133ba15d029a8a86f092a67dc12fe4823842d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for agenttape-0.1.0.tar.gz:

Publisher: release.yml on MITHRAN-BALACHANDER/AgentTape

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file agenttape-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: agenttape-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 72.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for agenttape-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ab330edce3cf279f49123d50e0a004896d15b986838dcf65af3e5e21d9dbcd98
MD5 6b8929555ec5b4958b5e71834b0972b6
BLAKE2b-256 90b72d8a296203e6672e16f572341088b0d2bb21bdd259978fabb0bf3d624e7f

See more details on using hashes here.

Provenance

The following attestation bundles were made for agenttape-0.1.0-py3-none-any.whl:

Publisher: release.yml on MITHRAN-BALACHANDER/AgentTape

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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