First-party Python SDK for Tracengent: instrument and govern agents (events, decision traces, authorization, tool governance, delegation).
Project description
Tracengent — Python SDK
First-party Python SDK for Tracengent: instrument and
govern agents written in Python with parity to the .NET SDK (src/Tracengent.Sdk).
Status: feature-complete (Phase 10). Full parity with the .NET SDK across telemetry, traces, authorization, tool governance, and delegation. The reference implementation is the .NET SDK; the contract is §3 of the phase doc.
Milestone status
| Milestone | Capability | State |
|---|---|---|
| M1 | Options + validation, JWT/permission helpers, JSON redactor (pure logic) | ✅ done |
| M2 | Event model, token provider, background dispatcher, record |
✅ done |
| M3 | Decision traces + auto-tracking + ambient context + authorize/ensure_authorized |
✅ done |
| M4 | has_permission (token-local) + framework bindings (FastAPI/Flask) |
✅ done |
| M5 | Tool governance: egress gate, MCP/function gate, redaction | ✅ done |
| M6 | Delegation: delegated session + attenuation (A2A) | ✅ done |
| M7 | Packaging + sample + conformance + (gated) integration tests | ✅ done |
Tests: 152 unit + 7 conformance, 3 gated integration tests (pytest -m integration). The
conformance suite replays the shared wire_contract.json
fixture and asserts the SDK's request shapes match the contract byte-for-byte (modulo volatile
ids/timestamps) — this same fixture is vendored into every Tracengent SDK. A runnable end-to-end
example lives in samples/demo_agent.py.
What works today (M1–M3)
from tracengent import TracengentClient, TracengentOptions, LlmCallResult, Money
opts = TracengentOptions.from_env(agent_id="travel-agent")
with TracengentClient(opts) as client:
# Open a decision trace — groups steps, tool calls and actions into one timeline.
with client.begin_trace("book a trip to Lisbon", actor_user_id="u_123") as trace:
trace.step("decided to search flights")
# Wrap tool calls / actions — timed and recorded automatically.
flights = trace.track_tool_call("search-flights", lambda: search(...))
# Govern an LLM call: reserve token budget before, reconcile actual usage after.
answer = trace.track_llm_call(
"summarize",
lambda: LlmCallResult(value=call_model(...), tokens=900, model="gpt"),
estimated_tokens=1000,
)
# Imperative authorization for a sensitive action (raises if denied).
# Send the spend's currency too — the platform converts it into the policy/budget
# currency before enforcing limits, so a USD charge is checked against a EUR cap.
client.ensure_authorized("payments:refund", {"amount": 280, "currency": "USD"})
trace.track_action("refund", lambda: do_refund(...), cost=Money.eur(280))
# leaving the trace flushes its completion; leaving the client flushes remaining events.
Outbound HTTP can be auto-recorded as tool_call events by routing it through a tracked client:
from tracengent import tracked_client
http = tracked_client(client, base_url="https://api.example.com")
http.get("/things") # recorded as a tool_call, attached to the active trace
Declarative gating for web-hosted agents (the equivalent of .NET's [RequireAgentPermission]):
from fastapi import FastAPI, Depends
from tracengent.integrations.fastapi import install_tracengent, require_agent_permission
app = FastAPI()
install_tracengent(app, client)
@app.post("/refunds", dependencies=[Depends(require_agent_permission("payments:refund"))])
def refund(): ... # 403s automatically when the agent lacks the permission
A Flask decorator (tracengent.integrations.flask) and a token-local coarse check
(client.has_permission("flights:book"), no round-trip) are also available.
Tool governance (Phase 8). Govern outbound tool calls the org doesn't own — block, hold for approval, or redact before the request leaves:
from tracengent import governed_client
# Every request through this client is authorized via /v1/tool-authorize first.
tools = governed_client(client, base_url="https://api.stripe.com")
tools.post("/v1/refunds", json={"amount": 280, "card": "4242"})
# -> denied/held → raises; allowed → forwarded with any redactions applied.
# Non-HTTP tools (MCP tools/call, LLM function calls):
client.tools.guard_function("transfer_funds", {"to": "...", "amount": 50}, invoke=do_transfer)
Delegation / agent-to-agent (Phase 5). Act under a delegated token and attenuate authority for a downstream agent:
session = client.begin_delegated_task(delegated_token) # token granted out of band
session.authorize("flights:book", {"amount": 280}) # intersects base policy with the grant
# Mint a narrower child token to hand to another agent for an A2A hop:
child = session.attenuate_for_call("agt_hotel", ["hotels:book"], max_amount=500)
Pure helpers are also exported directly:
from tracengent import permission_matches, Redaction, apply_redactions
permission_matches("flights:*", "flights:book") # True
apply_redactions('{"amount":100,"card":"4242"}', [Redaction("$.card", "mask")])
# -> '{"amount":100,"card":"***REDACTED***"}'
Requirements
- Python 3.10+
httpx(HTTP transport)
Development
cd sdk/python
pip install -e ".[dev]"
pytest -q # unit tests
ruff check . # lint
mypy # type-check
CI runs lint + type-check + tests on every push (see .github/workflows/ci.yml, job sdk-python).
Environment variables
| Var | Meaning |
|---|---|
TRACENGENT_URL |
Base URL of the Tracengent API |
TRACENGENT_CLIENT_ID |
Agent OAuth client id (key_...) — preferred |
TRACENGENT_CLIENT_SECRET |
Agent OAuth client secret (ags_...) |
TRACENGENT_INGEST_KEY |
Legacy org ingest key (agk_...) — fallback |
TRACENGENT_AGENT_ID |
Logical agent key reported with events |
TRACENGENT_ENVIRONMENT |
Environment tag (default production) |
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 tracengent-0.1.0.tar.gz.
File metadata
- Download URL: tracengent-0.1.0.tar.gz
- Upload date:
- Size: 39.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c50bdaf0355d38ff437b1b280e195d47b92df22b49d9096d8ae7db6bafb126b
|
|
| MD5 |
ef31d0f1e6dca12a95c10761553d4342
|
|
| BLAKE2b-256 |
3a6d23b028804bd18e0c4f07d83b2938b3dd532a1dfcf7969d8956843462b61f
|
File details
Details for the file tracengent-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tracengent-0.1.0-py3-none-any.whl
- Upload date:
- Size: 36.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dabe1a939488a1d88ae56a8417777802e9faaa827636b6266b9aad985992d94e
|
|
| MD5 |
4f8708b71f84622339b890271a73b4cb
|
|
| BLAKE2b-256 |
99357329b79e71e93be64562220c5304172713cfcff8586812f994e8ab79135e
|