Commit Graph
5771 Commits
Author SHA1 Message Date
nesquena-hermes dd4d4b2e90 Merge pull request #5241 — page archived sidebar rows + archived-search refetch (#5200, @santastabber)
Release v0.51.757 — page archived sidebar rows + archived-search refetch (#5200, @santastabber)
2026-06-29 15:38:06 -07:00
nesquena-hermes b753a11895 docs(changelog): page archived sidebar rows + archived-search refetch (#5200) 2026-06-29 22:35:32 +00:00
Jamie (Hermes) 0674a0198c perf(sessions): page archived sidebar rows 2026-06-29 22:24:35 +00:00
nesquena-hermes 61f07f6005 Merge pull request #5238 — collapse post-restart config reload stampede (#5235, @rodboev)
Release v0.51.756 — collapse post-restart config reload stampede (#5235, @rodboev)
2026-06-29 14:01:13 -07:00
nesquena-hermes 2add66f66d docs(changelog): collapse post-restart config reload stampede (#5235) 2026-06-29 20:58:04 +00:00
Rod Boev affdb40a1c fix(config): route stale model reads through shared reload gate (#5220) 2026-06-29 20:50:34 +00:00
Rod Boev 6653b7bd2f fix(config): collapse post-restart config reload stampede (#5220) 2026-06-29 20:50:34 +00:00
nesquena-hermes 45dabb2e15 Merge pull request #5236 — Neuralwatt provider env-var mapping (#4810, @b-yelverton)
Release v0.51.755 — Neuralwatt provider env-var mapping (#4810, @b-yelverton)
2026-06-29 13:49:08 -07:00
nesquena-hermes cd67e67af1 docs(changelog): add Neuralwatt provider env-var mapping (#4810) 2026-06-29 20:42:54 +00:00
Brett Yelverton 6c73e417e0 test: add regression coverage for neuralwatt provider env-var mapping
Mirrors test_issue2025_xiaomi_env_key.py pattern:
- _PROVIDER_ENV_VAR['neuralwatt'] == 'NEURALWATT_API_KEY'
- _provider_has_key('neuralwatt') with env var set
- _provider_has_key('neuralwatt') without env var
- model group appears in get_available_models() when config lists models
2026-06-29 20:41:16 +00:00
Brett Yelverton 0c338711df feat: add Neuralwatt provider support (env var mapping) 2026-06-29 20:41:16 +00:00
nesquena-hermes 31000a9ec1 Merge pull request #5234 — configurable voice silence timeout + continuous recognition (#5176, @ChonSong)
Release v0.51.754 — configurable voice silence timeout + continuous recognition (#5176, @ChonSong)
2026-06-29 13:37:37 -07:00
nesquena-hermes 5fd6051743 test(#5176): update sprint20 continuous-recognition assertion for the new opt-in default-false form 2026-06-29 20:28:26 +00:00
nesquena-hermes 2643f990c4 docs(changelog): configurable voice silence timeout + continuous recognition (#5176) 2026-06-29 20:22:26 +00:00
nesquena-hermes 0aea4c7e18 harden(#5176): clamp configurable voice silence timeout (maintainer hardening)
Apply the warm-review polish: parseInt radix 10, fall back to 1800 for
missing/NaN/non-positive values, and floor at 200ms so a mistyped tiny/negative
hermes-voice-silence-ms can't make the recognizer auto-send instantly. De-brittle
the source-string test to assert behavior (reads key / 1800 fallback / guards
non-positive) instead of one literal expression. Default behavior unchanged.
2026-06-29 20:21:22 +00:00
Sean 5bfa9a8ec0 feat(voice): make silence timeout and continuous recognition configurable via localStorage
The voice-mode loop hardcoded SILENCE_MS=1800 and
_recognition.continuous=false, giving users no way to tune the
auto-send timing or keep the mic open across natural pauses.

Changes:
- SILENCE_MS now reads from localStorage key 'hermes-voice-silence-ms'
  with 1800ms fallback — users set it from the dev console or a future
  settings toggle
- _recognition.continuous reads from 'hermes-voice-continuous' (default
  false) — set to 'true' to keep the mic open across pauses within an
  utterance, with the silence timer remaining the sole send decision

New test file (tests/test_issue4761_voice_mode_config.py, 8 tests)
pins both localStorage reads and verifies the surrounding voice-mode
infrastructure is intact.

Refs #4761
2026-06-29 20:19:40 +00:00
nesquena-hermes ca507138f7 Merge pull request #5233 — reduce false Connection Lost flapping under large session state (#5201, @franksong2702)
Release v0.51.753 — reduce false Connection Lost flapping under large session state (#5201, @franksong2702)
2026-06-29 13:16:25 -07:00
nesquena-hermes 978c5108bd docs(changelog): reduce false Connection Lost flapping under large session state (#5201) 2026-06-29 20:07:25 +00:00
nesquena-hermes 62fde9c32b test(#5201): widen hidden-tab skip-block window to 2900 after rebase (maintainer rebase-fix)
#5201 grows startSessionStream, pushing the hidden early-return skip path to
offset ~2247; #5172's test sliced an outer 2400 window that truncated the
skip_block before _startHiddenActiveStreamPoll(sid). Widen to 2900 so the
assertion reaches it. Both production hidden-poll paths are intact (Codex
verified); test-window only.
2026-06-29 20:06:18 +00:00
nesquena-hermes ac9d9b8f8c test(#5201): widen sse-visibility reopen window to 2200 after master-rebase (maintainer rebase-fix)
The rebase onto current master (which carries #5172's window bumps) left the
reopen-path test window at 1600, but #5201 grows startSessionStream so the
'else if (_sessionStreamHiddenSid)' reopen assertion now lands at offset ~1741.
Widen to 2200 (matching #5201's sibling windows) so the assertion reaches the
code. Test-window only; production unchanged.
2026-06-29 19:53:25 +00:00
Frank SongandPaperclip afbb3e5010 Fix session stream resume after live stream end
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-29 19:52:02 +00:00
Frank SongandPaperclip 47d8ac94d3 Harden connection flapping aftercare
Keep sidebar retries boot-scoped, preserve immediate source-change cache rebuilds, and tighten session stream ownership before closing duplicate SSE sockets.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-29 19:52:02 +00:00
Frank Song cbb644da69 Reduce connection lost flapping under large session state 2026-06-29 19:52:02 +00:00
nesquena-hermes ce425c7127 Merge pull request #5232 — anchor-fallback render-ownership regression harness (#5197, @franksong2702)
Release v0.51.752 — anchor-fallback render-ownership regression harness (#5197, @franksong2702)
2026-06-29 12:48:00 -07:00
nesquena-hermes 765460cb79 docs(changelog): anchor-fallback render-ownership regression harness (#5197) 2026-06-29 19:45:07 +00:00
Frank Song 7f98952db0 test: harden anchor fallback harness 2026-06-29 19:37:37 +00:00
Frank Song 7cdcadcbc4 test: lock anchor fallback render ownership 2026-06-29 19:37:37 +00:00
nesquena-hermes 99f487697d Merge pull request #5230 — Polish virtualize-transcript i18n + BOM strip (#5216, @leszek3737)
Release v0.51.751 — translate Polish virtualize-transcript setting + strip BOM (#5216, @leszek3737)
2026-06-29 12:08:16 -07:00
nesquena-hermes 80b0b6d74b docs(changelog): translate Polish virtualize-transcript setting + strip BOM (#5216) 2026-06-29 19:05:29 +00:00
Leszek ac4c7b0edf i18n(pl): translate virtualize-transcript setting, strip BOM
Translate settings_label_virtualize_transcript and its description into
Polish; they were still showing the English fallback. Also remove the
stray UTF-8 BOM from the top of the file.
2026-06-29 18:54:22 +00:00
nesquena-hermes b8ea322dbb Merge pull request #5229 — tighten new-conversation empty-state reuse guard (#5206, @franksong2702)
Release v0.51.750 — tighten new-conversation empty-state reuse guard (#5206, @franksong2702)
2026-06-29 11:50:48 -07:00
nesquena-hermes 0256773697 docs(changelog): tighten new-conversation empty-state reuse guard (#5206) 2026-06-29 18:44:28 +00:00
Frank SongandPaperclip fbb1e9567c test: align new chat guard static coverage
Update the older #1432 static regression to assert the extracted reusable-empty helper owns the message-count and in-flight checks, while both New Chat entry points call the helper. This keeps the test aligned with the shared guard introduced in PR #5206.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-29 18:38:25 +00:00
Frank Song 28c2c37c1c Fix new chat empty-session reuse guard 2026-06-29 18:38:25 +00:00
nesquena-hermes 60a45686e6 Merge pull request #5227 — memoize API-response redactor (#5204, @ducnhung70)
Release v0.51.749 — memoize API-response redactor to stop poll-storm CPU wedge (#5204, @ducnhung70)
2026-06-29 11:36:18 -07:00
nesquena-hermes bc810c6bf7 docs(changelog): memoize deterministic API response redactor (#5204) 2026-06-29 18:24:25 +00:00
nesquena-hermes dc38e42a26 test(#5204): lock redactor memoization contract (cached==uncached + oversize bypass) (auto-fix)
Adds the optional regression test the gate recommended: pins that
_redact_fn_cached stays byte-identical to _redact_fn_uncached for sensitive
input, is idempotent, and that >16KB inputs which bypass the lru_cache are
still redacted identically (no cache-skip secret leak). Production code
unchanged.
2026-06-29 18:23:41 +00:00
AnhNVT 9ad1fa0372 fix(redaction): memoize deterministic API response redactor
The combined credential redactor (~15 regex passes per string) runs on the
full message history of every /api/session response. Under concurrent
dashboard polling of unchanged sessions this became the dominant CPU cost
and, behind the GIL in the single-process server, serialized requests to
10-44s each — surfacing as repeated 'connection lost' in the browser as
the proxy/browser timed out and the frontend retried, piling on threads.

The redactor is pure and deterministic (force=True, fixed masking), so
identical strings always map to identical output and are safe to memoize
without invalidation. Wrap it in an lru_cache(maxsize=4096), gated to
strings <=16KB so a few giant tool-output dumps can't evict the many small
recurring strings or balloon RSS. Repeated polls become O(1) cache hits
(measured 3.7ms -> 0.002ms per 3KB marker string).

_redact_fn_cached is preserved as the call-site name so the existing
monkeypatch-based redaction tests bypass the cache unchanged (69/69 pass).
2026-06-29 18:22:18 +00:00
nesquena-hermes 791744ac29 Merge pull request #5226 — bound HTTP worker dispatch under reconnect storms (#5215, @rodboev)
Release v0.51.748 — bound HTTP worker dispatch under reconnect storms (#5215, @rodboev)
2026-06-29 11:20:06 -07:00
nesquena-hermes 6fe7a16fcd docs(changelog): bound HTTP worker dispatch under reconnect storms (#5215) 2026-06-29 18:11:11 +00:00
Rod Boev d548dabd21 Retrigger CI on validated head 2026-06-29 18:10:20 +00:00
Rod Boev 7744fe3f8b Keep disconnect intent explicit through server cleanup 2026-06-29 18:10:20 +00:00
Rod Boev ca5b20d2e6 Keep overflow cleanup off the accept loop 2026-06-29 18:10:20 +00:00
Rod Boev 55ad113ee7 fix(#5210): bound HTTP worker dispatch under reconnect storms 2026-06-29 18:10:20 +00:00
nesquena-hermes 68b211e0d5 Merge pull request #5223 — Windows-safe os.replace retry (#5196, @silent-reader-cn)
Release v0.51.747 — Windows-safe os.replace retry on session saves (#5196, @silent-reader-cn)
2026-06-29 11:09:33 -07:00
nesquena-hermes e7bd74cc13 docs(changelog): Windows-safe os.replace retry (#5196) 2026-06-29 18:06:41 +00:00
nesquena-hermes 683a96acda test(#5196): add _safe_replace retry/backoff coverage (auto-fix)
Adds the test the project's contribution rules require for non-trivial logic
(AGENTS.md). Covers: posix passthrough (1 call, no sleep), Windows
retry-then-succeed, reraise after exhausting 5 attempts (no silent success on a
save path), no-retry on non-PermissionError, and the 50/100/200/400ms backoff
sequence. Production _safe_replace unchanged.
2026-06-29 17:54:37 +00:00
wangyichen 17f2d898f3 fix: retry os.replace() on Windows WinError 5 (PermissionError)
Windows locks session JSON files briefly during antivirus scans or
browser polling, causing os.replace() to raise WinError 5
(ERROR_ACCESS_DENIED). Add _safe_replace() helper that retries with
exponential backoff (50ms to 800ms, max 5 attempts) on PermissionError.
No-op on non-Windows platforms.

Replaces all 5 os.replace() call sites in models.py:
- Session.save() (main file + backup)
- _write_session_index() (full rebuild + fast path)
- prune_session_from_index()
2026-06-29 17:53:41 +00:00
nesquena-hermes 7ef8b636a0 Merge pull request #5222 — Cmd/Ctrl+K skips text inputs (#5208, @nankingjing)
Release v0.51.746 — Cmd/Ctrl+K skips text inputs so kill-line works (#5208, @nankingjing)
2026-06-29 10:50:12 -07:00
nesquena-hermes a084a040a7 docs(changelog): skip Ctrl+K new-chat in text inputs (#5208) 2026-06-29 17:46:59 +00:00