Commit graph

1395 commits

Author SHA1 Message Date
Michael Lam
ecdbc8d4df fix: prevent sticky sidebar hover drag state 2026-05-05 19:17:27 -07:00
nesquena-hermes
d8cd5567e0
Merge pull request #1723 from nesquena/docs/1695-aiagent-troubleshooting
docs(troubleshooting): bake the #1695 diagnostic flow into the error message + a new troubleshooting doc
2026-05-05 15:16:08 -07:00
nesquena-hermes
29878259ca docs(troubleshooting): bake the #1695 diagnostic flow into the error message + a new troubleshooting doc
Closes #1695.

@Patrick-81 reported the bare "AIAgent not available -- check that
hermes-agent is on sys.path" error on a symlinked install (~/Programmes/hermes-agent
linked to ~/hermes-agent). The maintainer's response — three diagnostic
commands plus `pip install -e .` in the agent dir — fixed it for them.
This PR captures both halves of that learning so the next user with the
same shape doesn't have to file a new issue:

1. **Error message diagnostic block.** New helper
   `_aiagent_import_error_detail()` in api/streaming.py builds a multi-line
   diagnostic when the import fails, including:
     - the running Python interpreter
     - HERMES_WEBUI_AGENT_DIR (set value, or "(not set)")
     - sys.path entries that mention hermes/agent (or "no entries mention..."
       — itself a strong diagnostic signal)
     - the most-common fix (`pip install -e .` in the agent dir)
     - a pointer to docs/troubleshooting.md

   The original error message string is preserved as the FIRST line so
   existing log scrapers and docs-search keep matching.

   Helper is kept as a separate function so it stays out of the hot path
   until we actually need to raise — building it on every successful import
   would be wasted work.

