From 7f573e7184ae783d0a9747045ec60804c4e494d2 Mon Sep 17 00:00:00 2001 From: Anatolii Date: Mon, 29 Jun 2026 10:56:42 +0400 Subject: [PATCH] =?UTF-8?q?release:=200.8.2=20=E2=80=94=20coverage=20metad?= =?UTF-8?q?ata=20nesting=20+=20model=20fallback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps version after the wire-format regression fixes from PR #40: - coverage_report counters now nest under event.metadata (SdkTrackRequest drops unknown top-level keys) - NullRunSyncTransport._emit falls back to the request body's model field when the response extractor returns None - test_batch_response_parsing.py pins the post-2026-06-27 BatchTrackResponse schema (actions/messages) CHANGELOG entry added above 0.8.0. No public-API break. --- CHANGELOG.md | 39 +++++++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8c8ff7..14bdf10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,45 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html) --- +## [0.8.2] - 2026-06-29 + +Additive patch on top of 0.8.0. No public-API break. Continues the +0.8.0 wire-format audit with two regressions that were caught on +review and one contract test that pins the post-2026-06-27 backend +schema so a future rename can't silently break the SDK. + +### Fixed + +- **`track_coverage()` emits counter dicts under `event.metadata` + instead of the event top level.** Pre-fix the per-host `seen` / + `tracked` / `streaming_skipped` dicts sat at the event root, where + serde silently dropped them — `SdkTrackRequest` uses explicit + fields with no `#[serde(flatten)]` catchall, so unknown keys are + discarded. The dashboard's `last_coverage_pct` was permanently + `null` because every coverage report landed with empty + `seen`/`tracked`/`streaming_skipped` JSONB columns. Pin: + `tests/test_coverage_report.py::test_track_coverage_emits_wire_shape_with_metadata_nesting`. +- **Request-body model fallback in + `NullRunSyncTransport._emit`.** When the response body extractor + returns `None` for `model` (OpenAI Responses API, Anthropic + streaming edge cases), `_extract_model_from_request_body` reads + the model string the user embedded in the request body via + `ChatOpenAI(model="gpt-4.1-mini")`. Without this every such + call was zero-billed — backend `unwrap_or("default")` + + `DEFAULT_RATE` ≈ \$0/call. Unit-tested in + `tests/test_model_fallback.py`. + +### Tests + +- `tests/test_batch_response_parsing.py` pins the post-2026-06-27 + `BatchTrackResponse` shape (`actions: Vec`, + `messages: Vec`) and documents that the legacy + `actions_taken: Vec` field is intentionally dropped in + 0.8.0. Regression test so a future backend rename can't silently + break the SDK. + +--- + ## [0.8.0] - 2026-06-28 SDK↔backend wire-format audit. Closes a class of silent-fail-OPEN diff --git a/pyproject.toml b/pyproject.toml index 7142d9b..5bad448 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "nullrun" -version = "0.8.0" +version = "0.8.2" # Long form used by PyPI page meta-description and search snippets. # Kept under the 200-char preview threshold so the full line is visible # without an "expand" click. Keywords are matched against likely search