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.
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/PKG-INFO +13 -37
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/pyproject.toml +5 -5
- context_compiler_example_integrations-0.2.1/python/README.md +47 -0
- context_compiler_example_integrations-0.2.1/python/examples/checkpoint_continuation/README.md +65 -0
- context_compiler_example_integrations-0.2.1/python/examples/checkpoint_continuation/example.py +163 -0
- context_compiler_example_integrations-0.2.1/python/examples/checkpoint_continuation/fastapi/README.md +65 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/checkpoint_continuation/fastapi/app.py +65 -69
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/execution_authorization/expense_approval/README.md +4 -4
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/execution_authorization/expense_approval/example.py +39 -40
- {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
- {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
- {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
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/prompt_construction/litellm/README.md +32 -23
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/prompt_construction/litellm/basic.py +65 -120
- context_compiler_example_integrations-0.2.1/python/examples/prompt_construction/litellm/with_directive_drafter.py +371 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/prompt_construction/writing_assistant/README.md +1 -1
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/prompt_construction/writing_assistant/example.py +39 -43
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/schema_selection/refund_intake/example.py +13 -12
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/tool_gating/calendar_admin/example.py +40 -43
- {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
- {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
- {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
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/reference_integrations/litellm_proxy/README.md +17 -16
- context_compiler_example_integrations-0.2.1/python/reference_integrations/litellm_proxy/_litellm_support.py +34 -0
- {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
- context_compiler_example_integrations-0.2.1/python/reference_integrations/litellm_proxy/context_compiler_precall_hook_with_directive_drafter.py +184 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/reference_integrations/openwebui_pipe/README.md +57 -38
- {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
- {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
- context_compiler_example_integrations-0.1.2/python/README.md +0 -71
- context_compiler_example_integrations-0.1.2/python/examples/checkpoint_continuation/README.md +0 -77
- context_compiler_example_integrations-0.1.2/python/examples/checkpoint_continuation/example.py +0 -169
- context_compiler_example_integrations-0.1.2/python/examples/checkpoint_continuation/fastapi/README.md +0 -85
- context_compiler_example_integrations-0.1.2/python/examples/prompt_construction/litellm/confirmation_helper.py +0 -91
- context_compiler_example_integrations-0.1.2/python/examples/prompt_construction/litellm/with_directive_drafter.py +0 -524
- context_compiler_example_integrations-0.1.2/python/reference_integrations/litellm_proxy/context_compiler_precall_hook_with_directive_drafter.py +0 -289
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/.gitignore +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/LICENSE +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/context_compiler_example_integrations/__init__.py +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/context_compiler_example_integrations/examples/__init__.py +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/context_compiler_example_integrations/reference_integrations/__init__.py +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/_shared/__init__.py +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/_shared/litellm_request.py +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/_shared/provider_mode.py +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/execution_authorization/README.md +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/execution_authorization/expense_approval/__init__.py +0 -0
- {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
- {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
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/gateway_middleware/README.md +0 -0
- {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
- {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
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/prompt_construction/README.md +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/prompt_construction/writing_assistant/__init__.py +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/retrieval_filtering/README.md +0 -0
- {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
- {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
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/schema_selection/README.md +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/schema_selection/refund_intake/README.md +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/schema_selection/refund_intake/__init__.py +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/tool_gating/README.md +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/tool_gating/calendar_admin/README.md +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/examples/tool_gating/calendar_admin/__init__.py +0 -0
- {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
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/reference_integrations/litellm_proxy/_checkpoint_support.py +0 -0
- {context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/python/reference_integrations/litellm_proxy/config.example.yaml +0 -0
{context_compiler_example_integrations-0.1.2 → context_compiler_example_integrations-0.2.1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: context-compiler-example-integrations
|
|
3
|
-
Version: 0.1
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
##
|
|
78
|
+
## Package contents
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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).
|
context_compiler_example_integrations-0.2.1/python/examples/checkpoint_continuation/example.py
ADDED
|
@@ -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
|
+
```
|