context-compiler-example-integrations 0.1.2__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/PKG-INFO +13 -37
  2. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/pyproject.toml +5 -5
  3. context_compiler_example_integrations-0.2.1/python/README.md +47 -0
  4. context_compiler_example_integrations-0.2.1/python/examples/checkpoint_continuation/README.md +65 -0
  5. context_compiler_example_integrations-0.2.1/python/examples/checkpoint_continuation/example.py +163 -0
  6. context_compiler_example_integrations-0.2.1/python/examples/checkpoint_continuation/fastapi/README.md +65 -0
  7. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/checkpoint_continuation/fastapi/app.py +65 -69
  8. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/execution_authorization/expense_approval/README.md +4 -4
  9. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/execution_authorization/expense_approval/example.py +39 -40
  10. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/execution_authorization/expense_approval/fastapi/README.md +3 -3
  11. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/execution_authorization/expense_approval/fastapi/app.py +58 -35
  12. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/gateway_middleware/customer_support_routing/example.py +35 -40
  13. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/prompt_construction/litellm/README.md +32 -23
  14. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/prompt_construction/litellm/basic.py +65 -120
  15. context_compiler_example_integrations-0.2.1/python/examples/prompt_construction/litellm/with_directive_drafter.py +371 -0
  16. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/prompt_construction/writing_assistant/README.md +1 -1
  17. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/prompt_construction/writing_assistant/example.py +39 -43
  18. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/retrieval_filtering/chromadb_hr_policy_lookup/README.md +2 -3
  19. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/retrieval_filtering/chromadb_hr_policy_lookup/example.py +41 -45
  20. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/retrieval_filtering/hr_policy_lookup/README.md +1 -1
  21. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/retrieval_filtering/hr_policy_lookup/example.py +47 -48
  22. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/schema_selection/litellm_response_format/response_format.py +15 -23
  23. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/schema_selection/ollama_structured_output/README.md +1 -1
  24. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/schema_selection/ollama_structured_output/example.py +15 -23
  25. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/schema_selection/refund_intake/example.py +13 -12
  26. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/tool_gating/calendar_admin/example.py +40 -43
  27. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/tool_gating/mcp_calendar_admin/README.md +1 -1
  28. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/tool_gating/mcp_calendar_admin/example.py +49 -54
  29. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/tool_gating/mcp_calendar_admin/live_model.py +65 -33
  30. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/reference_integrations/litellm_proxy/README.md +17 -16
  31. context_compiler_example_integrations-0.2.1/python/reference_integrations/litellm_proxy/_litellm_support.py +34 -0
  32. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/reference_integrations/litellm_proxy/context_compiler_precall_hook.py +20 -56
  33. context_compiler_example_integrations-0.2.1/python/reference_integrations/litellm_proxy/context_compiler_precall_hook_with_directive_drafter.py +184 -0
  34. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/reference_integrations/openwebui_pipe/README.md +57 -38
  35. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/reference_integrations/openwebui_pipe/open_webui_pipe.py +115 -136
  36. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/reference_integrations/openwebui_pipe/open_webui_pipe_with_directive_drafter.py +276 -368
  37. context_compiler_example_integrations-0.1.2/python/README.md +0 -71
  38. context_compiler_example_integrations-0.1.2/python/examples/checkpoint_continuation/README.md +0 -77
  39. context_compiler_example_integrations-0.1.2/python/examples/checkpoint_continuation/example.py +0 -169
  40. context_compiler_example_integrations-0.1.2/python/examples/checkpoint_continuation/fastapi/README.md +0 -85
  41. context_compiler_example_integrations-0.1.2/python/examples/prompt_construction/litellm/confirmation_helper.py +0 -91
  42. context_compiler_example_integrations-0.1.2/python/examples/prompt_construction/litellm/with_directive_drafter.py +0 -524
  43. context_compiler_example_integrations-0.1.2/python/reference_integrations/litellm_proxy/context_compiler_precall_hook_with_directive_drafter.py +0 -289
  44. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/.gitignore +0 -0
  45. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/LICENSE +0 -0
  46. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/context_compiler_example_integrations/__init__.py +0 -0
  47. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/context_compiler_example_integrations/examples/__init__.py +0 -0
  48. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/context_compiler_example_integrations/reference_integrations/__init__.py +0 -0
  49. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/_shared/__init__.py +0 -0
  50. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/_shared/litellm_request.py +0 -0
  51. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/_shared/provider_mode.py +0 -0
  52. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/execution_authorization/README.md +0 -0
  53. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/execution_authorization/expense_approval/__init__.py +0 -0
  54. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/execution_authorization/expense_approval/fastapi/__init__.py +0 -0
  55. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/execution_authorization/expense_approval/fastapi/model_approval.py +0 -0
  56. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/gateway_middleware/README.md +0 -0
  57. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/gateway_middleware/customer_support_routing/README.md +0 -0
  58. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/gateway_middleware/customer_support_routing/__init__.py +0 -0
  59. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/prompt_construction/README.md +0 -0
  60. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/prompt_construction/writing_assistant/__init__.py +0 -0
  61. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/retrieval_filtering/README.md +0 -0
  62. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/retrieval_filtering/chromadb_hr_policy_lookup/__init__.py +0 -0
  63. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/retrieval_filtering/hr_policy_lookup/__init__.py +0 -0
  64. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/schema_selection/README.md +0 -0
  65. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/schema_selection/refund_intake/README.md +0 -0
  66. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/schema_selection/refund_intake/__init__.py +0 -0
  67. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/tool_gating/README.md +0 -0
  68. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/tool_gating/calendar_admin/README.md +0 -0
  69. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/tool_gating/calendar_admin/__init__.py +0 -0
  70. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/tool_gating/mcp_calendar_admin/__init__.py +0 -0
  71. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/reference_integrations/litellm_proxy/_checkpoint_support.py +0 -0
  72. {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/reference_integrations/litellm_proxy/config.example.yaml +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: context-compiler-example-integrations
3
- Version: 0.1.2
3
+ Version: 0.2.1
4
4
  Summary: Example integrations and enforcement-point demonstrations for Context Compiler.
5
5
  Project-URL: Homepage, https://github.com/rlippmann/context-compiler-example-integrations
6
6
  Project-URL: Repository, https://github.com/rlippmann/context-compiler-example-integrations
@@ -21,14 +21,14 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
21
  Classifier: Topic :: Software Development :: Libraries
22
22
  Classifier: Topic :: Software Development :: Testing
23
23
  Requires-Python: >=3.11
24
- Requires-Dist: context-compiler>=0.8.3
24
+ Requires-Dist: context-compiler<0.10,>=0.9.1
25
25
  Provides-Extra: all
26
26
  Requires-Dist: chromadb; extra == 'all'
27
- Requires-Dist: context-compiler-directive-drafter>=0.1.2; extra == 'all'
27
+ Requires-Dist: context-compiler-directive-drafter<0.3,>=0.2.0; extra == 'all'
28
28
  Requires-Dist: fastapi; extra == 'all'
29
29
  Requires-Dist: litellm; extra == 'all'
30
30
  Provides-Extra: drafter
31
- Requires-Dist: context-compiler-directive-drafter>=0.1.2; extra == 'drafter'
31
+ Requires-Dist: context-compiler-directive-drafter<0.3,>=0.2.0; extra == 'drafter'
32
32
  Provides-Extra: fastapi
33
33
  Requires-Dist: fastapi; extra == 'fastapi'
34
34
  Provides-Extra: litellm
@@ -61,7 +61,7 @@ pip install "context-compiler-example-integrations"
61
61
 
62
62
  That installs the shared core dependency only:
63
63
 
64
- - `context-compiler>=0.8.3`
64
+ - `context-compiler>=0.9.1,<0.10`
65
65
 
66
66
  Add extras only for the examples you want to inspect locally:
67
67
 
@@ -75,36 +75,12 @@ Open WebUI is not installed by this package. The Open WebUI reference
75
75
  integration assumes Open WebUI is already installed and configured as the host
76
76
  runtime.
77
77
 
78
- ## Generic examples
78
+ ## Package contents
79
79
 
80
- - [Checkpoint continuation](https://github.com/rlippmann/context-compiler-example-integrations/blob/main/python/examples/checkpoint_continuation/README.md): persisted confirmation and resume flows change host behavior across turns or requests
81
- - [Execution authorization](https://github.com/rlippmann/context-compiler-example-integrations/blob/main/python/examples/execution_authorization/README.md): protected host actions execute only when authoritative state allows them
82
- - [Gateway middleware](https://github.com/rlippmann/context-compiler-example-integrations/blob/main/python/examples/gateway_middleware/README.md): the host allows, blocks, or routes requests before downstream work runs
83
- - [Prompt construction](https://github.com/rlippmann/context-compiler-example-integrations/blob/main/python/examples/prompt_construction/README.md): the host builds different request or prompt payloads from authoritative state
84
- - [Retrieval filtering](https://github.com/rlippmann/context-compiler-example-integrations/blob/main/python/examples/retrieval_filtering/README.md): the host changes which documents are eligible or relevant before returning results
85
- - [Schema selection](https://github.com/rlippmann/context-compiler-example-integrations/blob/main/python/examples/schema_selection/README.md): the host picks different workflow or response schemas from authoritative state
86
- - [Tool gating](https://github.com/rlippmann/context-compiler-example-integrations/blob/main/python/examples/tool_gating/README.md): the host changes which tools are visible or executable at runtime
80
+ The installed package exposes the Python examples and reference-integration
81
+ modules under `context_compiler_example_integrations`.
87
82
 
88
- ## Reference integrations
89
-
90
- Python also includes reference integrations for runtime-specific behavior after
91
- the generic examples.
92
-
93
- Open a reference integration when you want to see the same kind of runtime
94
- behavior on a specific host or framework surface.
95
-
96
- Start with the generic example first, then use the Python reference
97
- integrations to inspect a runtime-specific path:
98
-
99
- - [LiteLLM Proxy reference integration](https://github.com/rlippmann/context-compiler-example-integrations/blob/main/python/reference_integrations/litellm_proxy/README.md)
100
- - [Open WebUI pipe reference integration](https://github.com/rlippmann/context-compiler-example-integrations/blob/main/python/reference_integrations/openwebui_pipe/README.md)
101
-
102
- ## Run an example
103
-
104
- To explore or run an example, use a repository checkout:
105
-
106
- 1. Clone
107
- [`context-compiler-example-integrations`](https://github.com/rlippmann/context-compiler-example-integrations).
108
- 2. Choose a generic example or a reference integration.
109
- 3. Open that example's README.
110
- 4. Follow the example-specific setup, runtime, and validation instructions.
83
+ For the enforcement-point catalog and repository navigation, see the [root
84
+ README](https://github.com/rlippmann/context-compiler-example-integrations/blob/main/README.md).
85
+ Each example and reference integration has its own setup, runtime, and
86
+ validation instructions.
@@ -4,14 +4,14 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "context-compiler-example-integrations"
7
- version = "0.1.2"
7
+ version = "0.2.1"
8
8
  description = "Example integrations and enforcement-point demonstrations for Context Compiler."
9
9
  readme = "python/README.md"
10
10
  requires-python = ">=3.11"
11
11
  license = { text = "Apache-2.0" }
12
12
  authors = [{ name = "Robert Lippmann" }]
13
13
  dependencies = [
14
- "context-compiler>=0.8.3",
14
+ "context-compiler>=0.9.1,<0.10",
15
15
  ]
16
16
  keywords = [
17
17
  "context-compiler",
@@ -47,12 +47,12 @@ Issues = "https://github.com/rlippmann/context-compiler-example-integrations/iss
47
47
  [project.optional-dependencies]
48
48
  all = [
49
49
  "chromadb",
50
- "context-compiler-directive-drafter>=0.1.2",
50
+ "context-compiler-directive-drafter>=0.2.0,<0.3",
51
51
  "fastapi",
52
52
  "litellm",
53
53
  ]
54
54
  drafter = [
55
- "context-compiler-directive-drafter>=0.1.2",
55
+ "context-compiler-directive-drafter>=0.2.0,<0.3",
56
56
  ]
57
57
  fastapi = [
58
58
  "fastapi",
@@ -67,7 +67,7 @@ retrieval = [
67
67
  [dependency-groups]
68
68
  dev = [
69
69
  "chromadb",
70
- "context-compiler-directive-drafter>=0.1.2",
70
+ "context-compiler-directive-drafter>=0.2.0,<0.3",
71
71
  "fastapi",
72
72
  "httpx2>=2.5.0",
73
73
  "httpx>=0.28.1",
@@ -0,0 +1,47 @@
1
+ # Context Compiler Example Integrations for Python
2
+
3
+ These examples show how authoritative state changes application behavior at runtime.
4
+
5
+ Each example demonstrates a single enforcement point where premise and policy influence what a host allows, routes, retrieves, builds, or executes.
6
+
7
+ - The core authority contract is provided by [`context-compiler`](https://github.com/rlippmann/context-compiler).
8
+ - Directive recognition can optionally be added with [`context-compiler-directive-drafter`](https://github.com/rlippmann/context-compiler-directive-drafter).
9
+ - These examples focus on where authoritative state changes application behavior.
10
+
11
+ *Prompt reinjection* influences ***model behavior***.
12
+
13
+ *Context Compiler* influences ***runtime behavior***.
14
+
15
+ ## Install options
16
+
17
+ Base installation keeps this package discovery-first:
18
+
19
+ ```shell
20
+ pip install "context-compiler-example-integrations"
21
+ ```
22
+
23
+ That installs the shared core dependency only:
24
+
25
+ - `context-compiler>=0.9.1,<0.10`
26
+
27
+ Add extras only for the examples you want to inspect locally:
28
+
29
+ - `pip install "context-compiler-example-integrations[drafter]"` for examples that use `context-compiler-directive-drafter`
30
+ - `pip install "context-compiler-example-integrations[retrieval]"` for ChromaDB retrieval filtering examples
31
+ - `pip install "context-compiler-example-integrations[fastapi]"` for FastAPI variants
32
+ - `pip install "context-compiler-example-integrations[litellm]"` for LiteLLM-oriented examples and reference integrations
33
+ - `pip install "context-compiler-example-integrations[all]"` to install all package-managed optional dependencies
34
+
35
+ Open WebUI is not installed by this package. The Open WebUI reference
36
+ integration assumes Open WebUI is already installed and configured as the host
37
+ runtime.
38
+
39
+ ## Package contents
40
+
41
+ The installed package exposes the Python examples and reference-integration
42
+ modules under `context_compiler_example_integrations`.
43
+
44
+ For the enforcement-point catalog and repository navigation, see the [root
45
+ README](https://github.com/rlippmann/context-compiler-example-integrations/blob/main/README.md).
46
+ Each example and reference integration has its own setup, runtime, and
47
+ validation instructions.
@@ -0,0 +1,65 @@
1
+ # State Persistence
2
+
3
+ Persisting authoritative compiler state lets a fresh host process recover the
4
+ same premise and policy decisions without recreating them from model output or
5
+ conversation history. This example shows state persistence in a generic Python
6
+ travel-booking flow.
7
+
8
+ ## Domain
9
+
10
+ The domain is a small travel-booking change flow.
11
+
12
+ The user selects a new itinerary, the compiler records that selection in
13
+ authoritative state, and the host later applies the booking change from a
14
+ restored engine.
15
+
16
+ ## Runtime
17
+
18
+ This is a generic Python example.
19
+
20
+ It does not call an LLM.
21
+
22
+ It does not use directive drafter.
23
+
24
+ ## What Context Compiler owns
25
+
26
+ Context Compiler owns:
27
+
28
+ - authoritative policy state
29
+ - serialization of that state through `export_json()`
30
+ - restoration of that state through `import_json()`
31
+
32
+ ## What the host owns
33
+
34
+ The host owns:
35
+
36
+ - the booking record
37
+ - persisted state storage
38
+ - process boundaries
39
+ - the runtime behavior that actually applies the itinerary change
40
+
41
+ The host reads restored authoritative Context Compiler state and decides whether
42
+ to apply the booking change.
43
+
44
+ ## Example behavior
45
+
46
+ 1. The host starts with a booking on `boston_trip`.
47
+ 2. The user selects `chicago_trip`.
48
+ 3. Context Compiler updates authoritative state.
49
+ 4. The host persists that state JSON.
50
+ 5. A fresh host process restores the saved state into a new engine.
51
+ 6. The host applies the booking change from the restored authoritative state.
52
+
53
+ ## Run
54
+
55
+ From the repository root:
56
+
57
+ ```bash
58
+ uv run python python/examples/checkpoint_continuation/example.py
59
+ uv run pytest python/tests/test_checkpoint_continuation_example.py
60
+ ```
61
+
62
+ ## FastAPI variant
63
+
64
+ For a request-boundary example, see
65
+ [python/examples/checkpoint_continuation/fastapi/README.md](fastapi/README.md).
@@ -0,0 +1,163 @@
1
+ """Minimal persistence example for a travel booking change."""
2
+
3
+ from collections.abc import Mapping
4
+ from dataclasses import dataclass, field
5
+ from typing import Literal, TypedDict
6
+
7
+ from context_compiler import Decision, DecisionKind, Engine, POLICY_USE, PolicyValue
8
+
9
+
10
+ class BookingRecord(TypedDict):
11
+ booking_id: str
12
+ active_itinerary: str
13
+
14
+
15
+ class BookingChangeRuntimeResult(TypedDict):
16
+ compiler_input: str
17
+ decision_kind: Literal["error", "update", "passthrough"]
18
+ message_to_user: str | None
19
+ persisted_state_json: str
20
+ selected_itinerary: str | None
21
+ host_applied_change: bool
22
+ active_itinerary: str
23
+
24
+
25
+ @dataclass
26
+ class EnginePersistenceStore:
27
+ """Host-owned persistence for serialized authoritative compiler state."""
28
+
29
+ saved_state_json: str | None = None
30
+
31
+ def save(self, state_json: str) -> None:
32
+ self.saved_state_json = state_json
33
+
34
+ def load(self) -> str:
35
+ if self.saved_state_json is None:
36
+ raise ValueError("no saved state")
37
+ return self.saved_state_json
38
+
39
+
40
+ @dataclass
41
+ class BookingHost:
42
+ """Host-owned runtime behavior for the booking example."""
43
+
44
+ booking: BookingRecord
45
+ applied_changes: list[str] = field(default_factory=list)
46
+
47
+ def apply_selected_itinerary(self, policies: Mapping[str, PolicyValue]) -> bool:
48
+ selected_itinerary = select_itinerary_from_policies(policies)
49
+ if selected_itinerary is None:
50
+ return False
51
+
52
+ self.booking["active_itinerary"] = selected_itinerary
53
+ self.applied_changes.append(selected_itinerary)
54
+ return True
55
+
56
+
57
+ def select_itinerary_from_policies(policies: Mapping[str, PolicyValue]) -> str | None:
58
+ """Select the host-visible itinerary from authoritative state."""
59
+
60
+ for item, kind in policies.items():
61
+ if kind == POLICY_USE:
62
+ return item
63
+ return None
64
+
65
+
66
+ def _decision_kind_name(
67
+ decision: Decision,
68
+ ) -> Literal["error", "update", "passthrough"]:
69
+ kind = decision.kind
70
+ if kind == DecisionKind.ERROR:
71
+ return "error"
72
+ if kind == DecisionKind.UPDATE:
73
+ return "update"
74
+ if kind == DecisionKind.NO_DIRECTIVE:
75
+ return "passthrough"
76
+ raise ValueError(f"unexpected decision kind: {kind}")
77
+
78
+
79
+ def persist_itinerary_selection(
80
+ engine: Engine,
81
+ *,
82
+ requested_itinerary: str,
83
+ ) -> BookingChangeRuntimeResult:
84
+ """Persist authoritative state after selecting an itinerary."""
85
+
86
+ compiler_input = f"use {requested_itinerary}"
87
+ decision = engine.step(compiler_input)
88
+ persisted_state_json = engine.export_json()
89
+ selected_itinerary = select_itinerary_from_policies(engine.policies)
90
+
91
+ return {
92
+ "compiler_input": compiler_input,
93
+ "decision_kind": _decision_kind_name(decision),
94
+ "message_to_user": decision.message
95
+ if decision.kind == DecisionKind.ERROR
96
+ else None,
97
+ "persisted_state_json": persisted_state_json,
98
+ "selected_itinerary": selected_itinerary,
99
+ "host_applied_change": False,
100
+ "active_itinerary": requested_itinerary
101
+ if selected_itinerary is not None
102
+ else "boston_trip",
103
+ }
104
+
105
+
106
+ def restore_engine_from_persisted_state(state_json: str) -> Engine:
107
+ """Restore authoritative compiler state into a fresh engine."""
108
+
109
+ engine = Engine()
110
+ engine.import_json(state_json)
111
+ return engine
112
+
113
+
114
+ def apply_restored_itinerary(
115
+ engine: Engine, host: BookingHost
116
+ ) -> BookingChangeRuntimeResult:
117
+ """Apply host behavior from restored authoritative compiler state."""
118
+
119
+ host_applied_change = host.apply_selected_itinerary(engine.policies)
120
+ selected_itinerary = select_itinerary_from_policies(engine.policies)
121
+
122
+ return {
123
+ "compiler_input": "",
124
+ "decision_kind": "update" if host_applied_change else "passthrough",
125
+ "message_to_user": None,
126
+ "persisted_state_json": engine.export_json(),
127
+ "selected_itinerary": selected_itinerary,
128
+ "host_applied_change": host_applied_change,
129
+ "active_itinerary": host.booking["active_itinerary"],
130
+ }
131
+
132
+
133
+ def run_demo() -> dict[str, BookingChangeRuntimeResult | str]:
134
+ """Run a deterministic persistence demonstration."""
135
+
136
+ initial_booking: BookingRecord = {
137
+ "booking_id": "booking-100",
138
+ "active_itinerary": "boston_trip",
139
+ }
140
+ first_engine = Engine()
141
+ engine_persistence_store = EnginePersistenceStore()
142
+
143
+ persisted_result = persist_itinerary_selection(
144
+ first_engine,
145
+ requested_itinerary="chicago_trip",
146
+ )
147
+ engine_persistence_store.save(persisted_result["persisted_state_json"])
148
+
149
+ restored_engine = restore_engine_from_persisted_state(
150
+ engine_persistence_store.load()
151
+ )
152
+ restored_host = BookingHost(booking=initial_booking.copy())
153
+ applied_result = apply_restored_itinerary(restored_engine, restored_host)
154
+
155
+ return {
156
+ "persisted_result": persisted_result,
157
+ "applied_result": applied_result,
158
+ "saved_state_json": engine_persistence_store.load(),
159
+ }
160
+
161
+
162
+ if __name__ == "__main__":
163
+ print(run_demo())
@@ -0,0 +1,65 @@
1
+ # State Persistence with FastAPI
2
+
3
+ Saved authoritative compiler state lets later HTTP requests recover the same
4
+ policy decisions instead of starting over. This example shows state
5
+ persistence across stateless HTTP request boundaries.
6
+
7
+ ## Enforcement Point
8
+
9
+ Authoritative state persistence
10
+
11
+ ## Domain
12
+
13
+ The domain is a small travel-booking change flow.
14
+
15
+ The first request selects `chicago_trip` in compiler state. A later request
16
+ restores that saved state and lets the host apply the booking change.
17
+
18
+ ## Runtime
19
+
20
+ This is a small FastAPI example.
21
+
22
+ FastAPI is secondary to the enforcement point.
23
+
24
+ It exists to show that the host can persist authoritative state between
25
+ separate HTTP requests and restore it later into a fresh engine.
26
+
27
+ ## Ownership Boundary
28
+
29
+ Context Compiler owns:
30
+
31
+ - authoritative policy state
32
+ - state export through `export_json()`
33
+ - state restore through `import_json()`
34
+
35
+ The host owns:
36
+
37
+ - persisted state storage
38
+ - request routing
39
+ - booking mutation
40
+
41
+ In this example, the host creates a fresh engine per request.
42
+
43
+ The second request applies the saved itinerary only because the host restores
44
+ the persisted authoritative state, not because the process remembered a
45
+ conversation.
46
+
47
+ ## Endpoints
48
+
49
+ - `POST /change-trip`
50
+ - updates authoritative state with `use chicago_trip`
51
+ - persists the resulting state JSON in the host store
52
+ - `POST /apply-trip`
53
+ - restores the saved state JSON into a fresh engine
54
+ - applies the booking change from restored policy state
55
+ - `GET /booking`
56
+ - returns the host-owned booking state
57
+
58
+ ## Validate
59
+
60
+ From the repository root:
61
+
62
+ ```bash
63
+ uv run pytest python/tests/test_fastapi_checkpoint_continuation_example.py
64
+ uv run pre-commit run --all-files
65
+ ```