Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "context-compiler"
version = "0.9.1"
version = "0.9.2"
description = "Deterministic conversational state engine for LLM applications."
readme = "README.md"
requires-python = ">=3.11"
Expand Down
16 changes: 8 additions & 8 deletions src/context_compiler/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,28 +46,28 @@ class _EvaluatedTransition(TypedDict):
class Engine:
"""Own the authoritative state and apply one directive transition at a time."""

__slots__ = ("_state",)
__slots__ = ("_working_memory",)

def __init__(self) -> None:
self._state: _WorkingMemory
self._working_memory: _WorkingMemory
self._replace_state(_initial_state())

@property
def premise(self) -> str | None:
"""Return the current premise from authoritative state."""

return self._state[STATE_PREMISE]
return self._working_memory[STATE_PREMISE]

@property
def policies(self) -> Mapping[str, PolicyValue]:
"""Return a defensive copy of the current policy mapping."""

return deepcopy(self._state[STATE_POLICIES])
return deepcopy(self._working_memory[STATE_POLICIES])

def export_json(self) -> str:
"""Serialize the current authoritative state to canonical JSON text."""

return json.dumps(self._state, sort_keys=True, separators=(",", ":"))
return json.dumps(self._working_memory, sort_keys=True, separators=(",", ":"))

def import_json(self, payload: str) -> None:
"""Replace authoritative state from previously exported JSON text.
Expand Down Expand Up @@ -100,7 +100,7 @@ def apply_directive(
) -> UpdateDecision | SemanticErrorDecision:
"""Evaluate and commit one canonical directive against authoritative state."""

evaluated = self._evaluate_directive_transition(self._state, directive)
evaluated = self._evaluate_directive_transition(self._working_memory, directive)
self._replace_state(evaluated["next_state"])
return evaluated["decision"]

Expand All @@ -118,12 +118,12 @@ def _evaluate_directive_transition(
}

def _replace_state(self, state: _WorkingMemory) -> None:
self._state = state
self._working_memory = state

def _pre_mutation_error(
self, directive: CanonicalDirective, *, state: _WorkingMemory | None = None
) -> SemanticErrorDecision | None:
candidate_state = self._state if state is None else state
candidate_state = self._working_memory if state is None else state
# Single error path: all error outcomes are detected before any mutation.
if (
directive.kind is DirectiveKind.SET_PREMISE
Expand Down
2 changes: 1 addition & 1 deletion tests/test_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ def test_import_json_rejects_policy_keys_that_normalize_to_empty(
def test_replace_use_errors_when_old_policy_is_not_use_in_invalid_internal_state() -> None:
engine = Engine()
# Defensive-path coverage for impossible external state values.
engine._state["policies"]["docker"] = "invalid" # type: ignore[assignment] # noqa: SLF001
engine._working_memory["policies"]["docker"] = "invalid" # type: ignore[assignment] # noqa: SLF001

decision = engine.step("use kubectl instead of docker")

Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading