github nesquena/hermes-webui v0.50.279
v0.50.279 — 8-PR sweep batch + Opus MUST-FIX caught

latest releases: v0.50.283, v0.50.282, v0.50.281...
4 hours ago

Release v0.50.279 — 8-PR batch from full PR sweep

End-to-end PR sweep of all 16 open PRs. Routes:

  • Merged in this batch (8): #1523, #1519, #1518, #1516, #1517, #1532, #1525, #1526
  • Closed as duplicates (2): #1528 (identical to #1517), #1529 (superseded by #1516)
  • Routed to maintainer-review (1): #1531 (Asunfly stowaway change in force-push to title aux generation that wasn't in PR description)
  • Stay on hold (5): #1418 (prereq hermes-agent#18534), #1464 (blocker — noResults ternary inverted), #1404 (UX — aronprins width feedback unresolved), #1353 (durability path, ready-for-review tagged for next batch), #1311 (draft + CONFLICTING)

Constituent PRs (8 merged)

Polish / UX (5 small)

PR Author LOC What
#1523 @franksong2702 2/2 Fork-indicator glyph: \u2482\u2442 (was PARENTHESIZED DIGIT FIFTEEN, now OCR FORK). Closes #1522.
#1519 @franksong2702 1/1 Onboarding API-key field stops losing focus during 400ms-debounced probe re-render — moved probe trigger from oninput to onblur. Closes #1503.
#1518 @franksong2702 5/2 Voice-mode pref toggle-off now stops the SpeechRecognition (was leaving recognizer running with no UI to stop it). Closes #1491.
#1516 @franksong2702 4/0 YAML code blocks render with newlines (Prism token spans had white-space: normal collapsing \n). Closes #1463.
#1517 @franksong2702 13/13 Consolidate __CACHE_VERSION____WEBUI_VERSION__ placeholder name (pure rename, no behavior change). Closes #1509.

State recovery + provider quota (3 backend)

PR Author LOC What
#1532 @ai-ag2026 38/3 Recover WebUI-origin state.db sessions when JSON sidecar missing (slice 1 of #1471). Removes hard-coded s.source != 'webui' predicate from read_importable_agent_session_rows().
#1525 @ai-ag2026 85/2 Clear stale runtime stream state proactively (slice 2 of #1471). New _clear_stale_stream_state() helper runs at /sessions/<id> GET boundary + before new turns. Frontend half: INFLIGHT[sid] cleared when server reports no active_stream_id.
#1526 @ai-ag2026 68/0 Forward configured max_tokens into AIAgent (was using provider-native ceilings → OpenRouter 402 quota errors). Adds 3 new quota-phrase classifiers. Refs #1524.

Test status

3936 → 3946 tests passing (+9 from constituent PRs + 1 conflict-marker regression guard added in-release per Opus MUST-FIX). Zero regressions.

Pre-release Opus advisor pass — MUST-FIX caught and absorbed

This release was nearly broken. Opus pass on stage-279 caught that the merge-conflict resolution between #1525 (cache-name manual suffix) and #1517 (rename) had never actually landedstatic/sw.js lines 10-14 still contained the literal <<<<<<< HEAD / ======= / >>>>>>> pr-1525 markers. The substring-based source-string tests still passed because __WEBUI_VERSION__ WAS in the file (just inside the conflict block).

Concrete impact pre-fix when shipped:

  • Service worker install event would throw on script load (SyntaxError: Unexpected token '<<')
  • SW would never reach activated state
  • Old SW (from v0.50.278) would keep controlling the page indefinitely
  • Frontend cache-bust pathway silently broken
  • The INFLIGHT[sid] clear (the frontend half of #1525's stale-stream cleanup) would never deliver to existing browsers

Resolution applied in stage: sw.js conflict markers removed, kept HEAD's CACHE_NAME = 'hermes-shell-__WEBUI_VERSION__' (post-#1517 rename) over the PR's -stale-stream-cleanup1 manual suffix. Natural version-token bump preserves the cache-invalidation guarantee.

Regression guard added in-release: new test_sw_js_has_no_merge_conflict_markers test scans for <<<<<<<, =======, >>>>>>> markers in static/sw.js. This couldn't happen silently again — a future merge that leaves conflict markers will fail CI.

Opus SHOULD-FIX deferred to follow-up

Filed as #1533: _clear_stale_stream_state() mutates session.active_stream_id outside the per-session lock (release pattern: hold STREAMS_LOCK only across the registry lookup, then mutate after release). Race window between registry-check and session-mutate could clobber a concurrent _handle_chat_start registration. Effect bounded (orphaned stream → retry, no data corruption). Opus explicitly said "probably fine to defer given the narrow window."

Diff stats

api/agent_sessions.py                    | 6 +-
api/routes.py                            | 30 +++-
api/streaming.py                         | 32 +++++-
static/boot.js                           | 7 +-
static/onboarding.js                     | 2 +-
static/sessions.js                       | ~20
static/style.css                         | 4 +
static/sw.js                             | 6 +-
tests/* (8 new files + edits)            | ~250 lines
CHANGELOG.md                             | +
ROADMAP.md                               | 2 +-
TESTING.md                               | 4 +-

Sweep methodology

Followed webui-full-pr-triage-release/references/extended-sweep-procedure.md Phases 0-9. Phase 0 fit-screen on all 16 open PRs, hold-readiness sweep, UX gate, merge queue build (small-first), stage merges (1 conflict resolved live), pre-release gate (clean state pytest + QA harness), Opus pass (MUST-FIX caught and absorbed), stamp + push.

Branches & cleanup

  • Tag: v0.50.279
  • Stage branch: stage-279
  • Worktree: /tmp/wt-stage-279 (cleaned up post-merge)
  • Closes #1463, #1491, #1503, #1509, #1522 (linked issues from constituent PRs)
  • Refs #1471, #1524 (umbrella issues with multiple slices)

Don't miss a new hermes-webui release

NewReleases is sending notifications on new releases.