Metadata-Version: 2.4
Name: pokayoke
Version: 0.3.1
Summary: Record-and-replay regression safety net for AI agents
Project-URL: Homepage, https://github.com/gornasnik/poka
Project-URL: Issues, https://github.com/gornasnik/poka/issues
License: MIT License
        
        Copyright (c) 2026 Gornasnik
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.11
Requires-Dist: anthropic>=0.94.0
Requires-Dist: click>=8.3.2
Requires-Dist: openai>=1.60.0
Requires-Dist: pydantic>=2.12.5
Description-Content-Type: text/markdown

# poka

Record-and-replay regression safety net for AI agents.

Capture a real agent run once, replay it in CI forever — offline, free, zero API cost.

```bash
pip install poka
```

---

## Overview

Think of a **fixture** as a vending machine stocked with AI responses.

**Record once** — poka intercepts every SDK call, lets it reach the real API,
and saves each request + response pair to a fixture file on disk.

**Replay forever** — poka intercepts the same calls and returns the stored
responses directly. No network request is made. Your code receives the exact
same object it would have gotten from the live API.

**Wrong coin → fail fast** — if your code makes a different call than what was
recorded (prompt changed, model changed, tools changed), poka raises an error
immediately with a diff instead of silently returning a stale response. See
[docs/matching.md](docs/matching.md#what-each-failure-looks-like) for the
shape of each kind of failure.

**Restock** — delete the fixture file and run once more. Poka falls through to
the real API, saves fresh responses, and you're back up to date.

---

## Quickstart

### Scatter `@poka.fixture` in your agent code

```python
import poka
from anthropic import Anthropic

@poka.fixture("fixtures/answer_ticket")
def answer_ticket(ticket: str) -> str:
    client = Anthropic()
    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        messages=[{"role": "user", "content": ticket}],
    )
    return response.content[0].text
```

- **First run** — fixture file absent → calls the real API, saves the fixture to disk.
- **Every run after** — fixture present → returns the recorded response instantly, no API call made.
- **Re-record** — delete the fixture file and run once more.

### Use it in tests

```python
def test_answer_ticket():
    result = answer_ticket("I want a refund")
    assert "refund policy" in result
```

No API key needed in CI. No tokens spent. The fixture is committed to version control alongside your code.

### Mark tool functions

```python
@poka.tool
def search_kb(query: str) -> dict:
    return db.search(query)
```

`@poka.tool` captures tool call inputs and outputs during recording, and returns the recorded output during replay — preventing side effects like DB writes or emails.

---

## Production

Poka is **disabled by default** (`POKA_ENABLED=0`). Set `POKA_ENABLED=1` in your development environment to activate recording and replay. In production, leave it unset — every `@poka.fixture`, `@poka.record`, and `@poka.replay` decorator is a zero-overhead no-op.

```bash
# .env (development only)
POKA_ENABLED=1
```

You can also toggle programmatically, for example to skip interception in specific tests:

```python
poka.disable()
poka.enable()
poka.is_enabled()  # True / False
```

---

## Explicit record and replay

For more control, use `poka.record` and `poka.replay` directly:

```python
# Record
with poka.record() as recorder:
    result = answer_ticket("I want a refund")

recorder.fixture.save("fixtures/refund.poka.json")

# Replay
from poka.fixture import Fixture

fixture = Fixture.load("fixtures/refund.poka.json")

with poka.replay(fixture):
    result = answer_ticket("I want a refund")
```

Both also work as decorators:

```python
@poka.record("fixtures/refund")
def run(): ...

@poka.replay("fixtures/refund")
def test(): ...
```

---

## Development setup

Requires [uv](https://docs.astral.sh/uv/getting-started/installation/). Install it with:

```bash
brew install uv
```

```bash
git clone https://github.com/gornasnik/poka.git
cd poka
uv sync --group dev
```

This uses `.python-version` (Python 3.11) and `uv.lock` to give every team member an identical environment.

### Common tasks

```bash
uv run pytest          # run tests
uv run ruff check .    # lint
uv run ruff format .   # format
uv run mypy            # type check
```

### Pre-commit hooks

```bash
uv run pre-commit install
```
