context-compiler 0.9.0.dev2__tar.gz → 0.9.0.dev3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/PKG-INFO +1 -1
  2. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/pyproject.toml +1 -1
  3. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/src/context_compiler/engine.py +2 -4
  4. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/src/context_compiler/grammar.py +15 -17
  5. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/.gitignore +0 -0
  6. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/LICENSE +0 -0
  7. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/README.md +0 -0
  8. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/01_llm_contradiction_clarify.py +0 -0
  9. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/02_llm_constraint_guardrail.py +0 -0
  10. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/03_llm_premise_guardrail.py +0 -0
  11. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/04_llm_tool_denylist_guardrail.py +0 -0
  12. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/05_llm_prompt_drift_vs_state.py +0 -0
  13. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/06_llm_context_compaction.py +0 -0
  14. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/07_llm_prompt_vs_state.py +0 -0
  15. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/08_llm_replacement_precondition.py +0 -0
  16. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/09_llm_confirmation_passthrough.py +0 -0
  17. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/README.md +0 -0
  18. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/__init__.py +0 -0
  19. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/common.py +0 -0
  20. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/llm_client.py +0 -0
  21. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/demos/run_demo.py +0 -0
  22. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/examples/01_persistent_guardrails.py +0 -0
  23. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/examples/02_configuration_and_correction.py +0 -0
  24. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/examples/03_ambiguity_with_clarification.py +0 -0
  25. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/examples/04_tool_governance_denylist.py +0 -0
  26. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/examples/05_llm_integration_pattern.py +0 -0
  27. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/examples/06_step_sequence_and_state_restore.py +0 -0
  28. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/examples/07_single_policy_correction.py +0 -0
  29. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/examples/08_controller_preview_diff.py +0 -0
  30. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/examples/README.md +0 -0
  31. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/examples/_util.py +0 -0
  32. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/host_support/__init__.py +0 -0
  33. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/host_support/provider_mode.py +0 -0
  34. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/src/context_compiler/__init__.py +0 -0
  35. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/src/context_compiler/audit.py +0 -0
  36. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/src/context_compiler/const.py +0 -0
  37. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/src/context_compiler/controller.py +0 -0
  38. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/src/context_compiler/decision_helpers.py +0 -0
  39. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/src/context_compiler/py.typed +0 -0
  40. {context_compiler-0.9.0.dev2 → context_compiler-0.9.0.dev3}/src/context_compiler/repl.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: context-compiler
3
- Version: 0.9.0.dev2
3
+ Version: 0.9.0.dev3
4
4
  Summary: Deterministic conversational state engine for LLM applications.
5
5
  Project-URL: Homepage, https://github.com/rlippmann/context-compiler
6
6
  Project-URL: Repository, https://github.com/rlippmann/context-compiler
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "context-compiler"
7
- version = "0.9.0dev2"
7
+ version = "0.9.0dev3"
8
8
  description = "Deterministic conversational state engine for LLM applications."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -17,7 +17,7 @@ from .const import (
17
17
  STATE_PREMISE,
18
18
  STATE_VERSION,
19
19
  )
20
- from .grammar import DirectiveKind, _parse_canonical_directive
20
+ from .grammar import DirectiveKind, decompose_directive
21
21
 
22
22
  PolicyValue = Literal["use", "prohibit"]
23
23
 
@@ -259,9 +259,7 @@ class Engine:
259
259
 
260
260
 
261
261
  def _parse_directive(user_input: str) -> Action | None:
262
- # Engine semantics intentionally depend on grammar's internal parsed form.
263
- # This keeps syntax authority in grammar without making the parser a public API.
264
- parsed = _parse_canonical_directive(user_input)
262
+ parsed = decompose_directive(user_input)
265
263
  if parsed is None:
266
264
  return None
267
265
 
@@ -26,7 +26,7 @@ class ValidatedDirective:
26
26
 
27
27
 
28
28
  @dataclass(frozen=True, slots=True)
29
- class _GrammarParsedDirective:
29
+ class CanonicalDirective:
30
30
  text: str
31
31
  kind: DirectiveKind
32
32
  operands: MappingProxyType[str, str]
@@ -243,7 +243,7 @@ def _contains_multiple_canonical_directives(text: str) -> bool:
243
243
  return False
244
244
 
245
245
 
246
- def _parse_replace_use(trimmed_text: str) -> _GrammarParsedDirective | None:
246
+ def _parse_replace_use(trimmed_text: str) -> CanonicalDirective | None:
247
247
  match = _REPLACE_RE.fullmatch(trimmed_text)
248
248
  if match is None:
249
249
  return None
@@ -258,14 +258,14 @@ def _parse_replace_use(trimmed_text: str) -> _GrammarParsedDirective | None:
258
258
  normalized_payload = _normalized_for_matching(trimmed_text)
259
259
  if normalized_payload.count(_INSTEAD_OF_DELIMITER) != 1:
260
260
  return None
