Local-first adaptive context compiler and privacy gateway for language models.
Project description
ContextIR
ContextIR is a local-first adaptive context compiler and privacy gateway for language models. It turns text into a compact, inspectable intermediate representation while retaining critical source fragments when a lossy summary would be unsafe.
Status: stable 1.0 API. ContextIR follows semantic versioning for the public
Python surface and the contextir.v2 contract. Semantic compression and PII
detection still require evaluation on each deployment's data.
Quick Start
python3 -m pip install contextir
ollama pull qwen3:0.6b
contextir run --model qwen3:0.6b --text "Reply with only READY."
from contextir import ContextPipeline, OllamaClient
pipeline = ContextPipeline(invoke=OllamaClient("qwen3:0.6b"))
result = pipeline.run(
"If payment 42 is complete, do not send it again.",
source_lang="en",
target_lang="en",
)
print(result.answer)
For document QA, pass the question separately instead of embedding it into the document:
result = pipeline.run(
long_document,
context_kind="retrieval",
query="What is the northern deployment credential?",
)
The document and query are masked together inside the trusted process. The masked query guides retrieval and is included in the model prompt and token budget, but is omitted from the public contract and safe trace.
The release wheel avoids a source checkout and Git dependency. A pinned Git install remains available for environments that prefer source builds.
For a two-minute integration and safe restoration example, see Quick start.
Why
Long agent histories and tool outputs consume model context with repeated facts, formatting, and sensitive values. ContextIR provides three explicit modes:
raw: masked source text, without protocol overhead;hybrid: semantic events plus source fragments containing negation, conditions, numbers, quotes, or protected placeholders;semantic: compact events only, for callers that accept lossy compression.
auto first distinguishes exhaustive tasks, document retrieval, and
operational history. Exhaustive tasks stay raw. Document QA uses local lexical
retrieval to keep the query, formatting instructions, and evidence spans
verbatim. Operational history continues to use inspectable events and critical
source fragments.
ContextPipeline is the product entry point. It measures candidate prompts
with a configurable target-model tokenizer, rejects compression without useful
savings, verifies output safety, and performs bounded fallback from semantic to
hybrid to raw context. The bundled model clients also reserve output tokens
and configurable chat-template overhead from their context window; ContextIR
packs ranked retrieval evidence to the remaining budget or refuses an unsafe
prompt before contacting the model.
For a query whose highest-ranked evidence segment is itself larger than the window, enable bounded chunked retrieval explicitly:
contextir run \
--model qwen3:0.6b \
--context-length 4096 \
--context-kind retrieval \
--query "What is the release code?" \
--chunked-retrieval \
--text "Read the document..."
This path chunks only retrieved evidence for reasoning tasks, selects relevant chunks locally, validates grounded map outputs, and performs at most one reduce call. It does not approximate exhaustive counting or transform tasks.
Install
From a checkout:
python3 -m pip install -e .
Optional Presidio integration:
python3 -m pip install -e '.[privacy]'
Advanced Compiler API
from contextir import ContextIR
gateway = ContextIR()
bundle = gateway.compile_private(
"If payment 42 is complete, do not send it again. Email person@example.test.",
source_lang="en",
target_lang="en",
mode="hybrid",
)
contract = bundle.contract
model_prompt = gateway.render_bundle(bundle)
# Restore only placeholders explicitly allowed by the application.
answer = gateway.restore("Contact PII_EMAIL_1", bundle, allowed={"PII_EMAIL_1"})
compile() returns only the public contract. compile_private() additionally
returns the local PII vault and source-reference map. Neither is inserted into
the model prompt.
For model-facing applications, prefer ContextPipeline over calling the
compiler directly. Use task="transform" for translation, rewriting, and
summarization where numbers, negation, constraints, and placeholders must
survive. Normal reasoning answers are not incorrectly required to echo the
request.
CLI
contextir run \
--backend ollama \
--model qwen3:0.6b \
--context-length 8192 \
--max-output-tokens 256 \
--prompt-overhead-tokens 32 \
--text "Summarize the current agent state."
contextir compile \
--text "Если платеж 42 выполнен, не отправляй его повторно." \
--source-lang ru \
--target-lang en \
--mode hybrid \
--out /tmp/contextir.json
contextir render --contract /tmp/contextir.json
The source checkout also exposes python3 scripts/contextir.py.
Contract
ContextIR v2 records:
- source and target language;
- intent and confidence;
- typed entities and protected placeholders;
- events with predicate, arguments, polarity, modality, condition, and source reference;
- execution and privacy constraints;
- optional lexical concepts;
- included source fragments and unresolved source references;
- prompt-size and latency statistics.
The packaged JSON Schema is available through:
from contextir.schemas import load_contract_schema
Privacy
The default detector is deliberately small and recognizes common emails, phones, payment-card-like values, and API-key-like tokens. Presidio can be used as an optional detector and extended with project-specific recognizers.
Automated PII detection is not a security boundary by itself. Keep the vault local, avoid logging prompt bodies, use explicit restoration allowlists, and evaluate recognizers on data representative of the deployment.
Current Evidence
The checked-in compiler smoke benchmark reports:
- 9 compiler and 12 product-pipeline cases;
- 0 expectation failures;
- 0 pipeline failures;
- 0 PII leaks into public contracts or rendered prompts;
0.3627prompt/source ratio on the one compression-eligible repeated-context case.
The first model-level A/B exposed a large quality loss in v0.3.0. Query-aware
routing corrected that failure. On the v0.5.0 nine-case Qwen3 8B run, raw and
auto both scored 0.7272, while auto reduced model input by 70.0% and mean
latency from 53.8 s to 2.51 s. An external 1,500-row Presidio Research
benchmark measured 0.8471 precision and 1.0000 recall for the dependency-free
email/phone/card profile. These are bounded results, not universal quality or
privacy claims; broader official tasks and deployment-specific PII evaluation
remain required.
A constrained-window retrieval smoke run packs the same long input to fit a
256-token Ollama context. Qwen3 0.6B and 8B both recovered cobalt-seven; the
backend reported 229 prompt tokens with 16 tokens reserved for output.
An oversized single-segment follow-up uses bounded chunked retrieval with a
256-token context. Qwen3 0.6B and 8B both recovered cobalt-seven from the
same selected chunk using one map call at 75% of the available prompt budget.
A constrained 2K-context A/B over ten official LongBench QA/retrieval examples
reduced measured backend input to 39.0% of raw for both tested models. Qwen3 8B
quality increased from 0.1668 to 0.6983 with a paired 95% bootstrap delta
of [0.2086, 0.8225]. Qwen3 0.6B increased from 0.1889 to 0.3121, but its
delta interval [-0.0154, 0.3392] does not establish a reliable quality gain.
All ten official cases used one packed direct call; a separate synthetic
oversized-segment diagnostic activated the map path and recovered the answer
with both models.
End-to-end baselines on the same Qwen3 8B run scored 0.6221 for a 32K
same-model neural summary and 0.1910 for Nomic embedding retrieval. ContextIR
scored 0.6983. Summary remained statistically competitive in quality on this
small subset, but processed 24.95x as many input tokens as ContextIR and took
32.0x its latency. The tested embedding configuration processed 33.43x as
many tokens and was significantly worse in paired quality. These costs include
preprocessing; they are not answer-prompt-only comparisons.
See the local model A/B card and benchmark roadmap.
Research Layer
The repository retains the earlier RU/EN lexical graph, graph embeddings,
synthetic translator, checkpoints, and roundtrip experiments. They are not
loaded by the default package path. Use the research extra and source checkout
for those experiments.
The old WordNet keyword roundtrip is preserved as a baseline, not presented as the production compiler. See RESEARCH_HISTORY.md.
Development
python3 -m pip install -e '.[dev,research]'
python3 -m unittest discover -s tests -v
python3 scripts/evaluate_contextir.py
python3 -m build
python3 -m twine check dist/*
Architecture, scope, contribution, and security guidance:
License
ContextIR code is licensed under Apache-2.0. Research datasets and derived lexical artifacts retain their upstream terms. See THIRD_PARTY_NOTICES.md before redistributing them.
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 contextir-1.4.0.tar.gz.
File metadata
- Download URL: contextir-1.4.0.tar.gz
- Upload date:
- Size: 71.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
014a7ae118e55023e6c097be007682cd5c29f3fd99b320bbeb59e6ef81d2aff4
|
|
| MD5 |
86fb2f94fcc20b050aa4fb804880bf92
|
|
| BLAKE2b-256 |
46aeb80e3be82459b93592baa19b5971ca725f221e4fb7dc85964991793c7ddf
|
Provenance
The following attestation bundles were made for contextir-1.4.0.tar.gz:
Publisher:
release.yml on mussolene/contextir
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
contextir-1.4.0.tar.gz -
Subject digest:
014a7ae118e55023e6c097be007682cd5c29f3fd99b320bbeb59e6ef81d2aff4 - Sigstore transparency entry: 2199925916
- Sigstore integration time:
-
Permalink:
mussolene/contextir@4ed7b96aaca64699e938d25b327fbf19a8e828a7 -
Branch / Tag:
refs/tags/v1.4.0 - Owner: https://github.com/mussolene
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4ed7b96aaca64699e938d25b327fbf19a8e828a7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file contextir-1.4.0-py3-none-any.whl.
File metadata
- Download URL: contextir-1.4.0-py3-none-any.whl
- Upload date:
- Size: 72.7 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 |
a46b8bb88fc7ea4e388a1954c73099d8e9dd0c97035d0dbd82651b486df5d103
|
|
| MD5 |
d43e71e6b62e710fa53210b266ad7e24
|
|
| BLAKE2b-256 |
0720ace81f8c842e15a7daa358957cc1935d3e6fdb73a50cf9cbb3bd2be97fb6
|
Provenance
The following attestation bundles were made for contextir-1.4.0-py3-none-any.whl:
Publisher:
release.yml on mussolene/contextir
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
contextir-1.4.0-py3-none-any.whl -
Subject digest:
a46b8bb88fc7ea4e388a1954c73099d8e9dd0c97035d0dbd82651b486df5d103 - Sigstore transparency entry: 2199926007
- Sigstore integration time:
-
Permalink:
mussolene/contextir@4ed7b96aaca64699e938d25b327fbf19a8e828a7 -
Branch / Tag:
refs/tags/v1.4.0 - Owner: https://github.com/mussolene
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4ed7b96aaca64699e938d25b327fbf19a8e828a7 -
Trigger Event:
push
-
Statement type: