Commit Graph
7195 Commits
Author SHA1 Message Date
Rod Boev 9bd96fb75d fix(#2422): support packaged Hermes Agent discovery 2026-07-14 01:06:49 +00:00
Rod Boev 53348df68d fix(#2422): allow Nix package version generation 2026-07-14 01:06:49 +00:00
Rod Boev b7f523c3a1 fix(#2422): tighten Nix module polish 2026-07-14 01:06:49 +00:00
Rod Boev 243f27e7ed fix(#2422): keep NixOS state private 2026-07-14 01:06:49 +00:00
Rod Boev 72b51a6b78 fix(#2422): avoid hardcoded agent site packages 2026-07-14 01:06:49 +00:00
Rod Boev 70514549c4 fix(#2422): harden NixOS packaged runtime 2026-07-14 01:06:49 +00:00
Rod Boev 1f505aad88 fix(#2422): pin the flake input for reproducible builds 2026-07-14 01:06:49 +00:00
Rod Boev 654a691155 fix(#2422): keep the Nix launch path declarative 2026-07-14 01:06:48 +00:00
Rod Boev 5bd940a49b fix(#2422): honor the service-mode host default 2026-07-14 01:06:48 +00:00
Rod Boev d77d956380 fix(#2422): validate env files before user drop 2026-07-14 01:06:48 +00:00
Rod Boev 09003b5e92 feat(#2422): add Nix flake package and NixOS module 2026-07-14 01:06:48 +00:00
nesquena-hermesandnesquena-hermes 11eb1b7a83 docs(changelog): stamp v0.52.28 stable section (first promotion since v0.52.0) (#6046)
Cuts the promoted range's bullets from [Unreleased] into a stamped
## [v0.52.28] section (41 bullets, v0.52.0..v0.52.28). Companion to the
v0.52.28 stable tag pushed by the promotion engine.

Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-07-13 16:54:47 -07:00
nesquena-hermes a1b60f304e Merge pull request #6044 from nesquena/stage/6042-ttft
Release exp: send-to-first-token latency instrumentation (#6042, #6006)
2026-07-13 15:56:49 -07:00
nesquena-hermes 7fb3d412f5 Release exp: instrument send-to-first-token latency (#6042, closes #6006). Thanks @rodboev.
Measure-only TTFT (ttft_ms) on the metering session + _firstTokenMs diagnostic. Computed once
on first token (no hot-path latency), all mutation under existing GlobalMeter._lock, existing
token/usage/cost metering unchanged. Codex SAFE (16-stream concurrency probe, no leak/None-deref)
+ stream-gate GREEN all modes + 22 tests.
2026-07-13 22:52:15 +00:00
nesquena-hermes f1480ad407 Merge branch 'rebase-6042' into stage/6042-ttft 2026-07-13 22:51:55 +00:00
Rod Boev 001d7985bc feat(#6006): instrument send-to-first-token latency 2026-07-13 17:56:44 -04:00
nesquena-hermes e5148f9dbe Merge pull request #6036 from nesquena/stage/6035-approval
Release exp: fix 'approve once' persisting as session approval (#6035, #6017)
2026-07-13 13:25:18 -07:00
nesquena-hermes ea5af7b6c8 Release exp: fix 'approve once' persisting as session approval (#6035, closes #6017). Thanks @rudidev08.
Local (non-gateway) _resolve_approval_legacy collapsed 'once'+'session' into approve_session()
→ 'approve once' silently persisted session-wide. Narrowed to choice=='session' only; 'once'
still resolves the current call but doesn't persist. Codex SAFE (adversarial: once resolves
current+no residue+next re-prompts, session/always/deny unregressed, gateway consistent, tests
non-vacuous + parked-thread probe of all 4 choices).
2026-07-13 20:16:26 +00:00
nesquena-hermes b86922ae38 Merge branch 'rebase-6035' into stage/6035-approval 2026-07-13 20:15:59 +00:00
rudidev08 34cf2de57a Fix: "Approve once" no longer persists as a session approval (#6017)
In the local (non-gateway) approval path, _resolve_approval_legacy grouped
"once" together with "session" and called approve_session() for both.
approve_session() records the pattern in the session-wide allowlist that the
guard later consults, so a single "Approve once" click silently approved every
later matching tool call for the whole session -- a destructive tool could then
run with no approval card.

Only "session"/"always" persist now. "once" falls through: the
resolve_gateway_approval() call below still unblocks the parked agent thread for
every choice, so the current tool call proceeds, but nothing is written to
_session_approved and the next matching guarded call re-prompts.

Adds tests/test_issue6017_approve_once_no_persist.py, asserting is_approved is
False after "once" and True after "session".
2026-07-13 13:05:52 -07:00
nesquena-hermes 07a1fad2c8 Merge pull request #6034 from nesquena/stage/6019-a11y
Release exp: a11y keyboard access for conversation actions menu (#6019)
2026-07-13 12:42:32 -07:00
nesquena-hermes d6684c091f Release exp: keyboard/screen-reader access for conversation actions menu (#6019). Thanks @sheldon-im.
ARIA (aria-expanded/controls, role=menu/menuitem) + focus-to-first-action on open +
Arrow/Home/End/Escape nav + focus-restore-to-trigger on close; existing click/touch unchanged.
Codex SAFE (isConnected-guarded restore, menu-scoped bounded arrow-nav, no listener leak
[25-cycle probe], 49 tests) + stream-gate GREEN.
2026-07-13 19:37:56 +00:00
nesquena-hermes e02636c58c Merge branch 'rebase-6019' into stage/6019-a11y 2026-07-13 19:24:30 +00:00
sheldon-im d7c2cc2d5d Restore focus from non-button session action menus 2026-07-13 19:24:09 +00:00
sheldon-im bc85711af2 Improve conversation actions menu keyboard access 2026-07-13 19:24:09 +00:00
nesquena-hermes 41f1eb5624 Merge pull request #6032 from nesquena/stage/r2-batch
Release exp: Round-2 batch — picker dedup (#5997) + zh-CN i18n (#6024)
2026-07-13 12:20:51 -07:00
nesquena-hermes 735d74df46 Release exp: Round-2 batch — model-picker dedup (#5997) + zh-CN localization fill (#6024)
#5997 (rodboev, closes #5989): proxy/catalog model-picker dedup, 4-round convergence.
  Colon-suffix collision closed (provider-context exact-prefix strip, :free/:thinking/:latest
  survive), 5 prior findings stay fixed. Codex SAFE r4 (73 tests) + stream-gate GREEN.
#6024 (Loukky): zh-CN localization fill (+55/-55, pure value replacement on existing keys,
  no key add/remove, no value-swap [en block 0 CJK], placeholders preserved).
Disjoint (static/ui.js picker logic / static/i18n.js locale data).
2026-07-13 19:17:13 +00:00
nesquena-hermes 4016130c24 Merge branch 'rebase-6024' into stage/r2-batch 2026-07-13 19:04:13 +00:00
nesquena-hermes 54a7bb2058 Merge branch 'rebase-5997' into stage/r2-batch 2026-07-13 19:04:12 +00:00
Loukky d1aa5945b6 Update i18n.js 2026-07-13 18:57:49 +00:00
Loukky 6ccf9168f2 [locale]Localization for Simplified Chinese
Translate all untranslated English strings into Simplified Chinese.
2026-07-13 18:57:49 +00:00
Rod Boev 3ada146d48 fix(#5989): keep colon-suffixed proxy models distinct 2026-07-13 18:57:15 +00:00
Rod Boev ff89f2ebd6 fix(#5989): keep cross-provider live rows selectable 2026-07-13 18:57:15 +00:00
Rod Boev 58725d5de9 fix(#5989): separate picker dedup from restore matching 2026-07-13 18:57:15 +00:00
Rod Boev 052effcfc4 fix(#5989): deduplicate proxy and catalog model rows in the picker 2026-07-13 18:57:15 +00:00
nesquena-hermes e4188ccd5e Merge pull request #6031 from nesquena/stage/6028-solo
Release exp: worktree unlock-before-remove (#6028, #6023)
2026-07-13 11:31:19 -07:00
nesquena-hermes 996705b7b1 Release exp: worktree unlock-before-remove so WebUI worktrees are reapable (#6028, #6023). Thanks @ayxuerui.
Fail-soft git worktree unlock before remove (agent locks worktrees it creates; git refuses
--force remove on locked → orphan accumulation). Dirty-guard still runs first. Codex SAFE,
13 tests pass. Shipped solo (unbundled from #6013 which has a full-suite test-interaction).
2026-07-13 18:27:44 +00:00
nesquena-hermes 1e2a01102a Merge branch 'verify-6028' into stage/6028-solo 2026-07-13 18:27:23 +00:00
Rui Xue c833f290a9 fix(worktrees): unlock before remove so WebUI-created worktrees can be reaped
WebUI-created worktrees are locked at creation by the agent
(cli._setup_worktree locks with --reason 'hermes pid=...'), but
remove_worktree_for_session never unlocked, so git refused every removal
with "use 'remove -f -f' to override or unlock first" — force=true
included, since a single --force cannot override a lock.

Mirror the agent's own _cleanup_worktree ordering: fail-soft
'git worktree unlock' right before the remove, after all
dirty/untracked/unpushed/stream/terminal guards have passed. Those
guards remain the real safety layer; force keeps meaning 'override
dirty working state', never 'override a foreign lock'.

Tests: locked worktree now removes cleanly without force; unlock is
fail-soft when the worktree was never locked; existing mocked
call-order assertions updated for the leading unlock call.

Fixes #6023
2026-07-13 17:47:58 +00:00
nesquena-hermes d486394f7b Merge pull request #6012 from nesquena/stage/5802-media
Release exp: render MEDIA: tokens inline during streaming (#5802)
2026-07-13 01:21:25 -07:00
nesquena-hermes 42d62e0793 Release exp: render MEDIA: tokens inline during streaming (#5802). Thanks @silent-reader-cn.
MEDIA tokens (image/video/audio/pdf/diff/csv/excalidraw) render inline in real time
during streaming incl split-across-chunk markers. Codex SAFE r4 (both prose regressions
closed — ownership preserved + fade retained, normal prose byte-identical to master, all
4 original findings fixed, security clean, no ReDoS), stream-gate GREEN all modes (hide_all
RED was load flake, isolated re-run clean). 227 tests + 18 real-SMD subtests pass. 4-round
convergence on the crown-jewel render + security path.
2026-07-13 08:17:52 +00:00
nesquena-hermes 2d1a2d15a0 Merge branch 'rebase-5802' into stage/5802-media 2026-07-13 08:06:28 +00:00
silent-reader-cn 946f7dbc2b fix(media): preserve scanner prose ownership 2026-07-13 07:41:13 +00:00
silent-reader-cn e13a75b7b1 test(media): cover fade MEDIA streaming splits 2026-07-13 07:41:13 +00:00
silent-reader-cn 3b19660235 fix(media): handle fade MEDIA prefix splits 2026-07-13 07:41:13 +00:00
silent-reader-cn a17370ad4a fix(media): harden streamed MEDIA rendering 2026-07-13 07:41:13 +00:00
silent-reader-cn 188a03bb28 fix: remove unused smd media test variable 2026-07-13 07:41:13 +00:00
silent-reader-cn 76940e821d fix: flush smd media tail on stream end 2026-07-13 07:41:13 +00:00
silent-reader-cn 547c218ddf fix: clear fallback smd media tail 2026-07-13 07:41:13 +00:00
silent-reader-cn ca3a1ac04d fix: accept extensionless streaming media urls 2026-07-13 07:41:13 +00:00