Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

README.md

Witnora Python SDK

The published package remains agentcert-sdk-python for compatibility. New code should use the Witnora class names; existing AgentCert imports remain supported.

import os
from agentcert_sdk import WitnoraClient

witnora = WitnoraClient(
    base_url=os.environ.get(
        "WITNORA_BASE_URL", os.environ.get("AGENTCERT_BASE_URL", "https://witnora.com")
    ),
    project_id=os.environ.get("WITNORA_PROJECT_ID") or os.environ["AGENTCERT_PROJECT_ID"],
    api_key=os.environ.get("WITNORA_API_KEY") or os.environ["AGENTCERT_API_KEY"],
)

decision = witnora.assess_action(
    externalId="purchase-order-4850",
    principal={"id": "procurement-agent", "type": "agent"},
    actionType="SUBMIT",
    targetSystem="MockERP",
    requestedPermissions=["MockERP:SUBMIT"],
    amount=4850,
    currency="USD",
    expectedState={"status": "SUBMITTED"},
)

The client uses only the Python standard library at runtime. It cannot register identities, grant permissions, or approve runtime actions. An owner or admin configures those controls in the Witnora workspace first.

Framework adapters

Adapters emit agentcert.envelope.v0.1 without adding framework dependencies to this package:

from agentcert_sdk.adapters import WitnoraTracingProcessor, BrowserUseAdapter, LangGraphAdapter

# LangGraph: inside `async for event in graph.astream_events(..., version="v2")`
LangGraphAdapter(witnora, agent_id="research-agent", run_id="run-42").record(event)

# OpenAI Agents SDK
processor = WitnoraTracingProcessor(witnora, agent_id="support-agent", run_id="run-43")
# add_trace_processor(processor)

# browser-use
on_step_start, on_step_end = BrowserUseAdapter(
    witnora, agent_id="browser-agent", run_id="run-44"
).hooks()
# Agent(..., register_new_step_callback=on_step_end)

See docs/universal-envelope.md for the field contract and trust boundaries.

Assurance observability

Use RunRecorder when a framework adapter is unnecessary:

from agentcert_sdk import WitnoraRunRecorder

recorder = WitnoraRunRecorder.start(
    witnora,
    {
        "externalId": "release-42",
        "kind": "release_gate",
    },
)
recorder.record_event(
    "onegent.outcome.verification",
    payload={"expected": "SUBMITTED", "observed": "SUBMITTED", "success": True},
)
recorder.complete(status="passed")

The recorder allocates an ordered sequence and trace-linked spans, sends bounded batches, and keeps a failed batch pending for an explicit retry. It is a thin assurance collector, not a general OpenTelemetry backend.

Universal tool semantics

from agentcert_sdk import instrument_async_tool

query = instrument_async_tool(
    recorder,
    {"schemaVersion": "agentcert.capability_manifest.v0.1", "id": "data.query"},
    database_sandbox.query,
    tool_name="sql_query",
)

The wrapper links started/completed/failed phases with one invocation ID and uploads only redacted descriptors. See docs/universal-agent-semantics.md.