context-compiler 0.9.0.dev5__tar.gz → 0.9.0.dev7__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 (37) hide show
  1. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/PKG-INFO +1 -1
  2. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/pyproject.toml +1 -1
  3. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/src/context_compiler/grammar.py +24 -49
  4. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/.gitignore +0 -0
  5. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/LICENSE +0 -0
  6. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/README.md +0 -0
  7. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/01_llm_contradiction_error.py +0 -0
  8. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/02_llm_constraint_guardrail.py +0 -0
  9. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/03_llm_premise_guardrail.py +0 -0
  10. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/04_llm_tool_denylist_guardrail.py +0 -0
  11. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/05_llm_prompt_drift_vs_state.py +0 -0
  12. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/06_llm_context_compaction.py +0 -0
  13. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/07_llm_prompt_vs_state.py +0 -0
  14. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/08_llm_replacement_precondition.py +0 -0
  15. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/09_llm_confirmation_no_directive.py +0 -0
  16. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/README.md +0 -0
  17. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/__init__.py +0 -0
  18. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/common.py +0 -0
  19. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/llm_client.py +0 -0
  20. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/demos/run_demo.py +0 -0
  21. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/examples/01_persistent_guardrails.py +0 -0
  22. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/examples/02_configuration_and_correction.py +0 -0
  23. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/examples/03_ambiguity_with_error.py +0 -0
  24. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/examples/04_tool_governance_denylist.py +0 -0
  25. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/examples/05_llm_integration_pattern.py +0 -0
  26. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/examples/06_step_sequence_and_state_restore.py +0 -0
  27. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/examples/07_single_policy_correction.py +0 -0
  28. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/examples/README.md +0 -0
  29. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/examples/_util.py +0 -0
  30. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/host_support/__init__.py +0 -0
  31. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/host_support/provider_mode.py +0 -0
  32. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/src/context_compiler/__init__.py +0 -0
  33. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/src/context_compiler/const.py +0 -0
  34. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/src/context_compiler/decision_helpers.py +0 -0
  35. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/src/context_compiler/engine.py +0 -0
  36. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/src/context_compiler/py.typed +0 -0
  37. {context_compiler-0.9.0.dev5 → context_compiler-0.9.0.dev7}/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.dev5
3
+ Version: 0.9.0.dev7
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.0dev5"
7
+ version = "0.9.0dev7"
8
8
  description = "Deterministic conversational state engine for LLM applications."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -21,17 +21,15 @@ class DirectiveKind(StrEnum):
21
21
  CLEAR_STATE = "clear_state"
22
22
 
23
23
 
24
- @dataclass(frozen=True, slots=True)
25
- class ValidatedDirective:
26
- """Classify text as one canonical directive kind without exposing operands."""
27
-
28
- text: str
29
- kind: DirectiveKind
30
-
31
-
32
24
  @dataclass(frozen=True, slots=True)
33
25
  class CanonicalDirective:
34
- """Represent one parsed canonical directive and its named operands."""
26
+ """Represent one parsed canonical directive and its named operands.
27
+
28
+ ``text`` preserves the original accepted input text. It may retain caller
29
+ formatting or casing and is not canonical serialized directive text; use
30
+ :func:`render_directive` to produce canonical directive text from semantic
31
+ kind and operands.
32
+ """
35
33
 
36
34
  text: str
37
35
  kind: DirectiveKind
@@ -182,10 +180,11 @@ def _operand_starts_with_token(value: str, token: str) -> bool:
182
180
  def match_canonical_directive_start(text: str, start: int) -> int | None:
183
181
  """Locate a canonical directive prefix at a given character position.
184
182
 
185
- This classifies whether canonical directive syntax begins at ``start`` and,
186
- when it does, returns the index immediately after the directive keyword
187
- prefix. It does not parse operands, validate the full directive payload, or
188
- evaluate multi-directive state semantics.
183
+ This is a shallow syntax-start matcher: it classifies whether canonical
184
+ directive syntax begins at ``start`` and, when it does, returns the index
185
+ immediately after the directive keyword prefix. It does not parse operands,
186
+ validate the full directive payload, or evaluate multi-directive state
187
+ semantics.
189
188
  """
