0.44.0 (2026-11-09)
⚠ BREAKING CHANGES
- packaging: keep PyTorch extras out of all (#4067)
Features
- pipeline: say whose request an OutcomeSnapshot is (#4698) (a2bcbd1)
- providers: add Hermes agent wrap support (#934) (7877241)
- proxy/model-router: add shadow mode (HEADROOM_MODEL_ROUTER_LOG_ONLY) (#2395) (861ef95)
- proxy: add lossless /v1/compress mode and detect provider by wire shape (#4617) (33f067a)
- proxy: expose per-request cost_usd in /stats recent_requests (#1079) (#1565) (84cedbf)
- proxy: expose shared Redis store availability in /health and /metrics (#4578) (602ca65)
- proxy: give turn hooks one conversation id per client conversation (#4496) (94a99ed)
- proxy: report DeepSeek as its own provider in dashboard (#2565) (9ad16a7)
- proxy: show per-request /stats metadata to token-authenticated callers (#4168) (9b2dec5)
- proxy: unified multi-upstream routing for Anthropic Cloud and local oMLX (#4597) (f896161)
- savings: carry cumulative actual output_tokens in history checkpoints (#2921) (8388ff5)
- wrap: add
headroom wrap droidfor Factory Droid (#4143) (bb8d18a) - wrap: make the Serena code-memory MCP opt-in (#4509) (2649835)
Bug Fixes
- asgi: stop buffering when the client disconnects (GHSA-mc2f-vg4v-2fh4) (#4701) (c6d7081)
- beacon: enforce the allowlist below the top-level keys (#4691) (456288d)
- binaries: fail closed on HEADROOM_BINARIES_ALLOW_UNVERIFIED=0/false (#3218) (da6d973)
- cache: record TTL observations with relative filenames (#4711) (51d9dc5)
- cache: round learned TTL upper bounds up to whole seconds (#4710) (13347e3)
- cache: save prefix-tracker state when the exit signal arrives (#4715) (3ba4223)
- ccr: lowercase the hash in the streaming feedback recorders (#2313) (3912c04)
- ci: keep the npm publish token out of install and build steps (#4690) (8f6366c)
- cli: resolve active proxy port for read commands (#3522) (02c4e92)
- content-router: trust confident HTML detection over mixed-content heuristics (#3627) (f50db67)
- dashboard: lifetime metrics and refresh (#2374) (eb9932a)
- doctor: recognize IPv6 loopback and case-insensitive proxy routing URLs (#3255) (2b0315b)
- install: decode Windows Task Scheduler XML output before parsing (#3969) (#4064) (b78e07d)
- install: make install status agree with doctor when the proxy is reachable (#3072) (#3141) (05431b2)
- langchain: check optional integration availability (#4042) (cde584d)
- learn: harden analyzer JSON parsing against malformed LLM output (#2471) (12864fc)
- learn: support opencode v2 session schema in learn scanner (#4199) (c05466a)
- lossless: fold only pure path listings, never markup (#4716) (0ccd559)
- memory: gracefully degrade on context lookup and initialization errors (#3251) (#4049) (00d4f44)
- metrics: cap savings_by_source rows and fold the rest into other (#4257) (2038fb2)
- packaging: keep PyTorch extras out of all (#4067) (a890521)
- proxy: add --no-ccr-response-handling flag to bypass response buffering (#3082) (#3100) (ce14271)
- proxy: bound the Bedrock Prometheus model label (#4694) (d70a8b7)
- proxy: drop headers named by Connection when forwarding responses (#4674) (3871b36)
- proxy: keep cold-turn reasoning drops sticky so the next warm turn reuses the cached prefix (#4592) (3544cf5)
- proxy: keep the Bedrock credentials provider when startup resolution fails (#4705) (5438f00)
- proxy: refresh Bedrock AWS credentials before they expire (#4696) (adc6724)
- proxy: rename leaked_threads metric to timed_out_workers_total (#3908) (bd164a2)
- proxy: track response.-prefixed item and content-part events in Responses SSE state (#4695) (8f4122f)
- router: compress tool_result blocks in mutable window with trailing messages (#4717) (0511bcd)
- router: ignore shell operators inside quoted arguments in read detection (#4646) (8cdce17)
- scripts: skip ci-precheck in the pre-push hook when a push only deletes refs (#4702) (cbcf8d8)
- sdk: keep Vercel AI SDK tool-result output kinds through compression (#4670) (ce42754)
- search_compressor: keep kept rows byte-for-byte and in input order (#3982) (a538740)
- smart-crusher: keep mixed-array dict rows and exact drop count with factor_out_constants (#4692) (ced2685)
- smart-crusher: keep the row the question names (#4713) (e6e2ebb)
- storage: return the latest snapshot from JSONLStorage.get (#4675) (b25c45b)
- tabular: split fixed-width rows on column boundaries, not on double spaces (#4541) (b80245e)
- tag-protector: do not treat a slash in an unquoted attribute as self-closing (#4681) (d5644cb)
- tag-protector: keep the enclosing tag open after a nested close in marker mode (#4682) (385d487)
- telemetry: keep install ID stateless (#3542) (27bba79)
- tokenizers: resolve chatgpt-4o-* aliases to o200k_base (#4672) (9648d2d)
- tokenizers: unwrap BatchEncoding in HuggingFaceTokenizer.count_messages (#2447) (9eed58f)
- vertex: explain Vertex failures in-band, correct the model/region matrix (#2640) (0ddaa56)
- wrap: route Claude Code's Bedrock mode through Headroom (#4316) (aa2093b)
Dependencies
- bump rusqlite from 0.40.2 to 0.41.1 (#4658) (74b7ac2)
- bump the cargo-minor-patch group with 3 updates (#4657) (c01cf07)
- bump the npm-minor-patch group across 1 directory with 2 updates (#4650) (def4ef1)
- update click requirement from >=8.3.3 to >=8.5.0 (#4655) (ea59ac3)
- update sqlite-vec requirement from >=0.1.6 to >=0.1.9 (#4654) (de1a1e0)
- update tree-sitter requirement from <0.27,>=0.25.2 to >=0.26.0,<0.27 (#4656) (910588e)
Want more savings? Headroom Enterprise saves more for teams and enterprises. Talk to us at hello@headroomlabs.ai or headroomlabs.ai.