Skip to main content

sakshi-sdk

Register your AI agents and witness their decisions. Python SDK for the Sakshi governance platform.

pip install sakshi-sdk   # imports as `sakshi`
from sakshi import SakshiClient

sakshi = SakshiClient("https://console.example.bank", api_key="...")

agent_id = sakshi.register(
    "loan-decision-agent",
    owner_name="Priya Sharma",
    owner_email="priya@example.bank",
    autonomy_tier="L2",
    blast_radius={"customer_facing": True, "spend_limit_inr": 500_000},
)

with sakshi.witness(
    agent_id,
    context={"application_id": "4471", "retrieved": chunks},
    model={"provider": "openai", "model": "gpt-5.2", "version": "2026-05"},
    client_ref="app-4471",  # idempotency key
) as w:
    w.step("plan", goal="assess repayment capacity")
    w.tool("bureau_pull", output=bureau_response)
    w.human("async_review", "arun@example.bank", verdict="approved")
    w.action(decision="approve", limit_inr=200_000)

Middlewares (all duck-typed — the SDK carries zero provider or framework dependencies):

from sakshi.middleware import watch_openai_compatible, witness_node, watch_langgraph, watch_mcp

llm = watch_openai_compatible(openai_client)   # also: watch_anthropic,
                                               # watch_gemini, watch_bedrock

# LangGraph (or any graph framework): per-node + per-run evidence
graph_builder.add_node("assess", witness_node(assess))
app = watch_langgraph(graph_builder.compile(), name="loan-flow")
# MCP (Model Context Protocol): witness tool calls + detect
# tool-manifest poisoning (OWASP MCP Top 10)
session = watch_mcp(mcp_client_session, server="tools.example")

# Google ADK (Agent Development Kit): one plugin witnesses every model
# and tool call in the agent tree, and can enforce in the tool path
from sakshi.middleware import SakshiAdkPlugin
runner = Runner(agent=root_agent, ...,
                plugins=[SakshiAdkPlugin(client, "loan-decision-agent", enforce=True)])

Inside an active witness block, every LLM call becomes an llm_call step with latency, token usage, and the served model identity (RBI draft para 56), and every graph node becomes a graph_node step with the state keys it updated. Works unchanged with self-hosted Ollama/vLLM via the OpenAI-compatible client. No active session — calls pass through untouched.

Regulatory helpers (RBI draft MRM 59(ii)-(iii), SEBI CP-P2):

with sakshi.witness(agent_id) as w:
    w.disclosure(channel="app", method="banner")   # told the customer it's AI
    ...

# customer asked for a human — synchronous, raises on failure
sakshi.request_human_handoff(agent_id, client_ref="app-4471",
                             reason="customer requested a human")

disclosure() records an ai_disclosure touchpoint (coverage becomes measurable evidence); request_human_handoff() parks a review item in the agent's team queue. A lost handoff is a compliance failure, so it never buffers or drops.

Delivery & retry semantics (v0.2):

  • register() is idempotent by name — rerunning your startup script returns the existing agent, never a duplicate.
  • witness() capture retries with jittered exponential backoff and is idempotent by client_ref — retries can never double-record.
  • enforce() never auto-retries: an evaluation is evidence and a routed action must not be double-enqueued. Unreachable platform raises SakshiEnforcementUnavailable (fail-closed) — your code decides.

Properties you can rely on:

  • Fail-open by default — if the platform is unreachable, your agent keeps running; records are buffered, retried, and dropped with a warning as the last resort. Governance must never take production down. Use fail_open=False for synchronous capture that raises.
  • Failures are evidence — an exception inside a witness block is captured as the decision outcome and re-raised.
  • PII-safe by design — Aadhaar/PAN/mobile and other Indian identifiers are detected and tokenized server-side at ingest, before storage or hashing.
  • register() is always synchronous: an unregistered agent should not run (RBI draft MRM guidance, para 21).

Call sakshi.flush() before shutdown in batch jobs; long-running services can rely on the atexit hook.

Download files

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

Source Distribution

sakshi_sdk-0.5.0.tar.gz (29.5 kB view details)

Uploaded Source

Built Distribution

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

sakshi_sdk-0.5.0-py3-none-any.whl (27.7 kB view details)

Uploaded Python 3

File details

Details for the file sakshi_sdk-0.5.0.tar.gz.

File metadata

  • Download URL: sakshi_sdk-0.5.0.tar.gz
  • Upload date:
  • Size: 29.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for sakshi_sdk-0.5.0.tar.gz
Algorithm Hash digest
SHA256 4c5040a2552a28126e99abd2c996e9492174d4afdc4d710b35f49679ab936324
MD5 0925566d6001991014e06efd59a6e61a
BLAKE2b-256 de55b736656c425dcd41d91b5e42e3d26e453bfe3f45eb30c7f2c9717e8ae208

See more details on using hashes here.

File details

Details for the file sakshi_sdk-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: sakshi_sdk-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 27.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for sakshi_sdk-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 86553a22df799f026da3547de3c22fe6fd234576ba04b0f98177f049e8191e81
MD5 e44ad56e4cf55dda3cbb04dfd9b2245f
BLAKE2b-256 4d7b90cdf19cd667a23616a71787fed767172a7602d97477e07c1efb7aa1b883

See more details on using hashes here.

Release history Release notifications | RSS feed

0.6.0

2 files

This release

0.5.0 This release

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

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