zanii-blackbox
The Python SDK for Zanii Blackbox, the flight recorder for AI agents.
Blackbox records every model call and tool call your agent makes, from a gateway that runs outside the agent's process. The records are hash-chained, so an edit or a deletion shows, and anchored as receipts that anyone can verify offline. This SDK is optional. It adds what only the agent knows (steps, its own tools, its checks, the outcome) as a second, independent record, and it reads and verifies what the gateway recorded.
pip install zanii-blackbox
# or
uv add zanii-blackbox
Python 3.11 or later. Fully typed.
Before you start
You need a running Blackbox gateway, self-hosted with Docker, Kubernetes or from source. A hosted UAE region is planned; write to info@zanii.agency for early access. The gateway holds your provider keys. Your agent gets a session token instead, and its model calls go through the gateway:
export BLACKBOX_URL=https://blackbox.example.com
export BLACKBOX_ADMIN_KEY=... # or a tenant key (bbxt_...)
Record a run
import os
import anthropic
from zanii_blackbox import session
url = os.environ["BLACKBOX_URL"]
with session(
url=url,
admin_key=os.environ["BLACKBOX_ADMIN_KEY"],
label="refund-agent",
budget_usd="2.00",
flight_plan={
"objective": "Process today's refund queue",
"expected_tools": ["lookup_order", "issue_refund"],
},
) as s:
# Model calls go through the gateway with the session's token, never your provider key.
client = anthropic.Anthropic(base_url=f"{url}/anthropic", api_key=s.token)
s.step("load queue")
s.tool_call("lookup_order", {"order": 8812})
s.tool_result("lookup_order", {"ok": True})
s.verify("amount-matches-invoice", True) # your own check, recorded as evidence
# A risky tool waits for a person, who sees the arguments in the cockpit.
answer = s.request_approval(
"issue_refund",
reason="Damaged on delivery",
args={"order": 8812, "amount_aed": "1250.00"},
)
if answer == "approved":
... # issue the refund
s.close("success")
answer is only "approved" when a person approved it. "rejected", "timeout" and "error" all mean don't run the tool.
With asyncio, use s = await asession(...) and async with. The calls that wait on the gateway have async versions: aflush, astate, arequest_approval and aclose.
What the SDK guarantees
- It never raises into your agent. If the gateway is down, the session keeps recording to disk and reports the problem in
s.stats.last_error. - It loses nothing it accepted. Every event is written to a local spool before it is sent, numbered without gaps, and resent until the gateway confirms it. After a crash,
blackbox drainsends what's left. - It stays out of the way. Recording is non-blocking with bounded memory. A recorded call costs about 0.4 ms (measured over 20,000 calls on a laptop); shipping happens in the background.
- It has one runtime dependency: the Zanii core library.
Frameworks
| Framework | Use |
|---|---|
| LangChain / LangGraph | BlackboxCallbackHandler(s), BlackboxAgentMiddleware, BlackboxCheckpointSaver (from zanii_blackbox.hooks.langgraph_checkpoint), and blackbox_hitl for human-in-the-loop |
| OpenAI Agents SDK | Runner.run(agent, ..., hooks=BlackboxRunHooks(s)) |
| Claude Agent SDK | BlackboxAgentHooks(s) |
| CrewAI | attach_crewai(s) |
| Pydantic AI | record_pydantic_ai(result, s) |
| Provider clients | wrap_anthropic, wrap_openai, wrap_gemini, wrap_bedrock link each call to the gateway's record |
The framework integrations are imported lazily, so installing this package doesn't pull any of them in.
Command line
The package installs a blackbox command:
blackbox sessions # the newest sessions, and whether each record verifies
blackbox tail ses_... # follow a session live
blackbox export ses_... --out run.json
blackbox verify run.json # verify an audit bundle offline, anywhere
blackbox reconcile ... # check an agent's own logs against the gateway's record
blackbox mcp-wrap --server files -- python server.py # record a local stdio MCP server
blackbox drain # send spooled events left by a stopped agent
Verify a record offline
from zanii_blackbox import verify_bundle
An audit bundle carries the events, the chain and the anchors. Checking it needs no account and no network, so an auditor or a regulator can check it independently.
Also in TypeScript
@zanii/blackbox has the same API in camelCase. Both SDKs must produce the same output on the same shared test vectors.
Support
- Website: zanii.agency
- Email: info@zanii.agency
- Security reports: info@zanii.agency, privately, not in a public issue
Licensed under Apache-2.0.
Metadata
Release files for zanii-blackbox 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| zanii_blackbox-0.1.0.tar.gz | 146.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| zanii_blackbox-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 329.3 kB
Release files / zanii_blackbox-0.1.0.tar.gz
| Download URL | zanii_blackbox-0.1.0.tar.gz |
|---|---|
| Size | 146.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2b4051917bdb74cc98a840356e8ea82f91d242dc36ff67734ecc6a66ae47fe5e
|
|
BLAKE2b-256 checksum How to use checksums |
cf6680cb2bd6599c6982f0ccccdc3b6c7fdd472b7e6dd03d2a28c6ebce91dec5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / zanii_blackbox-0.1.0-py3-none-any.whl
| Download URL | zanii_blackbox-0.1.0-py3-none-any.whl |
|---|---|
| Size | 183.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f1c43bb9dba39effabec6da8eb980a1c0c615d4387812f28353b0222bdc799b7
|
|
BLAKE2b-256 checksum How to use checksums |
42a158fce4b85eef0533a27683bb5013fa14fe840d707f70cd614876dba8ec9b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|