Skip to content

fix: Hermes Studio compat with gateway v0.20 api_server - #24

Open
bhongong wants to merge 8 commits into
JPeetz:mainfrom
bhongong:fix/v0.20-gateway-compat
Open

fix: Hermes Studio compat with gateway v0.20 api_server#24
bhongong wants to merge 8 commits into
JPeetz:mainfrom
bhongong:fix/v0.20-gateway-compat

Conversation

@bhongong

Copy link
Copy Markdown

Summary

Wiring fixes to make Hermes Studio work correctly against the Hermes gateway v0.18+ / v0.20 api_server (the aiohttp platform). The studio was built against the older FastAPI webapi surface, so several features degraded or broke on current gateways.

Changes (7 commits)

  1. API envelopeslistSessions/getMessages now accept the gateway's OpenAI-style {object:'list', data:[...]} responses (were expecting {items}/api/history crashed with undefined.slice).
  2. HERMES_HOME resolution — new src/server/hermes-home.ts (HERMES_HOME env, fallback ~/.hermes) swept across 17 server files that hardcoded ~/.hermes. On Windows (%LOCALAPPDATA%\hermes) the UI previously read an empty/wrong home (config, skills, memories).
  3. Config as a local feature — the gateway has no /api/config, so the config capability probe is false and "Hermes Agent Settings" rendered "Not available on this backend". Mark config available in feature-gates + useFeatureAvailable, wire providers/settings screens to the local /api/hermes-config route, and make MCP servers GET read local config.yaml.
  4. Model pickers — composer + settings called dead /api/available-models; now use /api/model/options (the dashboard picker inventory) so the dropdown lists the provider's real models.
  5. Dev proxy shadowing + CSP — the vite server.proxy['/api/hermes-proxy'] shadowed the TanStack route (which attaches the gateway token) → 401s in dev only; removed. CSP: allow cdn.jsdelivr.net (Monaco) + Google Fonts; frame-ancestors is ignored in <meta> so send X-Frame-Options: DENY as a real header instead.
  6. Terminal + tests — guard fitAddon.fit() on hidden (inactive) tabs to stop the xterm reading 'dimensions' crash; add closeEventStore() and call it before rmSync in tests so temp sqlite dirs delete on Windows.
  7. Build/deps — declare missing katex, remark-math, rehype-katex; make the dev script cross-platform (drop POSIX NODE_OPTIONS=... syntax).

Verification

  • npm run test 190/190 green (was 170/20 fail on Windows)
  • npm run build OK
  • Manually verified against a v0.20 gateway: chat, model picker, settings, terminal, files editor, MCP, history, session-status

The v0.20 api_server returns {object:'list', data:[...]} for /api/sessions
and /api/sessions/{id}/messages, but listSessions/getMessages expected an
{items} shape, so /api/history crashed on undefined.slice. Accept either.
The agent resolves its home from HERMES_HOME first (hermes_cli
_resolved_home), but the studio hardcoded ~/.hermes in 17 server files. On
Windows hosts where the real home is %LOCALAPPDATA%\\hermes this made the UI
read an empty/wrong config, skills, and memories. Add a shared hermesHome()
helper (HERMES_HOME env, falling back to ~/.hermes) and use it everywhere.
…Settings

The gateway api_server has no /api/config (admin_config_rw: false), so the
'config' capability probe is false and the Hermes Agent Settings screen
rendered 'Not available on this backend'. Config is served locally by
/api/hermes-config (reads/writes config.yaml), so: mark 'config' always
available in both feature-gate helpers, wire the providers/settings screens
to the local config route, and make MCP servers GET read local config.yaml.
…ntory

The composer and settings dialog called /api/available-models, which the
v0.20 api_server doesn't expose, so they degraded to the single /v1/models
entry. /api/model/options mirrors the dashboard picker inventory (48
providers, per-provider model lists). Point both pickers at it and parse the
providers[] shape; authenticate the gateway fetch server-side.
- Remove the /api/hermes-proxy dev-middleware proxy: it forwarded to the
  gateway without the bearer token and shadowed the TanStack route handler
  (which authenticates server-side), causing 401s in dev only.
- CSP: allow cdn.jsdelivr.net (Monaco editor) and Google Fonts; frame-ancestors
  is ignored in a <meta> CSP, so send X-Frame-Options: DENY as a real header
  (dev + prod) and drop the meta directive.
…st teardown

- terminal-workspace: fitAddon.fit() ran while the tab container is
  display:none (inactive tab), crashing xterm's renderer (reading
  'dimensions'). Wrap the mount-time fit in a try/catch; the existing
  refit-on-visible effect sizes it once active.
- event-store/analytics tests: close the sqlite handle (new
  closeEventStore()) before rmSync so temp dirs delete on Windows (EPERM).
markdown.tsx imports katex/remark-math/rehype-katex but they were never
declared, so install/build broke for the KaTeX chat renderer. The dev script
used POSIX env syntax (NODE_OPTIONS=... vite dev) that fails on Windows;
drop it so 'npm run dev' works cross-platform.
@vercel

vercel Bot commented Aug 14, 2026

Copy link
Copy Markdown

@bhongong is attempting to deploy a commit to the Joerg Peetz's projects Team on Vercel.

A member of the Team first needs to authorize it.

…token

Jobs, approvals, and skill-install routes fetched the gateway without the
API_SERVER_KEY bearer token, so those features 401'd on gateways that
require auth. Export authHeaders() from gateway-capabilities and apply it to
every direct fetch (hermes-jobs, hermes-jobs/\, approvals approve/deny,
skills install).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant