← All docs changelog/2026-04-23.md

Apr 23, 2026

Commits

fc2b8d8 — Add vLLM container warmup + live status polling to comparison page

The /comparison page now has per-slot Start buttons that spawn a non-blocking warmup via modal.FunctionCall, plus three new endpoints: POST /ml/serve/{slot}/warmup (spawn), GET /ml/serve/warmup/{call_id} (poll), and GET /ml/serve/{slot}/status (runner count + backlog). UI derives stopped/queued/loading/ready/error from the combined signal, shows elapsed time during cold start, and polls on staggered 15s (active) / 30s (idle) cadence with a decaying label-color pulse.

Changed:

  • ml/comparison.html — warmup buttons, status polling, state machine
  • ml/ml_endpoint.pyserve_warmup, serve_warmup_status, serve_container_status endpoints

24ba25c — Render response streams as live-parsed markdown in comparison page

Pulls marked + DOMPurify from jsdelivr, swaps <pre> response panels for sanitized .md-body divs, and re-parses the full accumulated text on every streaming chunk so formatting appears as tokens arrive. Falls back to pretty-printed JSON if the full response parses as valid JSON.

Changed:

  • ml/comparison.html — markdown rendering pipeline

c39b525 — Show time-to-ready in comparison warmup label

Captures Date.now() - startedAt the first poll that sees the warmup call flip to ready, resets on every new Start click. Label becomes e.g. "Ready after 2 min 15 sec" instead of just "Ready".

Changed:

  • ml/comparison.html — time-to-ready display

e1dbb8c — Fix triple-dash typo in integration test script (H6)

---output--output on lines 110 and 127, so bru actually writes results.json.

Changed:

  • integration-tests.sh

b7a1b4d — Remove duplicate deps and pin unpinned packages in requirements.txt (H7)

Remove duplicate openai, redis, google-genai entries; pin psycopg2-binary==2.9.11 and websockets==15.0.1 for reproducible builds.

Changed:

  • requirements.txt

1756f48 — Remove duplicate and unused imports across 7 files (M7)

crypto.py: duplicate base64/hashlib, 5 unused cryptography imports, redundant local struct. models/examples.py: duplicate NeedToKnowAccountDEKRequest. users_endpoint.py: unused register. voices_endpoint.py, geocoding_endpoint.py: unused aiohttp.web. livekit_endpoint.py: duplicate import core. litert.py: unused json.

Changed:

  • core/crypto.py, core/models/examples.py, geocoding/geocoding_endpoint.py, livekit_ts/livekit_endpoint.py, ml/mobile/litert.py, users/users_endpoint.py, voices/voices_endpoint.py

325bb13 — Fix duplicate Setup header in README.md (L3)

Rename first ## Setup (billing-specific) to ## Billing Module Setup to disambiguate from the general Setup section.

Changed:

  • README.md

a750367 — Add build.log and .coverage* to .gitignore, untrack build.log (L4)

Changed:

  • .gitignore, build.log (untracked)

d9d2104 — Centralize logger setup via get_logger() factory (Priority 2, partial)

New dev/core/logging_config.py with a shared get_logger(name) that reads LOG_LEVEL from env (defaults to DEBUG). Replaces duplicated 5-line logger boilerplate across 24 files with a single import + call. Print-to-logger conversion deferred to the follow-up sweep.

New files:

  • core/logging_config.pyget_logger() factory

Changed:

  • 24 files across core/, data/, livekit_ts/, ml/, model_proxy/, users/, tests/

21159dd — Convert print() to logger in core/ and users/ (print sweep 1/5)

core.py: 10 prints converted — auth header logging now redacted, debug prints use logger.debug(). Fixed local logger shadowing in CurrentUser(). mls.py: 1 print converted. users_endpoint.py: 2 prints converted — exception logging uses logger.exception().

Changed:

  • core/core.py, core/mls.py, users/users_endpoint.py

053c6fc — Convert print() to logger in ml/ diagnostic function (print sweep 2/5)

12 prints in test_vllm_startup() converted to logger.info/error. 9 prints in main() CLI entrypoint left as-is (user-facing terminal output).

Changed:

  • ml/ml_endpoint.py

55fc058 — Convert print() to logger in billing/ and capture/ (print sweep 3/5)

billing.py: ~95 prints converted. billing_endpoint.py: 17 prints. capture.py: 2 prints. capture_endpoint.py: 12 prints.

Changed:

  • billing/billing.py, billing/billing_endpoint.py, capture/capture.py, capture/capture_endpoint.py

0504247 — Convert print() to logger in geocoding/ and voices/ (print sweep 4/5)

geocoding.py: ~26 prints. geocoding_endpoint.py: ~15 prints. map_3d_tiles.py: 1 print. voices.py: 3 prints. voices_endpoint.py: 9 prints.

Changed:

  • geocoding/geocoding.py, geocoding/geocoding_endpoint.py, geocoding/map_3d_tiles.py, voices/voices.py, voices/voices_endpoint.py

5d09743 — Convert print() to logger in livekit_ts/ and websocket/ (print sweep 5/5)

livekit_server.py: 17 prints. livekit_helpers.py: 6. livekit_endpoint.py: 3. agent/image_segmentation.py: 3. websocket.py: 5. gemini.py: 5. 10 agents/ files: 498 prints. redis_dump.py skipped (CLI script, user-facing output).

Changed:

  • 16 files across livekit_ts/, websocket/

bffa045 — Convert print() to logger in billing/stripe_client.py and config.py (final)

stripe_client.py: 10 prints converted (webhook signature debug/errors). config.py: 1 print converted (missing env vars warning).

Changed:

  • billing/config.py, billing/stripe_client.py