The SDK

A governed agent in 10 lines.

cendor-sdk is a governed, provider-agnostic agent SDK. Cost budgets, a deterministicguardrails gate, tamper-evident audit, PII redaction, and record/replay testing are the foundation, not plugins — so the same ten lines run in production and in an offline test. In Python and TypeScript.

governed_agent.py
from cendor.sdk import Agent, tool, run, budget, guard, rules, Policy, AuditLog

@tool
def get_weather(city: str) -> str:
    "Current weather for a city."
    return f"Sunny in {city}"

agent = Agent(name="assistant", model="gpt-4o", tools=[get_weather],
              guardrails=[rules.keyword_deny(["ignore previous instructions"])])
log = AuditLog(system="support", path="audit.jsonl")

# budget caps pre-flight; the Gate blocks for $0; guard() redacts PII pre-send
with budget(usd=0.25, on_exceed="block"), guard(Policy.default(), audit=log):
    result = run(agent, "What's the weather in Paris?", audit=log)

print(result.output, result.cost)   # governed, gated, audited, replayable

Drop the budget/guard context and it's a plain agent on cendor-core alone — governance is opt-in, never a rewrite.

Watch · start here

The governed loop, running.

The story, the real ten-line agent running, and the seven-library map — the anchor for the SDK sub-series.

cendor-sdk: start governed
cendor-sdk: start governed
Why it's different

Governance is the foundation.

Other SDKs bolt observability on afterward. Here, every run is budgeted, gated, audited, and replayable by construction — built on the same seven libraries you can drop down to at any time. The cards below compose the six governance tools into the loop; squeeze engages automatically and core is the seam every call rides. Every chip is a link — drop into any library.

Budgets tokenguard

Pre-flight caps block or downgrade an over-budget call before a token is spent; per-feature / per-user cost attribution for free.

Guardrails gate guardrails

Agent(guardrails=[…]) gates four stages — input, tool call, tool result, output — and blocks, redacts, or flags. Deterministic rules run in microseconds for $0; opt-in detection tiers reach up to LLM judges and hosted rails, and a per-run override swaps rules per request.

PII redaction acttrace

guard() scans and redacts before send (or blocks) via a policy — detected secrets and PII are stripped before the request leaves your process, and the refusal is auditable.

Tamper-evident audit acttrace

Every call, tool, and decision — gate verdicts included — lands on a hash-chained log that verifies offline; one edited byte fails. Evidence to support compliance, not a guarantee.

Record / replay cassette

Capture a whole run once, replay it offline forever — deterministic evals over cassettes, no API key, no flakiness.

Context control contextkit squeeze

Agent(context_budget=…) assembles history to a token budget on every turn — oversized blocks compressed reversibly via squeeze (no direct call — it auto-wires when installed), with an honest receipt of what was kept or dropped.

Watch · the two-layer story

The seven libraries, inbuilt.

The loop on top, the full SDK-symbol → library map underneath — the SDK adds the loop, not the governance.

cendor-sdk — seven libraries, inbuilt
cendor-sdk — seven libraries, inbuilt
One run, end to end

What run() actually does.

Every step below happens on a single run(agent, input) — no per-call wiring. The same loop runs sync, async, and streaming.

  1. Input gate

    guardrails checks the user turn first — a block raises before any spend; a redact rewrites what the model will see.

  2. Assemble

    contextkit packs history into the token budget; squeeze compresses oversized blocks, reversibly.

  3. Pre-flight

    tokenguard projects the cost and blocks or downgrades over-cap calls; acttrace's guard() redacts secrets & PII before send.

  4. The call core

    Every provider call rides core's instrument() seam onto the event bus — one canonical shape, ten providers.

  5. Tool gates

    Each tool call and tool result passes the gate too — a blocked tool returns [blocked by …] to the model and the loop continues.

  6. Output gate

    The final answer is gated before you see it. On a block, opt into a bounded re-ask or buffered streaming checks (Python today — parity).

  7. Evidence

    Calls, tools, costs, and every gate decision land on the tamper-evident chain — and the whole run replays offline via cassette.

The receipt

Every run leaves evidence.

One governed run writes one hash-chained log — every entry correlated by a single trace id, verifiable offline, forever.

verify() offline

Re-walks the chain with no network and no key — one edited byte fails at the exact entry.

Refusals are entries too

A gate trip lands as a guardrail_decision; with a policy file, the decision records which policy was active (its hash and version).

Evidence packs

log.export(…, framework=…) maps entries to EU AI Act, ISO 42001, GDPR, or NIST AI RMF controls — evidence to support compliance, never a guarantee.

The agent surface

Everything an agent SDK needs.

Agent loop

Sync + async, streaming, bounded max_turns; steps harvested into Result.steps.

Native tools

@tool derives a JSON Schema from type hints (Optional/Union/Literal/nested Pydantic).

Handoff

Cross-provider handoff carries canonical history; supervisor() routing, segment-bound.

Memory & state

Session, SQLite store, summarizing memory, crash-resume checkpointing.

Structured output

dataclass / Pydantic / JSON-schema output_type with provider-native modes.

Interop

MCP client — call any external MCP server's tools from your agent; A2A server; M365 / Foundry adapter; post-hoc OTel gen_ai.* span trees — see the whole run journey live in Cendor Monitor.

Model-agnostic

One canonical message shape. Ten providers.

The provider is inferred from the model id (or forced). Provider extras stay optional — pip install "cendor-sdk[openai,anthropic]".

OpenAI (Chat Completions)OpenAI (Responses)AnthropicGoogle GeminiAWS BedrockOllamaHugging FaceMicrosoft Foundry (Chat)Microsoft Foundry (Responses)Foundry Local

…and beyond providers:

MCP tool clientA2A serverM365 Agents / Foundry adapterOpenTelemetry gen_ai spansCheckpoint / resume
Live docs · MCP

Point your assistant at the SDK docs.

Agent-mode assistants (Claude Code, Cursor, Copilot, Windsurf) can call the Cendor MCP server to look up the exact Agent / run / guardrails call-shape live — e.g. get_page("sdk/agents") — instead of guessing. Read-only, pull-based: your code never leaves your machine. Set it up →

remote https://mcp.cendor.ai
$ npx @cendor/mcp
$ uvx cendor-mcp
Go deeper

One video per capability.

The SDK sub-series — the loop, memory & retrieval, multi-agent, providers & interop, and production-readiness. Each one story-first, then the real code.

cendor-sdk — the loop
cendor-sdk — the loop
cendor-sdk — memory & retrieval
cendor-sdk — memory & retrieval
cendor-sdk — multi-agent
cendor-sdk — multi-agent
cendor-sdk — providers & interop
cendor-sdk — providers & interop
cendor-sdk — production-ready
cendor-sdk — production-ready
Get started

Start governed.

$ pip install "cendor-sdk[openai,anthropic]"
$ npm i @cendor/sdk openai

Bring one env var: OPENAI_API_KEY (or your provider's) — or pass api_key= / a pre-built client. The SDK builds the client for you; there's no Cendor key. Keys & providers →

Fastest: npx @cendor/init / uvx cendor-init detects the SDK and writes your AI-assistant rules files — offline, no key.

Pulls the seven governance libraries as hard deps. Already have a framework? Use the libraries beneath it instead.