From 65feb8b87a17ec629bf423d3021ed7349b331f90 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Sun, 13 Sep 2026 10:02:15 +0200 Subject: [PATCH] release api/v1.2.0 Webber through the boilerroom wrapper: flavor-adaptive tool_choice, session identity at rank 20, and the sanitized-client wiring fix that makes the choke point real. Co-Authored-By: Claude Fable 5 --- webber-api/CHANGELOG.md | 31 +++++++++++++++++++++++ webber-api/pyproject.toml | 2 +- webber-api/tests/test_provider_backend.py | 9 +++++-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/webber-api/CHANGELOG.md b/webber-api/CHANGELOG.md index a066e3c..50c0afc 100644 --- a/webber-api/CHANGELOG.md +++ b/webber-api/CHANGELOG.md @@ -7,6 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.2.0] - 2026-09-13 + +### Added + +- Backend adaptation at the provider choke point (workspace T-137): + the local backend's flavor is probed once — the boilerroom wrapper + names itself on `/health`, a bare llama-server serves `/props`, + Ollama answers neither — and every completion adapts. The agents' + `tool_choice: "required"` survives only on Ollama, where it is a + useful advisory nudge; llama-server enforces it per request, which + through the wrapper is an unbreakable tool loop. Through the wrapper + every completion carries webber's session identity — + `session: webber`, `eviction_order: 20` per the decided ranking + (tatlock phases 40, experts 35, librarian 30; lower parks sooner), + configurable via `BACKEND_SESSION_NAME`/`BACKEND_SESSION_RANK` — + and the wrapper's `balancing`/`compaction_due` body signals are + logged. A transport failure during the probe answers "ollama" + without caching, so a backend that was down at first call is + re-probed rather than misclassified forever. + +### Fixed + +- The sanitized OpenAI client was never used: the provider assigned + `self._openai_client`, an attribute nobody reads — + `OllamaProvider.client` serves `self._client`. Every completion + bypassed the null-content sanitizer since the class was introduced; + exposed 2026-09-13 when the wrapper 503'd a session-less request + that the choke point should have named. The sanitized client now + goes through the constructor's official `openai_client` parameter, + and a wiring test pins `provider.client` to the sanitized type. + ## [1.1.0] - 2026-08-11 ### Added diff --git a/webber-api/pyproject.toml b/webber-api/pyproject.toml index f966ba7..6ecf5f4 100644 --- a/webber-api/pyproject.toml +++ b/webber-api/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "webber-api" -version = "1.1.0" +version = "1.2.0" description = "Webber API - Multi-Agent AI Development Server" authors = [ {name = "jpmschweitzer"} diff --git a/webber-api/tests/test_provider_backend.py b/webber-api/tests/test_provider_backend.py index 829433f..ba19a50 100644 --- a/webber-api/tests/test_provider_backend.py +++ b/webber-api/tests/test_provider_backend.py @@ -82,7 +82,11 @@ def test_body_signals_are_logged(monkeypatch): monkeypatch.setattr(provider, "logger", StubLogger()) class Busy: - model_extra = {"balancing": [{"parked": "librarian"}], "compaction_due": True} + def __init__(self): + self.model_extra = { + "balancing": [{"parked": "librarian"}], + "compaction_due": True, + } provider._log_wrapper_signals(Busy()) assert any(kind == "info" and "parked" in msg for kind, msg in calls) @@ -91,7 +95,8 @@ def test_body_signals_are_logged(monkeypatch): calls.clear() class Quiet: - model_extra = {"balancing": [], "compaction_due": False} + def __init__(self): + self.model_extra = {"balancing": [], "compaction_due": False} provider._log_wrapper_signals(Quiet()) assert calls == []