Commit Graph

1375 Commits

Author SHA1 Message Date
nesquena-hermes 7edd43549d stage-batch43: extend #3018 carry-forward to _finishDone completion path (Opus review — most-frequent reproducer) 2026-05-30 00: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
nesquena-hermes 86d5d63593 Merge PR #3131 (preserve per-turn ephemeral fields) into stage-batch43 2026-05-30 00:20:58 +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 01c27806d4 Fix #3018: preserve per-turn ephemeral fields across session refreshes
`_turnUsage` (and `_turnDuration`, `_turnTps`, `_gatewayRouting`,
`_statusCard`) are computed client-side in `_finishDone()` and attached
to the last assistant message in `S.messages`. Three code paths replace
`S.messages` wholesale with fresh API data that lacks these fields:

  1. `_restoreSettledSession()` after a late `stream_end` or SSE error.
  2. The late-restore branch after `done` (messages.js ~L2247).
  3. `loadSession()` for active-session external refresh / focus-change.

When any of these fire after `done`, the badge/duration/gateway-pill
flashes for ~1s and disappears, never returning until the next message
or page reload.

Add `_carryForwardEphemeralTurnFields(prev, next)` that matches messages
by `(role, timestamp, content prefix)` — the same identity the renderer
already uses — and copies forward the ephemeral fields when the server
payload is missing them. Wire it into all three replace sites. The fix
is conservative: it only fills slots that are `null` on the new message,
so an authoritative server-side value (if/when the API ever surfaces
per-turn usage) wins automatically.

Picked Option A from the bug report (preserve on the client side) over
Option B (synthesize from `S.lastUsage`) because `lastUsage` is a
session-level aggregate; reconstructing per-turn breakdowns from it is
lossy. Option C (set `_streamFinalized` earlier) would suppress legit
late-arriving server data on transient errors.
2026-05-30 00:11:50 +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 111e7a11b1 Merge PR #3118 into stage-batch41
# Conflicts:
#	CHANGELOG.md
#	static/boot.js
2026-05-29 22:14:16 +00:00
nesquena-hermes de90ca3abe Merge PR #3117 into stage-batch41 2026-05-29 22:13:08 +00:00
nesquena-hermes ff78a422ca Merge PR #3139 into stage-batch40 2026-05-29 22:01:06 +00:00
nesquena-hermes d072039237 Merge PR #3130 into stage-batch40 2026-05-29 21:59:24 +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
Sanjays2402 e09c6aa6bd Fix #3076: don't force mobile send-on-Enter when a real keyboard is attached
A touch-primary device (`matchMedia('(pointer:coarse)')` is true) can
still have a physical keyboard available — Android tablet + Bluetooth
keyboard, detachable Surface, iPad + Magic Keyboard. The existing
`_mobileDefault` gate flipped Enter to newline on every such device the
moment the visual-viewport heuristic *thought* the soft keyboard was
open, which it often did when the on-screen IME hadn't actually come up
because the user is typing on the hardware keys. Result: Shift+Enter and
Ctrl+Enter never sent and the user could not submit at all.

Add `_hasFinePointerCoexisting()` (`(any-pointer:fine)`) and short-
circuit the mobile-default path when ANY fine pointer is present. That
flag is true whenever a real mouse/trackpad/stylus is paired, which is
the strongest browser signal we have for 'there is a hardware input rig
in the picture too'. Pure-touch phones/tablets are unaffected.
2026-05-29 03:26:12 -07:00
Sanjays2402 7c3d85d6c5 Fix #3107: throttle active-session external-refresh poll from 5s to 30s
The active-session 'is it externally updated?' fallback poll fires every
5 s. On long sessions this causes visible scroll churn (the rendered
message list is rebuilt and the scrollTop is restored on a 5-second
cadence) and a measurable network/CPU floor even when the user is just
reading.

This poll is a *fallback* for the case where the SSE session-events
stream is unavailable; SSE already invalidates the active session in
real time. Pushing it to 30 s keeps the safety net for SSE-broken
environments without it acting as a primary refresh path.

