Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tracengent-0.1.0.tar.gz (39.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tracengent-0.1.0-py3-none-any.whl (36.0 kB view details)

Uploaded Python 3

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

Hashes for tracengent-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8c50bdaf0355d38ff437b1b280e195d47b92df22b49d9096d8ae7db6bafb126b
MD5 ef31d0f1e6dca12a95c10761553d4342
BLAKE2b-256 3a6d23b028804bd18e0c4f07d83b2938b3dd532a1dfcf7969d8956843462b61f

See more details on using hashes here.

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

Hashes for tracengent-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dabe1a939488a1d88ae56a8417777802e9faaa827636b6266b9aad985992d94e
MD5 4f8708b71f84622339b890271a73b4cb
BLAKE2b-256 99357329b79e71e93be64562220c5304172713cfcff8586812f994e8ab79135e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page