8 Commits
Author SHA1 Message Date
hermes-agent 2b2dd23e03 chore(release): stamp v0.51.21 — 3-PR batch (P0 hotfix + auto-compression UI + shell HTML fallback)
3 PRs across kanban (#1843: P0 hotfix for v0.51.20 #1828's double-404
JSON corruption on the wire), streaming (#1838: SSE compressing event
bridge for auto-compression running state), and shell route (#1836:
HTML 503 fallback so / never returns JSON during restart races).

In-stage absorb:
- api/kanban_bridge.py: documented handle_kanban_* three-valued return
  contract with bool|None type annotations + docstring after PR #1843
  made False-vs-None load-bearing for the caller's 404 decision.

4805 → 4810 collected (+5). 4799 pass + 8 skip + 1 xfail + 2 xpass.
Browser API harness 11/11 green. JS syntax 1/1 clean.
Opus advisor SHIP verdict, 1 absorbed in-release, 1 deferred to follow-up.

Closes #1832, #1835. Hotfix for v0.51.20 #1828.
2026-05-07 18:53:37 +00:00
hermes-agent 5f6a55185c stage-315 absorb: document handle_kanban_* three-valued return contract
Per Opus pre-release verdict on PR #1843: the four handle_kanban_*
entry points declare '-> bool' but actually return True | None | False
(after PR #1843 made the False-vs-None distinction load-bearing for
the caller's '_kanban_unknown_endpoint' decision). Update the type
annotations to 'bool | None' and add a docstring on handle_kanban_get
(with cross-references on the three siblings) so a future contributor
adding a new return path doesn't accidentally produce a 0/'' value
that would silently revert the double-404 fix.

Test-only verification: kanban tests pass (49/49). Production behavior
unchanged. Cheap defensive cleanup per Nathan's standing absorb-in-release
default for ≤20-LOC documentation/type-annotation fixes.
2026-05-07 18:52:01 +00:00
hermes-agent ab348219ff chore(release): stamp v0.51.20 — 5-PR follow-on batch + 2 in-stage absorbs
5 contributor PRs across Kanban (#1828: stale-client recovery + hard-refresh
button + board-pointer drift fix), providers (#1827: Codex card live+cache
merge enhancing v0.51.19 #1812), cron (#1826: no-agent edits without prompt),
and workspace UI (#1825: cruft filter; #1822: heading root actions).

In-stage absorbs:
- static/panels.js: removed duplicate loadKanbanBoards tail call to avoid
  doubling /api/kanban/boards traffic under SSE-driven refreshes.
- tests/test_issue1807_codex_provider_card_live_models.py: CODEX_HOME
  isolation for v0.51.19 tests now load-bearing under PR #1827's cache merge.

Parallel-discovery resolution: #1821 (ai-ag2026, leaner) closed as
superseded by #1826 (Michaelyklam, more thorough — Mode badge,
disabled-prompt, i18n hint, screenshot).

4790 → 4805 collected (+15). 4794 pass + 8 skip + 1 xfail + 2 xpass.
Browser API harness 11/11 green. JS syntax 3/3 clean.
Opus advisor SHIP verdict, 1 absorbed in-release, 4 deferred to follow-ups.

Closes #1786, #1793, #1820, #1823.
2026-05-07 18:23:59 +00:00
hermes-agent a1eec6d191 stage-314 absorb: remove duplicate loadKanbanBoards tail call in loadKanban
PR #1828 added an await loadKanbanBoards() at the START of loadKanban() to
resolve the active board before board-scoped requests fire (so a stale saved
slug can fall back to default cleanly). The existing tail-of-function refresh
at line 1278 was harmless under one-time loads but doubles /api/kanban/boards
traffic under SSE-driven refreshes (debounced at 250ms via
_scheduleKanbanRefresh). The 30-second polling interval started by
_kanbanStartPolling() picks up any board state changes that arrive after
the render, so the tail call is redundant in PR #1828's new model.

Per Opus pre-release verdict: SHIP with this perf cleanup as in-release
absorb (5 LOC delta, clearly defensive, no behavior change for the
single-load case).
2026-05-07 18:21:56 +00:00
hermes-agent d69d0eb35b stage-314 absorb: isolate CODEX_HOME in v0.51.19 codex provider card tests
PR #1827 introduced _read_visible_codex_cache_model_ids() merging
into the providers card live-fetch path. The two v0.51.19 tests in
tests/test_issue1807_codex_provider_card_live_models.py predate that
helper and didn't isolate CODEX_HOME, so the dev machine's real
~/.codex/models_cache.json (which contains entries like
gpt-5.3-codex-spark from #1680) was leaking into their assertions.

Add CODEX_HOME isolation in the existing _configure_codex helper —
matches the pattern PR #1827's own test already uses. Test-only fix;
production code unchanged. Caught by pre-release pytest gate.
2026-05-07 18:09:40 +00:00
hermes-agent 0ed63968b6 Stage 314: PR #1827 — sync Codex provider card models with picker by @Michaelyklam
Note: PR #1827 was branched before v0.51.19 shipped #1812, which
introduced an initial (pure live-fetch) Codex provider card hook in
api/providers.py at the same line range. The contributor's PR was
filed AFTER #1812 shipped but their diff didn't yet account for it.
Stage 314 absorbs the contributor's intent (visible Codex cache
merge for gpt-5.3-codex-spark visibility) by replacing the v0.51.19
hook with the richer merged version directly in stage. Production
code change ≡ what the contributor's PR would have produced if
rebased onto current master. Test file + pr-media adopted verbatim.
Marker commit so the stage log makes the absorption visible.
2026-05-07 17:58:52 +00:00
hermes-agent b0407f9373 chore(release): stamp v0.51.19 — 15-PR contributor sweep + 1 in-stage absorb
- 15 contributor PRs across backend (workspace, IPv6, bootstrap pair,
  named custom provider routing, quota cards, live Codex models),
  frontend (sessions trio: optimistic-row preservation, cross-surface
  continuation, session-owned approval prompts; ui trio: workspace
  metadata strip, error toast Copy + hover-pause, file picker + HTML
  preview interactions), streaming (workspace-prefix dedupe), and
  ops (workspace user-turn repair script).
- 1 in-stage absorb on api/config.py: gate _resolve_configured_provider_id
  alias resolution behind resolve_alias flag so resolve_model_provider
  preserves raw provider strings for #1625 _LOCAL_SERVER_PROVIDERS
  literal-match.
- 1 in-stage test absorb on test_bootstrap_discover_agent.py: pin
  Path.home() in isolation helper so PR #1817 tests don't pick up
  the dev machine's real ~/.hermes/hermes-agent.
- 4747 → 4790 collected (+43). 4776 pass + 11 skip + 1 xfail + 2 xpass.
- Browser API harness 11/11 green. JS syntax 5/5 clean.
- Opus advisor SHIP verdict, 0 MUST-FIX, 0 SHOULD-FIX in-release.

Closes #1792, #1795, #1796, #1800, #1806, #1807, #1694.
2026-05-07 17:31:42 +00:00
hermes-agent 1f702c7569 stage-313 absorb: gate _resolve_configured_provider_id alias resolution + harden bootstrap test isolation
Two in-stage fixes for v0.51.19 batch:

1) api/config.py — add resolve_alias=False param to
   _resolve_configured_provider_id() and pass it from
   resolve_model_provider(). The PR #1818 swap from
   _resolve_provider_alias() to _resolve_configured_provider_id()
   was correct for active-provider/badge surfaces but broke #1625's
   local-server-provider literal-preservation contract: 'ollama' →
   'custom' and 'lm-studio' → 'lmstudio' alias-collapse caused
   _LOCAL_SERVER_PROVIDERS membership check to miss, breaking the
   model-id full-path preservation for LM Studio/Ollama. The new
   flag preserves the raw provider value when called from
   resolve_model_provider, and named-custom-slug + base-url
   fallback both still run unchanged.

2) tests/test_bootstrap_discover_agent.py — pin Path.home() in
   _isolate_discover_agent_dir so the hard-coded
   'Path.home() / .hermes / hermes-agent' / 'Path.home() /
   hermes-agent' candidates in discover_agent_dir() can't pick up
   the dev machine's real install. The original PR #1817 isolation
   helper covered HERMES_HOME, HERMES_WEBUI_AGENT_DIR, and
   REPO_ROOT but missed the Path.home() leak.

Both surfaced on full pytest pre-release gate, fixed in stage,
ship in v0.51.19. Tests: full suite green.
2026-05-07 17:07:48 +00:00