github nesquena/hermes-webui v0.50.292
v0.50.292 — 12-PR batch (multi-tab SSE + subpath routes + UX polish + 3 follow-ups)

latest releases: v0.50.295, v0.50.294, v0.50.293...
4 hours ago

v0.50.292 — 12-PR batch (multi-tab SSE + subpath routes + UX polish + 3 follow-ups)

12 PRs from 5 contributors. Closes #1578, #1583, #1584, #1595, #1613, #1620.

Hot path

  • Multi-tab SSE no longer splits stream tokens (#1598 by @Michaelyklam, closes #1584). Same session in two tabs was racing on a single queue.Queue — one tab might receive H while the other received allo. New StreamChannel broadcast class buffers events while no subscribers connected (so the first/reconnected tab still sees the stream tail) and broadcasts to all tabs once subscribed. Per Opus advisor: replay-inside-subscribe-lock prevents an event-ordering inversion when a 2nd tab subscribes mid-stream.

  • Frontend routes work under subpath mounts like /hermes/ (#1601 by @Michaelyklam). Auth redirect Location, 401 redirects, fetch URLs, EventSource URLs, SMD module import — all switched from root-absolute to mount-relative anchored against document.baseURI || location.href. Self-hosters running WebUI behind a reverse proxy or container ingress now work without Caddy/nginx rewrite workarounds.

  • macOS keepalive actually works now (#1609 by @franksong2702, closes #1583). v0.50.289 added TCP keepalive, but on macOS the entire try block was aborted by AttributeError from TCP_KEEPIDLE (Linux-only constant), so SO_KEEPALIVE was never set on Mac. Now: TCP_NODELAY, then SO_KEEPALIVE in own try, then per-platform timing — Linux uses TCP_KEEPIDLE/INTVL/CNT, macOS uses TCP_KEEPALIVE.

UX

  • Cross-source session continuations stay separate in the sidebar (#1602 by @ai-ag2026). A WebUI session continuing from a Telegram/CLI compression-chained parent stays as its own WebUI row instead of inheriting Telegram's title and source metadata.
  • Paste no longer drops text when clipboard has both (#1622 by @s905060, closes #1620). Pasting from rich-text sources (Notes, Word, Slack, browser selections) attaches a rendered preview alongside text/plain — handler used to swallow text and only attach the rogue image. Now defers to browser default text-paste when text is present; only intercepts on image-only (true screenshot paste).
  • Update banner shows tracked branch labels (#1605 by @ai-ag2026). WebUI (origin/master): 0 updates, Agent (origin/main): 32 updates instead of the ambiguous Agent: 32 updates.
  • Forked session sidebar indicator is recognizable and less noisy (#1621 by @franksong2702, fixes #1613). Replaces glyph with git-branch SVG, subtle until row hover, parent-title tooltip, removes hidden click-to-parent behavior.
  • Streaming markdown formats live segments under subpath mounts (#1600 by @Michaelyklam). First live segment now goes through renderMd() in the SMD-unavailable fallback path.

Bug fixes / hardening

  • Update compare URLs preserve git remote names ending in g/i/t (#1603 by @ai-ag2026). 'hermes-webui.git'.rstrip('.git') was producing 'hermes-webu'rstrip('.git') is a CHARACTER-CLASS strip, not a suffix strip. Now uses endswith('.git') slice.
  • Cron worker no longer silently ignores profile-context failures (#1608 by @franksong2702, closes #1578). _run_cron_tracked() was wrapping cron_profile_context_for_home(...) in try/except Exception that silently set ctx=None, leaving the worker thread unpinned against process-global HERMES_HOME. Same class as #1573. Lets exceptions propagate and kill the worker thread instead.
  • _pending_started_at truthy-check fallback (#1599 by @Sanjays2402, closes our own follow-up #1595). Now handles None, missing-attr, and explicit 0 uniformly. Closes the v0.50.290 retro loop.
  • pytest config-path isolation (#1597 by @Michaelyklam). Hermes Agent sessions could leak HERMES_CONFIG_PATH=~/.hermes/config.yaml into pytest, letting onboarding/provider tests touch the developer's live config. Override fixed at conftest module load before product imports.

Tests

4117 → 4142 passing (+25). 0 regressions. Full suite ~125s.

Pre-release verification

  • Opus advisor: SHIP verdict on full stage diff. Two SHOULD-FIX absorbed in-release per <20-LOC defensive policy:
    • api/config.py StreamChannel.subscribe() replay-inside-lock (closes the ordering inversion race)
    • static/sessions.js:1440 gateway SSE probe document.baseURI || location.href parity fix
  • JS syntax check: 6 modified .js files clean.
  • Browser API sanity: 11/11 endpoints OK on stage server.
  • Conflict resolution: static/index.html SMD import competing forms from #1600 (./static/...) and #1601 (static/...) — resolved to #1601's form (passes both PRs' tests via <base href> resolution).

Authors

Three of 12 PRs close our own follow-up issues filed in prior releases (#1578, #1583, #1595).


Full changelog: https://github.com/nesquena/hermes-webui/blob/master/CHANGELOG.md

Don't miss a new hermes-webui release

NewReleases is sending notifications on new releases.