Deterministic, dependency-free context-economy stages for code-writing agents.
Project description
The context element. Deterministic, dependency-free context shaping for code-writing agents — the same transform, every run.
Why this exists
An agent's tools return big lists of records: search hits, file reads, API responses. Before they reach the model's context window they must be cut down — and today that cutting is usually code the model improvises fresh each run, which drifts: different field choices, different truncation, different survivors, every time. contexel replaces the improvisation with vetted, versioned stages at the tool → context boundary. Same input, byte-identical context, on every run — a context contract instead of a nightly rewrite.
What you get
Six deterministic pipeline stages plus a merge combiner, over plain
list[dict] — the shape tools already return — with composition and
observability:
select— project to the fields you need (lossless)dedupe— drop duplicates by key, type-qualified, order preserved (lossless)rescore— BM25-style lexical relevance derived from the records' own text, so ranking doesn't have to trust the tool's scorerank— stable sort, missing-field records lasttruncate_field— clip a text field to a token cap, never exceeding ittrim_to_budget— keep the top records that fit a token budgetmerge— unify differently-shaped tool outputs into one schemapipeline([...])/@shaped/trace()— compose, pin at the tool boundary, and inspect what every stage removed
Token counting is pluggable twice over: the tokenizer (a dependency-free
estimate by default; tokens.use_tiktoken() for exact) and the
serializer (budgets are priced in the encoding your boundary actually
emits — JSON by default, or e.g. an ISON table).
No embeddings, no model calls, zero dependencies — pure Python 3.9+.
Install
pip install contexel # pure Python, zero dependencies
pip install "contexel[accurate]" # + tiktoken, for exact token counts
Sixty seconds
from contexel import select, dedupe, rescore, truncate_field, rank, trim_to_budget, trace
raw = search_tool(query=user_query) # a batch of verbose results
with trace() as t:
r = select(raw, ["title", "url", "snippet", "published"])
r = dedupe(r, key="url")
r = rescore(r, query=user_query, fields=("title", "snippet"))
r = truncate_field(r, "snippet", max_tokens=120)
r = rank(r, by="score", desc=True)
r = trim_to_budget(r, max_tokens=1500)
print(t.report()) # per-stage: records in -> out, tokens before -> after
context = r # only this distilled result enters the model's context
Or pin the policy at the tool boundary, so the model never sees raw output:
from contexel import shaped, stage, select, dedupe, trim_to_budget
@shaped([
stage(select, fields=["path", "line", "snippet"]),
stage(dedupe, key=["path", "line"]),
stage(trim_to_budget, max_tokens=2000),
])
def search_code(query: str) -> list[dict]:
return repo.search(query) # shaped identically, every call
Measured, not asserted
Benchmarked on the full CodeSearchNet python/test split (22,176 real
functions → 28,047 search-tool records) with 100 ground-truth episodes:
contexel is the only implementation among the near-neighbours
(hand-written glue, toolz, langchain-core, llama-index-core) that covers
all the operations natively, holds a 1,500-token budget in 100% of
episodes, keeps the needed record in 100% of them under both a strong and
a weak retrieval signal, and spends 100% of context tokens on unique,
needed fields — at 0 dependencies and a 13 ms import. It is also the
slowest budget-compliant row, because it does the most work per record —
and the limits are stated with the same care: recall@budget is bounded by
query specificity for any shaper, and rescore is lexical, not semantic.
Determinism is proven, not promised: the suite hashes the same contract's
output across fresh interpreters with different PYTHONHASHSEED values —
same SHA-256 every time, even when raw tool output carries fresh request
ids.
Full method and tables: benchmarks/COMPARISON.md · benchmarks/RESULTS.md
Where it fits
Inside agent-written code (programmatic tool calling), as a @shaped tool
wrapper, inside an MCP server, under LangChain/LlamaIndex via a thin
adapter, or ahead of a token-efficient encoding — each with a runnable
example in
examples/,
plus a complete no-API-key reference agent
(python -m reference_agent).
Links
- Docs: https://maheshvaikri-code.github.io/contexel/
- Source: https://github.com/maheshvaikri-code/contexel
- Changelog: https://github.com/maheshvaikri-code/contexel/blob/main/CHANGELOG.md
- License: MIT
Project details
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 contexel-0.1.14.tar.gz.
File metadata
- Download URL: contexel-0.1.14.tar.gz
- Upload date:
- Size: 1.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c5d8071e83322800abf8ecbd03f865e2bbcc96b55187e7ca340c8e24851ebad
|
|
| MD5 |
575a83fa16f57a4f91441f2061a0d87e
|
|
| BLAKE2b-256 |
8e19216361126bbcc9126206f26b9b3be0525c3fe99daf87d7ccca4a6c8a0f4d
|
File details
Details for the file contexel-0.1.14-py3-none-any.whl.
File metadata
- Download URL: contexel-0.1.14-py3-none-any.whl
- Upload date:
- Size: 13.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e77b3056c47e4b41374707a3bd5472a7ed8f98e83d6dabc969102fa482a2304
|
|
| MD5 |
757edca5405710dff417ea75fd22c064
|
|
| BLAKE2b-256 |
01878c09d5a9b2a3c30703d6893eefc508d837628e7f926555689083bd44fd2c
|