Metadata-Version: 2.4
Name: sbo3l-langchain
Version: 1.2.0
Summary: LangChain Python tool wrapping SBO3L — gate every agent payment intent through SBO3L's policy boundary.
Project-URL: Homepage, https://sbo3l.dev
Project-URL: Repository, https://github.com/B2JK-Industry/SBO3L-ethglobal-openagents-2026
Author-email: Daniel Babjak <babjak_daniel@hotmail.com>
License: MIT
Keywords: agent,ai-agent,langchain,policy,sbo3l,tool
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security :: Cryptography
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: pydantic<3,>=2.6
Provides-Extra: dev
Requires-Dist: mypy<2,>=1.10; extra == 'dev'
Requires-Dist: pydantic<3,>=2.6; extra == 'dev'
Requires-Dist: pytest<9,>=8.0; extra == 'dev'
Requires-Dist: ruff<1,>=0.4; extra == 'dev'
Provides-Extra: langchain
Requires-Dist: langchain-core<1,>=0.2; extra == 'langchain'
Provides-Extra: sdk
Requires-Dist: sbo3l-sdk<2,>=1.0.0; extra == 'sdk'
Description-Content-Type: text/markdown

# `sbo3l-langchain`

LangChain Python tool wrapping SBO3L. Mirror of `@sbo3l/langchain` (TypeScript).

> ⚠ **DRAFT (T-1-2):** depends on F-10 (`sbo3l-sdk`) merging + publishing to PyPI.

## Install

```bash
pip install sbo3l-langchain sbo3l-sdk langchain-core
```

## Quick start

```python
from langchain_core.tools import StructuredTool
from sbo3l_sdk import SBO3LClientSync, bearer
from sbo3l_langchain import sbo3l_tool

client = SBO3LClientSync(
    "http://localhost:8730",
    auth=bearer("my-bearer-token"),
)
descriptor = sbo3l_tool(client=client)
tool = StructuredTool.from_function(
    func=descriptor.func,
    name=descriptor.name,
    description=descriptor.description,
)
# Pass `tool` into your LangChain agent's tool list.
```

## What it does

The agent emits a tool call with a JSON-stringified APRP. The tool forwards
to `client.submit()` and returns a JSON envelope:

```json
{
  "decision": "allow",
  "deny_code": null,
  "matched_rule_id": "allow-low-risk-x402",
  "execution_ref": "kh-...",
  "audit_event_id": "evt-...",
  "request_hash": "...",
  "policy_hash": "..."
}
```

On `deny`, the LLM sees `deny_code` (`policy.budget_exceeded`,
`policy.token_unsupported`, etc.) and can self-correct or escalate.

## Idempotency

```python
descriptor = sbo3l_tool(
    client=client,
    idempotency_key=lambda body: f"{body['task_id']}-{body['nonce']}",
)
```

## Async clients

This factory returns a sync callback. Use `SBO3LClientSync` (httpx.Client
under the hood — safe inside any event loop). If you must use the async
client, create your own async tool that awaits `client.submit(...)`.

## Errors

Transport / auth failures surface as a JSON envelope with `error` (RFC 7807
domain code, e.g. `auth.required`) and `status`.

## License

MIT