2. **New docs/troubleshooting.md.** Symptom → Why → Diagnostic commands →
   Fix → When-to-file-a-bug template, with one entry to start: the
   "AIAgent not available" flow Patrick-81 walked through. Future
   recurring failure modes follow the same template. Required a one-line
   addition to .gitignore — docs/* is gitignored with an allowlist, and
   the new file needed `!docs/troubleshooting.md` to be tracked.

3. **README link.** docs/troubleshooting.md added to the `## Docs` section
   so users know where to look first.

13 regression tests in tests/test_1695_aiagent_import_error_detail.py:
9 for the helper output shape (preserves original message line, includes
running python, shows HERMES_WEBUI_AGENT_DIR set/unset both ways, includes
pip-install-e hint, points at troubleshooting doc, lists relevant sys.path
entries when present, says "no entries..." when absent, output is multi-line)
plus 4 for the docs-presence regression (file exists, has the AIAgent
section, includes pip install -e ., describes the diagnostic chain with
readlink + agent/__init__.py verification).

190 streaming/aiagent tests pass after the change. ast.parse on
api/streaming.py clean.

CI failure on prior push was due to the docs/* gitignore swallowing the
new troubleshooting.md file silently — this commit adds the allowlist
entry so the file is tracked.
2026-05-05 22:14:07 +00:00
nesquena-hermes
a6e2bbb263
Merge pull request #1724 from nesquena/stage-303
v0.51.6 — 5-PR full-sweep batch
2026-05-05 15:11:06 -07:00
Nathan Esquenazi
23bca0d955 chore(release): stamp v0.51.6 — 5-PR full-sweep batch
5 PRs (1 surface addition, 4 fixes):
- #1717 preserve imported session lineage (@ai-ag2026)
- #1718 preserve Activity count across focus changes (@Michaelyklam, closes #1715)
- #1719 elapsed timer in compact activity (@Michaelyklam, closes #1716)
- #1720 backend tool snippet cap raised to 4000 (@Michaelyklam, closes #1714)
- #1722 suppress stale preserved task lists (@ai-ag2026)

Tests: 4527 → 4537 (+10). Opus: SHIP, 6/6 verification clean.

Co-authored-by: ai-ag2026 <noreply@github.com>
Co-authored-by: Michael Lam <Michaelyklam1@gmail.com>
2026-05-05 22:09:08 +00:00
Nathan Esquenazi
b6567addb1 Stage 303: PR #1719 2026-05-05 21:58:21 +00:00
Nathan Esquenazi
cbdf770d36 Stage 303: PR #1722 2026-05-05 21:58:21 +00:00
Nathan Esquenazi
afe0c26df9 Stage 303: PR #1720 2026-05-05 21:58:21 +00:00
Nathan Esquenazi
220bd50795 Stage 303: PR #1717 2026-05-05 21:58:21 +00:00
Nathan Esquenazi
fb9823ea2e Stage 303: PR #1718 2026-05-05 21:58:20 +00:00
ai-ag2026
b66e720673 fix: suppress stale preserved task lists
Hide preserved compression task lists when the latest todo tool state
shows no pending or in-progress items. This prevents completed tasks from
reappearing after reloads or context compaction.

Tests: uv run --with pytest --with pyyaml python -m pytest -q tests/test_auto_compression_card.py
Tests: node --check static/ui.js
2026-05-05 23:00:18 +02:00
Michael Lam
f97b040985 fix: raise persisted tool snippet cap 2026-05-05 13:46:54 -07:00
Michael Lam
2c5acb9725 feat: show active elapsed timer in compact activity 2026-05-05 13:42:47 -07:00
Michael Lam
dd2bc38473 fix: preserve activity count across chat focus changes 2026-05-05 13:42:45 -07:00
ai-ag2026
8b34a79f02 fix: preserve imported session lineage visibility 2026-05-05 22:32:19 +02:00
nesquena-hermes
0ea3dfbdd1
Merge pull request #1713 from nesquena/stage-302
v0.51.5 — 4-PR full-sweep batch
2026-05-05 11:00:37 -07:00
Nathan Esquenazi
b59c6975a2 chore(release): stamp v0.51.5 — 4-PR full-sweep batch
4 PRs (1 surface addition, 3 fixes):
- #1688 VPS resource health Insights panel (@Michaelyklam, closes #693)
- #1709 preserve scroll on stream completion (@Michaelyklam, closes #1690)
- #1711 hide rename tooltip on folders (@nesquena-hermes, closes #1710)
- #1712 guard localStorage.setItem against QuotaExceededError (@24601)

Tests: 4504 → 4527 (+23). Opus: SHIP, 6/6 verification clean.

Held back: #1686 (Docker enhance) — Opus flagged sibling-repo dep that
breaks standalone clones. Left open for follow-up.

Co-authored-by: Michael Lam <Michaelyklam1@gmail.com>
Co-authored-by: 24601 <noreply@github.com>
2026-05-05 17:54:15 +00:00
test
b59164b0a8 Stage 302: PR #1688 2026-05-05 17:31:01 +00:00
Michael Lam
fe9e4645ac fix: move system health panel into insights 2026-05-05 17:30:56 +00:00
Michael Lam
fdeac578da feat: add VPS resource health panel 2026-05-05 17:30:56 +00:00
Nathan Esquenazi
967f7876e9 Stage 302: PR #1709 2026-05-05 17:29:47 +00:00
Nathan Esquenazi
77052fd4ec Stage 302: PR #1711 2026-05-05 17:29:47 +00:00
Nathan Esquenazi
bedcc41b08 Stage 302: PR #1712 2026-05-05 17:29:47 +00:00
Basit Mustafa
9a0a6214cf fix: guard localStorage.setItem('hermes-webui-model') against QuotaExceededError
On some setups the localStorage quota is exhausted; the bare setItem
call throws an unhandled DOMException that breaks model selection and
prevents the chat UI from loading.

Wrap both call-sites (boot.js model-select onChange, onboarding.js
_saveOnboardingDefaults) in try/catch so the error is logged to the
console as a warning instead of surfacing as a fatal exception.

Fixes: 'Failed to execute setItem on Storage: Setting the value of
hermes-webui-model exceeded the quota.'
2026-05-05 17:29:47 +00:00
nesquena-hermes
d3c8a7c6a5 fix(workspace): hide 'Double-click to rename' tooltip on folders (#1710)
The file-tree row tooltip says 'Double-click to rename' on every entry,
but folders don't actually rename on double-click — they navigate via
loadDir(). The tooltip is therefore misleading on directory rows.

Reported by @Deor in the WebUI Discord testers thread (May 5 2026):
'Ah that works yeah. May want to change the popup text as it also says
double click at the moment.'

Fix: gate the tooltip on item.type !== 'dir' so it only attaches to file
rows, where double-click does what the hint advertises. Folder rename
still reachable via the right-click context menu (unchanged).

Companion to #1698/#1702/#1707 — completes the rename-affordance triage:
- #1698 fixed: dblclick rename was unreachable on files (preview hijacked)
- #1707 fixed: single-click on filename did nothing (over-aggressive guard)
- #1710 (this PR): tooltip claimed dblclick-rename on folders too

Closes #1710

Tests: 4 source-level regression tests in tests/test_1710_folder_tooltip.py
guard the gate, the unchanged dir-dblclick navigate behaviour, the i18n key,
and that files still receive the tooltip. All 13 file-tree handler tests
(4 new + 9 from #1707) pass.
2026-05-05 16:41:30 +00:00
Michael Lam
311e69b0ba fix: preserve scroll on stream completion 2026-05-05 09:23:29 -07:00
nesquena-hermes
cebca4700b
Merge pull request #1708 from nesquena/fix/1707-workspace-name-click
fix(workspace): preserve single-click open + double-click rename on filename (#1707)
2026-05-05 09:16:42 -07:00
nesquena-hermes
b5e8e67d71 fix(workspace): preserve single-click open + double-click rename on filename (#1707)
Closes #1707 — single-click on a workspace tree filename did nothing.

#1698 was a regression where the filename's dblclick rename handler was
unreachable because the row's el.onclick (openFile) fired synchronously
on the first click. The fix in #1702 stopped click propagation on nameEl
— but that broke single-click activation entirely (#1707): clicking the
filename now did nothing, you had to click the icon or row whitespace
to open the file.

Restored fix preserves both intents via a 300ms debounced delegator:

  let _nameClickTimer = null;
  nameEl.onclick = (e) => {
    e.stopPropagation();
    if (_nameClickTimer) { clearTimeout(_nameClickTimer); _nameClickTimer = null; }
    _nameClickTimer = setTimeout(() => {
      _nameClickTimer = null;
      if (typeof el.onclick === 'function') el.onclick(e);
    }, 300);
  };
  nameEl.ondblclick = (e) => {
    e.stopPropagation();
    if (_nameClickTimer) { clearTimeout(_nameClickTimer); _nameClickTimer = null; }
    // ... existing rename body
  };

Single-click on nameEl schedules a setTimeout that calls el.onclick(e)
after the dblclick threshold passes (300ms — matches the OS dblclick
threshold on most platforms). Double-click cancels the pending timer
and triggers the existing rename input.

Cost: 300ms latency on file-open clicks. Acceptable trade for keeping
rename reachable on single-click.

Also updated tests/test_workspace_tree_rename.py to accept both the
pre-#1707 (pure stopPropagation) and post-#1707 (debounced delegator)
shapes — the original assertion was too narrow and would have rejected
the correct fix.

9 new regression tests in tests/test_1707_workspace_filename_click.py:
  - 6 source-level static-analysis checks on the patched handler shape
  - 3 behavioral tests via Node VM (synthesize click → 300ms delay,
    click → dblclick within tick → assert rename mounts + openFile
    is not called).

7 of 9 tests fail on master pre-fix (verified); all 9 pass after.
2026-05-05 16:13:58 +00:00
nesquena-hermes
4daa23874a
Merge pull request #1707 from nesquena/stage-301
v0.51.4 — 10-PR full-sweep batch
2026-05-05 08:56:38 -07:00
Nathan Esquenazi
451c946a30 chore(release): stamp v0.51.4 — 10-PR full-sweep batch
10 PRs (3 surfaces additions, 7 fixes):
- #1644 model picker chip + group count (@bergeouss, closes #1425)
- #1684 update network failures UX (@Michaelyklam, closes #1321)
- #1685 Codex spark models (@Michaelyklam, closes #1680)
- #1689 normalize profile base homes (@Michaelyklam, refs #749)
- #1693 adaptive title refresh deadlock (@ai-ag2026)
- #1701 normalize update banner URL (@Michaelyklam, closes #1691)
- #1702 workspace double-click rename (@Michaelyklam, closes #1698)
- #1703 cache invalidation on auth-store drift (@Michaelyklam, closes #1699)
- #1704 markdown fence lengths (@Michaelyklam, closes #1696)
- #1706 multi-image paste fix (@Michaelyklam, closes #1697)

Tests: 4477 → 4503 (+26). Opus: SHIP, 7/7 verification clean.

Co-authored-by: Michael Lam <Michaelyklam1@gmail.com>
Co-authored-by: ai-ag2026 <noreply@github.com>
Co-authored-by: bergeouss <noreply@github.com>
2026-05-05 15:54:12 +00:00
Nathan Esquenazi
2a838ee95a Stage 301: PR #1706 2026-05-05 15:49:28 +00:00
Michael Lam
8c8e2d3573 fix: keep multi-image paste attachments 2026-05-05 08:45:14 -07:00
Nathan Esquenazi
e5927c6d0a Stage 301: PR #1704 2026-05-05 15:41:44 +00:00
Nathan Esquenazi
debb4c5282 Stage 301: PR #1702 2026-05-05 15:41:43 +00:00
Nathan Esquenazi
8e7a9b1632 Stage 301: PR #1684 2026-05-05 15:41:43 +00:00
Nathan Esquenazi
651cd294d4 Stage 301: PR #1644 2026-05-05 15:41:43 +00:00
Nathan Esquenazi
a66feb2661 Stage 301: PR #1703 2026-05-05 15:41:43 +00:00
Nathan Esquenazi
08ea4fbc05 Stage 301: PR #1685 2026-05-05 15:41:43 +00:00
Nathan Esquenazi
bf8b5edc23 Stage 301: PR #1701 2026-05-05 15:41:43 +00:00
Nathan Esquenazi
db972afd99 Stage 301: PR #1693 2026-05-05 15:41:43 +00:00
Nathan Esquenazi
9dddb5b1d5 Stage 301: PR #1689 2026-05-05 15:41:43 +00:00
bergeouss
6173d6d0ea fix(ui): inline provider chip + group model count in model picker (#1425)
- Add .model-opt-provider chip (right-aligned, muted) on every model row
  that belongs to a provider group, making same-name models across
  providers visually distinguishable at a glance.
- Add per-group model count to group headings: 'OpenRouter (47)'.
- Add subtle border-top divider between provider groups for visual
  separation during scroll.

Scope: Shape A from #1425 — smallest change, ~15 LOC, no API churn.
Note: Settings model picker is a native <select> and already has optgroup
labels; this targets the custom dropdown used in the composer.

Closes #1425
2026-05-05 15:41:22 +00:00
Michael Lam
1997a48c81 test: keep model cache drift regression hermetic 2026-05-05 08:38:29 -07:00
Michael Lam
f76921d322 fix: honor markdown fence lengths 2026-05-05 08:36:17 -07:00
Michael Lam
c4ef5b6945 fix: invalidate model cache on auth-store drift 2026-05-05 08:33:44 -07:00
Michael Lam
ff232493ce fix: keep workspace rename double-click reachable 2026-05-05 08:33:34 -07:00
Michael Lam
dc7ba0c845 fix: normalize update banner repository URLs 2026-05-05 08:29:00 -07:00
Manfred
52e7916cb8 fix: avoid adaptive title refresh session lock deadlock 2026-05-05 12:51:13 +02:00
Michael Lam
d51510a7dc fix: keep HTTP update errors out of network recovery 2026-05-05 03:13:55 -07:00
Michael Lam
f6a532d7f0 fix: normalize named profile base homes 2026-05-05 00:00:29 -07:00