The libraries

Seven libraries. One problem each.

Each solves one production problem and works entirely on its own. Installed together, they cover the lifecycle of a production LLM call — cooperating through one event bus, never through imports. Six work around the call; the seventh, cendor-core, is the seam and the bus they all ride.

Watch · the tour

The seven libraries, in one pass.

The seven libraries
The seven libraries
One governed call

Six jobs. One bus. Zero imports between tools.

Scroll once and watch a single call travel the whole lifecycle. Every panel is the call shape that library's own page publishes — nothing invented.

one governed call · the lifecycle
stage 1 of 6
contextkit
assemble

Pack prioritized blocks into a token budget, evict by rule, and get an honest receipt of what was kept, shrunk, or dropped.

assemble.pycontextkit
from cendor.contextkit import Context, Block

ctx = Context(budget_tokens=8000, model="gpt-4o", reserve_output=500)
ctx.add(Block(retrieved_docs, priority=5, evict="compress"))

messages = ctx.assemble()   # fits the budget, deterministically
print(ctx.report())         # kept / shrunk / dropped + token math
  1. 1 · contextkitassemble

    Pack prioritized blocks into a token budget, evict by rule, and get an honest receipt of what was kept, shrunk, or dropped.

  2. 2 · squeezecompress

    Content-aware, deterministic compression — no LLM, and every original restores byte-for-byte.

  3. 3 · tokenguardbudget

    Pre-flight block or downgrade before a token is spent, plus per-feature / per-user cost attribution for free.

  4. 4 · guardrailsgate

    A deterministic gate at four stages — block, redact, or flag by keyword / regex / URL / length / JSON-schema. Offline, microseconds.

  5. 5 · cassettetest

    Whole-run capture — LLM and tool calls — replayed offline, deterministically, with no API key.

  6. 6 · acttraceguard + audit

    guard() detects secrets & PII before send; every call, decision, and refusal lands on a tamper-evident, verifiable log.

…and every stage rode one event bus — core's instrument() seam, ~15 µs, no tool importing another.

The one idea

One seam, many listeners.

Every tool that needs to see an LLM call usually monkey-patches your client — stack three and they fight. Cendor makes interception a single shared primitive.

instrument() normalizes every call

OpenAI (Chat + Responses), Anthropic, Hugging Face, Bedrock, Gemini, Ollama — detected by shape, so new models work the day they ship. Sync, async, streaming.

The event bus fans it out

Budgets, recording, and audit subscribe — none patches your client, none imports another. Adding a library is free at the call site.

Don't own the loop? Ingest it.

Managed runtimes emit OpenTelemetry gen_ai spans — feed them to otel.ingest() and the same tools keep working.

corethe seamcontextkitsqueezetokenguardguardrailscassetteacttraceotel

The mark is the architecture — core at the hub, everything else listening. Not a pipeline: each subscribes independently.

The seven libraries

Pick one, or the whole stack.

Each solves one problem, works alone, and pulls only cendor-core — together they cover the whole call.

Where it fits

Your framework stays. Cendor works above and below it.

One call, start to finish — what's yours, what's Cendor, and the single seam where they meet. You wrap the client once; every step after is automatic, over the bus.

your stackcendorthe seam
Build the prompt
01
Input

Your user, app, or system sends a request.

yours
02
Your agent framework

LangChain · OpenAI Agents SDK · LlamaIndex — or no framework at all.

yours
03
contextkit + squeeze

Pack the prompt into the token budget; oversized blocks compressed, reversibly.

cendor
04
Your tools

Wrapped with instrument_tool(), so tool calls join the same stream.

yours
Pre-flight — before the call runs
05
tokenguard

Blocks or downgrades an over-budget call before a token is spent.

cendor
06
guardrails

A deterministic gate on the input and tool calls — block, redact, or flag by keyword / regex / URL / length / schema. A block spends $0; every decision is recorded on the chain.

cendor
07
acttrace guard()

Detects secrets & PII and, per your policy, blocks the call or redacts them before send — recorded on the tamper-evident chain.

cendor
The call
08
core.instrument() — the seam

Every call is normalized and published to the event bus. One wrap, many listeners — no tool patches your client, none imports another.

After the call — automatic, via the bus
09
tokenguard

Records spend by feature and user; costs labeled reported vs estimated.

cendor
10
guardrails

Gates the model's output — block, redact, or flag the final answer before it leaves.

cendor
11
cassette

Records the run — replay it in tests, offline and deterministic.

cendor
12
acttrace

Appends to the tamper-evident log: calls, costs, context decisions, and what the policy flagged or refused.

cendor
13
Your observability

Any OpenTelemetry backend via core.otel — or ingest a managed runtime's spans back onto the bus. Want to see it? Watch locally in Cendor Monitor, the optional self-hosted monitor.

yours · optional
14
Output

The response — budgeted, scrubbed, recorded, and audited, with your code unchanged.

yours

The dependency graph is a star, not a web — adding a library is free at the call site. See the full architecture →

Get started

Use one, or all.

$ pip install cendor-libs
$ npm i @cendor/libs

the whole stack, version-pinned — Python or TypeScript — or any single piece: each pulls only cendor-core / @cendor/core.