github MakazhanAlpamys/Soup v0.53.9
v0.53.9 — Live Dashboard + UX + Bench + Standalone CLIs

latest releases: v0.76.0, v0.75.2, v0.75.1...
5 months ago

What's New

Eight features closing out the v0.44.x live-monitoring deferrals plus a long tail of standalone CLI wins.

  • #94 Live SSE training stream — /api/train/stream async endpoint with per-subscriber cursor (multi-tab safe); SoupTrainerCallback.on_log pushes TrainEvent to a thread-safe collections.deque(maxlen=1000); JS EventSource consumer auto-installed in the Web UI (window.onTrainEvent(payload) hook for plugins).
  • #95 Phone visibility via QR — soup ui --public binds 0.0.0.0, auto-derives the LAN IP via a SOCK_DGRAM connect-trick, prints a scannable ASCII QR code with the Bearer token embedded in ?token=…. The SPA bootstrap hydrates window._authToken from the query string + caches in sessionStorage + history.replaceStates the URL clean so the token never sits in browser history. --auth-token <T> lets operators pin a stable token across restarts (16-128 urlsafe-base64 chars).
  • #98 Reasoning-trace stripping — soup serve --reasoning-parser {deepseek-r1, qwen3, phi4, openthinker} strips <think>…</think> (and OpenThinker <|begin_of_thought|>…) from responses AFTER token metering so usage counts stay honest. Pre-compiled regex + 1 MiB cap + marker-token fast-path skip + leading-newline-only strip (preserves leading whitespace in code outputs).
  • #100 Tool Outputs panel — module-level ToolOutputsBuffer singleton + /api/tool-outputs JSON poll endpoint; trainer callback observes per-batch tool_calls count as a best-effort hook (no impact on training when off).
  • #15 soup tokenizer train — train a BPE tokenizer from a JSONL or .txt corpus via the tokenizers library. Raw-path os.lstat + S_ISLNK rejection (TOCTOU defence), 50 MiB total + 8 KiB per-line caps, post-mkdir output-dir re-check, --special-token NUL/oversize/dedup, vocab bounds [256, 200_000].
  • #26 Tail latency in bench — soup bench --p50 --p95 renders an extra per-prompt Rich table; --prompts-file gained symlink rejection on the raw path.
  • #28 Bench backend auto-detect — soup bench --backend auto (new default) probes MLX weights.npz (per-entry lstat symlink reject) → config.json model_type keyword → falls back to transformers. SOUP_BENCH_BACKEND env override available.
  • #12 Synthetic data walkthrough — examples/synthetic_workflow.{md,yaml} chains soup data generate → filter → score → decontaminate → train for an end-to-end recipe.

Install / Upgrade

pip install -U soup-cli==0.53.9
# or pin in pyproject.toml

GHCR Docker image: ghcr.io/makazhanalpamys/soup:0.53.9 (publishes ~10 min after release).

Security

3 review-agent waves (python / code / security / tdd) closed 0 CRITICAL + 11 HIGH + 14 MEDIUM + 9 LOW findings before tag. Notable:

  • set_auth_token rotation race fixed with a module-level threading.Lock (8-thread stress test); concurrent rotation can no longer leave a window where some requests see the old token and some the new.
  • QR token consumption: previously the token was rendered in the QR URL but no JS path picked it up — phones landed unauthenticated. Now the SPA bootstrap installs the token from ?token= on first load.
  • Tokenizer --input + --output symlink TOCTOU defence on the raw path BEFORE os.path.realpath resolution (matching v0.53.7 #106 policy).
  • SSE generator switched from sync time.sleep to async def + asyncio.sleep so uvicorn's loop stays unblocked under concurrent subscribers.
  • CORS regex auto-widens to loopback + RFC1918 in --public mode (the previous fixed allowlist http://0.0.0.0:port never matched a real Origin header).
  • _has_mlx_weights per-entry lstat so a symlinked weights.npz cannot trick bench --backend auto into MLX dispatch.

Known Limitations

  • SSE generator exits after max_ticks=200 (~20 s of quiet). Long-running quiet windows require client reconnect (standard SSE convention).
  • --reasoning-parser strip happens AFTER token metering: usage counts reflect the model's full output including the reasoning trace; only the visible response body has it stripped. Design choice for accurate billing.
  • detect_backend returns transformers silently for HF repo IDs (cwd-containment check short-circuits before MLX/config probing).
  • --public mode trusts the operator's LAN segment; Bearer token is the actual security gate.

Tests

8285 passed / 35 skipped on Ubuntu + macOS + Windows × Python 3.9 / 3.11 / 3.12.

Test count: 8257 → 8285 (+28 net; +57 in test_v0539.py minus relaxed v0.53.8 version-pin asserts).

Don't miss a new Soup release

NewReleases is sending notifications on new releases.