Commit graph

411 commits

Author SHA1 Message Date
nesquena-hermes
04ce7599e3 stage-batch11: #3330 pinned-scroll + #3311 inline-math currency
#3330 Fix pinned chat scroll after message rebuild
Co-authored-by: jianongHe <jianongHe@users.noreply.github.com>

#3311 fix: reject inline math when $ is followed by a digit (currency)
Co-authored-by: toanalien <toanalien@users.noreply.github.com>
2026-06-01 19:08:30 +00:00
AJV20
ec704356ac fix: hide attachment path markers in chat UI 2026-06-01 05:31:53 +00:00
nesquena-hermes
1aed605fb6 fix(#3267): harden collapsed tool-preview secret filter (Codex gate MUST-FIX)
Codex regression gate found the exact-name hidden-key set leaked secret-shaped
args (apiKey/access_token/clientSecret/Authorization/cookie/...) into the
always-visible collapsed tool-card header. Replace with a normalized
case-insensitive _toolArgPreviewKeyIsHidden() predicate matching secret-bearing
substrings + camelCase variants. Adds 22 parametrized regression tests pinning
the secret-key denial + a legit-key-still-shown guard. Co-authored-by preserved.
2026-05-31 19:21:15 +00:00
ai-ag2026
69072ac34d fix: keep collapsed tool previews quiet 2026-05-31 19:12:31 +00:00
emanon312
e24ca105d7 fix: extend upward scroll intent timeout to prevent streaming scroll snap-back
Increase MESSAGE_UPWARD_INTENT_MS from 450ms to 2000ms to fix a race
condition where the user scrolls up during streaming, pauses to read
for >450ms, and then gets snapped back to the bottom.

The root cause: after the 450ms upward-intent window expires, DOM layout
changes from the streaming markdown parser (smd), tool card insertions,
or code re-highlighting can trigger scroll events that the handler no
longer recognizes as user-initiated. When the resulting position lands
inside the 250px near-bottom zone for two consecutive samples, the
hysteresis counter re-pins (_scrollPinned=true) and the next streaming
token's scrollIfPinned() call forces scrollTop to the bottom.

With a 2-second window, the user's upward intent persists through typical
streaming DOM churn. Downward scrolling and the scroll-to-bottom button
are unaffected — movedUp requires top < _lastScrollTop-2 which is false
for downward movement regardless of the intent timeout.

Refs: #1360 (macOS momentum protection), #1731 (direction-aware unpin)
2026-05-31 16:53:57 +00:00
nesquena-hermes
4fa051ea14 fix(security/#3234 + #3219): unify case-folded path checks, fix workspace over-block, protect raw <pre> (Codex review #6)
1. routes.py: hoist a single case-folded path helper (_norm/_within_ci/_equal_ci)
   used for ALL deny + carve-out comparisons (consistent macOS/Windows safety).
2. routes.py: split the deny into (a) dir-based denies that ALWAYS fire (even
   inside the active workspace — so a workspace overlapping a state dir cannot
   expose sessions/memories), and (b) filename denies relaxed only by the
   carve-out. Fix the over-block: a workspace that is a proper DESCENDANT of a
   Hermes root (e.g. STATE_DIR/workspace) is a legit project workspace and keeps
   the carve-out; only a root-itself / ancestor / $HOME / profiles / state-subdir
   workspace disables it.
3. ui.js: move the bare file:// media-stash pass after the raw-<pre> stash too,
   so file:// inside a raw <pre> block stays literal (not just fenced/inline code).
2026-05-31 03:24:35 +00:00
nesquena-hermes
5758d4a827 fix(security/#3234 + #3219): case-fold deny checks + make bare file:// rewrite code-fence-aware (Codex review #5)
1. api/routes.py: case-fold /api/media deny filename + dir containment checks
   (os.path.normcase + casefold) so STATE.DB / Sessions/ cannot bypass the
   state/secret deny on case-insensitive filesystems (macOS/Windows).
2. static/ui.js: move the bare file:// media-stash pass to run AFTER fenced-block
   and inline-code stashing, so a file:// inside a code block / backtick span
   stays literal text instead of becoming an auto-loaded <img>. The MEDIA: stash
   keeps its first-position precedent.
Adds behavioral renderer tests (real renderMd via node) for fenced + inline code
file:// staying literal, bare file:// becoming media, and anchors keeping the
link path. Closes the last Codex review items for #3234.
2026-05-31 03:17:10 +00:00
AJV20
aae3b418f0 fix: render file artifact links as media 2026-05-31 02:24:55 +00:00
ai-ag2026
ce4026660e test: harden session link sanitization 2026-05-30 19:13:11 +00:00
ai-ag2026
d3ee17793a feat: add internal conversation links 2026-05-30 19:13:11 +00:00
ai-ag2026
97dde9a48e fix: restore legacy tool card visuals 2026-05-30 10:31:35 +02:00
AJV20
d34d11821b fix: label tool output cards persistently 2026-05-30 04:24:15 +00:00
AJV20
b53bc1a2ea fix: harden webui passive performance paths 2026-05-30 01:39:54 +00:00
nesquena-hermes
9059b8f5c3 Merge PR #3116 (stale unread + compression timer + tool-card dedup) into stage-batch43 2026-05-30 00:21:04 +00:00
mysoul12138
5b3771012a Fix tool card duplication: skip detail when snippet equals preview
When tc.snippet === tc.preview (common for no-progress tools where
both are set to the same result_snippet), the detail block would show
identical content as the header. Skip the detail block in this case.

This also handles the reload-path where derived entries get snippet
populated but no preview, so displaySnippet falls back to the snippet
content for the header — same deduplication applies.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 00:20:49 +00:00
mysoul12138
0002cda23d fix: stale unread dot, compression timer leak, tool card duplication (#3020, #2973)
#3020: Sync viewed-count in the polling path for actively-viewed sessions
so navigating away doesn't show a stale unread dot. Defensive clear of
completion-unread marker in _setSessionViewedCount.

#2973: Clear elapsed-timer attributes and interval when a live compression
card transitions from running to done, preventing the orphan timer from
overwriting the completed card state. Guarded by active-session check.

Tool card duplication: Route tool_complete result to tc.snippet (detail)
instead of tc.preview (header) to prevent identical content appearing in
both the card header and expanded detail section.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 00:20:49 +00:00
Sanjays2402
24b175045f Fix #3114: keep jump-to-question button on intermediate assistant messages
In multi-step turns (assistant -> tool_call -> assistant -> tool_call ->
final assistant), only the turn-final assistant bubble was rendering the
'jump to question' navigation button because the gate keyed on
isTurnFinalAssistant. Intermediate assistant bubbles that *do* have a
resolvable question raw-index lost the affordance entirely.

Switch the gate to 'show whenever questionRawIdxByAssistantRawIdx has a
target for this rawIdx', which is the actual precondition for the button
being meaningful. Turn-finality was a proxy for 'has a question target'
that under-covered multi-step turns.

No template/CSS change needed; _questionJumpButtonHtml already handles
the rawIdx-or-undefined contract.
2026-05-30 00:09:13 +00:00
nesquena-hermes
de90ca3abe Merge PR #3117 into stage-batch41 2026-05-29 22:13:08 +00:00
Philippe Le Rohellec
e6aa9271c2 fix(models): preserve provider-qualified model selections in the picker
- Stop provider-qualified or slash-qualified model inputs from fuzzy-matching a
  sibling catalog entry when the exact requested model is missing from the
  curated picker list.
- Preserve the raw typed selection so uncatalogued provider-routed models
  fall through to a temporary custom option instead of silently snapping to a
  nearby curated model.
- Add generalized regression coverage for provider-qualified uncatalogued
  picker selections.
2026-05-29 10:24:44 -07:00
mysoul12138
b476126cb9 fix(ui): match tool result snippet limit to backend (200 -> 4000 chars)
_cliToolResultSnippet truncated to 200 chars while the backend's
_tool_result_snippet uses 4000. This caused tool card details to be
more aggressively truncated after session reload than during live
streaming.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 12:34:10 +08:00
nesquena-hermes
f7b4c6b0f4 Merge PR #3087
# Conflicts:
#	CHANGELOG.md
2026-05-28 19:38:10 +00:00
nesquena-hermes
2f73eb0f8d Merge PR #3039
# Conflicts:
#	CHANGELOG.md
2026-05-28 18:27:03 +00:00
george-andraws
0f6eab301c Fix browser chat provider fallback on fresh sessions 2026-05-28 11:10:14 -07:00
nesquena-hermes
1c89c7d327 Merge PR #3064
# Conflicts:
#	CHANGELOG.md
2026-05-28 17:47:35 +00:00
Frank Song
10573ab8aa Fix session media image rendering 2026-05-28 18:05:01 +08:00
ai-ag2026
2ee249112a fix: defer streaming KaTeX for pending equations 2026-05-28 08:56:34 +02:00
Dennis Soong
5f901f579a fix: suppress timeout toasts for passive pollers 2026-05-28 11:13:00 +08:00
nesquena-hermes
540993ccaf Merge pull request #2938
# Conflicts:
#	CHANGELOG.md
2026-05-27 04:21:45 +00:00
nesquena-hermes
2d7d2cb31d Merge pull request #2958
# Conflicts:
#	CHANGELOG.md
2026-05-27 00:38:58 +00:00
nesquena-hermes
e0dfa0c586 Merge pull request #2792 2026-05-27 00:37:48 +00:00
nesquena-hermes
6c619f9e81 Merge pull request #2970 2026-05-27 00:19:20 +00:00
nesquena-hermes
80a9b0fa68 Merge pull request #2985
# Conflicts:
#	CHANGELOG.md
2026-05-27 00:03:02 +00:00
ai-ag2026
815df9de76 fix: vendor math and yaml assets for CSP 2026-05-26 23:49:02 +02:00
weiwei83
d0235b7f5a fix: remove dead #composerAttach selector (actual ID is #attachTray) 2026-05-26 21:29:18 +08:00
weiwei83
1c7dfc85b3 refactor: code review cleanup
- Rename _escHandler to _keyHandler (now handles nav keys too)
- Store counter reference (lb._counterEl) to avoid DOM query on every nav
- Remove dead 'let counter = null' and 'hasNav' closure variable
- Use lb._navImages directly in keyboard handler for consistency
- Add null guard on lb.querySelector('img') in _navigateLightbox
- Inline _updateLightboxCounter one-liner
- Fix CSS section comment 'Image lightbox close' → 'Image lightbox'
- Fix CHANGELOG placeholder (#PR → #2967)
2026-05-26 21:28:38 +08:00
weiwei83
84d0d56f53 refactor: address PR review — fix event listener churn and dead code
- _navigateLightbox now reads lb._navIndex / lb._navImages directly
  instead of receiving a closure-captured index and rebuilding the
  keyboard handler on every navigation. No more removeEventListener /
  addEventListener churn.
- Button onclick handlers also read the live lb._navIndex.
- Removed dead backward-compat string-type shim and its unused oldEl
  querySelector.
- Composer attach-tray chips now open single-image lightboxes (no
  sibling detection across staged uploads).
2026-05-26 21:21:30 +08:00
AlexeyDsov
08277fcd9c perf(ui): cache visWithIdx to skip O(N) scan on render window expansion 2026-05-26 11:24:23 +03:00
AlexeyDsov
f0dfe116ca perf(ui): limit renderMessages O(N) passes to visible window 2026-05-26 11:24:11 +03:00
AlexeyDsov
755ecb94cd perf(ui): cache renderMd output and lazy Prism.js highlighting 2026-05-26 11:23:50 +03:00
weiwei83
ecf7ca7c60 feat: add prev/next navigation to image lightbox
When multiple images appear in the same message, clicking any image
now opens a lightbox with prev/next navigation buttons (‹ / ›) and
keyboard support (← / →). An image counter (e.g. '3 / 5') is shown at
the bottom of the overlay.

- _openImgLightbox now receives the clicked <img> element to find
  sibling images within the same message container
- New _openImgLightboxWithNav, _navigateLightbox, _updateLightboxCounter
- CSS: .img-lightbox-nav (prev/next buttons), .img-lightbox-counter
- Close button (×), Escape key, and click-outside-to-close preserved
2026-05-26 15:16:03 +08:00
Frank Song
a9ea56040f Tighten interim progress activity boundaries 2026-05-26 11:32:34 +08:00
Frank Song
7a52dec35d feat(chat): open workspace links in preview 2026-05-26 08:57:31 +08:00
Frank Song
3836b5eee0 fix: block update apply without targets 2026-05-25 08:51:44 +08:00
Roberto Villegas
4c4922a0d5
fix(webui): harden reasoning chip provider coverage 2026-05-24 18:42:44 -06:00
Roberto Villegas
91976a8fae
fix(ui): re-sync reasoning chip on model change with provider context
Model picker onchange now calls syncReasoningChip after session model/
provider updates, and dropdown selections pass providerId so duplicate
bare model ids resolve to the correct backend capabilities.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 18:42:44 -06:00
Roberto Villegas
a9ce2889af
fix(ui): hide reasoning chip when model lacks effort levels
Resolve supported reasoning efforts per active model/provider and pass
that context through /api/reasoning so Composer and other non-configurable
models no longer show a misleading effort picker.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 18:42:31 -06:00
hermes-agent
d9b2dd5019 Stage 406: PR #2726 — fix(model): keep boot default precedence non-destructive by @starship-s
Cherry-picked via 3-way apply onto stage HEAD (post-Release-A/B/C1).
Resolved boot.js conflict: took PR's parameterized
populateModelDropdown({preferProfileDefaultOnFreshBoot:true}) call
(the whole point of #2726) on top of master's #2716 boot path.

Co-authored-by: starship-s <starship-s@github.users.noreply.github.com>
2026-05-24 18:58:37 +00:00
hermes-agent
9d95ba0b92 Stage 404: PR #2716 — Performance optimizations by @dobby-d-elf
nesquena APPROVED 2026-05-22. Cherry-picked onto post-v0.51.127
master via 3-way apply. Resolved api/routes.py conflict: master had
the inline correctness fix from the deep-review iteration; PR
refactors it into _metadata_only_message_summary() helper. Took the
helper AND added profile= threading (post-#2827 master adds
profile-aware state.db reads). Kept master's pre-existing
test_api_session_reload_drops_stale_cached_user_tail_after_saved_assistant
alongside the PR's new test_metadata_fast_path_matches_reconciliation_for_restamped_replays.

Co-authored-by: dobby-d-elf <dobby.the.agent@gmail.com>
2026-05-24 18:08:41 +00:00
AJV20
237bab753a feat: surface live activity timeline (#2847)
Squashed from 2 author commits:
- d2237e23 feat: surface live activity timeline
- eee57ec0 fix: satisfy activity timeline CI guards

Frontend-only telemetry from existing stream events. Replaces empty
Thinking… placeholder with observable run status (Waiting on model /
Waiting on tool result / Working for …). New CSS, new test file.
2026-05-24 16:13:00 +00:00
Frank Song
99c886c199 fix(workspace): open rendered preview links correctly 2026-05-24 15:52:35 +00:00