From eda34fdba9c713f54690dcb8ecb73f27150ad36b Mon Sep 17 00:00:00 2001 From: Robert Lippmann Date: Mon, 21 Sep 2026 00:57:04 -0400 Subject: [PATCH 1/2] chore: adopt stable compiler dependencies --- pyproject.toml | 8 ++-- python/README.md | 2 +- .../prompt_construction/litellm/README.md | 4 +- .../litellm_proxy/README.md | 2 +- .../openwebui_pipe/README.md | 10 ++-- .../openwebui_pipe/open_webui_pipe.py | 2 +- .../open_webui_pipe_with_directive_drafter.py | 4 +- python/tests/test_litellm_proxy_hooks.py | 16 +++---- .../test_litellm_with_directive_drafter.py | 34 ++++++------- ...t_openwebui_pipe_with_directive_drafter.py | 48 +++++++++---------- uv.lock | 20 ++++---- 11 files changed, 75 insertions(+), 75 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7ac9f1a..13c372b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ requires-python = ">=3.11" license = { text = "Apache-2.0" } authors = [{ name = "Robert Lippmann" }] dependencies = [ - "context-compiler==0.9.0dev13", + "context-compiler>=0.9.1,<0.10", ] keywords = [ "context-compiler", @@ -47,12 +47,12 @@ Issues = "https://github.com/rlippmann/context-compiler-example-integrations/iss [project.optional-dependencies] all = [ "chromadb", - "context-compiler-directive-drafter==0.2.0dev5", + "context-compiler-directive-drafter>=0.2.0,<0.3", "fastapi", "litellm", ] drafter = [ - "context-compiler-directive-drafter==0.2.0dev5", + "context-compiler-directive-drafter>=0.2.0,<0.3", ] fastapi = [ "fastapi", @@ -67,7 +67,7 @@ retrieval = [ [dependency-groups] dev = [ "chromadb", - "context-compiler-directive-drafter==0.2.0dev5", + "context-compiler-directive-drafter>=0.2.0,<0.3", "fastapi", "httpx2>=2.5.0", "httpx>=0.28.1", diff --git a/python/README.md b/python/README.md index 60b5c6a..a0f422f 100644 --- a/python/README.md +++ b/python/README.md @@ -22,7 +22,7 @@ pip install "context-compiler-example-integrations" That installs the shared core dependency only: -- `context-compiler>=0.9.0dev13` +- `context-compiler>=0.9.1,<0.10` Add extras only for the examples you want to inspect locally: diff --git a/python/examples/prompt_construction/litellm/README.md b/python/examples/prompt_construction/litellm/README.md index 8829479..25e6707 100644 --- a/python/examples/prompt_construction/litellm/README.md +++ b/python/examples/prompt_construction/litellm/README.md @@ -60,7 +60,7 @@ pip install "context-compiler-example-integrations[litellm]" export OPENAI_API_KEY=... ``` -These examples require `context-compiler>=0.9.0dev13`. +These examples require `context-compiler>=0.9.1,<0.10`. For `with_directive_drafter.py`: @@ -68,7 +68,7 @@ For `with_directive_drafter.py`: pip install "context-compiler-example-integrations[all]" ``` -That variant requires `context-compiler-directive-drafter>=0.2.0dev5`. +That variant requires `context-compiler-directive-drafter>=0.2.0,<0.3`. ## Quickstart (copy/paste) diff --git a/python/reference_integrations/litellm_proxy/README.md b/python/reference_integrations/litellm_proxy/README.md index bf6ae07..79f8fb7 100644 --- a/python/reference_integrations/litellm_proxy/README.md +++ b/python/reference_integrations/litellm_proxy/README.md @@ -108,7 +108,7 @@ For `context_compiler_precall_hook_with_directive_drafter.py`: pip install "context-compiler-example-integrations[all]" ``` -That variant requires `context-compiler-directive-drafter>=0.2.0dev5`. +That variant requires `context-compiler-directive-drafter>=0.2.0,<0.3`. For the opt-in runtime smoke test, install the proxy runtime extras: diff --git a/python/reference_integrations/openwebui_pipe/README.md b/python/reference_integrations/openwebui_pipe/README.md index 13d728f..79be582 100644 --- a/python/reference_integrations/openwebui_pipe/README.md +++ b/python/reference_integrations/openwebui_pipe/README.md @@ -56,7 +56,7 @@ Open WebUI is a separate runtime and must already be installed/configured separa Open WebUI also needs at least one real backend model/provider configured (for example Ollama or OpenAI) so `BASE_MODEL_ID` resolves to an actual model. Note: The `PROVIDER` environment contract used in LiteLLM examples/demos does not apply to OpenWebUI. OpenWebUI manages providers via its own connection settings and model IDs. -These examples require `context-compiler>=0.9.0dev13`. +These examples require `context-compiler>=0.9.1,<0.10`. ### Configuration @@ -68,7 +68,7 @@ These examples require `context-compiler>=0.9.0dev13`. If using `open_webui_pipe_with_directive_drafter.py`: - Install directive-drafter support if needed: - `pip install "context-compiler>=0.9.0dev13" "context-compiler-directive-drafter>=0.2.0dev5"` + `pip install "context-compiler>=0.9.1,<0.10" "context-compiler-directive-drafter>=0.2.0,<0.3"` - Optionally set `DRAFTER_MODEL_ID` to use a separate fallback drafting model - If neither model id is set, fallback uses `BASE_MODEL_ID` @@ -83,8 +83,8 @@ If frontmatter dependency installs are disabled, offline, or unavailable: 1. Install the package manually: -- Minimal pipe: `pip install "context-compiler>=0.9.0dev13"` -- Directive Drafter pipe: `pip install "context-compiler>=0.9.0dev13" "context-compiler-directive-drafter>=0.2.0dev5"` +- Minimal pipe: `pip install "context-compiler>=0.9.1,<0.10"` +- Directive Drafter pipe: `pip install "context-compiler>=0.9.1,<0.10" "context-compiler-directive-drafter>=0.2.0,<0.3"` 1. Import and enable the function in Open WebUI, then configure valves. @@ -244,7 +244,7 @@ rejection flows. - `DRAFTER_MODEL_ID must not match the selected pipe model id`: choose a real backend model id, not the pipe model id itself. - `DRAFTER_MODEL_ID is invalid or not configured in Open WebUI`: the fallback route hit a missing model; fix the configured fallback model or unset it to reuse `BASE_MODEL_ID`. - `ALLOW_MISSING_BASE_MODEL_FOR_DEBUG=true`: directive-only updates still run locally, but passthrough returns a deterministic debug message instead of calling a downstream model. -- imports fail after function upload: install `context-compiler>=0.9.0dev13` in the Open WebUI runtime, and add `context-compiler-directive-drafter>=0.2.0dev5` only for the Directive Drafter pipe, because the copied function runs from a temp/cached location. +- imports fail after function upload: install `context-compiler>=0.9.1,<0.10` in the Open WebUI runtime, and add `context-compiler-directive-drafter>=0.2.0,<0.3` only for the Directive Drafter pipe, because the copied function runs from a temp/cached location. ## Fallback notes diff --git a/python/reference_integrations/openwebui_pipe/open_webui_pipe.py b/python/reference_integrations/openwebui_pipe/open_webui_pipe.py index cef5dd3..b8fb1ec 100644 --- a/python/reference_integrations/openwebui_pipe/open_webui_pipe.py +++ b/python/reference_integrations/openwebui_pipe/open_webui_pipe.py @@ -3,7 +3,7 @@ author: rlippmann author_url: https://github.com/rlippmann/context-compiler-example-integrations version: 0.10.0 -requirements: context-compiler>=0.9.0dev13 +requirements: context-compiler>=0.9.1,<0.10 Minimal Open WebUI Pipe integration for Context Compiler. diff --git a/python/reference_integrations/openwebui_pipe/open_webui_pipe_with_directive_drafter.py b/python/reference_integrations/openwebui_pipe/open_webui_pipe_with_directive_drafter.py index cbee6c3..aaeb396 100644 --- a/python/reference_integrations/openwebui_pipe/open_webui_pipe_with_directive_drafter.py +++ b/python/reference_integrations/openwebui_pipe/open_webui_pipe_with_directive_drafter.py @@ -2,8 +2,8 @@ title: Context Compiler Open WebUI Pipe (Directive Drafter) author: rlippmann author_url: https://github.com/rlippmann/context-compiler-example-integrations -version: 0.10.2 -requirements: context-compiler>=0.9.0dev13, context-compiler-directive-drafter>=0.2.0dev5 +version: 0.10.3 +requirements: context-compiler>=0.9.1,<0.10, context-compiler-directive-drafter>=0.2.0,<0.3 Open WebUI integration with Context Compiler directive drafter. diff --git a/python/tests/test_litellm_proxy_hooks.py b/python/tests/test_litellm_proxy_hooks.py index d03d4e0..18b33b8 100644 --- a/python/tests/test_litellm_proxy_hooks.py +++ b/python/tests/test_litellm_proxy_hooks.py @@ -246,16 +246,16 @@ def test_current_turn_is_processed_exactly_once(monkeypatch) -> None: seen_inputs: list[str] = [] original_Engine = module.Engine - def Engine_with_tracking(): - engine = original_Engine() - original_step = engine.step + original_step = original_Engine.step + + def tracked_step(self, user_input: str): + seen_inputs.append(user_input) + return original_step(self, user_input) - def tracked_step(user_input: str): - seen_inputs.append(user_input) - return original_step(user_input) + monkeypatch.setattr(original_Engine, "step", tracked_step) - engine.step = tracked_step - return engine + def Engine_with_tracking(): + return original_Engine() monkeypatch.setattr(module, "Engine", Engine_with_tracking) data = { diff --git a/python/tests/test_litellm_with_directive_drafter.py b/python/tests/test_litellm_with_directive_drafter.py index 613d067..afe6cad 100644 --- a/python/tests/test_litellm_with_directive_drafter.py +++ b/python/tests/test_litellm_with_directive_drafter.py @@ -25,15 +25,15 @@ def test_directive_shaped_or_natural_language_input_is_drafted_before_engine_ste monkeypatch, ) -> None: compile_inputs: list[str] = [] - real_step = Engine().step - engine = Engine() - def step_with_capture(user_input: str): + real_step = Engine.step + + def step_with_capture(self: Engine, user_input: str): compile_inputs.append(user_input) - return real_step(user_input) + return real_step(self, user_input) - monkeypatch.setattr(engine, "step", step_with_capture) + monkeypatch.setattr(Engine, "step", step_with_capture) monkeypatch.setattr( module, "_get_directive_drafter", @@ -53,13 +53,13 @@ def test_rejected_canonical_directive_does_not_call_engine_step_or_mutate_state( ) -> None: engine = Engine() compile_inputs: list[str] = [] - real_step = engine.step + real_step = Engine.step - def step_with_capture(user_input: str): + def step_with_capture(self: Engine, user_input: str): compile_inputs.append(user_input) - return real_step(user_input) + return real_step(self, user_input) - monkeypatch.setattr(engine, "step", step_with_capture) + monkeypatch.setattr(Engine, "step", step_with_capture) monkeypatch.setattr( module, "_get_directive_drafter", @@ -88,13 +88,13 @@ def test_no_directive_keeps_normal_flow(monkeypatch) -> None: engine = Engine() compile_inputs: list[str] = [] llm_calls: list[list[dict[str, str]]] = [] - real_step = engine.step + real_step = Engine.step - def step_with_capture(user_input: str): + def step_with_capture(self: Engine, user_input: str): compile_inputs.append(user_input) - return real_step(user_input) + return real_step(self, user_input) - monkeypatch.setattr(engine, "step", step_with_capture) + monkeypatch.setattr(Engine, "step", step_with_capture) monkeypatch.setattr( module, "_get_directive_drafter", @@ -118,13 +118,13 @@ def test_unknown_directive_keeps_normal_flow(monkeypatch) -> None: engine = Engine() compile_inputs: list[str] = [] llm_calls: list[list[dict[str, str]]] = [] - real_step = engine.step + real_step = Engine.step - def step_with_capture(user_input: str): + def step_with_capture(self: Engine, user_input: str): compile_inputs.append(user_input) - return real_step(user_input) + return real_step(self, user_input) - monkeypatch.setattr(engine, "step", step_with_capture) + monkeypatch.setattr(Engine, "step", step_with_capture) monkeypatch.setattr( module, "_get_directive_drafter", diff --git a/python/tests/test_openwebui_pipe_with_directive_drafter.py b/python/tests/test_openwebui_pipe_with_directive_drafter.py index 161456a..c9550e0 100644 --- a/python/tests/test_openwebui_pipe_with_directive_drafter.py +++ b/python/tests/test_openwebui_pipe_with_directive_drafter.py @@ -209,16 +209,16 @@ def test_approval_applies_directive_through_engine_path(monkeypatch) -> None: compile_inputs: list[str] = [] real_Engine = module.Engine - def Engine_with_tracking(): - engine = real_Engine() - original_apply_directive = engine.apply_directive + original_apply_directive = real_Engine.apply_directive + + def tracked_apply_directive(self, directive): + compile_inputs.append(directive.text) + return original_apply_directive(self, directive) - def tracked_apply_directive(directive): - compile_inputs.append(directive.text) - return original_apply_directive(directive) + monkeypatch.setattr(real_Engine, "apply_directive", tracked_apply_directive) - engine.apply_directive = tracked_apply_directive - return engine + def Engine_with_tracking(): + return real_Engine() monkeypatch.setattr(module, "Engine", Engine_with_tracking) pipe = module.Pipe() @@ -456,16 +456,16 @@ def test_rejected_confirmation_does_not_apply_follow_up(monkeypatch) -> None: forwarded: list[dict[str, object]] = [] real_Engine = module.Engine - def Engine_with_tracking(): - engine = real_Engine() - original_step = engine.step + original_step = real_Engine.step - def tracked_step(user_input: str): - compile_inputs.append(user_input) - return original_step(user_input) + def tracked_step(self, user_input: str): + compile_inputs.append(user_input) + return original_step(self, user_input) - engine.step = tracked_step - return engine + monkeypatch.setattr(real_Engine, "step", tracked_step) + + def Engine_with_tracking(): + return real_Engine() async def forward( _: object, payload: dict[str, object], __: object @@ -542,16 +542,16 @@ def test_rejected_confirmation_does_not_leave_state( forwarded: list[dict[str, object]] = [] real_Engine = module.Engine - def Engine_with_tracking(): - engine = real_Engine() - original_step = engine.step + original_step = real_Engine.step - def tracked_step(user_input: str): - compile_inputs.append(user_input) - return original_step(user_input) + def tracked_step(self, user_input: str): + compile_inputs.append(user_input) + return original_step(self, user_input) - engine.step = tracked_step - return engine + monkeypatch.setattr(real_Engine, "step", tracked_step) + + def Engine_with_tracking(): + return real_Engine() async def forward( _: object, payload: dict[str, object], __: object diff --git a/uv.lock b/uv.lock index 4c3e850..521144f 100644 --- a/uv.lock +++ b/uv.lock @@ -658,23 +658,23 @@ wheels = [ [[package]] name = "context-compiler" -version = "0.9.0.dev13" +version = "0.9.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a8/99/d9340cda4349d2301818061ff19739e0e22eb3f4969249c2b69ae6510a87/context_compiler-0.9.0.dev13.tar.gz", hash = "sha256:733e5a84d22343cb0cf6e0fc435acc5943308b300eddb5d52d2a379d067ef383", size = 54371, upload-time = "2026-08-16T08:34:50.891Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/d3/eb0ee647005906f07ebc4a4622d96a830298358793d9861032479103cab1/context_compiler-0.9.1.tar.gz", hash = "sha256:a8bfea54a7d4549977c1746316b2ccc3b0104217b07834370e1c76c9ee235f9d", size = 50049, upload-time = "2026-09-08T03:13:35.441Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/56/261c3c7da43b49d057722e96e787aac7f8d76ae7bb4748bddae581312227/context_compiler-0.9.0.dev13-py3-none-any.whl", hash = "sha256:27b33f88c0fe6bca4d49f6af986eddac515e5da92e6c0a896d6a523e385ef641", size = 26482, upload-time = "2026-08-16T08:34:49.6Z" }, + { url = "https://files.pythonhosted.org/packages/c4/1e/2c7f932787bb0cf68ec116f20dff8874bf08641cbb20b76b9941bc987ee3/context_compiler-0.9.1-py3-none-any.whl", hash = "sha256:18d1f3eb9fe64d051b483a6226c795e6cfecfd6479ae4a31ddd14fa178c09d53", size = 22017, upload-time = "2026-09-08T03:13:33.993Z" }, ] [[package]] name = "context-compiler-directive-drafter" -version = "0.2.0.dev5" +version = "0.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "context-compiler" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3d/92/2b5487df80e887c27002f97c117edf2dfbde2022d67cd24e86c95961a5a0/context_compiler_directive_drafter-0.2.0.dev5.tar.gz", hash = "sha256:020fae29026fee0dd7f38c6a3d58d972c288ddd200df72ff7d2473fb64dd4f75", size = 280663, upload-time = "2026-09-02T07:24:26.502Z" } +sdist = { url = "https://files.pythonhosted.org/packages/89/21/c08999361a17084ed9c1744a69c95aded63433d338e01fbca92a0d11ed11/context_compiler_directive_drafter-0.2.0.tar.gz", hash = "sha256:4826794ae9370956a980c1083cee681e3e6d1e3d18108150bc12e539b574c190", size = 277969, upload-time = "2026-09-20T04:06:32.244Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/3a/11d2ef36aecb7df8c2388b3f6015958ceefc2971b802137188e02b2c8383/context_compiler_directive_drafter-0.2.0.dev5-py3-none-any.whl", hash = "sha256:158d2305c479fc25f572dd72a4eefd298d702b796db4fb62f48611a773ba8c58", size = 35113, upload-time = "2026-09-02T07:24:25.307Z" }, + { url = "https://files.pythonhosted.org/packages/89/1c/09f7033426070196ae2771290c40b7cbc26235cd4b3cb26343d535f27ccc/context_compiler_directive_drafter-0.2.0-py3-none-any.whl", hash = "sha256:4d86fc60ab22c6ec6b7126e369ad5ae5249338d3c863b15428e06f81c1b472df", size = 29947, upload-time = "2026-09-20T04:06:30.861Z" }, ] [[package]] @@ -726,9 +726,9 @@ proxy-runtime = [ requires-dist = [ { name = "chromadb", marker = "extra == 'all'" }, { name = "chromadb", marker = "extra == 'retrieval'" }, - { name = "context-compiler", specifier = "==0.9.0.dev13" }, - { name = "context-compiler-directive-drafter", marker = "extra == 'all'", specifier = "==0.2.0.dev5" }, - { name = "context-compiler-directive-drafter", marker = "extra == 'drafter'", specifier = "==0.2.0.dev5" }, + { name = "context-compiler", specifier = ">=0.9.1,<0.10" }, + { name = "context-compiler-directive-drafter", marker = "extra == 'all'", specifier = ">=0.2.0,<0.3" }, + { name = "context-compiler-directive-drafter", marker = "extra == 'drafter'", specifier = ">=0.2.0,<0.3" }, { name = "fastapi", marker = "extra == 'all'" }, { name = "fastapi", marker = "extra == 'fastapi'" }, { name = "litellm", marker = "extra == 'all'" }, @@ -739,7 +739,7 @@ provides-extras = ["all", "drafter", "fastapi", "litellm", "retrieval"] [package.metadata.requires-dev] dev = [ { name = "chromadb" }, - { name = "context-compiler-directive-drafter", specifier = "==0.2.0.dev5" }, + { name = "context-compiler-directive-drafter", specifier = ">=0.2.0,<0.3" }, { name = "fastapi" }, { name = "httpx", specifier = ">=0.28.1" }, { name = "httpx2", specifier = ">=2.5.0" }, From 9e465526a236fd91ea7594ba9200e274e1f1785b Mon Sep 17 00:00:00 2001 From: Robert Lippmann Date: Mon, 21 Sep 2026 01:06:33 -0400 Subject: [PATCH 2/2] chore: bump base Open WebUI pipe --- python/reference_integrations/openwebui_pipe/open_webui_pipe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/reference_integrations/openwebui_pipe/open_webui_pipe.py b/python/reference_integrations/openwebui_pipe/open_webui_pipe.py index b8fb1ec..5a64be6 100644 --- a/python/reference_integrations/openwebui_pipe/open_webui_pipe.py +++ b/python/reference_integrations/openwebui_pipe/open_webui_pipe.py @@ -2,7 +2,7 @@ title: Context Compiler Open WebUI Pipe author: rlippmann author_url: https://github.com/rlippmann/context-compiler-example-integrations -version: 0.10.0 +version: 0.10.1 requirements: context-compiler>=0.9.1,<0.10 Minimal Open WebUI Pipe integration for Context Compiler.