Metadata-Version: 2.4
Name: agenitry
Version: 0.1.0
Summary: Official Python SDK for the Agenitry audit-trail API — log AI agent actions, query events, and pull stats in two lines of code.
Project-URL: Homepage, https://agenitry.com
Project-URL: Documentation, https://github.com/concya/agenitry#readme
Project-URL: Repository, https://github.com/concya/agenitry
Author-email: Agenitry <ola@agenitry.com>
License-Expression: MIT
Keywords: agenitry,ai-agents,audit,compliance,ledger,observability
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# Agenitry Python SDK

> The event ledger for AI agents. One line to log, one URL to verify.

## The problem

Your AI agent takes actions — reservations, orders, comps, price changes — but nobody can see what happened or why. You're flying blind.

**Agenitry** gives every agent action a permanent, verifiable record. Log an event in one line. Share a URL. Done.

## Install

```bash
pip install agenitry
```

Zero dependencies. Python 3.9+.

## Quick start

```python
from agenitry import Agenitry

agent = Agenitry(api_key="ag_your_key", venue_id="nobo-downtown")

# Log an event — fire and forget by default
agent.log(action="order_captured", amount=42.50, direction="inbound")

# Await confirmation if you need the event ID
event = agent.log(action="reservation_booked", amount=0, direction="inbound", await_confirmation=True)
print(event["id"])  # evt_abc123

# Query events
result = agent.events(action="order_captured", limit=10)
for e in result["events"]:
    print(e["action"], e["amount"])

# Get stats
stats = agent.stats(period="7d")
print(stats["total_inbound"], stats["event_count"])
```

## Verify URL

Every event gets a permanent, shareable URL:

```
https://api.agenitry.com/v1/verify/{venue_id}/{event_id}
```

No login required. No dashboard needed. Just share the link and anyone can verify what happened.

## API Reference

### `Agenitry(api_key, venue_id, *, agent_id=None, base_url=None, max_retries=3, retry_base_delay=0.5)`

Create a new Agenitry client.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `api_key` | `str` | required | Your venue API key (`ag_...`) |
| `venue_id` | `str` | required | Your venue identifier |
| `agent_id` | `str` | `None` | Default agent ID for all events |
| `base_url` | `str` | `https://api.agenitry.com` | API base URL |
| `max_retries` | `int` | `3` | Max retry attempts on 429/5xx |
| `retry_base_delay` | `float` | `0.5` | Base delay in seconds (exponential backoff) |

### `agent.log(*, action, amount=None, direction=None, agent_id=None, context=None, await_confirmation=False)`

Log an event.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `action` | `str` | required | Event action (see below) |
| `amount` | `float` | `None` | Dollar amount |
| `direction` | `str` | `None` | `inbound`, `outbound`, or `internal` |
| `agent_id` | `str` | constructor default | Agent that performed the action |
| `context` | `dict` | `None` | Arbitrary JSONB context data |
| `await_confirmation` | `bool` | `False` | If `True`, waits for server response |

**Fire and forget** (default): `log()` returns immediately with `{id: "", status: "logged"}`. If the request fails, it's silently swallowed. Perfect for non-critical logging.

**Await confirmation**: `log()` waits for the server response and raises `AgenitryError` on failure. Use when you need the event ID or need to know it was persisted.

### Event Actions

| Action | Description | Direction | Example |
|--------|-------------|-----------|---------|
| `order_captured` | Agent captured an order | `inbound` | Voice agent took a $42.50 takeout order |
| `reservation_booked` | Agent booked a reservation | `inbound` | Chatbot reserved table 7 for 8pm |
| `price_changed` | Agent changed a price | `internal` | Agent updated happy hour draft from $6 to $7 |
| `item_86d` | Agent marked an item as unavailable | `internal` | Agent 86'd the tuna special |
| `comp_issued` | Agent issued a comp | `outbound` | Agent comped dessert for a regular |
| `purchase_order` | Agent placed a purchase order | `outbound` | Agent ordered 50 lbs of salmon |

### `agent.events(*, agent_id=None, action=None, direction=None, limit=None, offset=None, context=None)`

Query events for the venue.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `agent_id` | `str` | `None` | Filter by agent |
| `action` | `str` | `None` | Filter by action type |
| `direction` | `str` | `None` | Filter by direction |
| `limit` | `int` | `50` | Max events to return |
| `offset` | `int` | `0` | Pagination offset |
| `context` | `dict` | `None` | JSONB contains filter |

Returns a dict with `total`, `limit`, `offset`, `has_more`, and `events` list.

### `agent.stats(*, period=None)`

Get aggregate stats for the venue.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `period` | `str` | `today` | `today`, `7d`, `30d`, or `90d` |

Returns a dict with `total_inbound`, `total_outbound`, `event_count`, and `by_agent` breakdown.

### `AgenitryError`

Raised on API errors. Attributes:

| Attribute | Type | Description |
|-----------|------|-------------|
| `status` | `int` or `None` | HTTP status code (if available) |
| `body` | `dict` or `None` | Parsed response body (if JSON) |
| `code` | `str` | Error code: `NETWORK`, `HTTP`, or `PARSE` |

### `create_agenitry(api_key, venue_id, **kwargs)`

Factory function. Returns an `Agenitry` instance. Same arguments as the constructor.

## Type Aliases

```python
EventAction = Literal[
    "order_captured", "reservation_booked", "price_changed",
    "item_86d", "comp_issued", "purchase_order"
]

EventDirection = Literal["inbound", "outbound", "internal"]

StatsPeriod = Literal["today", "7d", "30d", "90d"]
```

## License

MIT