Getting started
Install the SDK, run one governed agent, and learn where each concept lives. Ten minutes, one API key (or none — the ungoverned example works offline with a recorded cassette).
1. Install
pip install "cendor-sdk[openai,anthropic]"
Provider SDKs are optional extras — [openai], [anthropic], [google], [bedrock],
[ollama], [huggingface], [azure], [foundry-local], plus [mcp], [otel], and [all].
The install bundles the whole Cendor stack by dependency; import only from cendor.sdk.
npm i @cendor/sdk openai
Provider SDKs are peer dependencies — add openai and/or @anthropic-ai/sdk for the providers
you call. ESM-only; Node LTS first, edge runtimes supported. Everything imports from
@cendor/sdk.
2. A governed agent in 10 lines
One agent, one tool, and all four governance layers — budget cap, PII guard, audit chain, and a cost/usage receipt:
from cendor.sdk import Agent, tool, run, budget, guard, Policy, AuditLog
@tool
def get_weather(city: str) -> str:
"""Current weather for a city.""" # schema derived from type hints + docstring
return f"Sunny in {city}"
agent = Agent(name="assistant", model="gpt-4o", tools=[get_weather],
instructions="Answer using tools when helpful.")
log = AuditLog(system="support", risk_tier="limited", path="audit.jsonl")
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) # the final answer
print(result.cost, result.usage) # Decimal money, real token usage
print([s.name for s in result.tool_steps]) # ["get_weather"]
import { Agent, tool, run, withBudget, guard, Policy, AuditLog } from '@cendor/sdk';
import { z } from 'zod';
const getWeather = tool(({ city }) => `Sunny in ${city}`, {
name: 'get_weather',
description: 'Current weather for a city',
parameters: z.object({ city: z.string() }), // TS has no runtime type hints — zod is the schema
});
const agent = new Agent({ name: 'assistant', model: 'gpt-4o', tools: [getWeather],
instructions: 'Answer using tools when helpful.' });
const audit = new AuditLog('support', { riskTier: 'limited', path: 'audit.jsonl' });
const result = await withBudget({ usd: 0.25, onExceed: 'block' }, () =>
guard({ policy: Policy.default(), audit }, () =>
run(agent, "What's the weather in Paris?", { audit })));
console.log(result.output); // the final answer
console.log(result.cost?.toString(), result.usage); // decimal money, real token usage
console.log(result.toolSteps.map((s) => s.name)); // ["get_weather"]
What each line buys you:
@tool/tool(...)— the JSON Schema comes from type hints + docstring (Python) or a zod schema (TS); it’s formatted per provider automatically.budget(usd=0.25, on_exceed="block")— a pre-flight cap: the over-budget call never runs.guard(Policy.default(), ...)— PII is redacted before the provider sees it.AuditLog(...)— every model and tool call lands in a tamper-evident hash chain (verify("audit.jsonl")checks it offline).result.cost— decimal money, never a float, aggregated across the whole run.
3. Run it ungoverned — core only
Every governance layer is optional. Drop the wrappers and it’s a bare loop on cendor-core:
from cendor.sdk import Agent, run
agent = Agent(name="a", model="gpt-4o", instructions="Be brief.")
result = run(agent, "Hello") # sync
result = await run.aio(agent, "Hello") # async — same signature
import { Agent, run } from '@cendor/sdk';
const agent = new Agent({ name: 'a', model: 'gpt-4o', instructions: 'Be brief.' });
const result = await run(agent, 'Hello'); // TS is async throughout
4. Make it testable
Record the run once; replay it offline forever — deterministic, no network, no keys. Cost and tokens are real on replay, so tests can assert spend too:
from cendor import cassette
with cassette.using("tests/fixtures/run.json"): # records on first run, replays after
result = run(agent, "What's the weather in Paris?")
import { using } from '@cendor/cassette';
const result = await using('tests/fixtures/run.json', () => // records once, replays after
run(agent, "What's the weather in Paris?"));
This is the foundation of the eval harness, which turns recorded trajectories into CI regression tests.
5. Where each concept lives
| I want to… | Go to |
|---|---|
Understand Agent, tool, run, Result | Agents & the loop |
| Cap spend, attribute cost, audit, redact | Governance |
| Make the agent remember across turns/processes | Memory & sessions |
| Give the agent my documents | Retrieval (RAG) |
| Use more than one agent | Multi-agent |
| Connect Gemini / Bedrock / Ollama / Hugging Face / Azure | Providers |
| Consume MCP tools, serve A2A, emit OTel spans | Ecosystem & interop |
| Survive crashes, retries, long runs | Production hardening |
| Gate regressions in CI | Eval & regression testing |
Coming from the libraries? Everything you already use —
budget,track,guard,Policy,AuditLog,trace— is the same object here, re-exported for one-import convenience. Nothing to relearn. The reverse also holds: see FAQ → libraries or SDK.