Metadata-Version: 2.4
Name: powerailabs-cassette
Version: 0.1.0
Summary: Test: record an agent run once, replay it forever — deterministic, offline, free. The vcrpy of the agent era.
Author: Raghav Mishra
License-Expression: MIT
Requires-Python: >=3.11
Requires-Dist: powerailabs-core<0.2,>=0.1
Description-Content-Type: text/markdown

# powerailabs-cassette

Record an agent run once; replay it forever — deterministic, offline, and free. Unlike `vcrpy`
(HTTP-only), it captures the *whole* run: every LLM call and tool call, in order.

**Agent tests that run in 0.2s with no API key.**

![status](https://img.shields.io/badge/status-building-yellow) ![license](https://img.shields.io/badge/license-MIT-blue)

🚧 building (v0) · `pip install powerailabs-cassette` · `from powerailabs import cassette`

```python
from powerailabs.core import instrument
from powerailabs import cassette

client = instrument(OpenAI())          # the same instrumented seam used in production

@cassette.use("triage_happy_path.json")   # record first run, replay after (auto mode)
def test_triage():
    result = my_agent.run("My card was charged twice")   # your real agent loop
    assert "refund" in result.tools_called
    assert cassette.semantic_match(result.answer, "offers a refund")
```

**Wrap-around, test-time only.** In production you do nothing; in tests, calls through the
instrumented client (and `instrument_tool`-wrapped tools) are recorded once by subscribing to
core's bus, then replayed by a core interceptor keyed on a normalized request hash — no second
patch, no network. Secrets/PII are redacted on record (cassettes get committed). `semantic_match`
asserts meaning, not bytes, so a reworded model answer doesn't break your test.

See [`docs/cassette.md`](../../docs/cassette.md). *Part of the PowerAI Labs stack — github.com/PowerAI-Labs/powerailabs.*
