Deterministic conversational state engine for LLM applications.
Project description
Context Compiler
A deterministic directive engine that converts explicit user instructions into structured conversational state for LLM applications.
Modern language models reason well but are unreliable at maintaining consistent state across interactions.
Corrections compete with earlier statements, constraints disappear, and long conversations accumulate contradictions.
The Context Compiler introduces a deterministic state layer that governs authoritative conversational state independently of the model.
The model performs reasoning and generation while the compiler manages facts and constraints. Once accepted, directives remain authoritative until explicitly corrected or reset.
Why “Compiler”?
Context Compiler treats explicit user directives as inputs to a deterministic process.
Instead of relying on the LLM to remember constraints across a conversation, user instructions are compiled into structured state before the model runs.
The idea is similar to a traditional compiler: user directives are translated into a structured representation that the rest of the system can rely on.
Installation
- Python 3.11+
pip install context-compiler- Dev/test:
uv sync --group devanduv run pytest - Examples: see examples/README.md
- Demonstrations: see demos/README.md
10-Second Example
User sets a constraint once:
User: don't use peanuts
State becomes:
{
"facts": {
"focus.primary": null
},
"policies": {
"prohibit": ["peanuts"]
},
"version": 1
}
Later in the conversation:
User: how should I make this curry?
The host supplies the authoritative state to the model so the constraint persists across turns.
Architecture
User Input
↓
Context Compiler
↓
Decision (passthrough | update | clarify)
↓
Host Application
↓
LLM
The compiler governs authoritative conversational state and never calls the LLM.
The host decides whether to call the model based on the returned Decision.
Decision API
Each user message produces a Decision.
class Decision(TypedDict):
kind: Literal["passthrough", "update", "clarify"]
state: dict | None
prompt_to_user: str | None
Meaning:
| kind | host behavior |
|---|---|
| passthrough | forward user input to LLM |
| update | forward input with updated state |
| clarify | show prompt_to_user and do not call the LLM |
Host Integration Example
engine = create_engine()
decision = engine.step(user_input)
if decision["kind"] == "clarify":
show_to_user(decision["prompt_to_user"])
else:
state = decision["state"] or engine.state
messages = build_messages(state, user_input)
render(call_llm(messages))
API Reference
| API | Description |
|---|---|
create_engine(...) |
Create a new compiler engine, optionally with replacement initial state. |
step(user_input) |
Parse one user turn and return a deterministic Decision. |
engine.state |
Read or replace full in-memory authoritative state. |
export_json() |
Export current state as JSON for persistence/transport. |
import_json(payload) |
Load state from exported JSON payload. |
State Model
The compiler maintains an authoritative state:
{
"facts": {
"focus.primary": null
},
"policies": {
"prohibit": []
},
"version": 1
}
State Access and Persistence
Hosts may inspect or replace in-memory state (engine.state) or persist it using export_json() and import_json(). State changes occur only through directives processed by step(). Storage is managed by the host application.
Fact Schema
The current schema contains a single exclusive slot: facts["focus.primary"].
This demonstrates deterministic fact replacement and correction behavior.
Richer schemas may be introduced in future releases.
State Properties
- Facts are exclusive (last write wins)
- Policies are additive
- No inference or semantic reasoning
Identical input sequences always produce identical compiler state. LLM responses may still vary unless deterministic decoding is used by the host.
Directive Examples
Hard negative directive:
User: don't use peanuts
Result:
{
"policies": {
"prohibit": ["peanuts"]
}
}
Fact configuration:
User: use vegetarian curry
State update:
facts.focus.primary = "vegetarian curry"
Correction:
User: actually vegan curry
Result:
facts.focus.primary = "vegan curry"
Ambiguous mutation:
User: no use peanuts
Compiler response:
Decision.kind = "clarify"
No state mutation occurs until confirmation.
Reset Commands
Two explicit reset commands are supported:
reset policiesclearspolicies.prohibitbut preserves the current fact (facts["focus.primary"])clear stateresets the full state to initial values
Example:
Before:
{
"facts": {"focus.primary": "vegetarian curry"},
"policies": {"prohibit": ["peanuts"]},
"version": 1
}
After reset policies:
{
"facts": {"focus.primary": "vegetarian curry"},
"policies": {"prohibit": []},
"version": 1
}
After clear state:
{
"facts": {"focus.primary": null},
"policies": {"prohibit": []},
"version": 1
}
Examples
Integration examples are available in the examples/ directory.
See examples/README.md for walkthroughs.
Quickstart
Run the interactive REPL:
context-compiler
Run an example:
python examples/01_persistent_guardrails.py
Run tests:
uv run pytest
Guarantees
- State changes only through explicit user directives or confirmation.
- Identical input sequences produce identical compiler state.
- Model responses never modify compiler state.
- Ambiguous directives trigger clarification instead of changing state.
These invariants are verified through behavioral tests and Hypothesis-based property tests.
Design Notes
More detailed design and milestone documents are available in:
License
Apache-2.0.
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 context_compiler-0.2.1.tar.gz.
File metadata
- Download URL: context_compiler-0.2.1.tar.gz
- Upload date:
- Size: 96.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2e33649824b5837600250162883572196c8fa4953149d969396e1a89495f2ef
|
|
| MD5 |
f213a9b21c9c325f1ef56c4701872fd8
|
|
| BLAKE2b-256 |
8d7d10c8301fb60e2e5ec864228858f7dc0ff0a113e04da54cd0344e0fe90e5a
|
File details
Details for the file context_compiler-0.2.1-py3-none-any.whl.
File metadata
- Download URL: context_compiler-0.2.1-py3-none-any.whl
- Upload date:
- Size: 14.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ac107159d3752a6536b5b9365d7f52528539fb6f3d525322fdb97fc983bbdec
|
|
| MD5 |
b2035a6633bbfb8e519a37fe6b3bc611
|
|
| BLAKE2b-256 |
0318cb5ece3f280b90755bd4007007c763b8cc676c9dc380372ddca979b71fb8
|