Skip to main content
The full public surface of the sakshi package. Everything here is importable directly:

Installation

The distribution is sakshi-sdk; the import is sakshi. Install the latest version from PyPI. Python 3.9 or newer. The only runtime dependency is httpx.

Client

base_url
str
required
Your Sakshi deployment. Sakshi is single-tenant, so this is your own instance (or https://demo.rotavision.com for the public demo).
api_key
str | None
default:"None"
An ingest key or governance token, sent as a bearer token. Mint one in the console under Admin, or see Authentication.
fail_open
bool
default:"True"
Decision capture mode. When True (default), captured records go onto a background queue and are delivered by a worker thread; if the platform is unreachable they are dropped with a warning so the host agent is never blocked. Set False for synchronous capture that raises on delivery failure, for batch jobs where losing evidence is worse than stopping. Note that enforce always fails closed regardless of this setting.
http_client
httpx.Client | None
default:"None"
Supply your own configured httpx.Client (custom transport, proxy, mTLS, timeouts). When supplied, Sakshi does not own it and will not close it. When omitted, Sakshi builds one against base_url with a 10s timeout.
max_retries
int
default:"3"
Attempts per captured record before it is dropped (fail-open) or raised (fail-closed), with jittered exponential backoff so a fleet of agents does not hammer a recovering platform in lockstep.
queue_size
int
default:"10000"
Bound on the in-memory capture queue. When it is full, the newest record is dropped with a warning rather than blocking the agent.
kill_poll_interval
float
default:"5.0"
Seconds between background polls of each agent’s kill-switch status. A halt stops the agent within one interval, even between evaluations. The poller is created lazily the first time you call enforce for an agent.
Capture is fail-open by default. Records can be silently dropped when the platform is unreachable. For evidence you cannot afford to lose, use fail_open=False, and call flush before the process exits.

register

Register an agent and get its id back. Always synchronous: an agent must not run unregistered. Idempotent by name, so it is safe to call on every startup.
name
str
required
Human-readable agent name. The idempotency key: a second call with the same name returns the existing agent instead of creating a duplicate.
owner_name
str
required
Accountable owner’s name.
owner_email
str
required
Accountable owner’s email.
autonomy_tier
str
default:"L0"
The agent’s autonomy tier (for example L0, L1).
blast_radius
dict | None
default:"None"
Structured description of what the agent can affect. Feeds the response-ladder default when a kill switch or safe mode is armed.
description
str | None
default:"None"
org_unit
str | None
default:"None"
Organizational unit the agent belongs to. Scopes review queues and org-unit enforcement on captured records.
returns
str
The agent id. Use it for every subsequent witness and enforce call.

witness

Open a witness session as a context manager. Record the steps as they happen; the decision record is written to the chain when the block exits. An exception raised inside the block is captured as the outcome and re-raised, because failures are evidence too.
agent_id
str
required
The id returned by register.
context
dict | None
default:"None"
Decision context. Identifiers you place here are tokenized at ingest, so raw PII never lands on the chain.
model
dict | None
default:"None"
Model identity for the decision (provider, name, version). Middlewares fill this in automatically from the provider’s response (RBI draft MRM para 56); a value you set is not overwritten.
policy_state
dict | None
default:"None"
Policy inputs known at the start of the decision. Refine mid-decision with decision.policy(...).
client_ref
str | None
default:"None"
Your correlation reference (for example an application id). Used for idempotent retries and for search in the console.
returns
WitnessSession
A context manager. The record is submitted on __exit__.

WitnessSession methods

Call these on the object bound in the with block to build the decision chain.
step(name, **data)
method
Append a generic step to the decision chain. name is a short verb (retrieve, assess); **data is arbitrary evidence for that step.
tool(name, output, **data)
method
Record a tool invocation: the tool name, its output, and any extra **data. Recorded as a tool step.
human(kind, who, **data)
method
Record a human touchpoint: the kind of involvement, who was involved, and any extra **data.
disclosure(channel='chat', method='banner', **data)
method
Record that the customer was told they are interacting with AI (RBI draft MRM 59(ii)). Lands an ai_disclosure touchpoint. The touchpoint is the evidence: coverage is measurable, assertion is not.
extraction(document_type, extracted, *, authorized=None, purpose=None, confidence=None, storage=None)
method
Record a document-extraction act. extracted and authorized are PII category names (aadhaar, pan, name, address), never values. When authorized is given, over-extraction (categories pulled beyond the authorized purpose) is computed for you. storage is the disposition of the raw value the agent produced, for example {"vault_ref": "V-8821", "residency": "IN", "retained_raw": False}. Sakshi evidences where it went; it never holds it.
access(reference_key, purpose, *, authorized_purposes=None, accessor=None)
method
Record a read of a stored, reference-keyed value. reference_key is the vault token, never the value. When authorized_purposes is given, an off-purpose read is flagged (DPDP purpose limitation on access). Sakshi witnesses that the read happened and whether it was on-purpose; it never detokenizes the value.
policy(**data)
method
Merge facts into policy state that are only known mid-decision, such as which routing outcome the policy engine actually chose.
action(**data)
method
Set the decision’s final action (outcome, amount, mode). If the block raises and no action was set, the outcome is recorded as error with the exception.
model_identity(**data)
method
Fill or refine the decision’s model identity. Middlewares call this with the provider-reported model and version; a key already set is not overwritten.

enforce

Route an intended action through the agent’s autonomy envelope before it runs. Enforcement fails closed: an unreachable platform raises rather than letting an ungoverned action through. The kill switch is consulted from the local poller cache first, then re-checked server-side inside the evaluation.
agent_id
str
required
action
str
required
Short verb for the intended action, for example approve_loan or transfer_funds.
stakes
float | None
default:"None"
Magnitude of the action (for example an amount in INR). Signals are non-negative and unbounded; they are not confined to 0..1.
confidence
float | None
default:"None"
The agent’s confidence, 0..1.
novelty
float | None
default:"None"
How novel the situation is, 0..1.
client_ref
str | None
default:"None"
Your correlation reference for the evaluation.
raise_on_hold
bool
default:"True"
When True (default), a block outcome raises SakshiBlocked and a sync_review outcome raises SakshiSyncReviewRequired. Set False to get the EnforcementDecision back for every outcome and branch on it yourself.

Outcomes

enforce returns an EnforcementDecision (a frozen dataclass):
outcome
str
One of auto, async_review, sync_review, block.
allowed
bool
Whether the agent may act now. True for auto and async_review (the latter allows the action with post-hoc review); False for sync_review and block.
matched_rule
str | None
The envelope rule that decided the outcome, if any.
envelope_version
int | None
The version of the autonomy envelope that was evaluated.
evaluation_id
str | None
Server-side id for this evaluation, for correlation and review lookup.
With raise_on_hold=False, branch on the decision directly:

Exceptions

SakshiBlocked
Exception
The platform refused the action: a kill switch is active, or a block-outcome rule matched. This must stop the host agent. Carries an optional .decision.
SakshiSyncReviewRequired
Exception
The action needs a human decision before it executes. The review queue item already exists server-side; the host agent must park the action. Carries .decision.
SakshiEnforcementUnavailable
Exception
The platform could not be reached for a decision. Unlike capture (fail-open), enforcement fails closed, so this is raised rather than defaulting to allow.
enforce is never retried automatically. A single evaluation either returns a decision or fails closed. Contrast with capture, which is buffered and retried.

request_human_handoff

The customer asked for a human (RBI draft MRM 59(iii)). Synchronous and raising: a lost handoff request is a compliance failure, so this never buffers or drops.
agent_id
str
required
client_ref
str | None
default:"None"
reason
str | None
default:"None"
returns
dict
The server response for the parked handoff (a handoff review-queue item).

flush and close

flush(timeout=10.0)
method
Block until every queued capture record has been delivered or dropped. Call it before a batch job exits, or before a short-lived process ends, to be sure buffered evidence has left the queue.
close()
method
Stop the kill-switch pollers, flush the capture queue, join the worker, and close the HTTP client if Sakshi owns it. When fail_open=True, close is registered with atexit, so it runs on normal interpreter shutdown; call it explicitly for deterministic cleanup.

Middlewares

If you would rather not hand-instrument every call, the SDK ships duck-typed middlewares that wrap the client you already use and record each model call on the active witness session, with the served model identity auto-filled. They carry no provider dependencies.
See Integrations for every middleware (watch_openai_compatible, watch_anthropic, watch_gemini, watch_bedrock, watch_langgraph, witness_node, watch_mcp) and worked examples. To govern agents over the Model Context Protocol, see MCP governance.

Quickstart

Register, witness, and verify the chain end to end.

Autonomy envelopes

How enforce routes actions to auto, review, or block.

Middlewares

One-line capture for OpenAI, Anthropic, Gemini, Bedrock, and LangGraph.

API reference

The endpoints the SDK calls, generated from the live spec.