Commit graph

2108 commits

Author SHA1 Message Date
nesquena-hermes
dbe58ffff5 changelog: preserve live Worklog through final settlement — no blank frame (#6473) 2026-07-30 18:06:22 +00:00
nesquena-hermes
f989c4828d changelog: reconnect transcript ordering — pending user above live worklog (#6419, #6457) 2026-07-29 22:51:18 +00:00
nesquena-hermes
86d3e6a571 changelog: hard-refresh session restore + PWA launch-action consume (#6507) 2026-07-29 22:22:05 +00:00
nesquena-hermes
16dfeeb3f0 docs(changelog): stamp v0.52.106 stable section (promotion) 2026-07-29 20:50:41 +00:00
nesquena-hermes
bff58ffb31 Revert "Merge pull request #6599 from nesquena/changelog/stamp-v0.52.113"
This reverts commit edb69763a7, reversing
changes made to b8f615e4bd.
2026-07-29 20:40:42 +00:00
nesquena-hermes
15e290dff0 docs(changelog): stamp v0.52.113 stable section (promotion) 2026-07-29 20:06:57 +00:00
nesquena-hermes
4e1a217670 changelog: reject trivial-echo session titles (#6529) 2026-07-26 20:23:01 +00:00
nesquena-hermes
10223e3145 changelog: SSE apperror relay-close fix (#6527) 2026-07-26 20:15:14 +00:00
nesquena-hermes
20972409e3 docs(changelog): repair admin model reload rebinding (#6477, @mspgle-dotcom) 2026-07-26 02:08:45 +00:00
nesquena-hermes
f8401f3be3 docs(changelog): reap idle abandoned terminals (#5844, @ai-ag2026) 2026-07-26 00:56:42 +00:00
nesquena-hermes
399cd7ab19
Release: credit collapsed wakeup cards (#6350, @b3nw) (#6466)
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-23 20:54:32 +00:00
nesquena-hermes
2bd05ee32b docs(changelog): #6349 composer keystroke resize round-trip fix 2026-07-23 04:15:46 +00:00
nesquena-hermes
06f968da5d docs(changelog): #6040 gateway approvals by run ID (#6008) 2026-07-23 02:43:49 +00:00
nesquena-hermes
d64897c539 docs(changelog): #6408 anchor-prose last-char finalize fix 2026-07-23 02:04:19 +00:00
nesquena-hermes
ddb6210c06 docs(changelog): #6319 public-share media leak fix (#6174) 2026-07-23 01:23:37 +00:00
nesquena-hermes
e5096d06a0 Release: #6113 per-turn used-model chip in transparent footer 2026-07-22 22:13:25 +00:00
nesquena-hermes
ef003ec958 Release: #6390 preserve scroll position after live-to-final settlement 2026-07-22 20:43:28 +00:00
nesquena-hermes
35834d49de Release exp-batch1: MIME safety (#6372), atomic config writes (#5797), ctl.sh foreign-instance guard (#5944) 2026-07-22 18:58:03 +00:00
nesquena-hermes
e9e9ed09a5
Release: #6148 alias-prefix model routing fix (exp-v0.52.141) (#6418)
* fix: resolve provider alias before matching _PROVIDER_MODELS (#6148)

* fix(backend): resolve model prefix through _PROVIDER_ALIASES before matching

- Fix IndentationError: dedent _canon_prefix assignment to 8 spaces
- Rebased onto upstream/master
- Add regression test: alias prefix (z-ai) resolves to canonical key (zai)
  and routes cross-provider through OpenRouter (#6131)

* fix(#6131): canonicalize both sides via _canonicalise_provider_id (idempotent) + regression tests

Codex found _resolve_provider_alias breaks Qwen (qwen->alibaba, not in _PROVIDER_MODELS)
and cross-routes alias-of-active-provider (raw vs canon asymmetry). Use the idempotent
_canonicalise_provider_id for both membership and equality. Adds 2 regression tests.

* docs(changelog): stamp #6148 alias-prefix model routing fix

---------

Co-authored-by: webtecnica <75556242+webtecnica@users.noreply.github.com>
Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
Co-authored-by: nesquena-hermes <agent@webui>
2026-07-22 09:51:37 +00:00
nesquena-hermes
478f7749ab
Release: #6107 per-model reasoning_efforts precedence (exp-v0.52.140) (#6417)
* fix: honor per-model reasoning effort metadata

* docs(changelog): stamp #6107 per-model reasoning_efforts precedence

---------

Co-authored-by: Charles Inglis <6466275+CharlesMcquade@users.noreply.github.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
Co-authored-by: nesquena-hermes <agent@webui>
2026-07-22 07:50:29 +00:00
nesquena-hermes
8586572da5
Release: #6389 stream-teardown leak fix (exp-v0.52.139) (#6416)
* fix(#6389): remove clear_offline_buffer() teardown blocks that cause data loss on late reconnects

Keep the real leak fixes:
- unregister_stream_owner() in both streaming.py and gateway_chat.py
- AGENT_INSTANCES.pop() in gateway_chat.py

The clear_offline_buffer() calls could clear a channel's offline buffer
after a late reconnect already fetched the channel but before it subscribed,
causing the reconnecting client to lose all buffered events (including
stream_end) and hang indefinitely on heartbeats.

STREAMS.pop() already releases registry ownership; GC reclaims the buffer
once the last outstanding channel reference is dropped, correctly preserving
replay for in-flight reconnects.

* docs(changelog): stamp #6389 stream-teardown leak fix

---------

Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
Co-authored-by: nesquena-hermes <agent@webui>
2026-07-22 04:09:49 +00:00
nesquena-hermes
7a3646bafd
docs(changelog): stamp #6403 (ja locale) + #6222 (id-linked tool anchor hydration) — exp-v0.52.138 (#6412) 2026-07-21 23:59:41 +00:00
nesquena-hermes
4fd314d033
docs(changelog): stamp #6312 terminal-error Worklog settlement hardening (exp-v0.52.137) (#6411) 2026-07-21 21:31:35 +00:00
nesquena-hermes
c0d9d81512
Release: add preference to hide new-chat welcome panel (#6183, @vaidu-ai) (#6387)
* feat: add option to hide new-chat welcome panel

* Release: add preference to hide new-chat welcome panel (#6183, @vaidu-ai)

---------

Co-authored-by: vaidu-ai <im@vaidu.net>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-21 04:45:11 +00:00
nesquena-hermes
4f063d16f8
Release: Artifacts pane long-filename readability + long-parent containment (#6078, @rodboev) (#6386)
* fix(#6067): keep artifact file names visible

# Conflicts:
#	static/style.css
#	static/workspace.js

* fix(#6067): bound long parent artifact tails inside the drawer

* Release: Artifacts pane long-filename readability + long-parent containment (#6078, @rodboev)

---------

Co-authored-by: Rod Boev <rod.boev@gmail.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-21 04:39:25 +00:00
nesquena-hermes
6b9b9dc808
Release: Kanban New-Task modal reachable on mobile (#6301, @jpalazz2) (#6384)
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-21 03:57:21 +00:00
nesquena-hermes
48b40d930a
Release: isolate Hermes home per streaming turn (#5877, @starship-s) (#6379)
* fix(profiles): isolate Hermes home per streaming turn

Assisted-by: OpenCode:gpt-5.3-codex-spark
Assisted-by: Hermes Agent:gpt-5.6-sol
Assisted-by: Codex:gpt-5.3-codex-spark

* fix(profiles): gate skill isolation by capability

Assisted-by: OpenCode:gpt-5.3-codex-spark
Assisted-by: Hermes Agent:gpt-5.6-sol
Assisted-by: Codex:gpt-5.3-codex-spark

* fix(profiles): harden fallback lock boundaries

Assisted-by: OpenCode:gpt-5.3-codex-spark
Assisted-by: Hermes Agent:gpt-5.6-sol

* test(profiles): adapt streaming isolation harness

Assisted-by: Codex:gpt-5.3-codex-spark
Assisted-by: Hermes Agent:gpt-5.6-sol

* Release: isolate Hermes home per streaming turn (#5877, @starship-s)

---------

Co-authored-by: starship-s <45587122+starship-s@users.noreply.github.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-21 03:48:00 +00:00
nesquena-hermes
0deef392f7
Release: consolidated Kanban board fills vertical space (#6308) (#6376)
* fix: Fix height of consolidated kanban board

There was a lot of empty space below the kanban board columns
in the condolidated view (particularly on desktop). Modify the
CSS such that the consolidated view always fills the viewport
vertical space.

* Release: consolidated Kanban board fills vertical space (#6308)

---------

Co-authored-by: Joe Palazzolo <joe@joepalazzolo.net>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-21 03:26:57 +00:00
nesquena-hermes
a725a0f71c
Release p1-batch: session cache cap 300→100 (#6362) + virtualization comment (#6318) (#6375)
* perf(transcript): enable DOM virtualization by default (re-enable #4346 fix) (#6151) (#6155)

* fix: revert DOM virtualization default to opt-in, fix gate RED (#6155)

* fix(#6351): lower default session cache cap

* Release p1-batch: session cache cap 300->100 (#6362) + virtualization comment (#6318)

---------

Co-authored-by: webtecnica <75556242+webtecnica@users.noreply.github.com>
Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>
Co-authored-by: Rod Boev <rod.boev@gmail.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-21 02:53:43 +00:00
nesquena-hermes
302843c89f
Release: compact completed image tool-results (#6315, @sjungwon03) (#6371)
* fix(session): compact completed native vision results

* streaming: guard image-part compaction against unhashable part.type (isinstance str) + regression test [maintainer fix on @sjungwon03 #6315]

* docs(changelog): stamp #6315 completed-image tool-result compaction

---------

Co-authored-by: sjungwon03 <sjungwon03@gmail.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-20 20:11:29 +00:00
nesquena-hermes
33d55ec897
Release: raster-data-URI redaction fast-path (#6311, @inch772) (#6367)
* fix(redaction): skip native raster data URIs

* fix(redaction): accept mixed-case raster MIME types

* fix(redaction): validate complete raster payloads

* docs(changelog): stamp #6311 raster-data-URI redaction fast-path

---------

Co-authored-by: Su Ahn Lee <11433303+inch772@users.noreply.github.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-20 16:30:04 +00:00
nesquena-hermes
4bdc22b7ce
Release: gateway-default MoA send (#5869, @rodboev) (#6365)
* fix(#5853): allow gateway-default MoA sends

* fix(#5853): freeze gateway auth to one locked snapshot

* docs(changelog): stamp #5869 gateway-default MoA send

---------

Co-authored-by: Rod Boev <rod.boev@gmail.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-20 14:29:22 +00:00
nesquena-hermes
be29c3f7c0
Release: run-journal summary cache (#6291, @sjungwon03) (#6355)
* perf(run-journal): cache unchanged run summaries

* fix(run-journal): reject cache after missing-file race

* run-journal cache: add st_ctime_ns to signature (close same-size mtime-preserving rewrite window) + regression test [maintainer fix on @sjungwon03 #6291]

* docs(changelog): stamp #6291 run-journal summary cache

---------

Co-authored-by: sjungwon03 <sjungwon03@gmail.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-20 09:12:32 +00:00
nesquena-hermes
dd554c1788
Release: Live Stream Anchor side-effects projection (#6204, @franksong2702) (#6348)
* fix: preserve anchor-owned side effects

* test: prove invisible anchor outcomes do not repaint

* docs(changelog): stamp #6204 Anchor side-effects projection

---------

Co-authored-by: Frank Song <franksong2702@gmail.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-20 04:56:51 +00:00
nesquena-hermes
942e952849
Release: fix Kanban column scrolling on mobile (#6306, @jpalazz2) (#6347)
* fix: Fix kanban scrolling in mobile viewports

Scrolling vertically (particularly in expanded view) in kanban on
a mobile viewport is difficult. The columns have overscroll
disabled, meaning tap and drag will only scroll within the column
and will not continue to the next section. On desktop it's much
easier to get the mouse outside the column div, on mobile you have
to deliberately try to tap very close to the edge of the viewport.

Disabling that behavior makes the experience much better

Author: Joe Palazzolo <joe@joepalazzolo.net>

* docs(changelog): stamp #6306 mobile Kanban column scroll fix

---------

Co-authored-by: Joe Palazzolo <joe@joepalazzolo.net>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-20 04:15:33 +00:00
nesquena-hermes
02b2b0aac1
Release: Live Stream stable Anchor run identity (#6201, @franksong2702) (#6346)
* fix: preserve live anchor run identity

* Validate envelope run ids before snapshot cursor use

* docs(changelog): stamp #6201 stable Anchor run identity

---------

Co-authored-by: Frank Song <franksong2702@gmail.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-20 04:10:06 +00:00
nesquena-hermes
98a67ee6cf
Release: pip-installable packaging metadata (#6337, @rodboev) (#6344)
* build(#2695): add packaging metadata for the current runtime layout

* docs(changelog): stamp #6337 pip-installable packaging metadata

---------

Co-authored-by: Rod Boev <rod.boev@gmail.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-20 02:17:52 +00:00
nesquena-hermes
4d9965b37a
Release: content search no longer evicts the working-set cache (#6084, @ai-ag2026) (#6343)
* fix(webui): keep the content search from evicting the user's working set

/api/sessions/search?content=1 walks EVERY session and pulls each one through
get_session(), which inserts it into the SESSIONS LRU and marks it
recently-used. On any install with more sessions than sessions_cache_max
(default 300), a single search therefore flushes the whole cache and refills it
with sessions the user is not looking at — the classic buffer-pool
scan-pollution problem. The sessions actually open in the UI are exactly the
ones evicted, and the search is keystroke-debounced, so it repeats while typing.

A scan reads each session exactly once, so nothing it touches has earned
"recently used". get_session_for_scan() reuses a resident session without
promoting it, and reads a cold one straight from disk without caching it. It
returns None rather than raising, since a scan skips what it cannot open.

This is a correctness fix for cache behaviour, not a latency fix. The
multi-second searches that led here were contention, not scan cost: a trivial
/api/profiles took 9.2s in the same window, and a full read+parse of ~1700 real
sessions measures ~4s total.

test_sessions_search_depth_validation patched api.routes.get_session. With the
search reading through the scan accessor it now patches get_session_for_scan —
left unfixed, two of its cases fail and the third passes vacuously against an
empty result set.

Validation:
  pytest tests/test_issue4765_sessions_lru_eviction.py
         tests/test_sessions_search_depth_validation.py   ->  13 passed
  Both added eviction tests fail on the pre-fix accessor (verified by revert):
  the working set drops from 4/4 to 0/4 resident after one scan.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(changelog): stamp #6084 content-search working-set preservation

---------

Co-authored-by: ai-ag2026 <261867348+ai-ag2026@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-20 01:21:18 +00:00
nesquena-hermes
307b7fce5f
Release: terminal-error settlement timing/seal (#6323) + Docker experimental builds (#6329) (#6341)
* fix: preserve timing and seal tool rows on terminal error (#6309)

* fix: publish Docker experimental builds to ghcr (#6298)

- Add exp-v* trigger to release workflow so experimental tags build
  and push Docker images
- Add :experimental floating tag for experimental channel, keeping
  :latest scoped to stable v* tags only
- Mark GitHub Releases from exp-v* tags as pre-releases
- Document available Docker tags (:latest, :experimental, version
  pins) in docs/docker.md

Closes #6298

* docs(changelog): stamp #6323 terminal-error timing/seal + #6329 Docker exp builds

---------

Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-19 22:17:36 +00:00
nesquena-hermes
10e5c52b10
Release: broadcast terminal output to every viewer (#5836, @ai-ag2026) (#6340)
* feat(terminal): broadcast output to every viewer instead of one shared queue

TerminalSession.output was a single queue.Queue read destructively by the SSE
handler. Two tabs/windows viewing the SAME session each open their own
EventSource, so two _handle_terminal_output handlers competed on that one queue:
every PTY chunk was delivered to exactly one of them. Each tab saw a disjoint
half of the byte stream, and only one ever received terminal_closed.

Output now fans out, mirroring StreamChannel/SessionChannel: each SSE consumer
subscribe()s its own queue (seeded with a bounded backlog so a first/late attach
still replays the recent scrollback, preserving the old buffer-until-first-
consumer behaviour), and put_output broadcasts to all subscribers. A slow
viewer's queue drops its own oldest chunk (drop-oldest, isolated per subscriber)
so one lagging tab can't starve another. The handler unsubscribes in a finally
so the subscriber list can't grow.

Stacked on the terminal fd-leak fix (same file).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: cover terminal broadcast lifecycle

* fix: serialize terminal subscriber fanout

* test: cover terminal unsubscribe publication race

* restore timing-flaky pytest.skip on test_terminal_survives_short_lived_request_thread (keep API-updated body); changelog #5836

---------

Co-authored-by: ai-ag2026 <261867348+ai-ag2026@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-19 22:08:29 +00:00
nesquena-hermes
4e768fe247
Release: gateway approval_id fallback (#6168) + update-check guard (#6180) + state-dir test isolation (#6305) (#6332)
* fix: catch unhandled exception in POST /api/updates/check (defensive hardening) (#6180)

* fix: generate non-empty approval_id when gateway approval.request omits it (#6008) (#6168)

* chore: mark update-check try/except as defensive-only guard, drop #6086 linkage

Per maintainer review, the try/except wrapper is defense-in-depth only —
it does NOT fix #6086 (root cause is signal/process-group reaping).
Updated log message and added inline comment to make this explicit.
Leave #6086 open.

* test: isolate state-dir probes from user state

* docs(changelog): stamp #6168 approval_id, #6180 update-check guard, #6305 test isolation

---------

Co-authored-by: webtecnica <75556242+webtecnica@users.noreply.github.com>
Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>
Co-authored-by: pxxD1998 <214340659+pxxD1998@users.noreply.github.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-19 17:41:07 +00:00
nesquena-hermes
31d4281a19
Release: optional Transparent Stream event timestamp chips (#6130, @rodboev) (#6300)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-07-18 20:58:41 -07:00
nesquena-hermes
17c2f2086c
Release: bg-process restart recovery (#6287) + Windows test-fixture symlink fallback (#6276) (#6294)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-07-18 20:10:01 -07:00
nesquena-hermes
6ad84d7dd3
fix(wakeup): route async-delegation completions by origin + durable-claim delivery (#6283)
Route async-delegation completions by the immutable origin_ui_session_id (exact origin tab) and deliver them through a durable claim/complete/release lifecycle so they arrive exactly once, restart-safe, on both the background wakeup and next-turn drain paths. Combines #6185 (@carlotestor) + #6159 (@sysophelper-droid); supersedes #6002/#6225.

Co-authored-by: carlotestor <carlotestor@users.noreply.github.com>
Co-authored-by: sysophelper-droid <sysophelper-droid@users.noreply.github.com>
2026-07-19 02:26:55 +00:00
nesquena-hermes
c67fd2dd27
Release: Artifacts filename-first + session-own-streaming + reduced-motion msg-row (#6161, #6165, #6166, @webtecnica) (#6282)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>
2026-07-18 17:53:57 -07:00
nesquena-hermes
b324eb91e2
Release: prevent bare-id picker revert on empty provider hint (#6199, @webtecnica) (#6280)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-07-18 16:57:28 -07:00
nesquena-hermes
94514458d9
docs(changelog): stamp v0.52.76 stable section (promotion) (#6269)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-07-18 21:25:26 +00:00
nesquena-hermes
be45c396ed
Release: render data:image URIs as images (#6209, @ai-ag2026) (#6270)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-07-18 14:15:26 -07:00
nesquena-hermes
bbb5446bd6
Release: deduplicate configured model badges (#6221, @happy5318) (#6268)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-07-18 12:48:50 -07:00
nesquena-hermes
69ffaf3443
Release: byte-size threshold for reconnect tail optimization (#6260, @webtecnica) (#6263)
* perf: optimize large session reconnect by adding file-size threshold to tail optimization (#6241)

When a sidecar JSON file exceeds 500 KB, the display-path tail optimization
now fires even if the message count is within the raw_budget. This prevents
sessions with few messages but large tool outputs (multi-MB JSON) from
forcing a full-scan merge of all messages on reconnect.

Changes:
- Added _sidecar_file_exceeds_threshold() helper
- Added _SIDECAR_BYTE_TAIL_THRESHOLD = 500_000 constant
- Fall-through to truncation in _state_db_since_timestamp_for_limited_display
  when the sidecar file exceeds the threshold, regardless of message count

* CHANGELOG: byte-size reconnect tail optimization (#6260)

---------

Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-07-18 11:21:22 -07:00