190
189
  if start < 0 or start >= len(text):
191
190
  return None
@@ -246,10 +245,11 @@ def _match_directive_token(
246
245
  def contains_multiple_canonical_directives(text: str) -> bool:
247
246
  """Report whether text contains more than one canonical directive start.
248
247
 
249
- This detects compound directive text by looking for multiple canonical
250
- directive prefixes in the same input. It does not parse directive operands,
251
- repair malformed text, or determine whether a whole string should be
252
- accepted as a single directive.
248
+ This detects compound directive structure by looking for multiple canonical
249
+ directive prefixes in the same input. It is not a replacement for full
250
+ directive validation, and it does not parse directive operands, repair
251
+ malformed text, or determine whether a whole string should be accepted as a
252
+ single directive.
253
253
  """
254
254
  first_start = match_canonical_directive_start(text, 0)
255
255
  if first_start is None:
@@ -290,8 +290,10 @@ def decompose_directive(text: str) -> CanonicalDirective | None:
290
290
 
291
291
  This determines whether ``text`` is a single canonical directive and, when
292
292
  it is, returns the directive kind plus canonical operand names with the
293
- original operand text preserved. It does not repair input, infer intent, or
294
- evaluate directive effects against compiler state.
293
+ original operand text preserved. Callers can determine whether ``text`` is
294
+ a complete canonical directive by checking whether this returns a non-`None`
295
+ result. It does not repair input, infer intent, or evaluate directive
296
+ effects against compiler state.
295
297
  """
296
298
  trimmed_text = _trim_ascii_whitespace(text)
297
299
  if trimmed_text == "":
@@ -394,32 +396,8 @@ def decompose_directive(text: str) -> CanonicalDirective | None:
394
396
  return None
395
397
 
396
398
 
397
- def validate_directive(text: str) -> ValidatedDirective | None:
398
- """Classify whether text is a canonical directive.
399
-
400
- This determines whether ``text`` belongs to one canonical directive family
401
- and returns only the normalized semantic kind needed for classification. It
402
- does not expose operands, render directives, repair malformed text, or
403
- evaluate any state transition.
404
- """
405
- parsed = decompose_directive(text)
406
- if parsed is None:
407
- return None
408
- return ValidatedDirective(text=parsed.text, kind=parsed.kind)
409
-
410
-
411
- def is_canonical_directive(text: str) -> bool:
412
- """Return whether text is exactly one canonical directive.
413
-
414
- This provides boolean directive classification for callers that only need a
415
- yes-or-no answer. It does not parse operands, explain rejection reasons, or
416
- perform validation beyond canonical grammar recognition.
417
- """
418
- return validate_directive(text) is not None
419
-
420
-
421
399
  def render_directive(kind: DirectiveKind, /, **operands: str) -> str:
422
- """Render canonical directive text from a semantic kind and operands.
400
+ """Produce canonical directive text from a semantic kind and operands.
423
401
 
424
402
  This determines the exact canonical spelling for an existing grammar
425
403
  capability and rejects operand combinations that would not round-trip as the
@@ -454,8 +432,8 @@ def render_directive(kind: DirectiveKind, /, **operands: str) -> str:
454
432
 
455
433
  operand_view = MappingProxyType(normalized_operands)
456
434
  rendered = spec.renderer(operand_view)
457
- validated = validate_directive(rendered)
458
- if validated is None or validated.kind is not normalized_kind:
435
+ decomposed = decompose_directive(rendered)
436
+ if decomposed is None or decomposed.kind is not normalized_kind:
459
437
  raise ValueError(f"Operands do not produce a canonical {normalized_kind.value} directive.")
460
438
  return rendered
461
439
 
@@ -463,11 +441,8 @@ def render_directive(kind: DirectiveKind, /, **operands: str) -> str:
463
441
  __all__ = [
464
442
  "CanonicalDirective",
465
443
  "DirectiveKind",
466
- "ValidatedDirective",
467
444
  "contains_multiple_canonical_directives",
468
445
  "decompose_directive",
469
- "is_canonical_directive",
470
446
  "match_canonical_directive_start",
471
447
  "render_directive",
472
- "validate_directive",
473
448
  ]