Tenet — runtime authority for AI agents. Gate every tool call through cost caps, approval gates, and a tamper-evident audit log.
Project description
Tenet — Python SDK
Runtime authority for AI agents. Gate every tool call through a cost cap, approval gates on irreversible actions, and a tamper-evident audit log.
Python is the primary Tenet SDK — the wedge persona builds on LangGraph / LangChain (both Python). Zero runtime dependencies (stdlib only).
Install
pip install tenet-python # (once published)
# or, from this repo:
pip install -e packages/sdk-python
Quickstart
from tenet import TenetClient
tenet = TenetClient(api_key="tnt_...") # or set TENET_API_KEY
decision = tenet.execute(
service="github",
tool_name="github.repos.delete",
arguments={"owner": "acme", "repo": "old-experiment"},
context={"env": "production"},
)
if decision.allowed:
do_the_delete()
elif decision.escalated:
print(f"Paused for approval — review {decision.review_id}")
elif decision.blocked:
print(f"Blocked: {decision.reason_codes}")
With LangGraph (the persona's stack)
from langchain_core.tools import tool
from tenet import TenetClient
tenet = TenetClient()
@tool
def delete_repo(owner: str, repo: str) -> str:
"""Delete a GitHub repository."""
d = tenet.execute(service="github", tool_name="github.repos.delete",
arguments={"owner": owner, "repo": repo})
if not d.allowed:
return f"Refused by Tenet ({d.outcome.value})."
# ... real delete here ...
return "deleted"
How it works (Model B)
You send a logical tool call — service + tool_name + arguments. Tenet
resolves the real downstream HTTP request from its tool catalog, governs it,
injects your stored credential server-side, and executes it. Your agent holds
only TENET_API_KEY; it never touches downstream credentials. Connect those
once in the dashboard (Settings → Connected services).
API
TenetClient(api_key=None, *, api_url=None, default_agent_id="python-sdk", timeout=30.0, poll_timeout=120.0, poll_interval=0.75).execute(*, service, tool_name, arguments=None, context=None, agent_id=None, request_id=None, wait=True) -> Decision.get_job(job_id) -> dict— poll one async job manually (forwait=False).Decision:.allowed/.escalated/.blocked/.executed, plus.outcome,.decision_id,.review_id,.reason_codes,.http_status,.raw,.job_id,.execution,.execution_error.
Contract
| HTTP | Outcome | Meaning |
|---|---|---|
| 200/202 + jobId | ALLOW | authorized; downstream runs async — the SDK polls the job and fills .execution (set wait=False to poll yourself) |
| 202 + reviewId | ESCALATE | held for human approval; auto-executes on approve |
| 403 | BLOCK | refused by policy |
| 401 | — | TenetAuthError (bad/missing/revoked key) |
.executed is True only when an ALLOW actually ran its downstream — an
ALLOW with no connected credential, a failed downstream, or a still-pending
job is allowed-but-not-executed.
Risk classification
Risk is classified by the resolved HTTP method, not the tool name — any
DELETE (or a flagged destructive POST like stripe.charges.create) is
treated as irreversible and gated, regardless of what the tool is named. So a
custom-named destructive tool can't slip past the approval gate.
Tests
cd packages/sdk-python && python -m unittest discover -s tests
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tenet_python-0.1.0.tar.gz.
File metadata
- Download URL: tenet_python-0.1.0.tar.gz
- Upload date:
- Size: 11.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3feb16f988ec57205fce735f3b5a8b23ac868589d6f66cbb43629994cc1c9245
|
|
| MD5 |
02b50997cb75035d9889328845e71b4a
|
|
| BLAKE2b-256 |
0868daab6b12e5628374924d093903f24713c619cbd42a49011dda29e732c2af
|
File details
Details for the file tenet_python-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tenet_python-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
856aa2cb3d9e31bc3a631b588ed2ae0b96d550bbf430aaf7d4318c8eb06963d2
|
|
| MD5 |
e7f3376fc14c4c5417f200f4b1e7a59f
|
|
| BLAKE2b-256 |
437ed87b7fa6b60c4743864680cb9a1b267f74c2e93eed0a57dfbae73bdf9ae6
|