412 Commits
Author SHA1 Message Date
nesquena-hermes 4e0ba56b8d Merge branch 'master' into pr-7625-fix 2026-09-25 22:01:40 -07:00
nesquena-hermesandhappy5318 94539cf074 docs(zh): correct the .env precedence note for start.ps1
The new "改完密码先验证一下" note said start.sh, start.ps1 and bootstrap.py all let
repo-.env values override an inline HERMES_WEBUI_PASSWORD. That holds for start.sh
(`set -a; source .env` runs before anything else), but start.ps1 skips any .env key that
is already set in the environment (start.ps1:70-72), so on native Windows the
`$env:HERMES_WEBUI_PASSWORD` shown in this section wins. start.ps1 runs server.py
directly, so the suggested HERMES_WEBUI_PRESERVE_ENV=1 did not apply to it either.

Keep the useful advice (check the login page actually asks for the new password, and
look for a stale value in .env), state the correct precedence for each launcher, and
drop the PRESERVE_ENV suggestion.

Co-authored-by: happy5318 <34227488+happy5318@users.noreply.github.com>
2026-09-26 05:01:24 +00:00
happy5318 c13a2ecf64 docs(zh): align Windows sections with start.ps1 / WSL-only autostart
Review feedback (nesquena 9/24, PR #7814):

1. §三.1 "首次准备" 原本让用户在 WebUI 仓库本地 `python -m venv venv`
   再 `pip install -r requirements.txt`,但 `start.ps1`(line 132-136)
   启动时优先用 `<hermes-agent>\venv\Scripts\python.exe`,找不到才
   回退到 PATH 上的 `python`——WebUI 本地的 venv 永远不会被它挑中。
   照原指南装的依赖会变成死代码,启动时仍然缺包。重写为:要求把
   requirements.txt 装进 hermes-agent 的 venv,列出 hermes-agent 的
   常见安装位置,保留 WebUI 本地 venv 作备选但明确警告。

2. §三.4 之前是 "Windows 开机自启",但内容(setup_webui_autostart.ps1
   → wsl.exe → scripts/wsl/hermes_webui_autostart.sh)实际上**只**
   启动 WSL 里的 WebUI,放在 native-Windows 章节里会误导用户以为
   native 启动也有自启配套。把它从 §三 抽出,单独成节
   "## 四、WSL 用户:Windows 开机自启",顶部加 WSL-only 提示,
   §四/§五 顺延为 §五/§六,FAQ 里的 cross-ref 同步更新,README
   中文链接文案改为 "...Windows 原生部署(自启仅适用 WSL 用户)"
   不再暗示 native 自启。

3. 顺手处理两条可选小项:

   a. start.sh / start.ps1 / bootstrap.py 都会从仓库 .env 加载
      `HERMES_WEBUI_PASSWORD`,且 .env 里的值**覆盖**命令行内联
      的 env var。在 §三.2 加 callout 提示:改完密码后打开登录页
      确认真的要求输入密码;如未生效就清 .env 或显式
      `HERMES_WEBUI_PRESERVE_ENV=1`。

   b. §六.1 "Tailscale 私有" 原写法 "仅你的 tailnet 设备可达" 在
      方案 B(`HERMES_WEBUI_HOST=0.0.0.0`)下不成立——`0.0.0.0`
      绑的是所有接口,"仅 tailnet" 完全靠防火墙那条
      `100.64.0.0/10` 规则兜底。改为:首选 `HERMES_WEBUI_HOST=
      $(tailscale ip -4)`(只绑 Tailscale 网卡,更严),次选
      `0.0.0.0` + 防火墙,并明确标注"防火墙被改/被关就立刻
      对 LAN/公网开放"。

保留 24dd1fbd 的 public-exposure note 修正。
2026-09-26 01:39:24 +08:00
nesquena-hermes 24dd1fbd58 docs(zh): correct the public-exposure note (WebUI does rate-limit logins; the gap is plaintext HTTP) 2026-09-24 19:47:45 +00:00
nesquena-hermes 15ac01e2c3 Merge PR #7785 into stage/0924-o 2026-09-24 19:15:12 +00:00
xiaobao a77956fcfd docs(zh): add Chinese remote-access guide (Tailscale, SSH tunnel, native Windows)
Companion to docs/remote-access.md for Chinese users, per the
contribution shape requested in #7393:

- Tailscale Serve preferred path (loopback + HTTPS MagicDNS), direct
  tailnet IP as fallback, SSH tunnel section
- Native Windows deployment via the official start.ps1 launcher with
  password auth; firewall rule scoped to the Tailscale CGNAT range
  (100.64.0.0/10) instead of an all-interfaces open
- Windows logon auto-start via the official
  scripts/windows/setup_webui_autostart.ps1 scheduled-task helper
- Explicit security boundary section distinguishing tailnet-private,
  LAN, and public exposure
- No machine-specific usernames/drives/model choices/popularity numbers
- Linked from the README docs index

Tests: test_readme_compat_section, test_issue3012_3006_docker_docs,
test_nix_flake_module_source all pass (17/17).
2026-09-25 02:37:52 +08:00
nesquena-hermes 96921c2cfc Merge PR #7577 into stage/0924-l 2026-09-24 17:53:18 +00:00
nesquena-hermes b26839b996 Merge PR #7632 into stage/0924-k 2026-09-24 16:53:13 +00:00
carlotestor 2dd1366033 fix: fingerprint .env values, parse manifests like the agent, gate stale models fallback on sources 2026-09-24 15:29:51 +00:00
Rocky df35836b75 fix: preserve transcript generations in sidebar projection
Rocky-Actor: Hermes Rocky
Rocky-Mode: interactive
2026-09-24 18:01:04 +03:00
carlotestor 05aae134cf Merge branch 'master' into feat/gateway-run-reattach-after-restart 2026-09-24 15:51:42 +01:00
nesquena-hermes c2c8ef5fce Merge PR #7301 from laitekin/fix/7299-hidden-session-poll 2026-09-24 11:26:41 +00:00
nesquena-hermes 0adc1f6e4f Merge PR #7754 from starship-s/fix/image-turn-display-context 2026-09-24 10:54:56 +00:00
latekin 08dbd87a36 Merge branch 'master' into fix/7299-hidden-session-poll 2026-09-24 18:20:37 +08: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
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
starship-s 5d42c2acd2 chore(chat): merge upstream for image-turn PR
Keep image-turn context tagging and upstream's typed steer-wrapper cleanup
in the same settlement path. Verify the combined recovery and streaming
behavior against current master.

Assisted-by: Hermes Agent:gpt-6-sol
2026-09-23 18:43:39 -06:00
starship-s c101b54c02 fix(chat): preserve journal recovery after a dead image turn
Count a proved WebUI-owned pending row in the display baseline before
accepting a state.db self-heal. Without assistant output past that turn,
leave pending state for the run journal to restore partial text and the
interruption marker instead of clearing it prematurely.

Assisted-by: Hermes Agent:gpt-6-sol
Assisted-by: Codex:gpt-6-luna
Assisted-by: Claude Code:claude-opus-5-5
2026-09-23 15:06:58 -06:00
starship-s d07c60a92a fix(chat): preserve submitted image turns on stale recovery
When a dead stream is reconciled from state.db, retain the submitted
prompt and attachment in the sidecar while keeping the Agent-enriched
row in model context. Use one parent snapshot for full-session conflict
projection so the sidecar owner is stable across the display merge.

Assisted-by: Hermes Agent:gpt-6-sol
Assisted-by: Codex:gpt-6-luna
Assisted-by: Claude Code:claude-opus-5-5
2026-09-23 14:39:11 -06:00
carlotestor 5d590bdc7f refactor: shrink gateway reattach diff without behaviour change
Inline endpoint resolution, fold HTTP error branches, merge duplicate
tests into parametrized cases, trim comments and docstrings.
2026-09-23 19:12:46 +00:00
carlotestor 7344c8df77 refactor: shrink profile-switch models cache diff
Reuse _get_models_cache_path(profile) for profile delete/create instead of a
second path helper, derive the fingerprint home from the auth store path, fold
the three switch test files into one parametrized file, and trim comments/docs.
Behaviour, source axes and switch fast path are unchanged.
2026-09-23 19:11:19 +00:00
starship-s 0be6a1f454 fix(chat): prevent duplicate bubbles for conflicting provider payloads
Record pending-turn proof under caller-owned session locks during normal
runs and credential recovery. Preserve both conflicting provider payloads
for replay, but display one sidecar-owned bubble when row identity and
visible content are unambiguous.

Assisted-by: Hermes Agent:gpt-6-sol
Assisted-by: Codex:gpt-6-luna
2026-09-23 12:56:46 -06:00
nesquena-hermes ab130f2cd0 Merge PR #7610 into stage/7610-oob-writeback 2026-09-23 18:23:35 +00:00
carlotestor 35bb952def fix: fingerprint model-provider plugin file contents, not just manifest version 2026-09-23 18:00:35 +00:00
starship-s 63c8e3df31 fix(chat): keep pending image turns private through reload
Persist trusted pending Agent timestamp evidence before the model call so
session reads, including metadata polls and cold reloads, keep only the
submitted prompt and attachment visible. Preserve conflicting provider
payloads without guessing which copy is newer.

Assisted-by: Hermes Agent:gpt-6-sol
Assisted-by: Codex:gpt-6-luna
2026-09-23 11:34:30 -06:00
carlotestor 2a742e13d6 Merge remote-tracking branch 'origin/master' into HEAD 2026-09-23 16:34:11 +00:00
carlotestor 7ba246bfc0 fix(gateway): reattach runs-API turns after a WebUI restart instead of marking them interrupted
A gateway-backed turn on the runs API executes in the Hermes Gateway, but the
run id only lived in process memory, so a WebUI restart orphaned the turn and
stale-pending repair appended 'Response interrupted' while the run finished
on the gateway.

- persist session.gateway_run {run_id, stream_id} as soon as POST /v1/runs returns
- send Idempotency-Key webui-<stream_id> so the gateway keeps a durable run record
- on startup (after bind, before serving) re-register the stream and follow
  GET /v1/runs/{id} until terminal; write back the real output, surface a
  parked approval once, keep Stop working, clear the record on every settlement
2026-09-23 16:30:21 +00:00
carlotestor 7f2e812280 fix: fingerprint .env key names and provider plugins; drop a profile's models cache on delete/create
A retained per-profile snapshot is now rejected after a switch when the target
profile's .env credential set or model-provider plugins changed, and a
recreated same-name profile no longer inherits the deleted profile's catalog.
2026-09-23 15:31:44 +00:00
webtecnica 618325501e Merge upstream/master into fix/oob-marker-writeback 2026-09-23 11:19:34 -03:00
webtecnica 6d1753bb6c fix(streaming): extract inner steer text from typed steer rows in place (#7600) 2026-09-23 11:19:25 -03:00
nesquena-hermes 9b6f70c959 Merge PR #7767 into stage/7767-runtime-model 2026-09-23 14:11:17 +00:00
nesquena-hermes c5d8e5fe4f Merge master into stage/7761-watcher-fence
# Conflicts:
#	CHANGELOG.md
2026-09-23 12:47:36 +00:00
Anthony Ruiz c45cab3779 feat(streaming): publish observed local runtime model to SSE and journal 2026-09-23 11:11:52 +00:00
nesquena-hermes dc554cbd1c Merge PR #7165 into stage/7165-custom-allowlist 2026-09-23 10:22:41 +00:00
Anthony Ruiz 986e0fdd85 fix(gateway-watcher): fence stale projections after final subscriber removal 2026-09-23 10:00:57 +00:00
happy5318andClaude Opus 4.8 0fcd584274 fix(models): dict-shaped models is per-model metadata, not an allowlist (re-gate 9/23)
Re-review #7165 (nesquena-hermes 2026-09-23T06:21:57Z, CHANGES_REQUESTED).

CORE: a dict-shaped custom_providers[].models mapping (what Hermes Agent's
setup flow writes, e.g. {chat-a: {context_length: 128000}}) was treated as an
allowlist by iterating its keys, collapsing the live /v1/models catalog to a
single saved default while the CLI live-probed the full list. The Agent defines
exactly this contract in hermes_cli/model_switch.py::_models_config_is_allowlist:
a mapping is per-model metadata, NOT a catalog narrow.

Fix (all 3 spec points):

1. api/routes.py::_custom_provider_allowlist_ids: added
   _custom_provider_models_discover_is_false(_cp) (mirrors
   api.config._provider_discover_allowed / Agent
   model_switch_providers.py:557: bool False or string false/no/0,
   case-insensitive). In the dict branch, when discovery is NOT explicitly
   false, return no allowlist so the live probe returns the full catalog.
   Only discover_models: false opts into treating dict keys as a pinned
   allowlist. List / JSON-array-string / Python-literal shapes stay plain
   allowlists.

2. tests/test_issue3718_live_models_custom_probe.py: removed the
   mapping-metadata param that asserted the regression; added two
   real-handler tests: test_dict_models_without_discover_false_does_not_gate
   (dict -> full _LIVE_CATALOG) and test_dict_models_with_discover_false_pins_to_keys
   (bool False / "false" / "no" / "0" -> pinned to keys).

3. docs/architecture/live-models-allowlist.md: documented that list and
   string shapes filter, and a dict filters only with discover_models: false.

Companion test update (blocker reported by the fix itself):

tests/test_byok_model_dropdown.py rightcode-codex entry encoded the removed
dict-as-allowlist behavior (models: {"gpt-5.5-mini": {}} asserting the response
collapsed to just that key). Added discover_models: False to preserve the
provider-scoping intent (no sibling leak) under the new contract.

Red/green verified: removing the dict-branch guard turns
test_dict_models_without_discover_false_does_not_gate red (collapsed catalog);
restoring it turns it green.

Verification: 3718 18 passed; byok 24 passed; neighbour sweep (46 files)
520 passed (2 pre-existing order-dependent flakes reproduce identically on
clean HEAD, verified via git stash); ruff curated gate OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-23 17:48:34 +08:00
happy5318 ff8e75c0be docs(models): document the /api/models/live allowlist runtime contract
Addresses the standing documentation finding: records the four evaluation
signals (discovered catalog defers, plural allowlist filters, singular model
never gates, no allowlist shows full catalog), serialized-list shapes, the
empty-allowlist-is-not-configured rule, and the probe-failure fallback.
Registered in docs/CONTRACTS.md per the #7556 precedent.
2026-09-23 16:58:09 +08:00
starship-s 5fd993cdd5 fix(chat): reconcile conflicting image-row provider payloads
A unique durable row remains one visible row when its sidecar provider payload is stale. Use the state.db payload for replay, cover repeated recovery, and document the image-turn ownership exception.

Assisted-by: Hermes Agent:gpt-6-sol
Assisted-by: Codex:gpt-6-luna
2026-09-23 02:50:40 -06:00
nesquena-hermes 69655b1fc6 Merge master (exp-v0.52.348) into stage/7749-terminal-handoff
# Conflicts:
#	CHANGELOG.md
2026-09-23 08:37:23 +00:00
nesquena-hermes adda410ec0 Merge master (exp-v0.52.347) into stage/7749-terminal-handoff
# Conflicts:
#	CHANGELOG.md
2026-09-23 08:29:47 +00:00
nesquena-hermes 64106a790d Merge master (exp-v0.52.347) into stage/7751-journal-seq
# Conflicts:
#	CHANGELOG.md
#	docs/rfcs/webui-run-state-consistency-contract.md
2026-09-23 08:28:18 +00:00
Frank Song 2bd87a002d fix(run-journal): allocate writer sequence within append transaction 2026-09-23 13:03:31 +08:00
laitekin a0e5e32e46 Merge current master while preserving recoverable hidden polling (#7299) 2026-09-23 12:18:23 +08:00
Frank Song bbca954c5c fix: gate idle recovery on exact runtime status
(cherry picked from commit 35597715018e598bf24f0b708cbd32b039533a99)
2026-09-23 11:57:31 +08:00
Frank Song ca2153ec54 fix: bound sidebar idle recovery for missing terminal events
(cherry picked from commit 1be0e114b32eefe14f94837ed3cf78aadc14ca9b)
2026-09-23 11:57:31 +08:00
Frank Song 5dcda6f537 fix: preserve terminal handoff across idle sidebar refresh
(cherry picked from commit 85f1c2d34b62b0ade85f51ed2cf8c1cf56f5ab9e)
2026-09-23 11:57:31 +08:00
Frank Song 861a10ec34 fix: preserve successor ownership of reused Agents
(cherry picked from commit e4037f1d785aa86074e7cc84025942da5c0cc13a)
2026-09-23 11:56:10 +08:00
Frank Song acdcddf5c9 fix: make Agent cache publication atomic with Stop
(cherry picked from commit c40c43e0eee76a829b113d0119a476a651b60125)
2026-09-23 11:56:10 +08:00
Frank Song 281e91aca3 fix: publish newly constructed agents only after Stop admission
(cherry picked from commit 84a12254fc36aaff628b7e8e43daf48dfd648e67)
2026-09-23 11:56:10 +08:00