stage-345: 2-PR low-risk batch — stream-ownership guard against stale writebacks + Refresh-usage button on provider quota card - #2153
Merged
Conversation
fix: guard stale stream writebacks (LumenYoung) Prevents stale WebUI stream workers from writing old results into a session after that session has already moved on to another stream. Adds new helper _stream_writeback_is_current() (a token equality check against the session's active_stream_id) and short-circuits the two finalize/cancel paths when the worker no longer owns the session writeback.
feat: add manual provider usage refresh (Jordan-SkyLF) Adds a 'Refresh usage' button on the Provider quota card in Settings → Providers, with cache: 'no-store' fetch + browser cache-bust query string. Pure browser-side cache-busting; the server-side /api/provider/quota endpoint has no cache layer yet (refresh=1 query param is currently a no-op server-side; the win is bypassing browser/proxy/SW caches).
SysAdminDoc
pushed a commit
to SysAdminDoc/hermes-webui
that referenced
this pull request
Jun 26, 2026
stage-345: 2-PR low-risk batch — stream-ownership guard against stale writebacks + Refresh-usage button on provider quota card
bernyforce
pushed a commit
to bernyforce/hermes-webui
that referenced
this pull request
Jul 29, 2026
stage-345: 2-PR low-risk batch — stream-ownership guard against stale writebacks + Refresh-usage button on provider quota card
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
stage-345 — small 2-PR contributor batch (v0.51.52)
Composition
Per Nathan's "no high-risk merges today" directive: only the 2 low-risk PRs ship this batch. The two higher-risk PRs were deferred to tomorrow with reasons captured.
What ships
#2136 — stale stream writeback guard
cancel_stream()clearsactive_stream_idearly so the UI can accept a new turn while the old worker unwinds. The old worker could still return later fromrun_conversation()and persist its stale result over the newer transcript — observed corruption pattern on cancel+retry over compressed continuations. New helper:…short-circuits both finalize paths (success path in
_run_agent_streaming, cancel path incancel_stream()). 89-line regression suite intests/test_stale_stream_writeback.py.#2150 — Refresh usage button on provider quota card
Frontend-only. Calls
/api/provider/quota?refresh=1&ts=<now>withcache: 'no-store'to bypass browser/SW/proxy caches. Therefresh=1query param is a no-op at the server today (no in-process cache layer inget_provider_quota()); the win is at the transport layer. Future maintainer follow-up may add server-side TTL caching, at which point the same param becomes load-bearing on both sides.What's deferred to tomorrow
hold,maintainer-review(1372 LOC is too large to land without explicit human eyes).Opus advisor finding (deferred to follow-up)
Opus flagged two additional
api/streaming.pywriteback sites that should also call_stream_writeback_is_current()but are pre-existing (not introduced by #2136):pending_user_messageand appends_error_messagewithout ownership check; if Worker A raises after rotation to Stream B, it stamps B's prompt with A's error._heal_resultwithout ownership check.Both pre-existing bug paths, medium severity, low probability. Filing a follow-up issue rather than expanding scope today.
Verification
run-browser-tests.sh: 20/20 QA + 11/11 API checks PASSED in 113s_stream_writeback_is_currenthelper present inapi/streaming.py(3 occurrences: def + 2 guard sites)Refreshing…/disabled/aria-busy=true) → after (recovered cleanly)python -m py_compileclean on all modified.pyfilesnode --checkclean onstatic/panels.jsStats
Closes
No linked issues in this batch. #2136 and #2150 both describe behavior they fix without
Closes #Nreferences.