Foundation for the Cendor stack: shared types, token counting, offline-first & refreshable prices, instrument(), event bus, OTel.
Project description
cendor-core
The shared foundation for the Cendor stack: canonical types, provider-aware token counting,
an offline price table, one instrument() interception point, an in-process event bus, and
OpenTelemetry GenAI emitters. Tiny on purpose — it's the blast radius for every other tool.
One instrument() call, every sibling tool observes the stream — no per-call wiring, offline by default.
· usually installed transitively ·
import cendor.core
from cendor.core import tokens, prices, instrument, bus
# Count tokens and price a call — fully offline, no API key, no network:
n = tokens.count([{"role": "user", "content": "Summarize the attached report in 3 bullets."}],
model="claude-opus-4-8")
cost = prices.estimate("claude-opus-4-8", input_tokens=n, output_tokens=200)
# Instrument any client once; tools subscribe to the normalized event stream:
@bus.subscribe
def on_call(call): # normalized LLMCall with usage + cost
print(call.provider, call.model, call.cost)
client = instrument(openai_or_anthropic_client) # idempotent, additive · sync · async · streaming
Highlights
instrument()— wrap any client once: OpenAI (Chat Completions + Responses API) · Anthropic · AWS Bedrock · Google Gemini (google-genai+ legacygoogle-generativeai) · Ollama, detected by shape; sync, async, and streaming; idempotent + additive.instrument_tool()does the same for tools.- Event bus —
subscribe/emit; thread-safe within a process; one failing subscriber never starves another. - Interceptor seam —
add_interceptor+Reroute/MISSpowers replay (cassette) and reroute / block (tokenguard) without a second patch point. - Token counting, three tiers — exact (
[tiktoken]) / BPE-estimate (o200k for Claude/Gemini) / offline heuristic;tokens.method(model)reports which is active;tokens.register()plugs in a precise counter. - Reasoning-token accounting —
Usage.reasoning_tokensbreaks out a reasoning/thinking model's internal reasoning (OpenAIreasoning_tokens, Geminithoughts_token_count), non-streaming and streaming. A subset ofoutput_tokens, so cost is unchanged; Gemini's separately-reported thoughts are now folded into the output total (fixing an under-count). - Offline-first, refreshable prices — bundled dated snapshot;
estimate() -> Decimal Money(neverfloat); optionalrefresh(source="litellm"|"openrouter"|"azure")from live no-auth sources, withage_days()/is_stale()staleness signals. Cached tokens are billed once (cached ⊆ input, normalized across providers), not at both the input and cached rate. A gateway-reported cost (e.g. OpenRouter'susage.cost) is preferred over the estimate and labeledcost_reportedvscost_estimated. - OpenTelemetry — emit
gen_ai.*spans, orotel.ingest()a managed runtime's spans onto the bus. Structural protocols (Compressor/EvictionStrategy/Sink/Subscriber/Handle) let the tools interlock without coupling.
Install cendor-core[tiktoken] for exact OpenAI counts (heuristic fallback otherwise), or [otel] to emit spans. Provider SDKs are always optional extras.
A rendered architecture diagram lives in docs/core.md (GitHub renders Mermaid; PyPI shows code as text).
See docs/core.md · CHANGELOG. Part of the Cendor stack — github.com/cendorhq/Cendor. Powered by PowerAI Labs. Apache-2.0; provided "as is", without warranty — use at your own risk (LICENSE §7–8).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cendor_core-1.0.0.tar.gz.
File metadata
- Download URL: cendor_core-1.0.0.tar.gz
- Upload date:
- Size: 42.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13bb332337f7e921f6f36dfa0890d0904ce89343a60d183ce3f911c6c56d9b13
|
|
| MD5 |
1c3eaf749967262c93439a63088f198e
|
|
| BLAKE2b-256 |
31dc640a172d04844279813debb88bfb8c5014647f3c52eb8097559a709eb3ec
|
Provenance
The following attestation bundles were made for cendor_core-1.0.0.tar.gz:
Publisher:
release.yml on cendorhq/Cendor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cendor_core-1.0.0.tar.gz -
Subject digest:
13bb332337f7e921f6f36dfa0890d0904ce89343a60d183ce3f911c6c56d9b13 - Sigstore transparency entry: 2063253604
- Sigstore integration time:
-
Permalink:
cendorhq/Cendor@1733d9d073230ac9448221f660fce4ab07a42c33 -
Branch / Tag:
refs/tags/core-v1.0.0 - Owner: https://github.com/cendorhq
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1733d9d073230ac9448221f660fce4ab07a42c33 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cendor_core-1.0.0-py3-none-any.whl.
File metadata
- Download URL: cendor_core-1.0.0-py3-none-any.whl
- Upload date:
- Size: 32.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ea3e6f11f2f8e2e2e00706f0df6f91835203cfe234ae53b367f17f631f28e42
|
|
| MD5 |
d5d6215fd4763832f7570a44689687ef
|
|
| BLAKE2b-256 |
f0a7323b5198e1a521f7e3fb530523e2821cdc81147722bb9a39a4c1b8bae83a
|
Provenance
The following attestation bundles were made for cendor_core-1.0.0-py3-none-any.whl:
Publisher:
release.yml on cendorhq/Cendor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cendor_core-1.0.0-py3-none-any.whl -
Subject digest:
6ea3e6f11f2f8e2e2e00706f0df6f91835203cfe234ae53b367f17f631f28e42 - Sigstore transparency entry: 2063253632
- Sigstore integration time:
-
Permalink:
cendorhq/Cendor@1733d9d073230ac9448221f660fce4ab07a42c33 -
Branch / Tag:
refs/tags/core-v1.0.0 - Owner: https://github.com/cendorhq
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1733d9d073230ac9448221f660fce4ab07a42c33 -
Trigger Event:
push
-
Statement type: