Commit graph

4883 commits

Author SHA1 Message Date
nesquena-hermes
29ceed3a72 fix(#4778): gate deferred rAF re-restore on still-unpinned (Opus gate)
Opus caught a narrow timing race: if a reader re-pins between the scroll-rebuild
guard engaging and its deferred rAF firing, the stale re-restore would yank them
back off the bottom. Gate the re-restore on _messageUserUnpinned at rAF time; the
minHeight release still always runs. Normal single-render unpinned case unaffected.
2026-06-23 16:19:50 +00:00
nesquena-hermes
f4af6d8419 fix(#4778): scroll-rebuild guard must not reclassify a pinned follower as unpinned
Codex regression gate caught: the guard predicate keyed on a raw messagesEl.scrollTop>0,
so a pinned reader transiently at bottomDistance>250 mid-render (assistant body grows
before the anchor scene re-renders) got flipped to _messageUserUnpinned=true/_scrollPinned=false
and lost auto-follow. Require an explicit non-follow signal (_messageUserUnpinned || _scrollPinned===false)
instead. Updated the existing guard test to a genuine unpinned reader + added a pinned-large-growth
regression. Co-authored-by: franksong2702
2026-06-23 16:17:01 +00:00
nesquena-hermes
c6d633fd2c Merge branch 'peek-4777' into stage/livestream-chat-scroll-4778-4777-4780
# Conflicts:
#	CHANGELOG.md
2026-06-23 16:09:00 +00:00
nesquena-hermes
a349b0b7e8 Merge branch 'peek-4780' into stage/livestream-chat-scroll-4778-4777-4780 2026-06-23 16:08:31 +00:00
nesquena-hermes
343cb0737e Merge branch 'peek-4778' into stage/livestream-chat-scroll-4778-4777-4780 2026-06-23 16:08:30 +00:00
Hermes Agent
ba6349bdcb fix: reset scroll state on session switch to prevent stale unpin blocking scroll-to-bottom 2026-06-23 17:19:50 +02:00
Frank Song
4c8e88ab2d fix: dedupe live compact worklog process prose 2026-06-23 23:03:04 +08:00
Frank Song
1269289d01 fix: guard live worklog scroll rebuilds 2026-06-23 23:00:32 +08:00
nesquena-hermes
8a98626967
Merge pull request #4776 from nesquena/stage-4774-release
Release v0.51.603 — Release VJ (cache app-shell template, #4774)
2026-06-23 06:42:54 -07:00
nesquena-hermes
f3a509e2e9 Release v0.51.603 — Release VJ (cache app-shell template, #4774) 2026-06-23 13:39:07 +00:00
nesquena-hermes
9cc3f30d82 test(#4774): point asset-version-encoding test at relocated shell-render helper
#4774 moved the version-token substitution from the index route handler into the cached
_render_index_shell_base() helper. quote(WEBUI_VERSION, safe='') encoding is intact (verified),
just relocated, so the source-marker test scanning the route block no longer found it. Updated
to check the helper. Maintainer test-fix on boriken72's PR.
2026-06-23 13:27:40 +00:00
nesquena-hermes
7c9fef2fb3 stage #4774 (boriken72): cache app-shell template 2026-06-23 13:14:02 +00:00
boriken72
c6994b501a perf: cache app-shell template instead of re-reading index.html per request
The `/`, `/index.html`, and `/session/<id>` routes are the hottest
navigations. Each request re-read the ~190 KB static/index.html from disk
and re-applied two process-constant token substitutions
(__WEBUI_VERSION__, __MAX_UPLOAD_BYTES__), then ran inject_extension_tags()
(which itself reads the extension state + manifest from disk).

WEBUI_VERSION and MAX_UPLOAD_BYTES are fixed for the process lifetime, so
this caches the partially rendered template in an in-process cache keyed by
(size, mtime_ns) -- mirroring the existing _STATIC_CACHE pattern in this
file -- so a redeploy is still picked up without a restart. The per-session
CSRF token and runtime extension tags are still applied per request, so
output is byte-identical to before.

Verified: byte-identical to the old inline render, CSRF still varies per
request, cache invalidates on mtime change, ~5x faster shell render in a
local microbenchmark. Adds tests/test_index_shell_template_cache.py.
2026-06-23 09:01:59 -04:00
nesquena-hermes
2d857f8b5a
Merge pull request #4773 from nesquena/stage-4769-release
Release v0.51.602 — Release VI (sidebar fetches only active source bucket, #4766/#4769)
2026-06-23 05:23:22 -07:00
nesquena-hermes
49e0f84474 Release v0.51.602 — Release VI (sidebar fetches only active source bucket, #4766/#4769) 2026-06-23 12:19:34 +00:00
nesquena-hermes
ced64ff1f3 stage #4769 v2 (rodboev): sidebar source-bucket pushdown, re-push 2026-06-23 12:07:34 +00:00
Rod Boev
148a1bfab2 Keep source-bucket cleanup tied to real session origin 2026-06-23 07:58:55 -04:00
Rod Boev
df4cdf7f9b Prevent stale cross-bucket rows during source-tab switches 2026-06-23 07:49:46 -04:00
Rod Boev
52557d1137 Keep isolated sidebar dedupe harnesses aligned with source-map cleanup 2026-06-23 07:44:03 -04:00
Rod Boev
0f5e0d71b7 Keep sidebar state helpers compatible with isolated JS harnesses 2026-06-23 07:37:42 -04:00
Rod Boev
f5f8f48006 Keep hidden source state through failed source refreshes 2026-06-23 07:06:07 -04:00
Rod Boev
742a19ab70 Keep sidebar partition proofs aligned with helper counts 2026-06-23 06:58:53 -04:00
Rod Boev
efb784730a Keep sidebar source fallbacks honest under refresh failure 2026-06-23 06:51:12 -04:00
Rod Boev
534008c3fc Preserve hidden source runtime state across tab refreshes 2026-06-23 06:39:34 -04:00
Rod Boev
4ee5ef0d01 fix(#4766): harden source-tab refresh state 2026-06-23 06:21:15 -04:00
Rod Boev
73a209aca7 fix(#4766): close review gaps in sidebar source filtering 2026-06-23 06:10:16 -04:00
Rod Boev
9a5a3eb6d5 fix(#4766): filter /api/sessions by active source bucket 2026-06-23 05:56:00 -04:00
nesquena-hermes
fa3d612a4e
Merge pull request #4764 from nesquena/stage-4451-release
Release v0.51.601 — Release VH (sidebar lineage running/unread state when continuation hidden, #4451)
2026-06-22 23:21:45 -07:00
nesquena-hermes
c7034655b6 Release v0.51.601 — Release VH (sidebar lineage running/unread state when continuation hidden, #4451) 2026-06-23 06:17:44 +00:00
nesquena-hermes
c8ccfa93b1 stage #4451 (santastabber): bubble hidden lineage stream state
# Conflicts:
#	CHANGELOG.md
2026-06-23 06:06:23 +00:00
nesquena-hermes
34d8470009
Merge pull request #4763 from nesquena/stage-4474-release
Release v0.51.600 — Release VG (suppress footer jitter during virtual-scroll measurement, #4474)
2026-06-22 22:54:00 -07:00
nesquena-hermes
f748854a69 Release v0.51.600 — Release VG (suppress footer jitter during virtual-scroll measurement, #4474) 2026-06-23 05:49:23 +00:00
Rod Boev
c1355f9e6a Clarify the measurement transition guard and make its test precise 2026-06-23 05:48:36 +00:00
Rod Boev
2f7fe9da32 fix(#4346): harden footer jitter cleanup test 2026-06-23 05:48:36 +00:00
Rod Boev
8b74045bf8 fix(#4346): address review findings — classList fakes, .msg-time guard, test precision 2026-06-23 05:48:36 +00:00
Rod Boev
028fb61f3a fix(#4346): suppress footer jitter during virtual scroll measurement re-renders 2026-06-23 05:48:36 +00:00
nesquena-hermes
0953e7ca8e
test(#4740): fix two order/load-dependent full-suite flakes (test-only) (#4762)
* test(#4740): pin HERMES_HOME in readonly-scope pool test to fix order-dependent flake

test_active_request_readonly_scope_blocks_pool_env_seed failed only under
full-suite ordering (passed in isolation). Root cause, captured via an
assertion-time diagnostic: the readonly scope correctly blocks the process-env
credential fallback (branch 2 returns ''), but _has_explicit_pool_credentials
(branch 3) calls read_credential_pool, which falls back to the GLOBAL-root
auth.json via get_default_hermes_root() — and that reads os.environ['HERMES_HOME']
DIRECTLY, not the thread-local/scoped home. Under suite ordering HERMES_HOME
pointed at the shared persistent test state dir, where an earlier test had
persisted an openrouter credential_pool entry (source: env:OPENROUTER_API_KEY)
into auth.json. The global-root fallback found that leaked entry, so
_provider_has_key('openrouter') returned True and the assertion failed.

Fix: monkeypatch.setenv('HERMES_HOME', <tmp base>) so the global-root fallback
resolves to this test's own empty tmp dir with no leaked auth.json. Test-only;
no product change. Verified: passes in isolation AND the target test now passes
under the full suite (the only remaining full-suite reds were unrelated
subprocess-timeout SIGKILLs in test_tls_support under load, which pass on re-run).

* test(#4740): retry config-probe subprocesses in test_tls_support under load

The 3 TestTLSConfigFlag tests spawn a 'python -c' subprocess that imports
api.config (heavyweight) with a 10s timeout. Under the fully parallel full
suite the box can be saturated enough that the import exceeds 10s and the
runner SIGKILLs the child (returncode -9) — a pure resource-contention flake
(passes in isolation). Add _run_config_probe(): 60s timeout + retry on
TimeoutExpired/SIGKILL, returning a real non-zero exit immediately so genuine
failures still surface. Zero-flake-tolerance sweep (#4740).

---------

Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-06-22 22:41:42 -07:00
nesquena-hermes
45c8113f8b
Merge pull request #4760 from nesquena/stage-4758-release
Release v0.51.599 — Release VF (dedupe live progress reasoning echoes, #4758)
2026-06-22 22:14:37 -07:00
nesquena-hermes
9795fbac51 Release v0.51.599 — Release VF (dedupe live progress reasoning echoes, #4758) 2026-06-23 05:10:50 +00:00
nesquena-hermes
39eb7c40d2 stage #4758 (franksong2702): dedupe live progress reasoning echoes 2026-06-23 04:54:48 +00:00
Frank Song
a4470bd30c Deduplicate live progress reasoning echoes 2026-06-23 12:51:16 +08:00
nesquena-hermes
529eb51932
Merge pull request #4751 from nesquena/stage-4743-release
Release v0.51.598 — Release VE (preserve scroll across live worklog rebuilds, #4743)
2026-06-22 21:39:12 -07:00
nesquena-hermes
ecc00d56ac Release v0.51.598 — Release VE (preserve scroll across live worklog rebuilds, #4743) 2026-06-23 04:25:25 +00:00
nesquena-hermes
9fb371addd stage #4743 (franksong2702): preserve scroll across live Compact Worklog rebuilds 2026-06-23 04:14:05 +00:00
nesquena-hermes
9570b9bce4
Merge pull request #4744 from nesquena/stage-footer-wrap
Release v0.51.597 — Release VD (message footer wraps instead of overflowing, #4724-followup)
2026-06-22 21:10:14 -07:00
nesquena-hermes
064118d329 fix(ui): wrap message footer on narrow screens instead of overflowing (#4724-followup)
The assistant message footer (model · duration · tokens · cost · cache% · time · actions)
could overflow its row on mobile/narrow panes, pushing the per-message action buttons off
the right edge where they were unreachable. #4724 proposed ellipsing every stat, which
shrank them into unreadable stubs (D…, 98…). This instead lets .msg-foot flex-wrap to a
second line: every stat stays full-size + readable, the actions/time are pinned flex:0 0
auto so they never shrink and stay on-screen, and on wider screens where it already fits
wrap never triggers. Pure CSS. + source-structure regression test.

Co-authored-by: starship-s <starship-s@users.noreply.github.com>
2026-06-23 03:54:20 +00:00
Frank Song
4bb6fd132f Drop contributor changelog entry 2026-06-23 11:52:08 +08:00
Frank Song
61a7881056 Preserve scroll across live Worklog rebuilds 2026-06-23 11:42:36 +08:00
nesquena-hermes
6a0a215b55
Merge pull request #4739 from nesquena/stage-4729-release
Release v0.51.596 — Release VC (throttle reasoning SSE, #4729)
2026-06-22 20:05:21 -07:00
nesquena-hermes
9d3d6d4847 test(#4729): drop unused 're' import (ruff F401 lint gate) 2026-06-23 03:02:06 +00:00