context-compiler 0.7.2__tar.gz → 0.7.4__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.
- {context_compiler-0.7.2 → context_compiler-0.7.4}/AGENTS.md +10 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/PKG-INFO +64 -11
- {context_compiler-0.7.2 → context_compiler-0.7.4}/README.md +63 -10
- {context_compiler-0.7.2 → context_compiler-0.7.4}/docs/DescriptionAndMilestones.md +6 -6
- {context_compiler-0.7.2 → context_compiler-0.7.4}/docs/DesignPhilosophy.md +4 -4
- {context_compiler-0.7.2 → context_compiler-0.7.4}/docs/llm-preprocessor.md +4 -5
- {context_compiler-0.7.2 → context_compiler-0.7.4}/docs/multi-engine.md +3 -3
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/01_persistent_guardrails.py +2 -2
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/03_ambiguity_with_clarification.py +3 -3
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/04_tool_governance_denylist.py +2 -2
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/05_llm_integration_pattern.py +10 -8
- context_compiler-0.7.4/examples/08_controller_preview_diff.py +30 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/README.md +6 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/_util.py +12 -9
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/integrations/README.md +2 -2
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/integrations/litellm/README.md +1 -1
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/integrations/litellm/basic.py +22 -13
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/integrations/litellm/with_preprocessor.py +22 -13
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/integrations/litellm_proxy/README.md +1 -1
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/integrations/litellm_proxy/context_compiler_precall_hook.py +2 -1
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/integrations/litellm_proxy/context_compiler_precall_hook_with_preprocessor.py +2 -1
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/integrations/openwebui/README.md +9 -9
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/integrations/openwebui/open_webui_pipe.py +26 -14
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/integrations/openwebui/open_webui_pipe_with_preprocessor.py +26 -14
- {context_compiler-0.7.2 → context_compiler-0.7.4}/experimental/preprocessor/README.md +5 -5
- {context_compiler-0.7.2 → context_compiler-0.7.4}/pyproject.toml +1 -1
- {context_compiler-0.7.2 → context_compiler-0.7.4}/src/context_compiler/__init__.py +21 -1
- {context_compiler-0.7.2 → context_compiler-0.7.4}/src/context_compiler/const.py +5 -0
- context_compiler-0.7.4/src/context_compiler/decision_helpers.py +24 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/src/context_compiler/repl.py +1 -1
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/README.md +13 -1
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/api/public-api-v1.json +9 -1
- context_compiler-0.7.4/tests/fixtures/conformance/checkpoint/008_export_checkpoint_json_wrapper_shape.json +38 -0
- context_compiler-0.7.4/tests/fixtures/conformance/checkpoint/009_import_checkpoint_json_restores_authoritative_state_no_pending.json +39 -0
- context_compiler-0.7.4/tests/fixtures/conformance/checkpoint/010_checkpoint_json_round_trip_state_and_pending_parity.json +37 -0
- context_compiler-0.7.4/tests/fixtures/conformance/checkpoint/011_pending_clarification_through_checkpoint_json_restore_yes_resolution.json +45 -0
- context_compiler-0.7.4/tests/fixtures/conformance/checkpoint/012_import_checkpoint_json_malformed_rejected.json +25 -0
- context_compiler-0.7.4/tests/fixtures/conformance/checkpoint/013_import_checkpoint_json_invalid_shape_rejected.json +25 -0
- context_compiler-0.7.4/tests/fixtures/conformance/checkpoint/014_import_checkpoint_json_invalid_authoritative_state_rejected.json +25 -0
- context_compiler-0.7.4/tests/fixtures/conformance/checkpoint/015_import_checkpoint_json_invalid_payload_is_all_or_nothing.json +42 -0
- context_compiler-0.7.4/tests/fixtures/conformance/controller/001_step_update_envelope_and_state_snapshot.json +39 -0
- context_compiler-0.7.4/tests/fixtures/conformance/controller/002_preview_mutating_update_reports_would_mutate_and_no_live_mutation.json +58 -0
- context_compiler-0.7.4/tests/fixtures/conformance/controller/003_preview_idempotent_update_reports_non_mutating.json +69 -0
- context_compiler-0.7.4/tests/fixtures/conformance/controller/004_preview_clarify_reports_non_mutating_and_restores_pending.json +54 -0
- context_compiler-0.7.4/tests/fixtures/conformance/controller/005_preview_pending_yes_reports_mutation_but_preserves_live_pending.json +67 -0
- context_compiler-0.7.4/tests/fixtures/conformance/controller/006_state_diff_structural_changes.json +52 -0
- context_compiler-0.7.4/tests/fixtures/preprocessor/parse-canonical-directive-prohibit-peanuts.json +6 -0
- context_compiler-0.7.4/tests/fixtures/preprocessor/parse-malformed-near-miss-rejected.json +6 -0
- context_compiler-0.7.4/tests/fixtures/preprocessor/parse-multiple-directives-rejected.json +6 -0
- context_compiler-0.7.4/tests/fixtures/preprocessor/parse-no-directive-sentinel.json +6 -0
- context_compiler-0.7.4/tests/fixtures/preprocessor/parse-source-input-structured-json-directive-self-accepted.json +7 -0
- context_compiler-0.7.4/tests/fixtures/preprocessor/parse-unknown-directive-like-rejected.json +6 -0
- context_compiler-0.7.4/tests/test_decision_constants.py +70 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_fixtures.py +59 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/uv.lock +1 -1
- context_compiler-0.7.2/src/context_compiler/decision_constants.py +0 -5
- context_compiler-0.7.2/tests/test_decision_constants.py +0 -7
- {context_compiler-0.7.2 → context_compiler-0.7.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/.github/pull_request_template.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/.github/workflows/ci.yml +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/.github/workflows/publish-pypi.yml +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/.github/workflows/stress-tests.yml +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/.gitignore +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/.pre-commit-config.yaml +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/CODE_OF_CONDUCT.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/CONTRIBUTING.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/LICENSE +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/SECURITY.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/01_llm_contradiction_clarify.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/02_llm_constraint_guardrail.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/03_llm_premise_guardrail.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/04_llm_tool_denylist_guardrail.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/05_llm_prompt_drift_vs_state.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/06_llm_context_compaction.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/07_llm_prompt_vs_state.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/08_llm_replacement_precondition.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/09_llm_pending_clarification.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/README.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/__init__.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/common.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/llm_client.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/demos/run_demo.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/docs/DirectiveGrammarSpec.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/docs/README.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/docs/demos-results.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/evals/litellm_proxy_additional_findings.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/evals/litellm_proxy_behavioral_comparisons.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/evals/swe-bench/README.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/evals/swe-bench/RUBRIC.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/evals/swe-bench/manifest.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/evals/swe-bench/swe-bench.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/evals/swe-bench/tasks/django__django-12453.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/evals/swe-bench/tasks/django__django-13158.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/evals/swe-bench/tasks/django__django-13964.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/evals/swe-bench/tasks/django__django-15252.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/evals/swe-bench/tasks/matplotlib__matplotlib-23299.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/evals/swe-bench/tasks/psf__requests-1963.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/02_configuration_and_correction.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/06_transcript_replay.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/07_single_policy_correction.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/examples/integrations/litellm_proxy/config.example.yaml +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/experimental/__init__.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/experimental/preprocessor/__init__.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/experimental/preprocessor/constants.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/experimental/preprocessor/heuristic_preprocessor.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/experimental/preprocessor/output_validation.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/experimental/preprocessor/prompt_utils.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/experimental/preprocessor/prompts/default.txt +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/experimental/preprocessor/prompts/llama.txt +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/host_support/__init__.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/host_support/confirmation.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/host_support/provider_mode.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/src/context_compiler/controller.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/src/context_compiler/engine.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/src/context_compiler/observability.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/checkpoint/001_import_checkpoint_non_object_rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/checkpoint/002_import_checkpoint_unsupported_version_rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/checkpoint/003_import_checkpoint_invalid_pending_shape_rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/checkpoint/004_import_checkpoint_invalid_replacement_shape_rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/checkpoint/005_import_checkpoint_invalid_authoritative_state_rejected_atomically.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/checkpoint/006_import_checkpoint_pending_null_clears_existing_pending.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/checkpoint/007_import_checkpoint_pending_absent_clears_existing_pending.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/state-json/001_export_json_canonical_sorted_compact.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/state-json/002_import_json_invalid_json_rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/state-json/003_import_json_non_object_rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/state-json/004_import_json_unsupported_version_rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/state-json/005_import_json_empty_normalized_policy_key_rejected_atomically.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/state-json/006_import_json_valid_normalized_policy_key_accepted.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/001_set_premise_update.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/002_use_item_normalization.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/003_conflict_prohibit_clarify.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/004_remove_policy_missing_idempotent_update.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/005_exact_prefix_passthrough_leading_space.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/006_near_miss_set_premise_to.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/007_near_miss_change_premise_missing_to.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/008_replace_missing_source_clarify_prompt.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/009_pending_affirmative_normalized_token.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/010_pending_negative_normalized_token.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/011_pending_unmatched_reuses_prompt.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/012_clear_premise_populated_update.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/013_clear_premise_already_null_update.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/014_reset_policies_populated_update.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/015_reset_policies_already_empty_update.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/016_clear_state_populated_update.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/017_clear_state_already_empty_update.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/018_pending_affirmative_punctuation_token.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/step/019_pending_negative_punctuation_token.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/transcript/001_user_only_replay_state.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/transcript/002_non_string_user_content_ignored.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/transcript/003_stops_at_first_clarify_later_yes.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/conformance/transcript/004_stops_at_first_clarify_later_no.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/controller/preview_clarify_no_mutation.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/controller/preview_idempotent_no_mutation.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/README.md +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/expected/contradiction_clarify.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/expected/pending_clarify_no.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/expected/pending_clarify_unmatched.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/expected/pending_clarify_yes.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/expected/premise_lifecycle.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/expected/replacement_clarify.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/scenarios/contradiction_clarify.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/scenarios/pending_clarify_no.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/scenarios/pending_clarify_unmatched.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/scenarios/pending_clarify_yes.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/scenarios/premise_lifecycle.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/engine-regression/structured/scenarios/replacement_clarify.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/admin-alias-remove-policies-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/admin-alias-reset-policy-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/ambiguous-directive-adjacent.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/canonical-directive-bracket-wrapper.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/canonical-directive-case-normalized-use-docker.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/canonical-directive-clear-state-period.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/canonical-directive-clear-state.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/canonical-directive-paren-wrapper.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/canonical-directive-prohibit-peanuts.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/canonical-directive-quoted-payload-use-docker.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/canonical-directive-reset-policies-bang.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/canonical-directive-whitespace-collapsed-use-docker.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/fenced-code-block-directive-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/inline-prose-code-directive-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/list-prefix-directive-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/malformed-replacement-instead-docker-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/meta-prefix-directive-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/mixed-directive-task-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/mixed-intent-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/modal-please-clear-state-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/multiline-multi-directive-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/natural-language-dont-use-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/near-miss-change-premise-missing-to-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/near-miss-change-premise-to-empty-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/near-miss-prohibit-empty-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/near-miss-remove-policy-empty-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/near-miss-set-premise-empty-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/near-miss-set-premise-to-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/near-miss-use-empty-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/near-miss-use-instead-of-missing-new-item-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/near-miss-use-instead-of-missing-old-item-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/nested-wrapper-clear-state-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/ordinary-non-directive.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/parse-source-input-fenced-code-rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/parse-source-input-inline-prose-code-rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/parse-source-input-mixed-directive-task-rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/parse-source-input-multiline-rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/parse-source-input-question-form-rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/parse-source-input-quoted-payload-locked.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/parse-source-input-reported-speech-rejected.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/parse-source-input-safe-canonical-use-docker.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/parse-source-input-safe-canonicalization-use-docker.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/public-api-v1.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/question-can-you-use-docker-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/question-use-docker-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/quoted-exact-use-docker-backtick-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/quoted-exact-use-docker-single-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/quoted-exact-use-docker-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/quoted-reported-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/reported-speech-docs-say-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/sentence-adjacent-directive-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/unsupported-alias-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/validator-invalid-json-shape-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/validator-malformed-json-text-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/validator-malformed-sentinel-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/validator-malformed-text-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/validator-multi-candidate-directive-unknown.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/validator-sentinel-no-directive.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/validator-source-input-allow-safe-directive.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/validator-source-input-block-change-premise-rewrite.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/validator-source-input-block-set-premise-rewrite.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/fixtures/preprocessor/validator-structured-json-directive.json +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_04_grammar_edge_cases.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_04_llm_tool_governance.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_07_llm_prompt_engineering_comparison.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_api_contract_fixture.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_controller.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_demo_01_04_behavior.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_demo_05_prompt_contract.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_demo_07_output_clarity.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_demo_08_09_behavior.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_demo_compaction.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_demo_oracle_properties.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_engine.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_example_integrations_imports.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_examples.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_examples_behavior.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_examples_smoke.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_host_confirmation.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_host_observability.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_litellm_checkpoint_integration.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_litellm_integration_error_paths.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_litellm_preprocessor_model_config.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_llm_client.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_llm_demos.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_openwebui_pipe.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_openwebui_preprocessor_pipe.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_precompiler_prompt_utils.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_preprocessor_api_contract_fixture.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_preprocessor_conformance.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_preprocessor_heuristic.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_preprocessor_heuristic_properties.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_preprocessor_output_validation.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_preprocessor_validator_properties.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_properties.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_provider_helper.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_repl.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_repl_coverage.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_repl_properties.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_run_demo.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_smoke.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_structured_regression.py +0 -0
- {context_compiler-0.7.2 → context_compiler-0.7.4}/tests/test_transcript_replay.py +0 -0
|
@@ -75,6 +75,7 @@ Prefer modern typing syntax:
|
|
|
75
75
|
|
|
76
76
|
## PR guidance
|
|
77
77
|
- Never open or merge a PR targeting `main` from `main`; always use a feature branch.
|
|
78
|
+
- Always use the repository PR template when creating or updating PR descriptions.
|
|
78
79
|
- PR titles must use the same format as commits: `<type>: <summary>`.
|
|
79
80
|
- PR descriptions should include:
|
|
80
81
|
- what changed
|
|
@@ -82,6 +83,11 @@ Prefer modern typing syntax:
|
|
|
82
83
|
- Do not include a dedicated "Validation" section in PR text.
|
|
83
84
|
- Keep PR scope aligned to the requested task; if scope grows, ask for guidance before expanding.
|
|
84
85
|
|
|
86
|
+
## Issue guidance
|
|
87
|
+
- Always use the repository issue templates when creating or updating issues.
|
|
88
|
+
- Use `bug_report` for defects and regressions.
|
|
89
|
+
- Use `feature_request` for new capabilities or enhancements.
|
|
90
|
+
|
|
85
91
|
## CI
|
|
86
92
|
Do not modify GitHub CI workflows unless explicitly asked.
|
|
87
93
|
|
|
@@ -105,6 +111,10 @@ Prefer plain, concrete wording when accurate. Examples:
|
|
|
105
111
|
|
|
106
112
|
Avoid describing features only in architectural terms when a behavior-first explanation is possible.
|
|
107
113
|
|
|
114
|
+
Prefer direct subjects and strong verbs.
|
|
115
|
+
Avoid noun stacks and passive phrasing when a simpler active sentence is clearer.
|
|
116
|
+
Use simpler wording unless technical precision requires formal terminology.
|
|
117
|
+
|
|
108
118
|
Specification and contract documents are different:
|
|
109
119
|
- preserve precise terminology
|
|
110
120
|
- preserve unambiguous behavioral guarantees
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: context-compiler
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.4
|
|
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
|
|
@@ -40,11 +40,11 @@ Description-Content-Type: text/markdown
|
|
|
40
40
|
[](https://pypi.org/project/context-compiler/)
|
|
41
41
|
[](https://pypi.org/project/context-compiler/)
|
|
42
42
|
|
|
43
|
-
Some behaviors require explicit host-side state
|
|
43
|
+
Some behaviors require explicit host-side state handling.
|
|
44
44
|
|
|
45
45
|
Context Compiler is a deterministic host-side state layer for LLM applications.
|
|
46
|
-
It
|
|
47
|
-
|
|
46
|
+
It applies explicit premise and policy updates so state changes stay fixed and
|
|
47
|
+
repeatable.
|
|
48
48
|
|
|
49
49
|
## What prompting and reinjection can do
|
|
50
50
|
|
|
@@ -59,17 +59,17 @@ pending confirmations from checkpoints.
|
|
|
59
59
|
## What prompting cannot do by itself
|
|
60
60
|
|
|
61
61
|
Prompt text (including reinjected state text) helps, but it does not give your
|
|
62
|
-
app
|
|
62
|
+
app clear rules for when state can change. By itself, it does not provide:
|
|
63
63
|
|
|
64
64
|
- rules your app controls for state changes
|
|
65
65
|
- replacement precondition checks (`use X instead of Y` when `Y` may be absent)
|
|
66
66
|
- confirmation flows that must complete before anything else changes
|
|
67
|
-
- clear
|
|
67
|
+
- clear rules for when to block a change
|
|
68
68
|
- reliable checkpoint restore for both saved state and pending confirmation flow
|
|
69
69
|
|
|
70
70
|
## What Context Compiler provides
|
|
71
71
|
|
|
72
|
-
Context Compiler provides fixed host-side state
|
|
72
|
+
Context Compiler provides fixed host-side state handling:
|
|
73
73
|
|
|
74
74
|
- deterministic directive handling for explicit user state changes
|
|
75
75
|
- clarification instead of silent overwrite for blocked/ambiguous changes
|
|
@@ -139,22 +139,55 @@ Bare REPL input behavior remains unchanged.
|
|
|
139
139
|
|
|
140
140
|
Or in code:
|
|
141
141
|
```python
|
|
142
|
-
from context_compiler import
|
|
142
|
+
from context_compiler import (
|
|
143
|
+
create_engine,
|
|
144
|
+
get_clarify_prompt,
|
|
145
|
+
is_clarify,
|
|
146
|
+
is_update,
|
|
147
|
+
)
|
|
143
148
|
|
|
144
149
|
engine = create_engine()
|
|
145
150
|
|
|
146
151
|
user_input = "prohibit peanuts"
|
|
147
152
|
decision = engine.step(user_input)
|
|
148
153
|
|
|
149
|
-
if decision
|
|
150
|
-
show_to_user(decision
|
|
151
|
-
elif decision
|
|
154
|
+
if is_clarify(decision):
|
|
155
|
+
show_to_user(get_clarify_prompt(decision))
|
|
156
|
+
elif is_update(decision):
|
|
152
157
|
messages = build_messages(engine.state, user_input)
|
|
153
158
|
render(call_llm(messages))
|
|
154
159
|
else:
|
|
155
160
|
render(call_llm(user_input))
|
|
156
161
|
```
|
|
157
162
|
|
|
163
|
+
Controller quick example:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from context_compiler import (
|
|
167
|
+
get_decision_state,
|
|
168
|
+
is_update,
|
|
169
|
+
create_engine,
|
|
170
|
+
preview,
|
|
171
|
+
state_diff,
|
|
172
|
+
step,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
engine = create_engine()
|
|
176
|
+
|
|
177
|
+
before = engine.state
|
|
178
|
+
dry_run = preview(engine, "prohibit peanuts")
|
|
179
|
+
print(dry_run["would_mutate"]) # True
|
|
180
|
+
planned_change = state_diff(before, dry_run["state_after"])
|
|
181
|
+
print(planned_change["changed"]) # True
|
|
182
|
+
|
|
183
|
+
after_preview = engine.state
|
|
184
|
+
print(state_diff(before, after_preview)["changed"]) # False (preview does not mutate state)
|
|
185
|
+
|
|
186
|
+
applied = step(engine, "prohibit peanuts")
|
|
187
|
+
print(is_update(applied["decision"])) # True
|
|
188
|
+
print(get_decision_state(applied["decision"]) is not None) # True
|
|
189
|
+
```
|
|
190
|
+
|
|
158
191
|
## Installation
|
|
159
192
|
|
|
160
193
|
Requirements:
|
|
@@ -297,6 +330,10 @@ Meaning:
|
|
|
297
330
|
| update | authoritative state mutated; host may call LLM with updated state |
|
|
298
331
|
| clarify | show `prompt_to_user` and do not call the LLM |
|
|
299
332
|
|
|
333
|
+
For normal app code, prefer exported decision helpers (`is_clarify`,
|
|
334
|
+
`is_update`, `is_passthrough`, `get_clarify_prompt`, `get_decision_state`)
|
|
335
|
+
instead of direct key traversal.
|
|
336
|
+
|
|
300
337
|
---
|
|
301
338
|
|
|
302
339
|
### API Reference
|
|
@@ -334,6 +371,17 @@ Decision-kind constants are also exported for host branching readability:
|
|
|
334
371
|
- `DECISION_UPDATE`
|
|
335
372
|
- `DECISION_CLARIFY`
|
|
336
373
|
|
|
374
|
+
Decision helpers are also exported for common host-side checks:
|
|
375
|
+
- `is_update(decision)`
|
|
376
|
+
- `is_clarify(decision)`
|
|
377
|
+
- `is_passthrough(decision)`
|
|
378
|
+
- `get_clarify_prompt(decision)`
|
|
379
|
+
- `get_decision_state(decision)`
|
|
380
|
+
|
|
381
|
+
Policy value constants are exported for explicit policy comparisons:
|
|
382
|
+
- `POLICY_USE`
|
|
383
|
+
- `POLICY_PROHIBIT`
|
|
384
|
+
|
|
337
385
|
---
|
|
338
386
|
|
|
339
387
|
## State Model
|
|
@@ -348,6 +396,8 @@ The compiler keeps a current state snapshot that your app can trust.
|
|
|
348
396
|
Identical input sequences always produce identical state.
|
|
349
397
|
|
|
350
398
|
The internal structure of the state is intentionally opaque to host applications.
|
|
399
|
+
For normal reads, prefer `get_premise_value(state)` and
|
|
400
|
+
`get_policy_items(state, ...)` over direct key traversal.
|
|
351
401
|
|
|
352
402
|
---
|
|
353
403
|
|
|
@@ -384,6 +434,9 @@ Checkpoint object shape:
|
|
|
384
434
|
}
|
|
385
435
|
```
|
|
386
436
|
|
|
437
|
+
The checkpoint shape above is an explicit serialization contract. At this
|
|
438
|
+
boundary, direct key access is expected.
|
|
439
|
+
|
|
387
440
|
Notes:
|
|
388
441
|
|
|
389
442
|
- `pending` is `null` when no continuation is waiting for confirmation.
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
[](https://pypi.org/project/context-compiler/)
|
|
5
5
|
[](https://pypi.org/project/context-compiler/)
|
|
6
6
|
|
|
7
|
-
Some behaviors require explicit host-side state
|
|
7
|
+
Some behaviors require explicit host-side state handling.
|
|
8
8
|
|
|
9
9
|
Context Compiler is a deterministic host-side state layer for LLM applications.
|
|
10
|
-
It
|
|
11
|
-
|
|
10
|
+
It applies explicit premise and policy updates so state changes stay fixed and
|
|
11
|
+
repeatable.
|
|
12
12
|
|
|
13
13
|
## What prompting and reinjection can do
|
|
14
14
|
|
|
@@ -23,17 +23,17 @@ pending confirmations from checkpoints.
|
|
|
23
23
|
## What prompting cannot do by itself
|
|
24
24
|
|
|
25
25
|
Prompt text (including reinjected state text) helps, but it does not give your
|
|
26
|
-
app
|
|
26
|
+
app clear rules for when state can change. By itself, it does not provide:
|
|
27
27
|
|
|
28
28
|
- rules your app controls for state changes
|
|
29
29
|
- replacement precondition checks (`use X instead of Y` when `Y` may be absent)
|
|
30
30
|
- confirmation flows that must complete before anything else changes
|
|
31
|
-
- clear
|
|
31
|
+
- clear rules for when to block a change
|
|
32
32
|
- reliable checkpoint restore for both saved state and pending confirmation flow
|
|
33
33
|
|
|
34
34
|
## What Context Compiler provides
|
|
35
35
|
|
|
36
|
-
Context Compiler provides fixed host-side state
|
|
36
|
+
Context Compiler provides fixed host-side state handling:
|
|
37
37
|
|
|
38
38
|
- deterministic directive handling for explicit user state changes
|
|
39
39
|
- clarification instead of silent overwrite for blocked/ambiguous changes
|
|
@@ -103,22 +103,55 @@ Bare REPL input behavior remains unchanged.
|
|
|
103
103
|
|
|
104
104
|
Or in code:
|
|
105
105
|
```python
|
|
106
|
-
from context_compiler import
|
|
106
|
+
from context_compiler import (
|
|
107
|
+
create_engine,
|
|
108
|
+
get_clarify_prompt,
|
|
109
|
+
is_clarify,
|
|
110
|
+
is_update,
|
|
111
|
+
)
|
|
107
112
|
|
|
108
113
|
engine = create_engine()
|
|
109
114
|
|
|
110
115
|
user_input = "prohibit peanuts"
|
|
111
116
|
decision = engine.step(user_input)
|
|
112
117
|
|
|
113
|
-
if decision
|
|
114
|
-
show_to_user(decision
|
|
115
|
-
elif decision
|
|
118
|
+
if is_clarify(decision):
|
|
119
|
+
show_to_user(get_clarify_prompt(decision))
|
|
120
|
+
elif is_update(decision):
|
|
116
121
|
messages = build_messages(engine.state, user_input)
|
|
117
122
|
render(call_llm(messages))
|
|
118
123
|
else:
|
|
119
124
|
render(call_llm(user_input))
|
|
120
125
|
```
|
|
121
126
|
|
|
127
|
+
Controller quick example:
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from context_compiler import (
|
|
131
|
+
get_decision_state,
|
|
132
|
+
is_update,
|
|
133
|
+
create_engine,
|
|
134
|
+
preview,
|
|
135
|
+
state_diff,
|
|
136
|
+
step,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
engine = create_engine()
|
|
140
|
+
|
|
141
|
+
before = engine.state
|
|
142
|
+
dry_run = preview(engine, "prohibit peanuts")
|
|
143
|
+
print(dry_run["would_mutate"]) # True
|
|
144
|
+
planned_change = state_diff(before, dry_run["state_after"])
|
|
145
|
+
print(planned_change["changed"]) # True
|
|
146
|
+
|
|
147
|
+
after_preview = engine.state
|
|
148
|
+
print(state_diff(before, after_preview)["changed"]) # False (preview does not mutate state)
|
|
149
|
+
|
|
150
|
+
applied = step(engine, "prohibit peanuts")
|
|
151
|
+
print(is_update(applied["decision"])) # True
|
|
152
|
+
print(get_decision_state(applied["decision"]) is not None) # True
|
|
153
|
+
```
|
|
154
|
+
|
|
122
155
|
## Installation
|
|
123
156
|
|
|
124
157
|
Requirements:
|
|
@@ -261,6 +294,10 @@ Meaning:
|
|
|
261
294
|
| update | authoritative state mutated; host may call LLM with updated state |
|
|
262
295
|
| clarify | show `prompt_to_user` and do not call the LLM |
|
|
263
296
|
|
|
297
|
+
For normal app code, prefer exported decision helpers (`is_clarify`,
|
|
298
|
+
`is_update`, `is_passthrough`, `get_clarify_prompt`, `get_decision_state`)
|
|
299
|
+
instead of direct key traversal.
|
|
300
|
+
|
|
264
301
|
---
|
|
265
302
|
|
|
266
303
|
### API Reference
|
|
@@ -298,6 +335,17 @@ Decision-kind constants are also exported for host branching readability:
|
|
|
298
335
|
- `DECISION_UPDATE`
|
|
299
336
|
- `DECISION_CLARIFY`
|
|
300
337
|
|
|
338
|
+
Decision helpers are also exported for common host-side checks:
|
|
339
|
+
- `is_update(decision)`
|
|
340
|
+
- `is_clarify(decision)`
|
|
341
|
+
- `is_passthrough(decision)`
|
|
342
|
+
- `get_clarify_prompt(decision)`
|
|
343
|
+
- `get_decision_state(decision)`
|
|
344
|
+
|
|
345
|
+
Policy value constants are exported for explicit policy comparisons:
|
|
346
|
+
- `POLICY_USE`
|
|
347
|
+
- `POLICY_PROHIBIT`
|
|
348
|
+
|
|
301
349
|
---
|
|
302
350
|
|
|
303
351
|
## State Model
|
|
@@ -312,6 +360,8 @@ The compiler keeps a current state snapshot that your app can trust.
|
|
|
312
360
|
Identical input sequences always produce identical state.
|
|
313
361
|
|
|
314
362
|
The internal structure of the state is intentionally opaque to host applications.
|
|
363
|
+
For normal reads, prefer `get_premise_value(state)` and
|
|
364
|
+
`get_policy_items(state, ...)` over direct key traversal.
|
|
315
365
|
|
|
316
366
|
---
|
|
317
367
|
|
|
@@ -348,6 +398,9 @@ Checkpoint object shape:
|
|
|
348
398
|
}
|
|
349
399
|
```
|
|
350
400
|
|
|
401
|
+
The checkpoint shape above is an explicit serialization contract. At this
|
|
402
|
+
boundary, direct key access is expected.
|
|
403
|
+
|
|
351
404
|
Notes:
|
|
352
405
|
|
|
353
406
|
- `pending` is `null` when no continuation is waiting for confirmation.
|
|
@@ -10,9 +10,9 @@ conversations, and state can conflict over time.
|
|
|
10
10
|
This project adds a deterministic state layer that is independent of the model.
|
|
11
11
|
The model handles interpretation and generation; the engine handles premise and
|
|
12
12
|
policies. Only explicit user directives can change state.
|
|
13
|
-
|
|
14
|
-
without
|
|
15
|
-
|
|
13
|
+
When the model reasons and the engine owns state, behavior stays reliable
|
|
14
|
+
without retraining the model. The system never derives authoritative state from
|
|
15
|
+
model responses.
|
|
16
16
|
The goal is not to make the model smarter, but to make interactions
|
|
17
17
|
predictable: once a statement is corrected or scoped, future responses
|
|
18
18
|
must respect that change.
|
|
@@ -64,7 +64,7 @@ After correcting or constraining the assistant once, the behavior remains consis
|
|
|
64
64
|
### M3 — Cross-Session Recall (implemented, engine-level / host-enabled)
|
|
65
65
|
|
|
66
66
|
**Goal**
|
|
67
|
-
|
|
67
|
+
Help apps safely reuse saved exported state.
|
|
68
68
|
|
|
69
69
|
**Core capability:**
|
|
70
70
|
|
|
@@ -77,8 +77,8 @@ Extend app-level workflows around persisted exported state safely and intentiona
|
|
|
77
77
|
|
|
78
78
|
**Deliverables:**
|
|
79
79
|
|
|
80
|
-
- App-side storage
|
|
81
|
-
- App-side storage
|
|
80
|
+
- App-side storage and recovery patterns built on the existing import/export API
|
|
81
|
+
- App-side storage and recovery patterns for checkpoint object and checkpoint JSON restore
|
|
82
82
|
|
|
83
83
|
**User-visible outcome:**
|
|
84
84
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## The Problem with Implicit State
|
|
4
4
|
|
|
5
|
-
Modern LLM applications
|
|
5
|
+
Modern LLM applications often manage conversational state implicitly: the model reads the transcript, infers active constraints, and generates a response. This works well for short conversations and simple tasks.
|
|
6
6
|
|
|
7
7
|
It breaks down reliably in longer conversations, correction flows, and multi-turn constraint management. Constraints drift. Corrections get partially applied or treated as additive rather than authoritative replacements. Contradictions accumulate instead of resolving. The model interprets intent rather than enforcing it.
|
|
8
8
|
|
|
@@ -16,7 +16,7 @@ Explicit state management is not a new idea. Earlier AI systems maintained struc
|
|
|
16
16
|
|
|
17
17
|
The core insight is simple: maintain an explicit active set of rules rather than inferring the relevant context from history each time. What is in the active set is known with certainty. What is not in it is not active.
|
|
18
18
|
|
|
19
|
-
These approaches succeeded in narrow, well-defined domains
|
|
19
|
+
These approaches succeeded in narrow, well-defined domains because explicit state gives guarantees that implicit inference cannot. The limitation was not state management itself. Handling natural language and ambiguity was the hard part, and that work consumed most of the design effort.
|
|
20
20
|
|
|
21
21
|
Modern LLMs handle natural language interpretation and generation far more effectively than earlier systems. This changes the calculus: the language interface problem is largely addressed. As end-to-end neural approaches became dominant, many systems shifted toward transcript-driven implicit state management, assuming a capable model could handle state implicitly.
|
|
22
22
|
|
|
@@ -26,8 +26,8 @@ That assumption is incorrect in practice, for the structural reason described ab
|
|
|
26
26
|
|
|
27
27
|
Context Compiler applies explicit state management to the modern LLM context, with a clear division of responsibilities:
|
|
28
28
|
|
|
29
|
-
- The LLM handles what it
|
|
30
|
-
- The deterministic engine handles what probabilistic systems handle poorly
|
|
29
|
+
- The LLM handles what it does well: language understanding, reasoning, generation, and ambiguity in user intent
|
|
30
|
+
- The deterministic engine handles what probabilistic systems handle poorly: keep explicit state across turns, enforce constraints, and make corrections replace prior state instead of competing with it
|
|
31
31
|
|
|
32
32
|
The preprocessor layer bridges the two: it uses the LLM's language understanding to translate natural language directive intent into canonical form, which the deterministic engine can then process reliably. Fuzzy where it needs to be fuzzy, deterministic where determinism matters.
|
|
33
33
|
|
|
@@ -15,8 +15,7 @@ layer. Do not rely on repo-relative preprocessor paths.
|
|
|
15
15
|
|
|
16
16
|
## Architectural framing
|
|
17
17
|
|
|
18
|
-
The preprocessor
|
|
19
|
-
state changes.
|
|
18
|
+
The preprocessor helps your app, but it does not own state changes.
|
|
20
19
|
|
|
21
20
|
Model/tool-description translation can help with simple direct cases, but
|
|
22
21
|
integrations should not rely on model intent translation alone to decide when
|
|
@@ -25,10 +24,10 @@ state changes.
|
|
|
25
24
|
In simpler hosts without an embedded model, this preprocessor provides a
|
|
26
25
|
conservative translation path.
|
|
27
26
|
|
|
28
|
-
In model-assisted hosts, the app still
|
|
27
|
+
In model-assisted hosts, the app still validates outputs before applying them.
|
|
29
28
|
|
|
30
29
|
Both paths send canonical directives to the same deterministic engine. The
|
|
31
|
-
engine
|
|
30
|
+
engine controls state updates.
|
|
32
31
|
|
|
33
32
|
In MCP/tool-calling environments, over-eager tool calling on conversational or
|
|
34
33
|
ambiguous input is a known failure mode. Conservative preprocessing and
|
|
@@ -36,7 +35,7 @@ validation help reduce unintended mutation.
|
|
|
36
35
|
|
|
37
36
|
## Required flow
|
|
38
37
|
|
|
39
|
-
Recommended
|
|
38
|
+
Recommended flow:
|
|
40
39
|
|
|
41
40
|
1. heuristic preprocessing
|
|
42
41
|
2. validate candidate output
|
|
@@ -73,7 +73,7 @@ Introduce multiple engines only when you need **independent lifecycle or isolati
|
|
|
73
73
|
## Combining Policies from Multiple Sources
|
|
74
74
|
|
|
75
75
|
If you need to combine constraints from separate sources, do it explicitly in
|
|
76
|
-
host code
|
|
76
|
+
host code: replay directives through `step(...)` into a target engine.
|
|
77
77
|
|
|
78
78
|
Pattern:
|
|
79
79
|
|
|
@@ -81,5 +81,5 @@ Pattern:
|
|
|
81
81
|
2. Replay each directive via `engine.step(...)`
|
|
82
82
|
3. Handle any returned `clarify` decisions explicitly
|
|
83
83
|
|
|
84
|
-
This keeps conflict handling in normal engine
|
|
85
|
-
|
|
84
|
+
This keeps conflict handling in normal engine behavior and avoids adding merge
|
|
85
|
+
rules to core state APIs.
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
from _util import print_decision_summary, print_state_summary
|
|
4
4
|
|
|
5
|
-
from context_compiler import State, create_engine, get_policy_items
|
|
5
|
+
from context_compiler import POLICY_PROHIBIT, State, create_engine, get_policy_items
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def build_prompt(state: State, user_input: str) -> str:
|
|
9
|
-
prohibit = get_policy_items(state,
|
|
9
|
+
prohibit = get_policy_items(state, POLICY_PROHIBIT)
|
|
10
10
|
prohibit_text = ", ".join(prohibit) if prohibit else "(none)"
|
|
11
11
|
return (
|
|
12
12
|
"System: Follow authoritative conversation state.\n"
|
{context_compiler-0.7.2 → context_compiler-0.7.4}/examples/03_ambiguity_with_clarification.py
RENAMED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from _util import print_decision_summary, print_state_summary
|
|
4
4
|
|
|
5
|
-
from context_compiler import create_engine
|
|
5
|
+
from context_compiler import create_engine, get_clarify_prompt, is_clarify
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def fake_llm(user_input: str) -> str:
|
|
@@ -23,9 +23,9 @@ def main() -> None:
|
|
|
23
23
|
print_decision_summary(decision2)
|
|
24
24
|
print()
|
|
25
25
|
|
|
26
|
-
if decision2
|
|
26
|
+
if is_clarify(decision2):
|
|
27
27
|
print("Host behavior: clarification pending, do NOT call LLM.")
|
|
28
|
-
print(f"Clarify prompt: {decision2
|
|
28
|
+
print(f"Clarify prompt: {get_clarify_prompt(decision2)}")
|
|
29
29
|
else:
|
|
30
30
|
fake_llm("use peanuts")
|
|
31
31
|
print()
|
|
@@ -4,7 +4,7 @@ from dataclasses import dataclass
|
|
|
4
4
|
|
|
5
5
|
from _util import print_decision_summary, print_state_summary
|
|
6
6
|
|
|
7
|
-
from context_compiler import create_engine, get_policy_items
|
|
7
|
+
from context_compiler import POLICY_PROHIBIT, create_engine, get_policy_items
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@dataclass
|
|
@@ -32,7 +32,7 @@ def main() -> None:
|
|
|
32
32
|
print()
|
|
33
33
|
|
|
34
34
|
print("Host-side tool denylist behavior:")
|
|
35
|
-
prohibit = get_policy_items(state,
|
|
35
|
+
prohibit = get_policy_items(state, POLICY_PROHIBIT)
|
|
36
36
|
tools = [Tool("docker"), Tool("kubectl")]
|
|
37
37
|
for tool in tools:
|
|
38
38
|
if tool.name in prohibit:
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
from _util import print_decision_summary, print_state_summary
|
|
4
4
|
|
|
5
5
|
from context_compiler import (
|
|
6
|
-
DECISION_CLARIFY,
|
|
7
|
-
DECISION_PASSTHROUGH,
|
|
8
|
-
DECISION_UPDATE,
|
|
9
6
|
Engine,
|
|
10
7
|
State,
|
|
11
8
|
create_engine,
|
|
9
|
+
get_clarify_prompt,
|
|
10
|
+
get_decision_state,
|
|
11
|
+
is_clarify,
|
|
12
|
+
is_passthrough,
|
|
13
|
+
is_update,
|
|
12
14
|
)
|
|
13
15
|
|
|
14
16
|
|
|
@@ -27,15 +29,15 @@ def handle_turn(engine_input: str, engine: Engine) -> None:
|
|
|
27
29
|
print(f"User: {engine_input}")
|
|
28
30
|
print_decision_summary(decision)
|
|
29
31
|
|
|
30
|
-
if decision
|
|
32
|
+
if is_passthrough(decision):
|
|
31
33
|
print("Host action: passthrough -> call fake_llm() without state")
|
|
32
34
|
fake_llm(None, engine_input)
|
|
33
|
-
elif decision
|
|
35
|
+
elif is_update(decision):
|
|
34
36
|
print("Host action: update -> call fake_llm() with compiled state")
|
|
35
|
-
fake_llm(decision
|
|
36
|
-
elif decision
|
|
37
|
+
fake_llm(get_decision_state(decision), engine_input)
|
|
38
|
+
elif is_clarify(decision):
|
|
37
39
|
print("Host action: clarify -> show prompt, DO NOT call LLM")
|
|
38
|
-
print("clarify prompt:", decision
|
|
40
|
+
print("clarify prompt:", get_clarify_prompt(decision))
|
|
39
41
|
print()
|
|
40
42
|
|
|
41
43
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Example 8: controller preview + state diff + apply flow."""
|
|
2
|
+
|
|
3
|
+
from _util import print_decision_summary, print_state_summary
|
|
4
|
+
|
|
5
|
+
from context_compiler import create_engine, preview, state_diff, step
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main() -> None:
|
|
9
|
+
engine = create_engine()
|
|
10
|
+
|
|
11
|
+
state_before = engine.state
|
|
12
|
+
print_state_summary(state_before, "state before preview")
|
|
13
|
+
|
|
14
|
+
print("\nPreview: prohibit peanuts")
|
|
15
|
+
preview_result = preview(engine, "prohibit peanuts")
|
|
16
|
+
print("would_mutate:", preview_result["would_mutate"])
|
|
17
|
+
print_decision_summary(preview_result["decision"])
|
|
18
|
+
|
|
19
|
+
state_after_preview = engine.state
|
|
20
|
+
diff_after_preview = state_diff(state_before, state_after_preview)
|
|
21
|
+
print("state changed after preview:", diff_after_preview["changed"])
|
|
22
|
+
|
|
23
|
+
print("\nApply: prohibit peanuts")
|
|
24
|
+
step_result = step(engine, "prohibit peanuts")
|
|
25
|
+
print_decision_summary(step_result["decision"])
|
|
26
|
+
print_state_summary(step_result["state"], "state after step")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if __name__ == "__main__":
|
|
30
|
+
main()
|
|
@@ -40,3 +40,9 @@ Shows `compile_transcript(messages)` from a fresh engine and `engine.apply_trans
|
|
|
40
40
|
|
|
41
41
|
Demonstrates explicit single-policy correction without `reset policies`.
|
|
42
42
|
Shows `prohibit peanuts` -> `remove policy peanuts` -> `use peanuts`.
|
|
43
|
+
|
|
44
|
+
## 08_controller_preview_diff.py
|
|
45
|
+
|
|
46
|
+
Shows controller-layer dry-run behavior with `preview(engine, user_input)`.
|
|
47
|
+
Shows structural state inspection with `state_diff(state_before, state_after)`.
|
|
48
|
+
Shows `step(engine, user_input)` after preview to apply the same input.
|
|
@@ -2,10 +2,14 @@ import json
|
|
|
2
2
|
from typing import Any, Literal
|
|
3
3
|
|
|
4
4
|
from context_compiler import (
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
POLICY_PROHIBIT,
|
|
6
|
+
POLICY_USE,
|
|
7
|
+
get_clarify_prompt,
|
|
8
|
+
get_decision_state,
|
|
7
9
|
get_policy_items,
|
|
8
10
|
get_premise_value,
|
|
11
|
+
is_clarify,
|
|
12
|
+
is_update,
|
|
9
13
|
)
|
|
10
14
|
|
|
11
15
|
|
|
@@ -28,22 +32,21 @@ def print_state_summary(state: Any, label: str = "state") -> None:
|
|
|
28
32
|
|
|
29
33
|
print(f"{label}:")
|
|
30
34
|
print(f"- premise: {premise_text}")
|
|
31
|
-
print(f"- use policies: {_format_policy_values(state,
|
|
32
|
-
print(f"- prohibit policies: {_format_policy_values(state,
|
|
35
|
+
print(f"- use policies: {_format_policy_values(state, POLICY_USE)}")
|
|
36
|
+
print(f"- prohibit policies: {_format_policy_values(state, POLICY_PROHIBIT)}")
|
|
33
37
|
|
|
34
38
|
|
|
35
39
|
def print_decision_summary(decision: Any) -> None:
|
|
36
|
-
|
|
37
|
-
if kind == DECISION_UPDATE:
|
|
40
|
+
if is_update(decision):
|
|
38
41
|
print("result: updated")
|
|
39
|
-
state = decision
|
|
42
|
+
state = get_decision_state(decision)
|
|
40
43
|
assert isinstance(state, dict)
|
|
41
44
|
print_state_summary(state, "compiled state")
|
|
42
45
|
return
|
|
43
46
|
|
|
44
|
-
if
|
|
47
|
+
if is_clarify(decision):
|
|
45
48
|
print("result: clarify")
|
|
46
|
-
prompt = decision
|
|
49
|
+
prompt = get_clarify_prompt(decision)
|
|
47
50
|
if isinstance(prompt, str) and prompt:
|
|
48
51
|
print("clarify prompt:")
|
|
49
52
|
for line in prompt.splitlines():
|
|
@@ -17,7 +17,7 @@ export OPENAI_API_KEY=...
|
|
|
17
17
|
export PROVIDER=openai
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
Checkpoint continuation in these integration examples requires `context-compiler>=0.
|
|
20
|
+
Checkpoint continuation in these integration examples requires `context-compiler>=0.7.0`.
|
|
21
21
|
|
|
22
22
|
### Run
|
|
23
23
|
|
|
@@ -29,7 +29,7 @@ See the LiteLLM examples README for setup and usage:
|
|
|
29
29
|
- Context Compiler runs before each LLM call.
|
|
30
30
|
- If result is `clarify`, show the question and do not call the LLM.
|
|
31
31
|
- If result is `passthrough`, send normal user input.
|
|
32
|
-
- If result is `update`, use updated state and call the model with saved state
|
|
32
|
+
- If result is `update`, use updated state and call the model with saved state in the prompt.
|
|
33
33
|
|
|
34
34
|
## LiteLLM Proxy
|
|
35
35
|
|
|
@@ -105,7 +105,7 @@ Use `llama` only for LLM-only preprocessing with Llama-family models.
|
|
|
105
105
|
|
|
106
106
|
## Usage pattern
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
You can import these files as integration references in host applications.
|
|
109
109
|
|
|
110
110
|
- Import `handle_turn(...)` from either `basic.py` or `with_preprocessor.py`.
|
|
111
111
|
- Create and retain an engine instance in host/session state.
|