Commit graph

2796 commits

Author SHA1 Message Date
nesquena-hermes
d85eb85c25
Merge branch 'master' into fix/interim-anchor-final-character 2026-07-31 11:52:58 -07:00
Nathan Esquenazi
94a2091435
Merge branch 'master' into fix/interim-anchor-final-character 2026-07-31 11:11:50 -07:00
Nathan Esquenazi
eb1484bede
Merge branch 'master' into franksong2702/viewport-scroll-anchor-6414 2026-07-31 11:09:39 -07:00
Frank Song
89023eb191
Live-to-Final: prove historical hydration and fence terminal retry ownership (#6451)
* test: add historical hydration lifecycle proof

* fix: retry anchor persistence after terminal app errors

* fix: fence deferred anchor settlement ownership

* test: cover deferred anchor retry ownership

* fix: preserve terminal anchor retry across refresh

* fix: bind terminal anchor retry to turn owner

---------

Co-authored-by: Frank Song <franksong2702@gmail.com>
2026-07-31 11:04:40 -07:00
Frank Song
fd1879418d fix: queue pinned live scroll ownership check 2026-07-31 22:24:25 +08:00
Frank Song
cc5cf19710 test: exercise reachable live scroll restore boundary 2026-07-31 22:24:25 +08:00
Frank Song
a6a891f079 fix: keep live render harness fallback safe 2026-07-31 22:24:25 +08:00
Frank Song
713418dec0 test: cover live render scroll ownership boundary 2026-07-31 22:24:25 +08:00
Frank Song
7a320bea3c fix: preserve live scroll ownership on snapshot mismatch 2026-07-31 22:24:25 +08:00
Frank Song
a55096b81f fix: keep scroll ownership hooks harness-safe 2026-07-31 22:24:25 +08:00
Frank Song
5efc94f4b2 fix: preserve ownership of live scroll snapshots 2026-07-31 22:24:25 +08:00
Frank Song
5c3ead61a2 Restore unpinned desktop stream scroll 2026-07-31 22:24:25 +08:00
Frank Song
1c385e6935 Merge remote-tracking branch 'origin/master' into franksong2702/live-worklog-settle-no-blank 2026-07-31 01:27:57 +08:00
nankingjing
95a1647557 fix(#6419): route every recovery path through one pending_user_message merge helper
The mid-stream reconnect path could render the just-sent user message below
the live streaming assistant response it triggered, because
`refreshSession()` appended `pending_user_message` at the end of
`S.messages` unconditionally while `loadSession()` correctly inserted
it before the first live assistant message. When the client went through
its reconnect/recovery path mid-turn (typical on iOS PWA screen
lock/resume) the live assistant tail rendered above the prompt.

Centralize every recovery/reconnect reinsertion through one
identity-aware helper (`_mergePendingSessionMessage`) that:

- inserts the owning user turn before its live assistant/Worklog tail,
- appends only when no live tail exists,
- deduplicates against the current tail user row,
- remains idempotent across repeated resume probes.

`refreshSession()` now calls the same helper instead of pushing at
the end. `loadSession()` continues to use the helper unchanged.

Adds `tests/test_issue6419_pending_user_reconnect_order.py` pinning:
- the helper is defined exactly once at module top level,
- it inserts before live assistant and falls back to append,
- `refreshSession()` uses the helper and does not push unconditionally,
- `loadSession()` still merges before renderMessages in the INFLIGHT
  reattach branch.

Renames the inner end-marker in
`tests/test_gateway_sse_reconnect_dedupe.py` to a stable inside-loadSession
boundary (`// Phase 2a:`) since the helper is no longer nested.
2026-07-29 22:37:58 +00:00
Anthony Ruiz
127a57e0c5 fix(sessions): fully consume PWA launch action 2026-07-29 21:50:54 +00:00
Anthony Ruiz
cd04f5fcc2 fix(sessions): preserve active chat across hard refresh 2026-07-29 21:50:54 +00:00
pxxD1998
e2b052a637 fix(workspace): persist recovered session bindings 2026-07-29 18:22:22 +00:00
starship-s
69b26c1fa5 fix(streaming): complete interim anchor prose
Treat status-less interim assistant events as complete semantic boundaries so streaming Markdown flushes its final lookahead character before tool activity. Add behavior coverage for the real interim-to-tool Anchor pipeline.

Assisted-by: Hermes Agent:gpt-5.6-sol
Assisted-by: Codex:gpt-5.3-codex-spark
2026-07-24 12:30:46 -06:00
Frank Song
cbe353fb93 Scope preserveDom to live assistant turn only 2026-07-24 13:43:15 +08:00
Frank Song
30df3ce0fe Restore completion read-state ordering 2026-07-24 13:05:01 +08:00
Frank Song
65121ca1ad Sync viewed state before live settlement cache 2026-07-24 13:03:38 +08:00
Frank Song
7f0099f1f6 Fix live settlement test compatibility 2026-07-24 12:50:05 +08:00
Frank Song
ae264f71a3 Preserve live Worklog through final settlement 2026-07-24 12:43:34 +08:00
b3nw
e93b0c352a
feat: render process wakeups as collapsed summary cards (#6350)
Render structured background-process completions and watch matches as accessible collapsed cards while preserving raw fallback, verbatim output, and full watch patterns.

Co-authored-by: b3nw <b3nw@duck.com>
2026-07-23 20:52:51 +00:00
nesquena-hermes
3157f4cbf2 harden(#6349): strict finite-px min-height parse for the composer fast path
Codex re-gate found the single-row resize fast path used parseFloat on
getComputedStyle(el).minHeight, which reads a bogus pixel value for a
non-px unit (parseFloat('50%')===50) and would wrongly enable the fast
path, leaving an oversized composer stuck tall. Parse with a strict
/^<number>px$/ test so %, auto, empty, and calc() fail closed to the
full resize. Adds red-before-green regression coverage across units.

Co-authored-by: sheldon-im <sheldon-im@users.noreply.github.com>
2026-07-23 04:05:03 +00:00
nesquena-hermes
77d0b8609d Merge remote-tracking branch 'origin/master' into stage/6349 2026-07-23 03:25:14 +00:00
nesquena-hermes
575e45f76b polish(#6040): approval-counter CSS cleanup + i18n the pending-count string
Fable UX polish pass on the gateway approval counter:
- Move the crude inline style (font-size:0.75em;opacity:0.6;margin-top:4px) into
  a proper .approval-counter rule: 11px, color:var(--muted) (skin-safe vs opacity),
  margin:0 0 12px (fixes the 0px gap that left it flush against the buttons),
  tabular-nums for stable digits.
- i18n the '1 of N pending' string (was the only hardcoded-English string in an
  otherwise fully-localized approval card): new approval_pending_count key in en
  + 14 locales, wired via t() with an English fallback.

Co-authored-by: rodboev <rodboev@users.noreply.github.com>
2026-07-23 03:12:49 +00:00
nesquena-hermes
0d06ae3467 Merge remote-tracking branch 'origin/master' into stage/6040 2026-07-23 02:26:42 +00:00
starship-s
5bf77d558a fix: finalize sealed anchor prose at completion (#6408)
Anchor-owned process-prose rows kept the newest character as streaming-markdown
lookahead until the turn settled, so Compact Worklog prose immediately before a
tool card appeared one character short mid-stream. Finalize the cached parser
once when the row becomes 'completed' (running the same media/link/table cleanup
as the main body parser), guarded by a 'finalized' flag + self-heal on edit.

Co-authored-by: starship-s <starship-s@users.noreply.github.com>
2026-07-23 01:46:01 +00:00
nesquena-hermes
bbb417b3f1 stage: merge #6113 (per-turn used-model chip in transparent footer) 2026-07-22 22:13:08 +00:00
nesquena-hermes
6e2267dd5f stage: merge #6390 (scroll preservation after live-to-final settlement) 2026-07-22 20:43:04 +00:00
Rod Boev
6d9e4ac4c5 fix(#6008): keep stop failure toasts actionable across locales 2026-07-22 12:33:57 -04:00
Rod Boev
0a3a630856 fix(gateway): keep approval and stop acknowledgements honest 2026-07-22 12:31:12 -04:00
Rod Boev
f30178e18a fix(gateway): fall back safely without approval identities 2026-07-22 12:31:12 -04:00
Rod Boev
5826d76da0 fix(#6008): publish the authoritative approval head 2026-07-22 12:31:12 -04:00
Rod Boev
b907630f8f fix(#6008): keep gateway approvals attached to the right run 2026-07-22 12:31:11 -04:00
sheldon-im
a05cb953f2 fix: remeasure oversized composer appends 2026-07-22 13:27:11 +09:00
sheldon-im
a383525afe fix: restrict composer resize fast path to appends 2026-07-22 09:45:58 +09:00
nesquena-hermes
71fafbe21d Merge remote-tracking branch 'origin/master' into gate-6222 2026-07-21 23:24:54 +00:00
sheldon-im
b5b21c180c fix: refresh composer action on resize fast path 2026-07-22 07:11:33 +09:00
koshikai
005589bc82 fix(i18n): drop workspace_artifact_source_session from ja
Per tests/test_issue6067_artifact_paths.py, this key is intentionally
English-fallback-owned (same convention as profile_concept_*) and must
be absent from every non-English locale block. CI caught this
(test_issue6067_session_source_key_is_english_fallback_owned) — the key
now falls through to LOCALES.en[key] as intended, same as before.
2026-07-21 21:52:02 +00:00
koshikai
62ac52ff17 feat(i18n): refresh Japanese (ja) locale to parity with upstream master
master was ~1,070 commits behind nesquena/hermes-webui:master, and roughly
40 of those touched static/i18n.js: new features (workspace panel, session
sharing, extensions gallery, cron sentence-builder UI, gateway controls),
plus a community PR that bulk-translated the old TODO-placeholder set
across all locales. Rebasing the old ja branch directly conflicted because
the English source text itself had moved since those translations were
written.

Rebuilt the ja block against current upstream/master instead: reused the
existing translation wherever the paired English source is unchanged, and
wrote fresh translations for everything new, reworded, or still sitting in
English. ja is back to full key parity with en per this repo's own
tests/test_japanese_locale.py contract (key coverage, duplicate-key
parity, placeholder preservation, arrow-function parity).

Left brand/acronym terms (MCP, YOLO, JSON, HTML, URL, sk-..., Hermes
Agent) and profile_concept_* (explicitly English-fallback-owned per
tests/test_issue2147_profile_concept_help.py) untouched, matching this
repo's existing convention across all locales.
2026-07-21 21:52:01 +00:00
Frank Song
ae8fb0abb7 Merge remote-tracking branch 'origin/master' into paperclip/pr-6222 2026-07-22 05:31:35 +08:00
b3nw
34cc5dbeb2 fix: resolve transparent footer metadata from final segment (#6068 gate r2)
A tool-using Transparent Stream turn renders multiple assistant segments
(activity segment(s) then the final answer). Turn metadata — including
_usedModel — is stamped only on the final assistant message, but the
transparent footer read it via turn.querySelector('.assistant-segment'),
which returns the FIRST segment and thus no metadata. Combined with the
generic footer yielding model ownership to transparent mode, the model
label disappeared entirely on exactly the tool turns where per-turn
attribution matters most.

- Add _transparentTurnMetaMessage(turn): scan .assistant-segment
  [data-msg-idx] last→first for the final metadata-bearing assistant
  message, falling back to the last assistant segment.
- Use it for the transparent footer's duration/model/TTFT/usage instead
  of querySelector's first match.
- Non-blocking UX (per gate): preserve the full uncompacted model id in a
  hover title on both the transparent .lf-model span and the settled
  .msg-used-model-inline chip.
- Tests: behavioral multi-segment harness asserting exactly one .lf-model
  (and the correct final-segment metadata + hover title), plus wiring
  checks for the segment-scan helper.
2026-07-21 16:02:50 +00:00
b3nw
9bf876598d fix: stamp post-run agent.model + one model label per turn (#6068 gate)
Addresses the three gate-review blockers on #6113:

- Fallback attribution: read the served model from agent.model AFTER the
  run (the agent mutates it when a fallback fires) instead of the pre-run
  resolved_model, for both the persisted _usedModel and SSE used_model.
- Gateway double-label: suppress the additive chip whenever
  _gatewayRouting is present, and pass msg._usedModel to
  _formatGatewayModelLabel as its model fallback when routing omits
  used_model.
- Transparent double-label: skip the generic .msg-used-model-inline chip
  when the transparent turn footer owns the model label (.lf-model).

Also per Greptile: settled footer now orders the model chip after the
duration (elapsed - model - ...) to match the transparent footer, and the
test file gains its trailing newline.
2026-07-21 16:02:50 +00:00
b3nw
30aef85b18 feat: stamp per-turn used model in footer stats (#6068)
Record resolved_model on assistant messages as _usedModel, expose used_model
in the usage SSE payload, and render model chips in transparent and settled
turn footers while suppressing duplicates when gateway routing already shows
used_model.
2026-07-21 16:02:49 +00:00
Frank Song
de96c1d384 fix: harden terminal error worklog settlement 2026-07-21 15:05:17 +08:00
webtecnica
25d39da00e fix(stream): preserve reader viewport anchor through live-to-settlement collapse
Issue #6385: when a streaming turn settles, the two-render sequence
(keep-open expanded worklog → collapsed worklog) could displace the
reader's viewport because the second render captured its scroll snapshot
from the intermediate expanded state, not from the original live DOM.

Root cause
----------
The STREAM_DONE handler in messages.js:

1. Arms keep-settled-worklog-open token → renderMessages({preserveScroll:true})
   → worklog rendered EXPANDED (height-stable swap preventing shrink jump)

2. Disarms token → _renderMessagesWithScrollSnapshot()
   → This function called _captureMessageScrollSnapshot() which captured
     the scroll anchor from the expanded-worklog DOM (step 1 output),
     then called renderMessages with the worklog COLLAPSED (keep-open gone),
     then tried to restore from the expanded-state snapshot.

   The snapshot's semantic anchor (row key, session idx, top offset) was
   captured from a DOM where the worklog was expanded. After the collapse
   render the worklog is no longer at that position — anchor keys don't
   match, the semantic restore fails, and the viewport jumps to a
   unrelated scrollTop.

Fix
---
- Capture the scroll snapshot from the LIVE DOM (before any settlement
  renders) and pass it as  to the second render.
- Modify _renderMessagesWithScrollSnapshot() to accept a pre-captured
  snapshot via options._prescrollSnapshot, using it instead of capturing
  a fresh one from the current DOM state.

This ensures the collapse render anchors to the content the reader was
actually viewing, not to a stale intermediate expanded-worklog position.

Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>
2026-07-21 02:12:06 -03:00
Frank Song
9e7106de33 Merge remote-tracking branch 'origin/master' into paperclip/pr-6222 2026-07-21 12:55:27 +08:00
nesquena-hermes
c0d9d81512
Release: add preference to hide new-chat welcome panel (#6183, @vaidu-ai) (#6387)
* feat: add option to hide new-chat welcome panel

* Release: add preference to hide new-chat welcome panel (#6183, @vaidu-ai)

---------

Co-authored-by: vaidu-ai <im@vaidu.net>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-21 04:45:11 +00:00