261
- return _GrammarParsedDirective(
261
+ return CanonicalDirective(
262
262
  text=trimmed_text,
263
263
  kind=DirectiveKind.REPLACE_USE,
264
264
  operands=MappingProxyType({"new_item": new_item, "old_item": old_item}),
265
265
  )
266
266
 
267
267
 
268
- def _parse_directive(text: str) -> _GrammarParsedDirective | None:
268
+ def decompose_directive(text: str) -> CanonicalDirective | None:
269
269
  trimmed_text = _trim_ascii_whitespace(text)
270
270
  if trimmed_text == "":
271
271
  return None
@@ -275,17 +275,17 @@ def _parse_directive(text: str) -> _GrammarParsedDirective | None:
275
275
  normalized = _normalized_for_matching(trimmed_text)
276
276
 
277
277
  if normalized == "clear premise":
278
- return _GrammarParsedDirective(
278
+ return CanonicalDirective(
279
279
  text=text, kind=DirectiveKind.CLEAR_PREMISE, operands=MappingProxyType({})
280
280
  )
281
281
  if normalized == "reset policies":
282
- return _GrammarParsedDirective(
282
+ return CanonicalDirective(
283
283
  text=text,
284
284
  kind=DirectiveKind.RESET_POLICIES,
285
285
  operands=MappingProxyType({}),
286
286
  )
287
287
  if normalized == "clear state":
288
- return _GrammarParsedDirective(
288
+ return CanonicalDirective(
289
289
  text=text, kind=DirectiveKind.CLEAR_STATE, operands=MappingProxyType({})
290
290
  )
291
291
 
@@ -296,7 +296,7 @@ def _parse_directive(text: str) -> _GrammarParsedDirective | None:
296
296
  value = match.group("value")
297
297
  if not _operand_has_content(value) or _operand_starts_with_token(value, "to"):
298
298
  return None
299
- return _GrammarParsedDirective(
299
+ return CanonicalDirective(
300
300
  text=text,
301
301
  kind=DirectiveKind.SET_PREMISE,
302
302
  operands=MappingProxyType({"value": value}),
@@ -309,7 +309,7 @@ def _parse_directive(text: str) -> _GrammarParsedDirective | None:
309
309
  value = match.group("value")
310
310
  if not _operand_has_content(value):
311
311
  return None
312
- return _GrammarParsedDirective(
312
+ return CanonicalDirective(
313
313
  text=text,
314
314
  kind=DirectiveKind.CHANGE_PREMISE,
315
315
  operands=MappingProxyType({"value": value}),
@@ -332,7 +332,7 @@ def _parse_directive(text: str) -> _GrammarParsedDirective | None:
332
332
  or _INSTEAD_OF_DELIMITER in normalized_item
333
333
  ):
334
334
  return None
335
- return _GrammarParsedDirective(
335
+ return CanonicalDirective(
336
336
  text=text,
337
337
  kind=DirectiveKind.USE_ITEM,
338
338
  operands=MappingProxyType({"item": item}),
@@ -345,7 +345,7 @@ def _parse_directive(text: str) -> _GrammarParsedDirective | None:
345
345
  item = match.group("item")
346
346
  if not _operand_has_content(item):
347
347
  return None
348
- return _GrammarParsedDirective(
348
+ return CanonicalDirective(
349
349
  text=text,
350
350
  kind=DirectiveKind.PROHIBIT_ITEM,
351
351
  operands=MappingProxyType({"item": item}),
@@ -358,7 +358,7 @@ def _parse_directive(text: str) -> _GrammarParsedDirective | None:
358
358
  item = match.group("item")
359
359
  if not _operand_has_content(item):
360
360
  return None
361
- return _GrammarParsedDirective(
361
+ return CanonicalDirective(
362
362
  text=text,
363
363
  kind=DirectiveKind.REMOVE_POLICY,
364
364
  operands=MappingProxyType({"item": item}),
@@ -368,16 +368,12 @@ def _parse_directive(text: str) -> _GrammarParsedDirective | None:
368
368
 
369
369
 
370
370
  def validate_directive(text: str) -> ValidatedDirective | None:
371
- parsed = _parse_directive(text)
371
+ parsed = decompose_directive(text)
372
372
  if parsed is None:
373
373
  return None
374
374
  return ValidatedDirective(text=parsed.text, kind=parsed.kind)
375
375
 
376
376
 
377
- def _parse_canonical_directive(text: str) -> _GrammarParsedDirective | None:
378
- return _parse_directive(text)
379
-
380
-
381
377
  def match_canonical_directive_start(text: str, start: int) -> int | None:
382
378
  return _match_canonical_directive_start(text, start)
383
379
 
@@ -426,8 +422,10 @@ def render_directive(kind: DirectiveKind, /, **operands: str) -> str:
426
422
 
427
423
 
428
424
  __all__ = [
425
+ "CanonicalDirective",
429
426
  "DirectiveKind",
430
427
  "ValidatedDirective",
428
+ "decompose_directive",
431
429
  "is_canonical_directive",
432
430
  "render_directive",
433
431
  "validate_directive",