feat(runtime): route goal through adapter seam#2544
Conversation
17b8b74 to
b23fb6c
Compare
|
CI is green on the amended Slice 3c implementation head Verification recap:
Scope remains intentionally narrow: adapter delegate methods plus |
|
Reviewing head b23fb6c: The slice does what it advertises and the response‑shape preservation test at A few observations worth weighing before merge. 1. Under the flag, the adapter is a structural no‑op —
|
|
Thanks — I pushed follow-up commit What changed:
Verification:
No scope expansion: still no backend queue scheduler, goal scheduler, runner/sidecar ownership move, new runtime-surrogate state, or public response-shape expansion. |
|
Follow-up CI is green on head
So the review-feedback follow-up is ready for maintainer review/release batching. |
718a4c7
… 0.51.92) (#560) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/nesquena/hermes-webui](https://github.com/nesquena/hermes-webui) | patch | `0.51.90` → `0.51.92` | --- ### Release Notes <details> <summary>nesquena/hermes-webui (ghcr.io/nesquena/hermes-webui)</summary> ### [`v0.51.92`](https://github.com/nesquena/hermes-webui/blob/HEAD/CHANGELOG.md#v05192--2026-05-19--Release-BP-stage-385--7-PR-full-sweep-batch--RFC-Slice-3c-clarification--workspace-tree-icon-alignment--project-move-cache-refresh--auto-compression-handoff-metadata--Grok-OAuth-provider-catalog--anonymous-custom-endpoint-picker-fallback--PWA-standalone-reload--pull-to-refresh) [Compare Source](nesquena/hermes-webui@v0.51.91...v0.51.92) ##### Fixed - **PR [#​2563](nesquena/hermes-webui#2563 by [@​Michaelyklam](https://github.com/Michaelyklam) (closes [#​2554](nesquena/hermes-webui#2554)) — Align workspace-tree file rows with sibling directory rows by reserving the same expand/collapse toggle slot for files via a new `.file-tree-toggle-placeholder` element. Expanded directories now show child files stepped in at the same icon column as child folders. Directory toggles and file interactions are unchanged; source-level regression coverage and before/after PNGs included. - **PR [#​2561](nesquena/hermes-webui#2561 by [@​nanookclaw](https://github.com/nanookclaw) (closes [#​2551](nesquena/hermes-webui#2551)) — Refresh the authoritative `_allSessions` cache when the project picker moves a session to/from a project. Previous code mutated only the shallow sidebar row copy, so `renderSessionListFromCache()` re-read the unchanged cache and repainted a stale project dot until the next `/api/sessions` poll healed the UI. Both the "Removed from project" and "Moved to <project>" branches now write the new `project_id` into `_allSessions[idx]` before re-rendering. - **PR [#​2567](nesquena/hermes-webui#2567 by [@​dso2ng](https://github.com/dso2ng) (refs [#​2477](nesquena/hermes-webui#2477)) — Surface automatic-compression handoff metadata through the `compressed` SSE event so the active browser stream keeps its completion card even after the backend rotates the session id from the origin to a compressed continuation. The event now carries both `old_session_id` and `new_session_id`/`continuation_session_id`; the frontend `compressed` listener accepts either, and the automatic-compression detail line names the compressed continuation session so the done state isn't silently dropped. - **PR [#​2568](nesquena/hermes-webui#2568 by [@​Michaelyklam](https://github.com/Michaelyklam) (closes [#​2545](nesquena/hermes-webui#2545)) — Add the Hermes Agent `xai-oauth` provider to the WebUI's OAuth provider catalog so Grok OAuth accounts authenticated via the Hermes CLI appear in Settings → Providers and the `/api/models` picker. The provider is treated as CLI-managed OAuth (no WebUI API-key form) and uses the live Hermes CLI model catalog when available with a Grok 4.20 static fallback. - **PR [#​2550](nesquena/hermes-webui#2550 by [@​espokaos-ops](https://github.com/espokaos-ops) (refs [#​2542](nesquena/hermes-webui#2542)) — Keep anonymous custom OpenAI-compatible endpoints in the model picker even when the configured `/v1/models` probe fails. Lightweight relays and llama-server-style deployments that authenticate `/v1/chat/completions` but not `/v1/models` no longer have their provider group silently dropped from the picker. Users can type a model id manually in the free-form input when no live catalog is available. ##### Added - **PR [#​2548](nesquena/hermes-webui#2548 by [@​espokaos-ops](https://github.com/espokaos-ops) — Add a PWA-standalone reload affordance. A small refresh button appears in the app titlebar (visible only under `@media (display-mode: standalone), (display-mode: fullscreen)`) so users running the WebUI as an installed home-screen PWA can reload without re-launching the app. Adds a complementary pull-to-refresh gesture on the messages container with an 80px threshold and a smooth-scroll-to-top guard so accidental triggers while reading history feel intentional. 4-viewport screenshots (390/1280/1440/1920, light/dark, hover/idle) included under `docs/pr-media/2548/`. ##### Documentation - **PR [#​2560](nesquena/hermes-webui#2560 by [@​Michaelyklam](https://github.com/Michaelyklam) (refs [#​1925](nesquena/hermes-webui#1925)) — Clarify the RuntimeAdapter Slice 3c state after [#​2544](nesquena/hermes-webui#2544) shipped. The RFC now distinguishes shipped `/api/goal` routing through `RuntimeAdapter.update_goal(...)` from the still-staged `queue_message(...)` protocol method, and explicitly warns not to add a new server-side queue endpoint or queue scheduler merely for adapter symmetry while `/queue` remains browser-side queue/drain behavior. ### [`v0.51.91`](https://github.com/nesquena/hermes-webui/blob/HEAD/CHANGELOG.md#v05191--2026-05-18--Release-BO-stage-384--5-PR-full-sweep-batch--reasoning-replay-history-fix--archive-extract-per-session-inbox--fallback-streaming-warnings--sanitized-custom-provider-env-hints--Slice-3c-queuegoal-adapter-routing) [Compare Source](nesquena/hermes-webui@v0.51.90...v0.51.91) ##### Fixed - **PR [#​2536](nesquena/hermes-webui#2536 by [@​Michaelyklam](https://github.com/Michaelyklam) (closes [#​2514](nesquena/hermes-webui#2514), refs [#​2535](nesquena/hermes-webui#2535)) — Stop reasoning-only Thinking entries from being replayed into provider-facing history as blank assistant turns. Long WebUI sessions were accumulating duplicated stale Thinking blocks and inflated Activity/tool metadata on later turns when reasoning-only display entries (from interrupted/canceled turns) got reinserted into the restored conversation history. The fix keeps visible Thinking cards in the transcript while filtering them out of provider-facing replay. Settled compact Activity rerenders now also clear previously inserted Thinking rows before rebuilding the visible transcript. - **PR [#​2520](nesquena/hermes-webui#2520 by [@​OneFat3](https://github.com/OneFat3) (refs [#​2247](nesquena/hermes-webui#2247)) — Route archive extraction (`/api/upload/extract`) through the per-session attachment inbox (`_session_attachment_dir`) instead of hardcoded `Path(s.workspace)`, matching the single-file upload path. Extracted archives now land at `<attachment_root>/<session_id>/<archive_stem>/` so session deletion cleanup covers them and per-session isolation is preserved when `HERMES_WEBUI_ATTACHMENT_DIR` is configured. - **PR [#​2505](nesquena/hermes-webui#2505 by [@​cyberdyne187](https://github.com/cyberdyne187) — Surface provider fallback and rate-limit lifecycle notices as auto-clearing fallback warnings in the streaming composer status. The new bridge in `_agent_status_callback` matches agent lifecycle messages containing `rate limited` / `switching to fallback` / `falling back` / `fallback activated` / `trying fallback` and emits them as `warning` events with `type=fallback`, so the existing `static/messages.js` warning channel surfaces them with the correct auto-clear contract instead of letting them drop silently. - **PR [#​2556](nesquena/hermes-webui#2556 by [@​Michaelyklam](https://github.com/Michaelyklam) (closes [#​2541](nesquena/hermes-webui#2541)) — Sanitize auto-generated custom-provider API-key environment variable names so endpoint-derived provider ids such as `custom:gpu.local-8000` use POSIX-safe names like `CUSTOM_GPU_LOCAL_8000_API_KEY`. Runtime custom-provider key resolution now checks the sanitized env var first and falls back to the legacy punctuation-preserving name with a one-shot deprecation warning. Configured literal `api_key` values and explicit `key_env` config are unchanged. ##### Documentation - **PR [#​2544](nesquena/hermes-webui#2544 by [@​Michaelyklam](https://github.com/Michaelyklam) (refs [#​1925](nesquena/hermes-webui#1925)) — Implement the first Slice 3c RuntimeAdapter control routing. `RuntimeAdapter` / `LegacyJournalRuntimeAdapter` now expose `queue_message(...)` and `update_goal(...)` as protocol-translator delegates, and the `/api/goal` route uses `update_goal(...)` only when `HERMES_WEBUI_RUNTIME_ADAPTER=legacy-journal` is enabled while preserving the legacy-direct response shape. The change keeps `/queue`'s existing browser-side drain semantics and goal post-turn evaluation in the current agent loop; no runner/sidecar, WebUI-owned queue, goal scheduler, cached-agent table, or execution-survives-restart claim is introduced. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19--> Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/560
Thinking Path
RuntimeAdapter.update_goal(...)whenHERMES_WEBUI_RUNTIME_ADAPTER=legacy-journalis enabled./queuedrain into/api/chat/start; this PR does not invent a backend queue or continuation scheduler.What Changed
queue_message(...)andupdate_goal(...)to theRuntimeAdapterprotocol andLegacyJournalRuntimeAdapter./api/goalthroughLegacyJournalRuntimeAdapter.update_goal(...)only under the default-offlegacy-journaladapter flag./api/goalresponse shape by returning the legacy goal payload rather than adapter-only fields.CHANGELOG.mdfor the Slice 3c implementation.Why It Matters
This advances #1925’s control-plane migration without jumping to runner/sidecar execution ownership. Goal controls now cross the same adapter seam as cancel, approval, and clarify under the opt-in flag, while post-turn goal evaluation and continuation remain owned by the existing agent conversation loop until the later runner/sidecar slice.
Verification
env -u HERMES_CONFIG_PATH -u HERMES_WEBUI_HOST /home/michael/.hermes/hermes-agent/venv/bin/python -m pytest tests/test_runtime_adapter_seam.py -q→15 passedenv -u HERMES_CONFIG_PATH -u HERMES_WEBUI_HOST /home/michael/.hermes/hermes-agent/venv/bin/python -m pytest tests/test_runtime_adapter_seam.py tests/test_goal_command_webui.py tests/test_issue_1932_goal_hook_unrelated_turns.py tests/test_stage326_pending_goal_continuation_race.py tests/test_1062_busy_input_modes.py tests/test_cmd_idle_fallback.py -q→83 passedenv -u HERMES_CONFIG_PATH -u HERMES_WEBUI_HOST /home/michael/.hermes/hermes-agent/venv/bin/python -m pytest tests/ -q→5956 passed, 6 skipped, 3 xpassed, 8 subtests passed in 92.72s/home/michael/.hermes/hermes-agent/venv/bin/python -m py_compile api/runtime_adapter.py api/routes.py tests/test_runtime_adapter_seam.py tests/test_goal_command_webui.pygit diff --checkRisks / Follow-ups
/queueremains browser-side queued input that drains through the existing chat-start path; this PR adds the adapter delegate seam but does not create a backend queue API or durable scheduler.update_goal(...)controls goal state mutations only. Post-turn goal evaluation and continuation still live in the existing agent loop, per the docs(runtime): define queue goal control gate #2509 gate.Model Used
OpenAI Codex GPT-5.5 via Hermes Agent, with terminal/file tools for code changes, tests, git, and GitHub PR workflow.
Refs #1925