Metadata-Version: 2.4
Name: agentbouncr
Version: 0.1.2
Summary: Python SDK for AgentBouncr — Governance for AI Agents
Project-URL: Homepage, https://agentbouncr.com
Project-URL: Documentation, https://agentbouncr.com/api/docs
Project-URL: Repository, https://github.com/agentbouncr/enterprise
Project-URL: Issues, https://github.com/agentbouncr/enterprise/issues
Author-email: AgentBouncr <hello@agentbouncr.com>
License-Expression: MIT
License-File: LICENSE
Keywords: agents,ai,governance,langchain,safety
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
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx<1.0.0,>=0.24.0
Provides-Extra: dev
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: langchain
Requires-Dist: langchain-core<1.0.0,>=0.2.0; extra == 'langchain'
Description-Content-Type: text/markdown

# agentbouncr

[![PyPI version](https://img.shields.io/pypi/v/agentbouncr.svg)](https://pypi.org/project/agentbouncr/)
[![Python versions](https://img.shields.io/pypi/pyversions/agentbouncr.svg)](https://pypi.org/project/agentbouncr/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Governance for autonomous AI agents. Every tool call is checked against your policies **before** execution.

Works with **LangChain**, **LangGraph**, **CrewAI**, **AutoGen** — or any framework. Drop-in callback for LangChain users, plain HTTP client for everyone else.

## Installation

```bash
pip install agentbouncr
```

For LangChain integration:

```bash
pip install "agentbouncr[langchain]"
```

## 30-Second Quickstart

```python
from agentbouncr import AgentBouncr

client = AgentBouncr(api_key="sk_live_your_key_here")

result = client.evaluate(
    agent_id="my-research-agent",
    tool="send_email",
    params={"to": "user@example.com"},
)

if result.allowed:
    send_email(to="user@example.com")
else:
    print(f"Blocked by policy: {result.reason}")
```

## LangChain in 3 Lines

```python
from agentbouncr import AgentBouncr
from agentbouncr.langchain import AgentBouncrCallbackHandler

client = AgentBouncr(api_key="sk_live_your_key_here")
handler = AgentBouncrCallbackHandler(client, agent_id="my-research-agent")

executor = AgentExecutor(agent=agent, tools=tools)
executor.invoke({"input": "Find the latest AI news"}, config={"callbacks": [handler]})
```

Every tool call now passes through AgentBouncr first. Denied calls raise `GovernanceDeniedError`.

> **Important — pass callbacks at invoke time, not in the constructor.**
> In LangChain 0.3.x, passing `callbacks=[handler]` to `AgentExecutor(...)`
> attaches the handler to the executor but does **not** reliably propagate
> it to the inner tool runs. The `on_tool_start` hook then never fires and
> governance is silently bypassed. Always pass callbacks via the per-call
> `config={"callbacks": [handler]}` argument to `.invoke()` / `.stream()` /
> `.ainvoke()` — this is the supported path and the one we test against.

LangGraph works the same way:

```python
app = create_react_agent(llm, tools)
app.invoke({"messages": [...]}, config={"callbacks": [handler]})
```

### Coverage

The handler intercepts standard LangChain/LangGraph **tool runs** via
`on_tool_start`. That covers the patterns used by `create_react_agent`,
`AgentExecutor` with `Tool` / `StructuredTool` / `BaseTool` subclasses,
and native function-calling tool wrappers.

It does **not** intercept code paths that bypass the tool abstraction
— for example a raw `Runnable` chain that calls an external API
directly, or a custom node in a LangGraph that invokes an HTTP client
without wrapping it as a tool. For those, call `client.evaluate(...)`
yourself before the side effect.

## Authentication

Get an API key from your [AgentBouncr Dashboard](https://agentbouncr.com/dashboard) under **Settings → API Keys**.

```python
client = AgentBouncr(api_key="sk_live_...")
```

For multi-workspace setups:

```python
client = AgentBouncr(
    api_key="sk_live_...",
    tenant_id="your-workspace-id",
)
```

## Configuration

```python
client = AgentBouncr(
    api_key="sk_live_...",
    base_url="https://agentbouncr.com",  # default
    timeout=5.0,                              # request timeout in seconds
    max_retries=3,                            # exponential backoff for 5xx/429
    tenant_id=None,                           # optional X-Tenant-Id header
)
```

## Error Handling

```python
from agentbouncr import (
    AgentBouncrError,        # base class
    AuthenticationError,     # 401
    ValidationError,         # 400
    RateLimitError,          # 429 after retries exhausted
    ServerError,             # 5xx after retries exhausted
    TimeoutError,            # request exceeded timeout
    GovernanceDeniedError,   # raised by LangChain handler when policy denies
)
```

## Links

- **API Documentation:** https://agentbouncr.com/api/docs
- **Dashboard:** https://agentbouncr.com/dashboard
- **Quickstart Guide:** [docs/quickstart.md](docs/quickstart.md)
- **TypeScript SDK:** [`agentbouncr` on npm](https://www.npmjs.com/package/agentbouncr)

## License

MIT — see [LICENSE](LICENSE).

The AgentBouncr backend is commercial software. The SDK is open source so you can audit, patch, and integrate freely.
