This release restructures the served dashboard around a savings-led
information hierarchy, publishes the first reviewed wall-clock
time-remaining forecast calibration cell, makes the retry primitives
directly importable from a new core module, fixes a request-accounting bug
for bodyless model requests, fixes tokenpak serve to honor the configured
port and the TOKENPAK_PORT environment variable, expands the dev extra
to include the dependencies the typed proxy surfaces import, and refreshes
dependency lockfiles to close open security advisories.
Added
- Published the first reviewed time-remaining forecast calibration cell —
claude-sonnet-5/ unknown effort / streaming — into the per-cell publication table added in 1.23.0. This makesstatus: "available"(with a realremaining_time_likely_50_ms/remaining_time_ceiling_90_msband) reachable for that one cell; every other cell continues to report"insufficient_data". The mechanism remains gated behind its existing default-off master switch (TOKENPAK_TIME_FORECAST_BANDS/time_forecast_bands.enabled, both still default-off) — populating the table only makes the cell eligible, it does not change the shipped default. See thetime_forecastsection indocs/api-reference.md. - The retry engine (
RetryEngine,RetryExhaustedError,ImmediateAlertError,load_recent_retry_events, and their supporting constants) is now directly importable fromtokenpak.core.retry. The existingtokenpak.orchestration.retryimport path continues to work unchanged — it is now a compatibility re-export of the identical objects, not a copy. No behavior change.
Changed
- The served dashboard (
/dashboard) is restructured around a seven-block information hierarchy, savings-led:
- Savings hero — today's tokens and dollars saved, large and centered at the top of the page (an honest "not yet measured" state when there is no data yet).
- Status strip — one combined health signal (Healthy / Idle / Degraded / Error) plus its three supporting facts: credentials, last-request time, and queue depth. Replaces the previously buried status dot.
- Compression chart — last-24h original vs. compressed tokens,
backed by the same query the CLI
statuscommand already uses. - Cache strip — separates the product-attributed cache hit rate (cache reads this product's own cache marker produced) from the general provider-level cache hit rate, plus a client/proxy/unknown token breakdown. This replaces a card that was labeled as a cache hit rate but was actually derived from proxy uptime; that formula is removed.
- Recent requests — the last 20 requests (time, client, model, tokens in/out, savings, cache origin).
- Mode / session breakdown — retained as-is.
- Quick actions — retained as-is.
Backend support is additive and fails open when the request log is
unavailable: new GET /savings and GET /recent endpoints, and a new
window_24h field on the existing GET /cache-stats and
GET /metrics/dashboard responses. The dashboard's client-side refresh
interval also changes from 30s to 5s, and polling now pauses while the
browser tab is backgrounded.
tokenpak.core.runtime.proxyremains importable as a compatibility path for the launcher, which now lives intokenpak.proxy.bootstrap.
Fixed
- A model-endpoint request sent with no body no longer causes the proxy to log a spurious internal error after the response has already been delivered to the client. The request's usage is now recorded normally instead of being dropped.
tokenpak servenow honors the configuredport(<config-dir>/config.yaml) andTOKENPAK_PORTwhen--portis not given, instead of always binding the built-in default. Precedence:--portflag >TOKENPAK_PORTenv var
config file
port> 8766.
Dependencies
- The
devextra now pulls intokenpak[serve](fastapi,uvicorn,starlette,jinja2,python-multipart,websockets) alongside the existingtokenpak[dispatch]pull-in, so a plainpip install -e ".[dev]"can import, test, andmypy --strictthe proxy subsystem and the telemetry dashboard/query/ingest HTTP surfaces it imports at module level.
Security
- Refreshed pinned lockfile versions to close open dependency advisories.
aiohttp3.14.1 → 3.14.3 (CVE-2026-69244, CVE-2026-69243, CVE-2026-59881),cryptography49.0.0 → 50.0.1 (CVE-2026-69247), andh24.3.0 → 4.4.1 (CVE-2026-71554) are core runtime dependencies, so this closes the exposure window for anyone installing from the pinneduv.lock(a plainpip install tokenpakwas already unaffected — the declared version ranges have no upper pin, so a fresh resolve already picks up the patched releases). Also bumpednltk3.10.0 → 3.10.3, which is not part of the base install and is only pulled in by the optionalcompressionandllamaindexextras; one nltk advisory (CVE-2026-81726) has no upstream fix yet and remains open for anyone using those extras. Thesdk/andpackages/tokenpak-js/npm lockfiles were refreshed forbrowserslistandjs-yaml, both dev-tooling-only transitive dependencies with no runtime exposure for consumers of those packages; thepackages/tokenpak-jslockfile also picked up abrace-expansionbump (1.1.16 → 1.1.18, also a dev-only transitive dependency with no runtime exposure) as an incidental result of the samenpm audit fixpass.