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.
The seven libraries, in one pass.
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.
Pack prioritized blocks into a token budget, evict by rule, and get an honest receipt of what was kept, shrunk, or dropped.
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 · contextkitassemble
Pack prioritized blocks into a token budget, evict by rule, and get an honest receipt of what was kept, shrunk, or dropped.
- 2 · squeezecompress
Content-aware, deterministic compression — no LLM, and every original restores byte-for-byte.
- 3 · tokenguardbudget
Pre-flight block or downgrade before a token is spent, plus per-feature / per-user cost attribution for free.
- 4 · guardrailsgate
A deterministic gate at four stages — block, redact, or flag by keyword / regex / URL / length / JSON-schema. Offline, microseconds.
- 5 · cassettetest
Whole-run capture — LLM and tool calls — replayed offline, deterministically, with no API key.
- 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.
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.
OpenAI (Chat + Responses), Anthropic, Hugging Face, Bedrock, Gemini, Ollama — detected by shape, so new models work the day they ship. Sync, async, streaming.
Budgets, recording, and audit subscribe — none patches your client, none imports another. Adding a library is free at the call site.
Managed runtimes emit OpenTelemetry gen_ai spans — feed them to otel.ingest() and the same tools keep working.
The mark is the architecture — core at the hub, everything else listening. Not a pipeline: each subscribes independently.
Pick one, or the whole stack.
Each solves one problem, works alone, and pulls only cendor-core — together they cover the whole call.
Pack prioritized blocks into a token budget, evict by rule, get an honest receipt of what was kept, shrunk, or dropped.
explore →Content-aware, deterministic compression for JSON, logs, code, prose — no LLM, and every original restores byte-for-byte.
explore →Pre-flight block or downgrade before a token is spent, plus per-feature / per-user cost attribution for free.
explore →A deterministic gate at four stages — block, redact, or flag by keyword / regex / URL / length / JSON-schema. Offline, microseconds.
explore →Whole-run capture — LLM and tool calls — replayed offline, deterministically, with no API key.
explore →guard() detects secrets & PII before send; every call, decision, and refusal lands on a tamper-evident, verifiable log.
explore →Types, token counting, offline prices, the instrument() seam, and the event bus every tool rides. Zero hard dependencies.
explore →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 user, app, or system sends a request.
LangChain · OpenAI Agents SDK · LlamaIndex — or no framework at all.
Pack the prompt into the token budget; oversized blocks compressed, reversibly.
Wrapped with instrument_tool(), so tool calls join the same stream.
Blocks or downgrades an over-budget call before a token is spent.
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.
guard()Detects secrets & PII and, per your policy, blocks the call or redacts them before send — recorded on the tamper-evident chain.
Every call is normalized and published to the event bus. One wrap, many listeners — no tool patches your client, none imports another.
Records spend by feature and user; costs labeled reported vs estimated.
Gates the model's output — block, redact, or flag the final answer before it leaves.
Records the run — replay it in tests, offline and deterministic.
Appends to the tamper-evident log: calls, costs, context decisions, and what the policy flagged or refused.
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.
The response — budgeted, scrubbed, recorded, and audited, with your code unchanged.
The dependency graph is a star, not a web — adding a library is free at the call site. See the full architecture →
Use one, or all.
the whole stack, version-pinned — Python or TypeScript — or any single piece: each pulls only cendor-core / @cendor/core.