Regression introduced in 467ef33a.
2026-05-29 03:25:49 -07:00
Dennis Soong f5dc9477ff fix: submit composer on numpad enter 2026-05-29 13:00:15 +08: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 1a6409764a Merge PR #3093
# Conflicts:
#	CHANGELOG.md
2026-05-28 19:49:34 +00:00
nesquena-hermes f7b4c6b0f4 Merge PR #3087
# Conflicts:
#	CHANGELOG.md
2026-05-28 19:38:10 +00:00
theseussss b554fd8078 fix(reasoning): 推理强度补齐 max 档,与 hermes_constants 对齐
WebUI 镜像的 VALID_REASONING_EFFORTS 此前止于 xhigh,漏了底层
hermes_constants 已有的 max 档。补齐后端常量、前端命令/下拉/帮助文本,
并同步快照测试。支持 max thinking 的 provider(如 Anthropic)现可在
composer 下拉和 /reasoning 命令中选到 Max。
2026-05-29 03:05:02 +08:00
AJV20 2cb3c9f10b Merge remote-tracking branch 'origin/master' into HEAD
# Conflicts:
#	CHANGELOG.md
#	tests/test_workspace_git.py
2026-05-28 14:50:33 -04: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
AJV20 cf6e3111c4 Merge remote-tracking branch 'origin/master' into fix/webui-bugfix-sweep
# Conflicts:
#	CHANGELOG.md
2026-05-28 13:56:00 -04:00
nesquena-hermes a3fc305aeb Merge PR #3077
# Conflicts:
#	CHANGELOG.md
#	tests/test_webui_gateway_chat_backend.py
2026-05-28 17:47:56 +00:00
nesquena-hermes 1c89c7d327 Merge PR #3064
# Conflicts:
#	CHANGELOG.md
2026-05-28 17:47:35 +00:00
nesquena-hermes c642c1e438 Merge PR #3069
# Conflicts:
#	CHANGELOG.md
2026-05-28 17:47:34 +00:00
nesquena-hermes 83f8080103 Merge PR #3053
# Conflicts:
#	CHANGELOG.md
2026-05-28 17:47:34 +00:00
AJV20 60d4b2d990 fix: harden WebUI bugfix sweep 2026-05-28 13:38:50 -04:00
nesquena-hermes 2107160bf7 Merge PR #3054
# Conflicts:
#	CHANGELOG.md
2026-05-28 16:11:16 +00:00
nesquena-hermes 2443db60b6 Merge PR #3071
# Conflicts:
#	CHANGELOG.md
2026-05-28 16:11:15 +00:00
AJV20 923b719ed1 fix: surface gateway auth errors in browser 2026-05-28 11:12:58 -04:00
AJV20 0f26b99a11 fix: preserve clarify fallback ownership 2026-05-28 08:35:26 -04:00
AJV20 9e69db9920 fix: show cron sessions in project filter 2026-05-28 08:10:15 -04:00
Frank Song 10573ab8aa Fix session media image rendering 2026-05-28 18:05:01 +08:00
ai-ag2026 c197e0c091 fix: allow current-pane SSE reconnect when unfocused 2026-05-28 09:02:06 +02:00
ai-ag2026 2ee249112a fix: defer streaming KaTeX for pending equations 2026-05-28 08:56:34 +02:00
Frank Song 9ddf36f510 fix: reset _messagesTruncated flag on new session creation
newSession() did not reset _messagesTruncated or _oldestIdx, unlike
loadSession() which resets both at line 590. When a user switched from
a long session (messages > _INITIAL_MSG_LIMIT) to a new session, the
stale _messagesTruncated=true caused renderMessages() to show the
'Scroll up or click to load older messages' indicator on a fresh
conversation with only 1 message.

Add the same reset that loadSession() already performs so newSession()
starts with clean pagination state.
2026-05-28 12:13:30 +08:00
Dennis Soong 5f901f579a fix: suppress timeout toasts for passive pollers 2026-05-28 11:13:00 +08:00
Florian Krause 8408a3dd22 fix: reattach SSE on session-switch return + close leaked stream connections (#2925)
Squash-merged pr-2925 into stage-batch33. Closes #2924.
2026-05-28 02:48:17 +00:00
Dustin afc8aea4b4 ux(composer): cap composer-box max-width at 1600px on ultrawide viewports (#2946)
Squash-merged pr-2946 into stage-batch33.
2026-05-28 02:47:30 +00:00
nesquena-hermes 7006bb5c7a Merge pull request #3008 2026-05-28 01:43:22 +00:00
nesquena-hermes 0614ca63d8 Merge pull request #3010 2026-05-28 01:24:17 +00:00
sunilkumarvalmiki b14ef7735f Fix workspace save icon contrast 2026-05-27 19:17:46 +05:30
ai-ag2026 ffd9f337b1 fix(chat): scope settled stream cleanup to source 2026-05-27 09:10:43 +02:00
BonyFish 9141a55ae0 fix test error 2026-05-27 15:05:47 +08:00
BonyFish 3a676b704a feat: add skill usage counter to insights page
- Add api/skill_usage.py for .usage.json read/write with atomic updates
- Track skill_view (view_count), skill_manage (use_count), skill_patch
  (patch_count) invocations per SSE stream completion
- Add GET /api/skills/usage endpoint returning per-skill usage stats
- Render Skill Usage card in Insights panel after LLM Wiki card
- Add i18n keys for en, zh, zh-Hant, ja, it locales
- Add 17 tests covering read/increment logic, API route, and streaming hook
2026-05-27 14:44:28 +08:00
Frank Song 8ab9235e00 Preserve server running state in sidebar merge 2026-05-27 12:29:57 +08:00
nesquena-hermes 540993ccaf Merge pull request #2938
# Conflicts:
#	CHANGELOG.md
2026-05-27 04:21:45 +00:00
BonyFish ea3d4ec0b3 feat(cron): dynamic delivery options from API instead of hardcoded select
Replace the hardcoded 4-option deliver dropdown (local/discord/telegram/slack)
with a dynamic select populated from a new GET /api/crons/delivery-options
endpoint that reads _KNOWN_DELIVERY_PLATFORMS from hermes-agent.

Key changes:
- Add GET /api/crons/delivery-options endpoint returning all known platforms
- Frontend loads options asynchronously on first cron form open, with caching
- Enable deliver editing for existing jobs (was previously disabled)
- Include deliver in update payload when editing cron jobs
- Fallback to local-only if API unavailable
- Custom deliver values (e.g. feishu:oc_xxx) shown with * suffix
- Add cron_deliver_custom i18n key to all 12 locales
- Add 5 integration tests for the new endpoint
2026-05-27 10:58:49 +08:00
nesquena-hermes 2d7d2cb31d Merge pull request #2958
# Conflicts:
#	CHANGELOG.md
2026-05-27 00:38:58 +00:00