Commit Graph
8654 Commits
Author SHA1 Message Date
carlotestor 05aae134cf Merge branch 'master' into feat/gateway-run-reattach-after-restart 2026-09-24 15:51:42 +01:00
nesquena-hermes 9a00b652c1 Merge pull request #7809 from nesquena/stage/0924-i
release: #6717 virtual measurement retry budget stops resetting on window oscillation (exp-v0.52.374)
2026-09-24 07:41:42 -07:00
nesquena-hermes 1c4d5abf28 docs(changelog): #6717 virtual measurement retry budget no longer resets on window oscillation 2026-09-24 14:26:51 +00:00
nesquena-hermes 38c5c69b63 Merge PR #6717 into stage/0924-i 2026-09-24 14:26:32 +00:00
nesquena-hermes 28edb04ebd test: widen renderMessages() source window in R16d guard-order probe
The #6717 burst-reset call grows the renderMessages() preamble, pushing the
render-window reset past the probe's 1400-char slice. Widen it to 2400; the
guard-before-reset ordering assertion is unchanged and still passes on master.
2026-09-24 14:02:48 +00:00
nesquena-hermes 73d08d3cfb test: follow the #6717 render-scheduler signature; guard the burst reset for node harnesses
_scheduleMessageVirtualizedRender now takes (force, request), so the two
structural probes in test_issue4346_vscroll_footer_jitter.py matched nothing.
renderMessages() calls _resetMessageVirtualMeasurementBurst(), which node
harnesses that extract renderMessages() alone (test_compaction_current_summary_fallback.py)
don't define; guard it with typeof like the file's other optional helpers.
2026-09-24 13:43:12 +00:00
nesquena-hermes fdf7e5e429 Merge pull request #7807 from nesquena/stage/0924-h
release: #6895 custom-provider model prefix stripped before send
2026-09-24 06:35:56 -07:00
nesquena-hermes 82ee11c71f docs(changelog): #6895 custom-provider model prefix stripped before send 2026-09-24 13:25:26 +00:00
nesquena-hermes 1cb16f6037 Merge PR #6895 into stage/0924-h 2026-09-24 13:25:15 +00:00
nesquena-hermes 0052266c5d Merge pull request #7806 from nesquena/stage/0924-g
release: #6565 gateway reset and tool children stay separate from the parent session
2026-09-24 06:18:24 -07:00
nesquena-hermes 3f76b8a3a9 docs(changelog): #6565 lineage reset/tool children stay separate 2026-09-24 13:04:39 +00:00
nesquena-hermes 30f12dc526 Merge PR #6565 into stage/0924-g 2026-09-24 13:04:21 +00:00
nesquena-hermes 1633658fa5 test(#6717): assert the non-consecutive repeat condition
The production guard now ends the burst only on a non-consecutive repeat
(A -> B -> A), so a window needing a second re-measure is not mistaken for
oscillation. Update the structural assertion to that condition.
2026-09-24 12:57:14 +00:00
Anthony Ruiz f3545da572 fix(lineage): keep tool children separate across readers 2026-09-24 11:53:47 +00:00
Anthony Ruiz a41bfe8690 fix(lineage): honor _reset_from, fail closed on untrusted markers, hash full watcher payload
Layer three additive pieces on top of the #7021 / #6931 continuation
predicate without changing its shape or CONTINUATION_STARTED_AT_TOLERANCE_SECONDS:

- _reset_from is a boundary marker alongside _branched_from/_delegate_from
  (Hermes Agent stamps it in gateway/session_recovery.py and filters it in
  _NON_CONTINUATION_CHILD_FILTER_SQL). The same predicate drives the sidebar
  listing, lineage metadata/report and the transcript stitcher.
- _branch_markers() returns ('none' | 'markers' | 'unknown', markers);
  unparsable, non-object, too-deep, or non-string marker payloads are
  'unknown' and fail closed as a lineage boundary instead of degrading to
  "no markers" (fail open).
- gateway_watcher._snapshot_hash() hashes the complete canonicalized published
  payload, and the cheap fingerprint covers model_config, so a projection change
  to title/created_at/metadata with fixed (id, updated_at, message_count) emits
  sessions_changed.
2026-09-24 11:53:47 +00:00
webtecnica c784ef7a12 fix(ui): preserve endpoint-style custom slugs host:port in model parsers (#6884) 2026-09-24 08:50:30 -03:00
webtecnica 0cbf16a51c fix(perf): treat only non-consecutive repeat cycle keys as oscillation (#6717) 2026-09-24 08:44:04 -03:00
nesquena-hermes d1b3787573 Merge pull request #7805 from nesquena/stage/0924-f
Release exp-v0.52.371: bound hidden-tab session polling while preserving profile recovery (#7301)
2026-09-24 04:43:48 -07:00
nesquena-hermes 5a2105684d docs(changelog): stamp #7301 under [Unreleased] 2026-09-24 11:27:12 +00:00
nesquena-hermes c2c8ef5fce Merge PR #7301 from laitekin/fix/7299-hidden-session-poll 2026-09-24 11:26:41 +00:00
nesquena-hermes 9bf585ae88 Merge pull request #7804 from nesquena/stage/0924-e
Release exp-v0.52.370: keep image-turn context out of user bubbles; Edit/Undo keeps removed image turns removed (#7754)
2026-09-24 04:20:29 -07:00
nesquena-hermes cb7852cdc1 docs(changelog): stamp #7754 under [Unreleased] 2026-09-24 10:55:11 +00:00
nesquena-hermes 0adc1f6e4f Merge PR #7754 from starship-s/fix/image-turn-display-context 2026-09-24 10:54:56 +00:00
nesquena-hermes 315ea7d3a8 fix(models): let a marked image row consume its replay slot
The row-id fast path for a marked native-image mirror row continued
without advancing state_replay_idx, unlike the ordinary and multimodal-
mirror replay paths. The edited checkpoint then never read as consumed,
so a rerun reply that exists only in state.db was truncated. Master (no
marker branch) keeps that reply.

Advance the replay index when the resolved sidecar row is the next
expected visible row, the same guard the mirror branch uses. Adds a
regression that fails without the fix: sidecar [u1,a1,img#42,a_img,uE],
state [.., marked img#42, a_img, u_old, a_old, uE, aE], watermark 900,
boundary 861 -> aE survives, u_old/a_old stay out.

Found by the release-manager advisor gate on #7754.
2026-09-24 10:47:47 +00:00
nesquena-hermes 0c3550f4a7 Merge pull request #7802 from nesquena/stage/0924-d
Release exp-v0.52.369: scope MCP status, inventory and /reload-mcp to the request profile (#7720)
2026-09-24 03:33:03 -07:00
latekin 08dbd87a36 Merge branch 'master' into fix/7299-hidden-session-poll 2026-09-24 18:20:37 +08:00
nesquena-hermes 026bad541d docs(changelog): stamp #7720 under [Unreleased] 2026-09-24 09:58:07 +00:00
nesquena-hermes 19908b5db4 Merge PR #7720: scope MCP status, inventory and /reload-mcp to the request profile 2026-09-24 09:58:07 +00:00
nesquena-hermes d261041a9a test(mcp): import the fake server class under mcp 1.x and 2.x
mcp 2.x removed mcp.server.fastmcp (the high-level server is now
mcp.server.MCPServer), so the fake stdio server in this test failed to
start on hosts with mcp 2.x installed and four tests failed there. CI pins
mcp<2, so this only affected local runs. Try the 1.x import first and fall
back to the 2.x name.
2026-09-24 09:57:52 +00:00
starship-s 089fb57d25 fix(chat): honor edit watermarks for distinct image rows
Apply the existing truncation and checkpoint-order eligibility to marked
state.db image rows before insertion. Keep removed turns out of full,
limited, and model-context reads without changing no-watermark replay.
Preserve conflicting provider payloads for a uniquely proven retained
image row across Undo without restoring distinct removed rows.

Assisted-by: Hermes Agent:gpt-6-sol
Assisted-by: Codex:gpt-6-luna
2026-09-24 03:04:50 -06:00
nesquena-hermes 05602c96fd Merge pull request #7801 from nesquena/stage/0924-c
Release exp-v0.52.368: phone soft-keyboard Enter inserts a newline (#6746)
2026-09-24 01:27:20 -07:00
nesquena-hermes 3f29a5be08 docs(changelog): stamp #6746 under [Unreleased] 2026-09-24 08:05:40 +00:00
nesquena-hermes 10faa69155 Merge PR #6746 from happy5318/fix/mobile-enter-newline 2026-09-24 08:05:12 +00:00
tancouandClaude Fable 5.1 3b7b5cbe7c fix(mcp): reconcile an emptied profile config on reload; list portable plugin tools
Review gate on #7720 (two regressions reproduced against master with the
installed Agent):

1. Deleting a profile's last MCP server left ADOPTED tools callable after
   /reload-mcp. The scoped teardown only stops connections the profile owns,
   and the Agent's discover_mcp_tools() returns before its reconcile step
   when the profile's config has no server, so an adopted shared connection
   was never judged against the config. /reload-mcp now calls
   register_mcp_servers({}) under the profile's scope before rediscovery:
   the Agent's overlay heal detaches only this profile's overlay for servers
   its config no longer has; the owner's connection keeps running (master's
   wildcard shutdown stopped the owner too).

2. Portable plugin MCP servers are merged by the Agent at runtime and never
   appear in the profile's raw ``mcp_servers``; the registry fallback
   required a config entry and dropped every plugin tool from
   /api/mcp/tools and the Notes inventory. The profile's own registry slot
   (registry_tool_owned_by_view) is the isolation check; the config is not
   an allowlist any more.

Tests (red before, green after): agent-free unit tests for both (the fake
agent now models the overlay heal and discovery's empty-config early
return), and a real-Agent integration test for the adopted-then-deleted
case (owner connection survives, adopter slot emptied, "Removed" reported).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 09:53:02 +02:00
tancouandClaude Fable 5.1 dbf0179c53 fix(mcp): report runtime_scope on /api/notes/sources and surface it in the Notes drawer
Review follow-up on #7720 (Greptile P2): the external Notes drawer reads the
same profile-bound MCP inventory as the MCP panel but dropped the
``runtime_scope`` label, so a profile whose runtime scope could not be
confirmed rendered its note sources as inactive/configured with no
explanation. ``/api/notes/sources`` now returns ``runtime_scope`` and the
drawer shows the existing ``mcp_runtime_scope_unavailable`` notice (same key,
no new locale strings) when it is ``unavailable``.

Tests: the skewed-routing unit test now also asserts the notes response
carries ``runtime_scope: "unavailable"`` with its sources inactive.
docs/troubleshooting.md mentions the drawer next to the panel.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 09:53:02 +02:00
tancouandClaude Opus 5 90b814f673 fix(mcp): scope MCP status, inventory and /reload-mcp to the request profile
Two profiles configuring a same-named MCP server shared one connection and
the MCP settings panel showed another profile's runtime ("Active, N tools"
next to an empty inventory); /reload-mcp stopped every profile's servers and
rediscovered from the process-default config.

- api.profiles._set_hermes_home() is the single writer of the process-profile
  home: it records get_process_profile_home() and hands it to Hermes Agent's
  hermes_constants.pin_process_hermes_home when available, at startup and on
  switch_profile(process_wide=True), so the per-turn HERMES_HOME mirror no
  longer makes every turn look like the process profile (bare-name,
  cross-profile MCP keys) and the anchor cannot drift from HERMES_HOME.
- Run get_mcp_status/registry reads and /reload-mcp inside
  api.mcp_runtime.mcp_runtime_scope(): request profile's Hermes-home override
  and secret scope (root included), no os.environ mutation, restored on exit.
- One ledger predicate, ledger_key_serves_view() (owned via
  _server_scope_keys/key scope, or adopted via _server_tool_scopes), is shared
  by status, inventory and the reload summary. The Agent's launch-profile view
  is process-wide and name-indexed, so filter_runtime_status_to_view()
  rebuilds connected/tools/status/error from the entries serving the profile:
  the root profile never shows a routed profile's connection (nor lets its own
  parked failed-spawn task borrow a routed profile's live same-named one).
- Inventory lists only tools in the profile's own registry slot for servers it
  configures; responses carry runtime_scope.
- Fail closed when the agent's routing does not match the resolved profile:
  hide runtime data (runtime_scope "unavailable", shown as a notice in the MCP
  panel, 14 locales) and refuse /reload-mcp.
- /reload-mcp shuts down only the profile's own ledger names (parked
  included), drops its own connect cooldown/error entries so a failed spawn is
  retried (the wildcard cleared every cooldown; a scoped shutdown only clears
  the live keys it tears down), rediscovers under the profile's home and
  counts live connections only. The bare wildcard remains for agents without
  profile-scoped MCP.
- Signature introspection is centralized (accepts_keywords) and falls back to
  the bare call instead of blanking every status; ledger key helpers resolve
  to the Agent's tools.mcp_tool_scope when present; tools.mcp_tool is
  resolved by full name so stubbed agents still work.
- ARCHITECTURE.md §4.10 and docs/troubleshooting.md document the boundary.
- Tests: agent-free contract (models adoption, parked tasks, cooldowns and the
  process-wide root view) and real-Agent integration (fake stdio MCP server,
  skips without hermes-agent + mcp SDK).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 09:53:02 +02:00
happy5318 bbebe23f7e fix(mobile): preserve tablet hardware-keyboard Enter behavior 2026-09-24 15:26:06 +08:00
nesquena-hermes 2d1e6f812a Merge pull request #7800 from nesquena/stage/0924-b
release: exp-v0.52.367 (#7798 CLI-archived sessions stay archived)
2026-09-24 00:04:26 -07:00
nesquena-hermes 60f61f9038 docs(changelog): stamp #7798 under [Unreleased] 2026-09-24 06:57:37 +00:00
nesquena-hermes 18cf0fa0ba Merge PR #7798 from webtecnica/fix/7548-cli-archived-sessions-projection 2026-09-24 06:57:17 +00:00
nesquena-hermesandwebtecnica 5ecf92382a test(#7548): mark the monkeypatch-target import as intentional (ruff F401)
Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>
2026-09-24 06:56:57 +00:00
nesquena-hermesandwebtecnica afcb1bf420 test(#7548): expect archived=None for a missing sidecar
The sidecar default is now 'no opinion' (None) so the projection can fall
back to state.db's archived flag. Update the #4842 perf test's missing-
sidecar expectation to match.

Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>
2026-09-24 06:45:50 +00:00
nesquena-hermes 5bfe845fbc Merge pull request #7797 from nesquena/stage/0924-a
Release: bounded recovery reads (#7628), prompt notifications (#7493), per-instance settings file (#6433)
2026-09-23 21:31:34 -07:00
webtecnica 98b002d96b fix(sessions): preserve state.db archived status for sessions without sidecars (#7548) 2026-09-24 01:06:03 -03:00
nesquena-hermes 3116280dce docs(changelog): stamp #7628, #7493, #6433 under [Unreleased] 2026-09-24 03:38:33 +00:00
nesquena-hermes a1b3c068f7 docs: document HERMES_WEBUI_SETTINGS_FILE (#6433) incl. restart-to-change note 2026-09-24 03:15:28 +00:00
nesquena-hermes 16acb63a6d fix(notifications): auto-request 'default' permission at most once per page
A pending approval/clarify prompt re-surfaces on every 1.5s poll tick, and
with permission still 'default' (second browser/device) each tick issued a
non-gesture Notification.requestPermission() and toasted 'notifications
denied'. Auto requests are now made once per page; the explicit Send-test
path still always asks. Release-gate hardening on top of #7493.
2026-09-24 03:15:09 +00:00
nesquena-hermes ea5f7730be Merge PR #6433 into stage/0924-a 2026-09-24 03:15:02 +00:00
nesquena-hermes 1c4072228e Merge PR #7493 into stage/0924-a 2026-09-24 03:15:02 +00:00
nesquena-hermes 0b8d6d6fd8 Merge PR #7628 into stage/0924-a
# Conflicts:
#	static/messages.js
2026-09-24 03:15:02 +00:00