context-compiler 0.7.0__tar.gz → 0.7.2__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.0 → context_compiler-0.7.2}/PKG-INFO +82 -39
- {context_compiler-0.7.0 → context_compiler-0.7.2}/README.md +81 -38
- {context_compiler-0.7.0 → context_compiler-0.7.2}/demos/01_llm_contradiction_clarify.py +25 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/demos/02_llm_constraint_guardrail.py +38 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/demos/03_llm_premise_guardrail.py +26 -1
- {context_compiler-0.7.0 → context_compiler-0.7.2}/demos/04_llm_tool_denylist_guardrail.py +37 -9
- {context_compiler-0.7.0 → context_compiler-0.7.2}/demos/05_llm_prompt_drift_vs_state.py +27 -1
- {context_compiler-0.7.0 → context_compiler-0.7.2}/demos/07_llm_prompt_vs_state.py +21 -1
- context_compiler-0.7.2/demos/08_llm_replacement_precondition.py +137 -0
- context_compiler-0.7.2/demos/09_llm_pending_clarification.py +167 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/demos/README.md +66 -8
- {context_compiler-0.7.0 → context_compiler-0.7.2}/demos/common.py +50 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/demos/llm_client.py +87 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/demos/run_demo.py +64 -8
- context_compiler-0.7.2/docs/demos-results.md +157 -0
- context_compiler-0.7.2/docs/llm-preprocessor.md +116 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/README.md +10 -10
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/integrations/README.md +6 -5
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/integrations/litellm/README.md +15 -8
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/integrations/litellm_proxy/README.md +4 -3
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/integrations/openwebui/README.md +22 -13
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/integrations/openwebui/open_webui_pipe.py +44 -22
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/integrations/openwebui/open_webui_pipe_with_preprocessor.py +39 -20
- {context_compiler-0.7.0 → context_compiler-0.7.2}/experimental/preprocessor/README.md +36 -5
- {context_compiler-0.7.0 → context_compiler-0.7.2}/pyproject.toml +1 -1
- {context_compiler-0.7.0 → context_compiler-0.7.2}/src/context_compiler/observability.py +1 -1
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_demo_01_04_behavior.py +30 -6
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_demo_05_prompt_contract.py +5 -4
- context_compiler-0.7.2/tests/test_demo_08_09_behavior.py +162 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_llm_client.py +116 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_openwebui_pipe.py +206 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_openwebui_preprocessor_pipe.py +199 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_run_demo.py +175 -2
- {context_compiler-0.7.0 → context_compiler-0.7.2}/uv.lock +1 -1
- context_compiler-0.7.0/docs/demos-results.md +0 -67
- context_compiler-0.7.0/docs/llm-preprocessor.md +0 -66
- {context_compiler-0.7.0 → context_compiler-0.7.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/.github/pull_request_template.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/.github/workflows/ci.yml +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/.github/workflows/publish-pypi.yml +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/.github/workflows/stress-tests.yml +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/.gitignore +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/.pre-commit-config.yaml +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/AGENTS.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/CODE_OF_CONDUCT.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/CONTRIBUTING.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/LICENSE +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/SECURITY.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/demos/06_llm_context_compaction.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/demos/__init__.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/docs/DescriptionAndMilestones.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/docs/DesignPhilosophy.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/docs/DirectiveGrammarSpec.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/docs/README.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/docs/multi-engine.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/evals/litellm_proxy_additional_findings.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/evals/litellm_proxy_behavioral_comparisons.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/evals/swe-bench/README.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/evals/swe-bench/RUBRIC.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/evals/swe-bench/manifest.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/evals/swe-bench/swe-bench.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/evals/swe-bench/tasks/django__django-12453.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/evals/swe-bench/tasks/django__django-13158.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/evals/swe-bench/tasks/django__django-13964.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/evals/swe-bench/tasks/django__django-15252.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/evals/swe-bench/tasks/matplotlib__matplotlib-23299.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/evals/swe-bench/tasks/psf__requests-1963.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/01_persistent_guardrails.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/02_configuration_and_correction.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/03_ambiguity_with_clarification.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/04_tool_governance_denylist.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/05_llm_integration_pattern.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/06_transcript_replay.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/07_single_policy_correction.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/_util.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/integrations/litellm/basic.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/integrations/litellm/with_preprocessor.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/integrations/litellm_proxy/config.example.yaml +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/integrations/litellm_proxy/context_compiler_precall_hook.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/examples/integrations/litellm_proxy/context_compiler_precall_hook_with_preprocessor.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/experimental/__init__.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/experimental/preprocessor/__init__.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/experimental/preprocessor/constants.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/experimental/preprocessor/heuristic_preprocessor.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/experimental/preprocessor/output_validation.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/experimental/preprocessor/prompt_utils.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/experimental/preprocessor/prompts/default.txt +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/experimental/preprocessor/prompts/llama.txt +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/host_support/__init__.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/host_support/confirmation.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/host_support/provider_mode.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/src/context_compiler/__init__.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/src/context_compiler/const.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/src/context_compiler/controller.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/src/context_compiler/decision_constants.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/src/context_compiler/engine.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/src/context_compiler/repl.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/README.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/api/public-api-v1.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/checkpoint/001_import_checkpoint_non_object_rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/checkpoint/002_import_checkpoint_unsupported_version_rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/checkpoint/003_import_checkpoint_invalid_pending_shape_rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/checkpoint/004_import_checkpoint_invalid_replacement_shape_rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/checkpoint/005_import_checkpoint_invalid_authoritative_state_rejected_atomically.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/checkpoint/006_import_checkpoint_pending_null_clears_existing_pending.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/checkpoint/007_import_checkpoint_pending_absent_clears_existing_pending.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/state-json/001_export_json_canonical_sorted_compact.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/state-json/002_import_json_invalid_json_rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/state-json/003_import_json_non_object_rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/state-json/004_import_json_unsupported_version_rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/state-json/005_import_json_empty_normalized_policy_key_rejected_atomically.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/state-json/006_import_json_valid_normalized_policy_key_accepted.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/001_set_premise_update.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/002_use_item_normalization.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/003_conflict_prohibit_clarify.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/004_remove_policy_missing_idempotent_update.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/005_exact_prefix_passthrough_leading_space.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/006_near_miss_set_premise_to.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/007_near_miss_change_premise_missing_to.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/008_replace_missing_source_clarify_prompt.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/009_pending_affirmative_normalized_token.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/010_pending_negative_normalized_token.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/011_pending_unmatched_reuses_prompt.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/012_clear_premise_populated_update.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/013_clear_premise_already_null_update.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/014_reset_policies_populated_update.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/015_reset_policies_already_empty_update.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/016_clear_state_populated_update.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/017_clear_state_already_empty_update.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/018_pending_affirmative_punctuation_token.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/step/019_pending_negative_punctuation_token.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/transcript/001_user_only_replay_state.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/transcript/002_non_string_user_content_ignored.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/transcript/003_stops_at_first_clarify_later_yes.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/conformance/transcript/004_stops_at_first_clarify_later_no.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/controller/preview_clarify_no_mutation.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/controller/preview_idempotent_no_mutation.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/README.md +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/expected/contradiction_clarify.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/expected/pending_clarify_no.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/expected/pending_clarify_unmatched.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/expected/pending_clarify_yes.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/expected/premise_lifecycle.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/expected/replacement_clarify.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/scenarios/contradiction_clarify.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/scenarios/pending_clarify_no.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/scenarios/pending_clarify_unmatched.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/scenarios/pending_clarify_yes.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/scenarios/premise_lifecycle.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/engine-regression/structured/scenarios/replacement_clarify.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/admin-alias-remove-policies-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/admin-alias-reset-policy-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/ambiguous-directive-adjacent.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/canonical-directive-bracket-wrapper.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/canonical-directive-case-normalized-use-docker.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/canonical-directive-clear-state-period.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/canonical-directive-clear-state.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/canonical-directive-paren-wrapper.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/canonical-directive-prohibit-peanuts.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/canonical-directive-quoted-payload-use-docker.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/canonical-directive-reset-policies-bang.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/canonical-directive-whitespace-collapsed-use-docker.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/fenced-code-block-directive-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/inline-prose-code-directive-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/list-prefix-directive-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/malformed-replacement-instead-docker-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/meta-prefix-directive-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/mixed-directive-task-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/mixed-intent-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/modal-please-clear-state-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/multiline-multi-directive-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/natural-language-dont-use-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/near-miss-change-premise-missing-to-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/near-miss-change-premise-to-empty-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/near-miss-prohibit-empty-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/near-miss-remove-policy-empty-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/near-miss-set-premise-empty-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/near-miss-set-premise-to-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/near-miss-use-empty-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/near-miss-use-instead-of-missing-new-item-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/near-miss-use-instead-of-missing-old-item-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/nested-wrapper-clear-state-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/ordinary-non-directive.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/parse-source-input-fenced-code-rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/parse-source-input-inline-prose-code-rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/parse-source-input-mixed-directive-task-rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/parse-source-input-multiline-rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/parse-source-input-question-form-rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/parse-source-input-quoted-payload-locked.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/parse-source-input-reported-speech-rejected.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/parse-source-input-safe-canonical-use-docker.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/parse-source-input-safe-canonicalization-use-docker.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/public-api-v1.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/question-can-you-use-docker-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/question-use-docker-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/quoted-exact-use-docker-backtick-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/quoted-exact-use-docker-single-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/quoted-exact-use-docker-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/quoted-reported-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/reported-speech-docs-say-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/sentence-adjacent-directive-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/unsupported-alias-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/validator-invalid-json-shape-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/validator-malformed-json-text-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/validator-malformed-sentinel-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/validator-malformed-text-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/validator-multi-candidate-directive-unknown.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/validator-sentinel-no-directive.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/validator-source-input-allow-safe-directive.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/validator-source-input-block-change-premise-rewrite.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/validator-source-input-block-set-premise-rewrite.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/fixtures/preprocessor/validator-structured-json-directive.json +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_04_grammar_edge_cases.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_04_llm_tool_governance.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_07_llm_prompt_engineering_comparison.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_api_contract_fixture.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_controller.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_decision_constants.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_demo_07_output_clarity.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_demo_compaction.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_demo_oracle_properties.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_engine.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_example_integrations_imports.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_examples.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_examples_behavior.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_examples_smoke.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_fixtures.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_host_confirmation.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_host_observability.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_litellm_checkpoint_integration.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_litellm_integration_error_paths.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_litellm_preprocessor_model_config.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_llm_demos.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_precompiler_prompt_utils.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_preprocessor_api_contract_fixture.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_preprocessor_conformance.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_preprocessor_heuristic.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_preprocessor_heuristic_properties.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_preprocessor_output_validation.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_preprocessor_validator_properties.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_properties.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_provider_helper.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_repl.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_repl_coverage.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_repl_properties.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_smoke.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_structured_regression.py +0 -0
- {context_compiler-0.7.0 → context_compiler-0.7.2}/tests/test_transcript_replay.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: context-compiler
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
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
|
|
@@ -34,22 +34,59 @@ Provides-Extra: litellm-proxy
|
|
|
34
34
|
Requires-Dist: litellm[proxy]>=1.0.0; extra == 'litellm-proxy'
|
|
35
35
|
Description-Content-Type: text/markdown
|
|
36
36
|
|
|
37
|
-
|
|
38
37
|
# Context Compiler
|
|
39
38
|
|
|
40
39
|
[](https://pypi.org/project/context-compiler/)
|
|
41
40
|
[](https://pypi.org/project/context-compiler/)
|
|
42
41
|
[](https://pypi.org/project/context-compiler/)
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
Some behaviors require explicit host-side state machinery.
|
|
44
|
+
|
|
45
|
+
Context Compiler is a deterministic host-side state layer for LLM applications.
|
|
46
|
+
It handles explicit state transitions for premise and policies so that mutation
|
|
47
|
+
rules are fixed and repeatable.
|
|
48
|
+
|
|
49
|
+
## What prompting and reinjection can do
|
|
50
|
+
|
|
51
|
+
Prompting and reinjection are useful. In many real systems, reinjecting saved
|
|
52
|
+
state text is enough to keep instructions and policies persistent across turns.
|
|
53
|
+
|
|
54
|
+
Context Compiler adds host-owned transition rules for behaviors that plain text
|
|
55
|
+
reinjection does not implement by itself: replace `X` only if `X` exists, block
|
|
56
|
+
conflicting changes and ask for confirmation, and restore saved state plus
|
|
57
|
+
pending confirmations from checkpoints.
|
|
58
|
+
|
|
59
|
+
## What prompting cannot do by itself
|
|
60
|
+
|
|
61
|
+
Prompt text (including reinjected state text) helps, but it does not give your
|
|
62
|
+
app controlled rules for when state can change. By itself, it does not provide:
|
|
63
|
+
|
|
64
|
+
- rules your app controls for state changes
|
|
65
|
+
- replacement precondition checks (`use X instead of Y` when `Y` may be absent)
|
|
66
|
+
- confirmation flows that must complete before anything else changes
|
|
67
|
+
- clear decisions about when a change is blocked
|
|
68
|
+
- reliable checkpoint restore for both saved state and pending confirmation flow
|
|
69
|
+
|
|
70
|
+
## What Context Compiler provides
|
|
71
|
+
|
|
72
|
+
Context Compiler provides fixed host-side state machinery:
|
|
73
|
+
|
|
74
|
+
- deterministic directive handling for explicit user state changes
|
|
75
|
+
- clarification instead of silent overwrite for blocked/ambiguous changes
|
|
76
|
+
- pending confirmation flows that must resolve before anything else changes
|
|
77
|
+
- checkpoint export/import for restoring saved state and pending confirmation flow
|
|
78
|
+
- structured saved state that the host can pass to the model
|
|
47
79
|
|
|
48
|
-
|
|
80
|
+
The model generates responses. The compiler owns state transitions.
|
|
49
81
|
|
|
50
|
-
|
|
82
|
+
## How the compiler metaphor works
|
|
51
83
|
|
|
52
|
-
Context Compiler
|
|
84
|
+
Context Compiler treats important instructions as structured state instead of
|
|
85
|
+
temporary prompt text.
|
|
86
|
+
|
|
87
|
+
Like a compiler, it parses input, validates it, applies fixed rules, and
|
|
88
|
+
produces a stable representation the host can use. It is not source-code
|
|
89
|
+
compilation and not a reasoning model.
|
|
53
90
|
|
|
54
91
|
## Does it work?
|
|
55
92
|
|
|
@@ -59,7 +96,13 @@ Yes, on the current scored demo set.
|
|
|
59
96
|
- Scored checks (**6 demos per model**; Demo 6 excluded): baseline **26 / 42**, compiler **42 / 42**, compiler+compact **42 / 42**.
|
|
60
97
|
- Across tested models, compiler-mediated paths pass all scored scenarios; baseline behavior is model-dependent.
|
|
61
98
|
|
|
62
|
-
|
|
99
|
+
Interpretation guide:
|
|
100
|
+
- Demos `01`-`05` and `07` focus on persistence and policy-following behavior.
|
|
101
|
+
- Demos `08`/`09` focus on rules for when state is allowed to change.
|
|
102
|
+
- Demos `08`/`09` show what prompt text does not implement by itself.
|
|
103
|
+
- Plain reinjection can produce plausible responses, but it does not check whether replacement is allowed or wait for confirmation before saving changes.
|
|
104
|
+
|
|
105
|
+
→ [Full results and demo output](demos/README.md)
|
|
63
106
|
Canonical matrix: [docs/demos-results.md](docs/demos-results.md)
|
|
64
107
|
|
|
65
108
|
## Quickstart
|
|
@@ -74,9 +117,9 @@ context-compiler --json < input.txt
|
|
|
74
117
|
`context-compiler` launches the interactive REPL.
|
|
75
118
|
|
|
76
119
|
`--with-preprocessor` enables the experimental preprocessor before each REPL turn
|
|
77
|
-
(
|
|
78
|
-
|
|
79
|
-
|
|
120
|
+
(simple rule-based checks plus conservative validation). For near-miss inputs,
|
|
121
|
+
the preprocessor does not rewrite the text. It passes the input to the engine,
|
|
122
|
+
and the engine can return `clarify`.
|
|
80
123
|
|
|
81
124
|
`--json` enables machine-readable NDJSON output for non-interactive usage
|
|
82
125
|
(one complete JSON object per processed input line).
|
|
@@ -88,7 +131,7 @@ Preload options keep saved rules separate from in-progress confirmation state:
|
|
|
88
131
|
continuation checkpoint (saved state + pending confirmation state).
|
|
89
132
|
|
|
90
133
|
REPL commands (controller layer, not engine directives):
|
|
91
|
-
- `state` shows current
|
|
134
|
+
- `state` shows current saved state.
|
|
92
135
|
- `preview <input>` runs deterministic dry-run without mutating live state.
|
|
93
136
|
- `step <input>` is an explicit alias of normal bare-input step behavior.
|
|
94
137
|
|
|
@@ -139,27 +182,25 @@ uv run pytest
|
|
|
139
182
|
|
|
140
183
|
---
|
|
141
184
|
|
|
142
|
-
## Why “Compiler”?
|
|
143
|
-
|
|
144
|
-
Context Compiler treats explicit user directives as inputs to a fixed, repeatable process.
|
|
145
|
-
|
|
146
|
-
Instead of relying on the LLM to remember constraints across a conversation, user instructions are compiled into structured state before the model runs.
|
|
147
|
-
|
|
148
|
-
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.
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
185
|
## FAQ
|
|
153
186
|
|
|
154
187
|
**Is this just prompt reinjection?**
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
188
|
+
Reinjection helps with persistence, and it remains useful. Context Compiler
|
|
189
|
+
handles a different problem: rules for when state is allowed to change.
|
|
190
|
+
|
|
191
|
+
Examples:
|
|
192
|
+
- replacement semantics (`use X instead of Y`) when `Y` may not exist
|
|
193
|
+
- contradiction detection before applying a mutation
|
|
194
|
+
- lifecycle enforcement (for example, you cannot change an unset premise)
|
|
195
|
+
- pending clarification flows that must be resolved before other mutations
|
|
196
|
+
|
|
197
|
+
In short: reinjection carries state forward; Context Compiler decides when your
|
|
198
|
+
app should change state.
|
|
158
199
|
|
|
159
200
|
**Isn’t this just prompt engineering?**
|
|
160
201
|
It complements prompt engineering, but solves a different problem. Prompting
|
|
161
|
-
shapes model behavior
|
|
162
|
-
|
|
202
|
+
shapes model behavior. Context Compiler enforces state rules and updates state
|
|
203
|
+
only through explicit directives.
|
|
163
204
|
|
|
164
205
|
---
|
|
165
206
|
|
|
@@ -179,36 +220,38 @@ Later in the conversation:
|
|
|
179
220
|
User: how should I make this curry?
|
|
180
221
|
```
|
|
181
222
|
|
|
182
|
-
Your
|
|
223
|
+
Your host sends the saved policy state with this later request, so the model is
|
|
224
|
+
constrained by explicit state (`peanuts: prohibit`) instead of relying on memory
|
|
225
|
+
of earlier conversation text.
|
|
183
226
|
|
|
184
227
|
---
|
|
185
228
|
|
|
186
229
|
## Deterministic behavior (examples)
|
|
187
230
|
|
|
188
|
-
|
|
231
|
+
Context Compiler makes mutation rules explicit so behavior stays repeatable.
|
|
189
232
|
|
|
190
233
|
**Explicit directive**
|
|
191
234
|
```text
|
|
192
235
|
set premise concise replies
|
|
193
236
|
```
|
|
194
237
|
- Base model: silently accepts / rewrites
|
|
195
|
-
- Context Compiler: applies a
|
|
238
|
+
- Context Compiler: applies a repeatable state update
|
|
196
239
|
|
|
197
240
|
**State-dependent operation**
|
|
198
241
|
```text
|
|
199
242
|
clear state
|
|
200
243
|
use podman instead of docker
|
|
201
244
|
```
|
|
202
|
-
-
|
|
203
|
-
- Context Compiler:
|
|
245
|
+
- Without explicit state transition rules: behavior depends on host/model handling
|
|
246
|
+
- Context Compiler: returns `clarify` before changing state
|
|
204
247
|
|
|
205
248
|
**Lifecycle enforcement**
|
|
206
249
|
```text
|
|
207
250
|
clear state
|
|
208
251
|
change premise to formal tone
|
|
209
252
|
```
|
|
210
|
-
-
|
|
211
|
-
- Context Compiler:
|
|
253
|
+
- Without explicit transition checks: behavior depends on host/model handling
|
|
254
|
+
- Context Compiler: asks for clarification and keeps saved state unchanged
|
|
212
255
|
|
|
213
256
|
---
|
|
214
257
|
|
|
@@ -227,7 +270,7 @@ Decision
|
|
|
227
270
|
Host Application
|
|
228
271
|
├─ clarify → ask user
|
|
229
272
|
├─ passthrough → call LLM
|
|
230
|
-
└─ update → call LLM with compiled state
|
|
273
|
+
└─ update → authoritative state mutated; host may call LLM with compiled state
|
|
231
274
|
```
|
|
232
275
|
|
|
233
276
|
The compiler owns state updates and never calls the LLM.
|
|
@@ -251,7 +294,7 @@ Meaning:
|
|
|
251
294
|
| kind | host behavior |
|
|
252
295
|
|:-----------:|-----------------------------------------------|
|
|
253
296
|
| passthrough | forward user input to LLM |
|
|
254
|
-
| update |
|
|
297
|
+
| update | authoritative state mutated; host may call LLM with updated state |
|
|
255
298
|
| clarify | show `prompt_to_user` and do not call the LLM |
|
|
256
299
|
|
|
257
300
|
---
|
|
@@ -315,7 +358,7 @@ The internal structure of the state is intentionally opaque to host applications
|
|
|
315
358
|
- `export_json()` / `import_json()` transport **authoritative state only**
|
|
316
359
|
- checkpoint APIs transport **serialized continuation**:
|
|
317
360
|
- authoritative state
|
|
318
|
-
- pending confirmation
|
|
361
|
+
- pending confirmation flow state
|
|
319
362
|
|
|
320
363
|
Checkpoint object shape:
|
|
321
364
|
|
|
@@ -357,7 +400,7 @@ When to use checkpoint APIs:
|
|
|
357
400
|
|
|
358
401
|
- stateless host/integration boundaries where engine instances are short-lived.
|
|
359
402
|
- resume after interruption without losing pending clarification flow.
|
|
360
|
-
- preserve confirmation
|
|
403
|
+
- preserve pending confirmation flow state (`pending`) across process/request boundaries.
|
|
361
404
|
|
|
362
405
|
---
|
|
363
406
|
|
|
@@ -1,19 +1,56 @@
|
|
|
1
|
-
|
|
2
1
|
# Context Compiler
|
|
3
2
|
|
|
4
3
|
[](https://pypi.org/project/context-compiler/)
|
|
5
4
|
[](https://pypi.org/project/context-compiler/)
|
|
6
5
|
[](https://pypi.org/project/context-compiler/)
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
Some behaviors require explicit host-side state machinery.
|
|
8
|
+
|
|
9
|
+
Context Compiler is a deterministic host-side state layer for LLM applications.
|
|
10
|
+
It handles explicit state transitions for premise and policies so that mutation
|
|
11
|
+
rules are fixed and repeatable.
|
|
12
|
+
|
|
13
|
+
## What prompting and reinjection can do
|
|
14
|
+
|
|
15
|
+
Prompting and reinjection are useful. In many real systems, reinjecting saved
|
|
16
|
+
state text is enough to keep instructions and policies persistent across turns.
|
|
17
|
+
|
|
18
|
+
Context Compiler adds host-owned transition rules for behaviors that plain text
|
|
19
|
+
reinjection does not implement by itself: replace `X` only if `X` exists, block
|
|
20
|
+
conflicting changes and ask for confirmation, and restore saved state plus
|
|
21
|
+
pending confirmations from checkpoints.
|
|
22
|
+
|
|
23
|
+
## What prompting cannot do by itself
|
|
24
|
+
|
|
25
|
+
Prompt text (including reinjected state text) helps, but it does not give your
|
|
26
|
+
app controlled rules for when state can change. By itself, it does not provide:
|
|
27
|
+
|
|
28
|
+
- rules your app controls for state changes
|
|
29
|
+
- replacement precondition checks (`use X instead of Y` when `Y` may be absent)
|
|
30
|
+
- confirmation flows that must complete before anything else changes
|
|
31
|
+
- clear decisions about when a change is blocked
|
|
32
|
+
- reliable checkpoint restore for both saved state and pending confirmation flow
|
|
33
|
+
|
|
34
|
+
## What Context Compiler provides
|
|
35
|
+
|
|
36
|
+
Context Compiler provides fixed host-side state machinery:
|
|
37
|
+
|
|
38
|
+
- deterministic directive handling for explicit user state changes
|
|
39
|
+
- clarification instead of silent overwrite for blocked/ambiguous changes
|
|
40
|
+
- pending confirmation flows that must resolve before anything else changes
|
|
41
|
+
- checkpoint export/import for restoring saved state and pending confirmation flow
|
|
42
|
+
- structured saved state that the host can pass to the model
|
|
11
43
|
|
|
12
|
-
|
|
44
|
+
The model generates responses. The compiler owns state transitions.
|
|
13
45
|
|
|
14
|
-
|
|
46
|
+
## How the compiler metaphor works
|
|
15
47
|
|
|
16
|
-
Context Compiler
|
|
48
|
+
Context Compiler treats important instructions as structured state instead of
|
|
49
|
+
temporary prompt text.
|
|
50
|
+
|
|
51
|
+
Like a compiler, it parses input, validates it, applies fixed rules, and
|
|
52
|
+
produces a stable representation the host can use. It is not source-code
|
|
53
|
+
compilation and not a reasoning model.
|
|
17
54
|
|
|
18
55
|
## Does it work?
|
|
19
56
|
|
|
@@ -23,7 +60,13 @@ Yes, on the current scored demo set.
|
|
|
23
60
|
- Scored checks (**6 demos per model**; Demo 6 excluded): baseline **26 / 42**, compiler **42 / 42**, compiler+compact **42 / 42**.
|
|
24
61
|
- Across tested models, compiler-mediated paths pass all scored scenarios; baseline behavior is model-dependent.
|
|
25
62
|
|
|
26
|
-
|
|
63
|
+
Interpretation guide:
|
|
64
|
+
- Demos `01`-`05` and `07` focus on persistence and policy-following behavior.
|
|
65
|
+
- Demos `08`/`09` focus on rules for when state is allowed to change.
|
|
66
|
+
- Demos `08`/`09` show what prompt text does not implement by itself.
|
|
67
|
+
- Plain reinjection can produce plausible responses, but it does not check whether replacement is allowed or wait for confirmation before saving changes.
|
|
68
|
+
|
|
69
|
+
→ [Full results and demo output](demos/README.md)
|
|
27
70
|
Canonical matrix: [docs/demos-results.md](docs/demos-results.md)
|
|
28
71
|
|
|
29
72
|
## Quickstart
|
|
@@ -38,9 +81,9 @@ context-compiler --json < input.txt
|
|
|
38
81
|
`context-compiler` launches the interactive REPL.
|
|
39
82
|
|
|
40
83
|
`--with-preprocessor` enables the experimental preprocessor before each REPL turn
|
|
41
|
-
(
|
|
42
|
-
|
|
43
|
-
|
|
84
|
+
(simple rule-based checks plus conservative validation). For near-miss inputs,
|
|
85
|
+
the preprocessor does not rewrite the text. It passes the input to the engine,
|
|
86
|
+
and the engine can return `clarify`.
|
|
44
87
|
|
|
45
88
|
`--json` enables machine-readable NDJSON output for non-interactive usage
|
|
46
89
|
(one complete JSON object per processed input line).
|
|
@@ -52,7 +95,7 @@ Preload options keep saved rules separate from in-progress confirmation state:
|
|
|
52
95
|
continuation checkpoint (saved state + pending confirmation state).
|
|
53
96
|
|
|
54
97
|
REPL commands (controller layer, not engine directives):
|
|
55
|
-
- `state` shows current
|
|
98
|
+
- `state` shows current saved state.
|
|
56
99
|
- `preview <input>` runs deterministic dry-run without mutating live state.
|
|
57
100
|
- `step <input>` is an explicit alias of normal bare-input step behavior.
|
|
58
101
|
|
|
@@ -103,27 +146,25 @@ uv run pytest
|
|
|
103
146
|
|
|
104
147
|
---
|
|
105
148
|
|
|
106
|
-
## Why “Compiler”?
|
|
107
|
-
|
|
108
|
-
Context Compiler treats explicit user directives as inputs to a fixed, repeatable process.
|
|
109
|
-
|
|
110
|
-
Instead of relying on the LLM to remember constraints across a conversation, user instructions are compiled into structured state before the model runs.
|
|
111
|
-
|
|
112
|
-
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.
|
|
113
|
-
|
|
114
|
-
---
|
|
115
|
-
|
|
116
149
|
## FAQ
|
|
117
150
|
|
|
118
151
|
**Is this just prompt reinjection?**
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
152
|
+
Reinjection helps with persistence, and it remains useful. Context Compiler
|
|
153
|
+
handles a different problem: rules for when state is allowed to change.
|
|
154
|
+
|
|
155
|
+
Examples:
|
|
156
|
+
- replacement semantics (`use X instead of Y`) when `Y` may not exist
|
|
157
|
+
- contradiction detection before applying a mutation
|
|
158
|
+
- lifecycle enforcement (for example, you cannot change an unset premise)
|
|
159
|
+
- pending clarification flows that must be resolved before other mutations
|
|
160
|
+
|
|
161
|
+
In short: reinjection carries state forward; Context Compiler decides when your
|
|
162
|
+
app should change state.
|
|
122
163
|
|
|
123
164
|
**Isn’t this just prompt engineering?**
|
|
124
165
|
It complements prompt engineering, but solves a different problem. Prompting
|
|
125
|
-
shapes model behavior
|
|
126
|
-
|
|
166
|
+
shapes model behavior. Context Compiler enforces state rules and updates state
|
|
167
|
+
only through explicit directives.
|
|
127
168
|
|
|
128
169
|
---
|
|
129
170
|
|
|
@@ -143,36 +184,38 @@ Later in the conversation:
|
|
|
143
184
|
User: how should I make this curry?
|
|
144
185
|
```
|
|
145
186
|
|
|
146
|
-
Your
|
|
187
|
+
Your host sends the saved policy state with this later request, so the model is
|
|
188
|
+
constrained by explicit state (`peanuts: prohibit`) instead of relying on memory
|
|
189
|
+
of earlier conversation text.
|
|
147
190
|
|
|
148
191
|
---
|
|
149
192
|
|
|
150
193
|
## Deterministic behavior (examples)
|
|
151
194
|
|
|
152
|
-
|
|
195
|
+
Context Compiler makes mutation rules explicit so behavior stays repeatable.
|
|
153
196
|
|
|
154
197
|
**Explicit directive**
|
|
155
198
|
```text
|
|
156
199
|
set premise concise replies
|
|
157
200
|
```
|
|
158
201
|
- Base model: silently accepts / rewrites
|
|
159
|
-
- Context Compiler: applies a
|
|
202
|
+
- Context Compiler: applies a repeatable state update
|
|
160
203
|
|
|
161
204
|
**State-dependent operation**
|
|
162
205
|
```text
|
|
163
206
|
clear state
|
|
164
207
|
use podman instead of docker
|
|
165
208
|
```
|
|
166
|
-
-
|
|
167
|
-
- Context Compiler:
|
|
209
|
+
- Without explicit state transition rules: behavior depends on host/model handling
|
|
210
|
+
- Context Compiler: returns `clarify` before changing state
|
|
168
211
|
|
|
169
212
|
**Lifecycle enforcement**
|
|
170
213
|
```text
|
|
171
214
|
clear state
|
|
172
215
|
change premise to formal tone
|
|
173
216
|
```
|
|
174
|
-
-
|
|
175
|
-
- Context Compiler:
|
|
217
|
+
- Without explicit transition checks: behavior depends on host/model handling
|
|
218
|
+
- Context Compiler: asks for clarification and keeps saved state unchanged
|
|
176
219
|
|
|
177
220
|
---
|
|
178
221
|
|
|
@@ -191,7 +234,7 @@ Decision
|
|
|
191
234
|
Host Application
|
|
192
235
|
├─ clarify → ask user
|
|
193
236
|
├─ passthrough → call LLM
|
|
194
|
-
└─ update → call LLM with compiled state
|
|
237
|
+
└─ update → authoritative state mutated; host may call LLM with compiled state
|
|
195
238
|
```
|
|
196
239
|
|
|
197
240
|
The compiler owns state updates and never calls the LLM.
|
|
@@ -215,7 +258,7 @@ Meaning:
|
|
|
215
258
|
| kind | host behavior |
|
|
216
259
|
|:-----------:|-----------------------------------------------|
|
|
217
260
|
| passthrough | forward user input to LLM |
|
|
218
|
-
| update |
|
|
261
|
+
| update | authoritative state mutated; host may call LLM with updated state |
|
|
219
262
|
| clarify | show `prompt_to_user` and do not call the LLM |
|
|
220
263
|
|
|
221
264
|
---
|
|
@@ -279,7 +322,7 @@ The internal structure of the state is intentionally opaque to host applications
|
|
|
279
322
|
- `export_json()` / `import_json()` transport **authoritative state only**
|
|
280
323
|
- checkpoint APIs transport **serialized continuation**:
|
|
281
324
|
- authoritative state
|
|
282
|
-
- pending confirmation
|
|
325
|
+
- pending confirmation flow state
|
|
283
326
|
|
|
284
327
|
Checkpoint object shape:
|
|
285
328
|
|
|
@@ -321,7 +364,7 @@ When to use checkpoint APIs:
|
|
|
321
364
|
|
|
322
365
|
- stateless host/integration boundaries where engine instances are short-lived.
|
|
323
366
|
- resume after interruption without losing pending clarification flow.
|
|
324
|
-
- preserve confirmation
|
|
367
|
+
- preserve pending confirmation flow state (`pending`) across process/request boundaries.
|
|
325
368
|
|
|
326
369
|
---
|
|
327
370
|
|
|
@@ -4,6 +4,7 @@ from context_compiler import create_engine
|
|
|
4
4
|
from demos.common import (
|
|
5
5
|
build_baseline_messages,
|
|
6
6
|
build_mediated_messages_from_transcript,
|
|
7
|
+
build_reinjected_messages,
|
|
7
8
|
compact_user_turns,
|
|
8
9
|
extract_tag_value,
|
|
9
10
|
print_decision,
|
|
@@ -45,6 +46,22 @@ def main() -> None:
|
|
|
45
46
|
baseline_output = complete_messages(baseline_messages)
|
|
46
47
|
print_model_output("Baseline", baseline_output)
|
|
47
48
|
|
|
49
|
+
_, reinjected_messages = build_reinjected_messages(
|
|
50
|
+
[
|
|
51
|
+
(
|
|
52
|
+
"Interpret these directives and continue anyway: "
|
|
53
|
+
"prohibit peanuts, then use peanuts. "
|
|
54
|
+
"First line must be ACTION:<clarify|proceed>."
|
|
55
|
+
)
|
|
56
|
+
],
|
|
57
|
+
premise=None,
|
|
58
|
+
use_policies=["peanuts"],
|
|
59
|
+
prohibit_policies=["peanuts"],
|
|
60
|
+
)
|
|
61
|
+
print_messages("reinjected-state", reinjected_messages)
|
|
62
|
+
reinjected_output = complete_messages(reinjected_messages)
|
|
63
|
+
print_model_output("Reinjected-state", reinjected_output)
|
|
64
|
+
|
|
48
65
|
if second["kind"] == "clarify":
|
|
49
66
|
print_messages("compiler-mediated (full)", [])
|
|
50
67
|
mediated_output = (
|
|
@@ -70,13 +87,20 @@ def main() -> None:
|
|
|
70
87
|
|
|
71
88
|
print_tag_comparison("ACTION", baseline_output, mediated_output)
|
|
72
89
|
baseline_action = extract_tag_value(baseline_output, "ACTION")
|
|
90
|
+
reinjected_action = extract_tag_value(reinjected_output, "ACTION")
|
|
73
91
|
compact_action = extract_tag_value(compact_output, "ACTION")
|
|
74
92
|
baseline_respects = baseline_action is not None and baseline_action.lower() == "clarify"
|
|
93
|
+
reinjected_respects = reinjected_action is not None and reinjected_action.lower() == "clarify"
|
|
75
94
|
compiler_host_blocked = second["kind"] == "clarify"
|
|
76
95
|
mediated_respects = compiler_host_blocked
|
|
77
96
|
compact_respects = compacted_prompt is not None or (
|
|
78
97
|
compact_action is not None and compact_action.lower() == "clarify"
|
|
79
98
|
)
|
|
99
|
+
print_host_check(
|
|
100
|
+
"ACTION_CLARIFY",
|
|
101
|
+
yes_no(reinjected_respects),
|
|
102
|
+
context="reinjected-state",
|
|
103
|
+
)
|
|
80
104
|
print_host_check(
|
|
81
105
|
"COMPILER_BLOCKED_LLM",
|
|
82
106
|
yes_no(compiler_host_blocked),
|
|
@@ -90,6 +114,7 @@ def main() -> None:
|
|
|
90
114
|
print_spec_report(
|
|
91
115
|
test_name="01_contradiction_block — host clarification gate",
|
|
92
116
|
baseline_pass=baseline_respects,
|
|
117
|
+
reinjected_state_pass=reinjected_respects,
|
|
93
118
|
compiler_pass=mediated_respects,
|
|
94
119
|
compiler_compact_pass=compact_respects,
|
|
95
120
|
expected="host should block LLM call on contradictory directive until clarification",
|
|
@@ -6,6 +6,7 @@ from context_compiler import create_engine
|
|
|
6
6
|
from demos.common import (
|
|
7
7
|
build_baseline_messages,
|
|
8
8
|
build_mediated_messages_from_transcript,
|
|
9
|
+
build_reinjected_messages,
|
|
9
10
|
compact_user_turns,
|
|
10
11
|
print_decision,
|
|
11
12
|
print_host_check,
|
|
@@ -129,6 +130,24 @@ def main() -> None:
|
|
|
129
130
|
context="baseline",
|
|
130
131
|
)
|
|
131
132
|
|
|
133
|
+
_, reinjected_messages = build_reinjected_messages(
|
|
134
|
+
[user_inputs[1]],
|
|
135
|
+
premise=None,
|
|
136
|
+
use_policies=[],
|
|
137
|
+
prohibit_policies=["peanuts"],
|
|
138
|
+
extra_system_prompt=(
|
|
139
|
+
"If the user requests a prohibited item, refuse the literal request. "
|
|
140
|
+
"State briefly that the request conflicts with policy, then provide "
|
|
141
|
+
"the closest safe alternative recipe that excludes prohibited items."
|
|
142
|
+
),
|
|
143
|
+
)
|
|
144
|
+
print_messages("reinjected-state", reinjected_messages)
|
|
145
|
+
reinjected_output = complete_messages(reinjected_messages)
|
|
146
|
+
print_model_output("Reinjected-state", reinjected_output)
|
|
147
|
+
reinjected_refusal = refusal_detected(reinjected_output)
|
|
148
|
+
reinjected_safe_alternative = safe_alternative_detected(reinjected_output)
|
|
149
|
+
reinjected_violation = recipe_includes_prohibited_item(reinjected_output)
|
|
150
|
+
|
|
132
151
|
mediated_messages = build_mediated_messages_from_transcript(
|
|
133
152
|
engine.state,
|
|
134
153
|
user_inputs,
|
|
@@ -171,6 +190,21 @@ def main() -> None:
|
|
|
171
190
|
if compacted_prompt is not None:
|
|
172
191
|
compact_safe_alternative = True
|
|
173
192
|
|
|
193
|
+
print_host_check(
|
|
194
|
+
"REFUSAL_DETECTED",
|
|
195
|
+
yes_no(reinjected_refusal),
|
|
196
|
+
context="reinjected-state",
|
|
197
|
+
)
|
|
198
|
+
print_host_check(
|
|
199
|
+
"RECIPE_INCLUDES_PROHIBITED",
|
|
200
|
+
yes_no(reinjected_violation),
|
|
201
|
+
context="reinjected-state",
|
|
202
|
+
)
|
|
203
|
+
print_host_check(
|
|
204
|
+
"SAFE_ALTERNATIVE_DETECTED",
|
|
205
|
+
yes_no(reinjected_safe_alternative),
|
|
206
|
+
context="reinjected-state",
|
|
207
|
+
)
|
|
174
208
|
print_host_check(
|
|
175
209
|
"REFUSAL_DETECTED",
|
|
176
210
|
yes_no(mediated_refusal),
|
|
@@ -202,12 +236,16 @@ def main() -> None:
|
|
|
202
236
|
context="compiler-mediated + compact",
|
|
203
237
|
)
|
|
204
238
|
baseline_pass = not baseline_violation
|
|
239
|
+
reinjected_pass = (
|
|
240
|
+
reinjected_refusal or reinjected_safe_alternative
|
|
241
|
+
) and not reinjected_violation
|
|
205
242
|
compiler_pass = (mediated_refusal or mediated_safe_alternative) and not mediated_violation
|
|
206
243
|
compact_pass = (compact_refusal or compact_safe_alternative) and not compact_violation
|
|
207
244
|
passed = baseline_violation and compiler_pass and compact_pass
|
|
208
245
|
print_spec_report(
|
|
209
246
|
test_name="02_constraint_drift — persistent prohibition",
|
|
210
247
|
baseline_pass=baseline_pass,
|
|
248
|
+
reinjected_state_pass=reinjected_pass,
|
|
211
249
|
compiler_pass=compiler_pass,
|
|
212
250
|
compiler_compact_pass=compact_pass,
|
|
213
251
|
expected=(
|
|
@@ -6,6 +6,7 @@ from context_compiler import create_engine
|
|
|
6
6
|
from demos.common import (
|
|
7
7
|
build_baseline_messages,
|
|
8
8
|
build_mediated_messages_from_transcript,
|
|
9
|
+
build_reinjected_messages,
|
|
9
10
|
compact_user_turns,
|
|
10
11
|
extract_tag_value,
|
|
11
12
|
print_decision,
|
|
@@ -89,6 +90,16 @@ def main() -> None:
|
|
|
89
90
|
baseline_output = complete_messages(baseline_messages)
|
|
90
91
|
print_model_output("Baseline", baseline_output)
|
|
91
92
|
|
|
93
|
+
_, reinjected_messages = build_reinjected_messages(
|
|
94
|
+
[user_inputs[0], user_inputs[1], user_inputs[2]],
|
|
95
|
+
premise="vegan curry",
|
|
96
|
+
use_policies=[],
|
|
97
|
+
prohibit_policies=[],
|
|
98
|
+
)
|
|
99
|
+
print_messages("reinjected-state", reinjected_messages)
|
|
100
|
+
reinjected_output = complete_messages(reinjected_messages)
|
|
101
|
+
print_model_output("Reinjected-state", reinjected_output)
|
|
102
|
+
|
|
92
103
|
mediated_messages = build_mediated_messages_from_transcript(engine.state, user_inputs)
|
|
93
104
|
print_messages("compiler-mediated (full)", mediated_messages)
|
|
94
105
|
mediated_output = complete_messages(mediated_messages)
|
|
@@ -108,15 +119,19 @@ def main() -> None:
|
|
|
108
119
|
print_tag_comparison("PREMISE", baseline_output, mediated_output)
|
|
109
120
|
|
|
110
121
|
baseline_premise = extract_tag_value(baseline_output, "PREMISE")
|
|
122
|
+
reinjected_premise = extract_tag_value(reinjected_output, "PREMISE")
|
|
111
123
|
mediated_premise = extract_tag_value(mediated_output, "PREMISE")
|
|
112
124
|
compact_premise = extract_tag_value(compact_output, "PREMISE")
|
|
113
125
|
baseline_uses_vegan = _plan_uses_value(baseline_output, "vegan")
|
|
114
126
|
baseline_uses_vegetarian = _plan_uses_value(baseline_output, "vegetarian")
|
|
127
|
+
reinjected_uses_vegan = _plan_uses_value(reinjected_output, "vegan")
|
|
128
|
+
reinjected_uses_vegetarian = _plan_uses_value(reinjected_output, "vegetarian")
|
|
115
129
|
mediated_uses_vegan = _plan_uses_value(mediated_output, "vegan")
|
|
116
130
|
mediated_uses_vegetarian = _plan_uses_value(mediated_output, "vegetarian")
|
|
117
131
|
compact_uses_vegan = _plan_uses_value(compact_output, "vegan")
|
|
118
132
|
compact_uses_vegetarian = _plan_uses_value(compact_output, "vegetarian")
|
|
119
133
|
baseline_respects = not baseline_uses_vegetarian
|
|
134
|
+
reinjected_respects = not reinjected_uses_vegetarian
|
|
120
135
|
mediated_respects = not mediated_uses_vegetarian
|
|
121
136
|
compact_respects = compacted_prompt is None and not compact_uses_vegetarian
|
|
122
137
|
print_host_check(
|
|
@@ -128,6 +143,15 @@ def main() -> None:
|
|
|
128
143
|
),
|
|
129
144
|
context="baseline",
|
|
130
145
|
)
|
|
146
|
+
print_host_check(
|
|
147
|
+
"PLAN_VALUES",
|
|
148
|
+
(
|
|
149
|
+
f"vegan={yes_no(reinjected_uses_vegan)}, "
|
|
150
|
+
f"vegetarian={yes_no(reinjected_uses_vegetarian)}, "
|
|
151
|
+
f"premise_tag={reinjected_premise or 'MISSING'}"
|
|
152
|
+
),
|
|
153
|
+
context="reinjected-state",
|
|
154
|
+
)
|
|
131
155
|
print_host_check(
|
|
132
156
|
"PLAN_VALUES",
|
|
133
157
|
(
|
|
@@ -149,6 +173,7 @@ def main() -> None:
|
|
|
149
173
|
print_spec_report(
|
|
150
174
|
test_name="03_explicit_premise_change — stale value removed",
|
|
151
175
|
baseline_pass=baseline_respects,
|
|
176
|
+
reinjected_state_pass=reinjected_respects,
|
|
152
177
|
compiler_pass=mediated_respects,
|
|
153
178
|
compiler_compact_pass=compact_respects,
|
|
154
179
|
expected="explicit premise change should remove the stale vegetarian value",
|
|
@@ -157,7 +182,7 @@ def main() -> None:
|
|
|
157
182
|
"both compiler-mediated paths used vegan value"
|
|
158
183
|
if mediated_respects and compact_respects and baseline_uses_vegetarian
|
|
159
184
|
else (
|
|
160
|
-
"all
|
|
185
|
+
"all four paths used vegan value"
|
|
161
186
|
if baseline_respects and mediated_respects and compact_respects
|
|
162
187
|
else (
|
|
163
188
|
"at least one compiler-mediated path included stale vegetarian value"
|