nesquena-hermes
4f1623520d
feat: clarify dialog flow and refresh recovery ( #520 ) - merge PR #522
2026-04-15 07:27:57 +00:00
Hermes Agent
505bfc6a9a
feat: clarify dialog flow and refresh recovery ( #520 )
...
Implements and stabilizes the clarify dialog UX in Hermes WebUI.
New clarify state module (api/clarify.py):
- Per-session pending queue with threading.Event unblocking
- Gateway notify registration/unregistration
- Duplicate clarify deduplication while unresolved
- resolve/clear helpers
New clarify HTTP endpoints (api/routes.py):
- GET /api/clarify/pending
- POST /api/clarify/respond
- GET /api/clarify/inject_test (loopback-only, for tests)
Streaming integration (api/streaming.py):
- clarify_callback wired to AIAgent.run_conversation()
- SSE 'clarify' event emitted to WebUI
- Blocks tool flow until response/timeout/cancel
- 409 guard: session already has an active stream returns active_stream_id
- MCP lazy discovery on first stream start
Frontend (static/messages.js, ui.js, sessions.js, index.html, style.css, i18n.js):
- Clarify card with numbered choices + Other + free-text input
- Composer lock while clarify is active
- DOM self-healing if card node is removed during rerender
- SSE 'clarify' event listener + fallback polling (1.5s interval)
- Session switch / reconnect stops/starts clarify polling
- 409 conflict: reattaches to active stream and queues user input
- CLARIFY_MIN_VISIBLE_MS = 30000 timer dedup (mirrors approval card pattern)
- i18n keys in en/es/de/zh-Hans/zh-Hant locales
Tests:
- tests/test_clarify_unblock.py: 14 new tests (queue, callbacks, HTTP endpoints)
- tests/test_sprint30.py: 31 new clarify tests (HTML, CSS, i18n, JS, streaming)
- tests/test_sprint36.py: expand search window (stopClarifyPolling pushes setBusy further)
Total tests: 1246 (was 1209)
Co-authored-by: franksong2702 <138988108+franksong2702@users.noreply.github.com >
2026-04-15 07:25:52 +00:00
Hermes Agent
1bd0341243
fix: expand test_sprint36 search window for setBusy after stopClarifyPolling additions
2026-04-15 07:24:53 +00:00
Frank Song
ccba2f5c01
feat: harden clarify dialog flow and refresh recovery
2026-04-15 13:10:50 +08:00
nesquena-hermes
45d3dc0f68
fix: suppress N/A source_tag in session list sidebar ( fixes #429 )
...
fix: suppress N/A source_tag in session list sidebar (fixes #429 )
2026-04-14 15:15:05 -07:00
nesquena-hermes
69cd0832de
fix: suppress N/A source_tag in session list sidebar ( fixes #429 )
...
fix(renderer): extend _al_stash to include <img> tags — fixes broken image rendering
2026-04-14 15:14:57 -07:00
Hermes Agent
7b9f08c774
fix: suppress N/A source_tag in session list sidebar ( #429 )
...
- sessions.js _formatSourceTag(): return null for unrecognised tags
instead of raw string — prevents legacy 'N/A' values from surfacing
- sessions.js metaBits push: guarded with _stLabel null check so only
known platform labels appear in the session metadata line
- sessions.js [SYSTEM:] title fallback: drop raw s.source_tag middle
term, fall back directly to 'Gateway' for unknown sources
7 new tests in test_issue429.py.
1 updated test in test_sprint40_ui_polish.py (new guarded push pattern).
Closes #429
2026-04-14 22:14:31 +00:00
Hermes Agent
2810233af4
fix(renderer): extend _al_stash to include <img> tags, preventing autolink from mangling src= URLs
...
Bug: the autolink pass stashed <a> tags (via _al_stash) before running,
but did not stash <img> tags. When  was converted to an <img>
tag by the image pass, the subsequent autolink regex matched the URL
inside src="..." and wrapped it in <a href="...">url</a>, producing
src="<a href="...">url</a>" — a completely broken image source.
Fix: extend the _al_stash regex from:
(<a\b[^>]*>[\s\S]*?<\/a>)
to:
(<a\b[^>]*>[\s\S]*?<\/a>|<img\b[^>]*>)
This stashes both <a> and self-closing <img> tags before autolink runs,
then restores them after, so the URL inside src= is never touched.
Adds 7 regression tests in tests/test_issue487b.py.
2026-04-14 22:09:36 +00:00
nesquena-hermes
642f4536f0
docs: update TESTING.md and ROADMAP.md to v0.50.44 / 1195 tests
...
docs: update TESTING.md and ROADMAP.md to v0.50.44 / 1195 tests
2026-04-14 15:06:29 -07:00
Hermes Agent
f0d49b5b59
docs: update TESTING.md and ROADMAP.md to v0.50.44 / 1195 tests
2026-04-14 22:06:11 +00:00
nesquena-hermes
e6447ebad2
fix: code-in-table CSS sizing + markdown image rendering ( fixes #486 , #487 )
...
fix: code-in-table CSS sizing + markdown image rendering (fixes #486 , #487 )
2026-04-14 14:52:59 -07:00
Hermes Agent
887893ecd1
fix: code-in-table CSS sizing + markdown image rendering ( #486 , #487 )
...
- static/style.css: add td code / th code rules (font-size 0.85em,
padding 1px 4px, vertical-align baseline) for both .msg-body and
.preview-md to fix cramped inline code in table cells (#486 )
- static/ui.js inlineMd(): add image pass ( → <img
class=msg-media-img>) running while _code_stash is active (protects
image syntax inside backticks), add _img_stash (\x00G) to shield
rendered <img> src= from autolink, add img to SAFE_INLINE (#487 )
- static/ui.js renderMd() outer: add image pass before outer link pass
for images in plain paragraphs, add img to SAFE_TAGS allowlist (#487 )
- tests/test_issue486_487.py: 45 new tests covering CSS source checks,
JS source structure, rendering behaviour, and combination edge cases
(code + image + link in same table cell, image inside code span, etc.)
Closes #486 , closes #487
2026-04-14 21:52:34 +00:00
nesquena-hermes
75de03c99f
Merge pull request #478 from nesquena/release/v0.50.43
...
release: v0.50.43 — markdown rendering fixes + KaTeX CSP
2026-04-14 14:23:38 -07:00
Hermes Agent
d8ab326b73
fix(renderer): fix two remaining renderMd issues found during browser QA
...
1. ** inside was corrupted** — the outer bold/italic pass at line 480 ran
after the outer backtick→<code> pass at line 457, causing esc() to corrupt <code> tags
into <code> inside <strong>. Fix: add _ob_stash to protect <code> tags from
the outer bold/italic pass.
2. **Table cells with [label](url) produced double <a> tags** — the outer [label](url) pass
ran BEFORE the table regex, converting links to <a> tags in the raw table source.
Then inlineMd() processed those <a> tags again and autolink re-linked the URL inside
href="...". Fix: moved the outer link pass to AFTER the table pass so table cells
get their links from inlineMd() only, which has its own _link_stash protection.
2026-04-14 21:22:20 +00:00
Hermes Agent
7753e954e5
docs: correct v0.50.43 test count to 1150
2026-04-14 21:15:46 +00:00
Hermes Agent
2343dc1d85
docs: v0.50.43 CHANGELOG + version bump (test count TBD)
2026-04-14 21:15:02 +00:00
Hermes Agent
85f1017514
fix(csp): allow cdn.jsdelivr.net for font-src so KaTeX fonts load ( fixes #477 )
2026-04-14 21:14:33 +00:00
Hermes Agent
eb7ec5bac3
fix(renderer): backtick code spans inside bold/italic no longer get esc'd
2026-04-14 21:14:00 +00:00
Hermes Agent
b673006b7f
fix(renderer): address review feedback on PR #475
2026-04-14 21:13:53 +00:00
Nathan Esquenazi
5a79dd0dc9
fix: remove double semicolon in inlineMd link stash restore
2026-04-14 21:13:34 +00:00
Hermes Agent
0a570ada87
fix(renderer): prevent double-linking and esc() corruption in renderMd()
2026-04-14 21:13:33 +00:00
nesquena-hermes
53acc8e0e1
Merge pull request #476 from nesquena/release/v0.50.42
...
release: v0.50.42 — session display fixes + model UX polish (sprint 42)
2026-04-14 14:08:46 -07:00
Hermes Agent
34b98285a1
fix(ui): add custom option to <select> when model ID not in curated list (enables custom model IDs)
2026-04-14 21:06:23 +00:00
Hermes Agent
e228b1414f
fix(tests): shared helpers in test_sprint42.py; correct test count to 1130
2026-04-14 21:04:37 +00:00
Hermes Agent
bb445ffe9a
docs: v0.50.42 CHANGELOG, version bump (test count TBD)
2026-04-14 20:58:30 +00:00
Hermes Agent
2eb0679104
fix(tests): consolidate sprint-42 test_sprint42.py — all 20 tests in one file
2026-04-14 20:58:01 +00:00
Hermes Agent
12949a2771
feat(ui): add custom model ID input to model picker dropdown ( fixes #444 )
2026-04-14 20:56:56 +00:00
Nathan Esquenazi
7b0fb246ee
fix: merge duplicate const lastAsst declarations into single lookup
2026-04-14 20:56:54 +00:00
Hermes Agent
f86581e3e5
fix(ui): persist thinking/reasoning trace across page reload ( fixes #427 )
2026-04-14 20:56:53 +00:00
Hermes Agent
3c5ca2db62
fix(sessions): replace [SYSTEM: titles with platform name for gateway sessions ( fixes #441 )
2026-04-14 20:56:52 +00:00
Hermes Agent
c7381ee3f1
fix(ui): context indicator prefers latest usage over stale session data ( fixes #437 )
2026-04-14 20:56:50 +00:00
nesquena-hermes
32669f4a5b
Merge pull request #459 from nesquena/release/v0.50.41
...
release: v0.50.41 — MEDIA: inline image rendering in chat (fixes #450 )
2026-04-14 12:37:14 -07:00
Hermes Agent
c9a0e02301
docs: v0.50.41 CHANGELOG, version bump, test count (1117)
2026-04-14 19:36:14 +00:00
Hermes Agent
bfb9bbb0bf
fix: use _content_disposition_value() for RFC 5987 filename encoding in /api/media
2026-04-14 19:35:53 +00:00
Nathan Esquenazi
5507dae3d7
fix: restrict /api/media allowed roots — remove ~ (home dir)
2026-04-14 19:35:52 +00:00
Hermes Agent
0349df6ee4
feat(ui): render MEDIA: images inline in web UI chat ( fixes #450 )
2026-04-14 19:35:52 +00:00
nesquena-hermes
8c36203dd4
Merge pull request #457 from nesquena/release/v0.50.40
...
release: v0.50.40 — session UI polish, test port isolation, 6 bug fixes
2026-04-14 12:13:11 -07:00
Hermes Agent
c4d1e8c5d0
docs: correct v0.50.40 test count to 1098
2026-04-14 19:11:04 +00:00
Hermes Agent
c0c0195f7f
fix(tests): consolidate sprint-40 test file, fix module-scope vars, update sidebar-time assertion
2026-04-14 19:10:23 +00:00
Hermes Agent
8199fa333e
docs: v0.50.40 CHANGELOG and version bump (test count TBD)
2026-04-14 19:07:10 +00:00
Hermes Agent
77769750c2
fix(panels): apply profile default workspace to new session after profile switch ( fixes #424 )
2026-04-14 19:06:37 +00:00
Nathan Esquenazi
b3ad60d2c9
fix(routing): strip provider prefix from model ID when custom base_url is configured ( fixes #433 )
2026-04-14 19:06:35 +00:00
Nathan Esquenazi
85d8aad0ae
fix(ux): mute Telegram badge color and format source tag as display name ( fixes #442 )
2026-04-14 19:06:33 +00:00
Nathan Esquenazi
f1590fdb07
fix(sessions): return None instead of 'unknown' for missing gateway session model ( fixes #443 )
2026-04-14 19:06:22 +00:00
Nathan Esquenazi
3776b09f4a
fix(ui): active session title uses var(--gold) instead of hardcoded #e8a030 ( fixes #440 )
2026-04-14 19:05:26 +00:00
Hermes Agent
2400e14a31
fix(sidebar): hide session timestamps entirely to give titles full width
2026-04-14 19:04:49 +00:00
Nathan Esquenazi
69b0a905a4
fix(sidebar): move session timestamp below title to prevent truncation
2026-04-14 19:04:49 +00:00
Hermes Agent
c3251ea97d
fix(tests): auto-derive unique port+state-dir per worktree (fixes parallel pytest)
2026-04-14 19:04:48 +00:00
nesquena-hermes
924c833878
Merge pull request #448 from nesquena/release/v0.50.39
...
release: v0.50.39 — orphan session fix + first-password session continuity
2026-04-14 11:01:11 -07:00
Nathan Esquenazi
5fd7dc0c17
docs: v0.50.39 CHANGELOG, version bump, test count (1078)
2026-04-14 17:54:54 +00:00