Skip to main content

Tenet — runtime authority for AI agents. Gate every tool call through cost caps, approval gates, and a tamper-evident audit log.

Project description

Marchward — 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 Marchward SDK — the wedge persona builds on LangGraph / LangChain (both Python). Zero runtime dependencies (stdlib only).

Install

pip install tenet-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 Marchward ({d.outcome.value})."
    # ... real delete here ...
    return "deleted"

How it works (Model B)

You send a logical tool call — service + tool_name + arguments. Marchward 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 (for wait=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


Download files

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

Source Distribution

marchward-0.1.0.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

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

marchward-0.1.0-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

Details for the file marchward-0.1.0.tar.gz.

File metadata

  • Download URL: marchward-0.1.0.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for marchward-0.1.0.tar.gz
Algorithm Hash digest
SHA256 646d1c61c7ce0f441dcae1a348dfa0d49f28ca99e8abeedff45148889851415a
MD5 1497af4df3a8b2de67747d81157298f9
BLAKE2b-256 fc8537cfd5b8493253b83c827a251fcc4d9e6dc03a017ca05c085fa56ffb72be

See more details on using hashes here.

File details

Details for the file marchward-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: marchward-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for marchward-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5358d630e3b560c4e8218995aebc0228a6f68d7315dd287d3b052a60edd9d566
MD5 741bf8acb35cadc86e0ff07a6ef37d9c
BLAKE2b-256 40dc0f6ec793ab7de7351f0983588f3ae911009ecc01616902053426fa3a13bd

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