Skip to content

fix(gateway): respect NEXT_PUBLIC_GATEWAY_URL for hermes/demo adapter defaults#3

Open
andreab67 wants to merge 2 commits into
fathah:mainfrom
andreab67:feat/respect-public-gateway-url-for-hermes-demo
Open

fix(gateway): respect NEXT_PUBLIC_GATEWAY_URL for hermes/demo adapter defaults#3
andreab67 wants to merge 2 commits into
fathah:mainfrom
andreab67:feat/respect-public-gateway-url-for-hermes-demo

Conversation

@andreab67
Copy link
Copy Markdown

Summary

resolveDefaultGatewayProfile() already honors NEXT_PUBLIC_GATEWAY_URL for the openclaw adapter via the DEFAULT_UPSTREAM_GATEWAY_URL constant defined a few lines above:

const DEFAULT_UPSTREAM_GATEWAY_URL =
  process.env.NEXT_PUBLIC_GATEWAY_URL || "ws://localhost:18789";

…but the demo / hermes branch returned a hardcoded "ws://localhost:18789", ignoring the env var entirely. Because Next.js inlines NEXT_PUBLIC_* env vars at build time, that literal got compiled into 5+ chunks in .next/, so split-host deployments (browser on laptop, adapter on a separate VM) had no way to make the client-side WebSocket reach the adapter without a post-build sed of the bundle.

This is a one-line behavioral fix: switch the demo / hermes default to the same DEFAULT_UPSTREAM_GATEWAY_URL constant the openclaw branch uses.

Diff

     case "demo":
     case "hermes":
-      return { url: "ws://localhost:18789", token: "" };
+      // Honor NEXT_PUBLIC_GATEWAY_URL for the hermes/demo default the same
+      // way openclaw does — DEFAULT_UPSTREAM_GATEWAY_URL already wraps the
+      // env var with a localhost fallback, so single-host installs are
+      // unchanged but split-host (browser ≠ adapter) deployments work
+      // without a post-build sed of the .next bundle.
+      return { url: DEFAULT_UPSTREAM_GATEWAY_URL, token: "" };

Why this matters

Real-world deployment context: hermes-agent + hermes-office adapter run on a Hyper-V VM at `192.168.x.y`. The Studio UI is served via a Caddy reverse-proxy on the same VM at `hermes.andrea-house.com:3000`. The browser opens that URL on a separate workstation. Without this change, the browser-side bundle tries to connect to `ws://localhost:18789` — which is the workstation's localhost, not the VM's — and fails with ECONNREFUSED. The only workaround was sed-ing every `.next/` chunk on every rebuild, which is what we documented at hermes-vps:scripts/hermes-office-restore-patches.sh.

This change makes the env-var path Just Work for hermes and demo adapters, the same way it already does for openclaw.

Backwards compatibility

Fully backwards compatible:

  • DEFAULT_UPSTREAM_GATEWAY_URL falls back to \"ws://localhost:18789\" when `NEXT_PUBLIC_GATEWAY_URL` is unset, so single-host installs see the exact same string as before.
  • No new env var is added — this just makes the existing one work in two more code paths.

Pairs with

#2 — adds server-side HERMES_ADAPTER_HOST env var so the adapter can bind on a non-loopback NIC. Together, the two PRs remove the last brittle local patches needed to run hermes-office on a LAN-served VM.

Test plan

  • Default behavior unchanged: with NEXT_PUBLIC_GATEWAY_URL unset, DEFAULT_UPSTREAM_GATEWAY_URL falls back to \"ws://localhost:18789\" exactly as before
  • With NEXT_PUBLIC_GATEWAY_URL=wss://hermes.andrea-house.com:18789, the constant resolves to that value at build time and gets inlined into the hermes / demo adapter default
  • openclaw branch behavior is unchanged (it already used DEFAULT_UPSTREAM_GATEWAY_URL)
  • No new dependencies, no API surface changes

🤖 Generated with Claude Code

… defaults

resolveDefaultGatewayProfile() already honors NEXT_PUBLIC_GATEWAY_URL
for the openclaw adapter via DEFAULT_UPSTREAM_GATEWAY_URL, but the
demo/hermes branch returned a hardcoded "ws://localhost:18789",
ignoring the env var. That literal got inlined into 5+ chunks in the
.next/ bundle at build time, so split-host deployments (browser on
laptop, adapter on a separate VM) had to post-build sed the bundle to
make the WebSocket reachable.

This switches the demo/hermes default to the same DEFAULT_UPSTREAM_GATEWAY_URL
constant the openclaw branch uses. Single-host installs are unchanged
(DEFAULT_UPSTREAM_GATEWAY_URL falls back to "ws://localhost:18789"
when the env var is unset). Split-host installs now Just Work by
exporting NEXT_PUBLIC_GATEWAY_URL=wss://your-host:18789 before
`npm run build`.

Pairs with PR fathah#2 (server-side HERMES_ADAPTER_HOST env var). Together
they remove the last two brittle local patches needed to run a
hermes-office instance on a LAN-served VM.
@andreab67
Copy link
Copy Markdown
Author

Build verification

Ran the test plan locally on this branch (andreab67/hermes-office:feat/respect-public-gateway-url-for-hermes-demo, node 25.9.0, Next 16.1.7, npm install clean).

Build #1NEXT_PUBLIC_GATEWAY_URL unset (single-host fallback)

$ rm -rf .next && unset NEXT_PUBLIC_GATEWAY_URL && npm run build
$ grep -lc 'ws://localhost:18789' .next/static/chunks/*.js .next/server/chunks/*.js
1  .next/static/chunks/81b0fd8594e480fe.js                                ← gateway-client default
4  .next/static/chunks/c8f78d6f5451afd6.js                                ← UI placeholders (SettingsPanel, ConnectStep, GatewayConnectScreen)
1  .next/server/chunks/src_lib_studio_settings-store_ts_6b8813cf._.js    ← server-only fallback
$ grep -lc 'wss://hermes' .next/static/chunks/*.js
0

5 occurrences of ws://localhost:18789 in client chunks — the localhost fallback is preserved exactly as before. Single-host installs unchanged.

Build #2NEXT_PUBLIC_GATEWAY_URL=wss://hermes.andrea-house.com:18789 (split-host)

$ rm -rf .next && export NEXT_PUBLIC_GATEWAY_URL='wss://hermes.andrea-house.com:18789' && npm run build
$ grep -lc 'ws://localhost:18789' .next/static/chunks/*.js .next/server/chunks/*.js
4  .next/static/chunks/c8f78d6f5451afd6.js                                ← UI placeholder text only (intentional)
1  .next/server/chunks/src_lib_studio_settings-store_ts_6b8813cf._.js    ← server-only fallback (intentional)
$ grep -lc 'wss://hermes\.andrea-house\.com:18789' .next/static/chunks/*.js
1  .next/static/chunks/7962bbfd092c0b41.js                                ← gateway-client default — env value inlined ✓

The 81b0fd… client chunk that contained the hardcoded "ws://localhost:18789" for the hermes/demo branch is gone. Its replacement chunk (7962bb…, hash changed because content changed) contains the env value wss://hermes.andrea-house.com:18789. The fix works as intended.

What's intentionally NOT changed by this PR

  • The 4 occurrences in c8f78d6f… are placeholder= UI text in SettingsPanel.tsx, ConnectStep.tsx, GatewayConnectScreen.tsx — display hints, not connection defaults.
  • The 1 occurrence in src_lib_studio_settings-store_ts_… is server-side only (fs.readFileSync call site) and never ships to the browser.

Both are intentional separate concerns and out of scope for this 1-line fix.

🤖 Verified with Claude Code

Copy link
Copy Markdown

@uzzaidev uzzaidev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review — UzzAI Hermes Lab

Reviewed by: @uzzaidev (Hermes agentic review)


1. O que a mudança faz

Alinha o comportamento dos adapters demo e hermes com o adapter openclaw, substituindo o URL hardcoded ws://localhost:18789 pela constante DEFAULT_UPSTREAM_GATEWAY_URL que já respeita NEXT_PUBLIC_GATEWAY_URL.

2. Corretude da lógica

✅ Correta. DEFAULT_UPSTREAM_GATEWAY_URL já está definida no mesmo arquivo com fallback adequado:

const DEFAULT_UPSTREAM_GATEWAY_URL =
  process.env.NEXT_PUBLIC_GATEWAY_URL || 'ws://localhost:18789'

A mudança é mínima e cirúrgica — exatamente o necessário.

3. Riscos e edge cases

  • Sem risco para single-host: fallback garante comportamento idêntico quando NEXT_PUBLIC_GATEWAY_URL não está definido.
  • Atenção em builds CI/CD: NEXT_PUBLIC_* é inlined em build time pelo Next.js. Se o env var não estiver disponível no momento do build, o fallback localhost será compilado no bundle — comportamento esperado e documentado.
  • Edge case WSS vs WS: se o deploy usar TLS, NEXT_PUBLIC_GATEWAY_URL deve ser wss:// — responsabilidade do operador, não do código.

4. Backwards compatibility

✅ Totalmente compatível. Sem NEXT_PUBLIC_GATEWAY_URL, resultado é string idêntica à anterior.

5. Qualidade do código

✅ Comentário explicativo bem escrito e justificado. Uma linha de mudança efetiva com 5 linhas de contexto — proporção adequada para uma fix de segurança de configuração.

6. Veredito

✅ APPROVE

Fix legítima, bem documentada, zero risco de regressão para instalações single-host. Resolve um problema real de deploy split-host sem adicionar complexidade.

7. Score

9/10 — ponto a menos apenas pela ausência de teste automatizado, mas reconheço que testar comportamento de NEXT_PUBLIC_* em Next.js é não-trivial por ser compile-time.


Review gerada pelo pipeline agentic Hermes Lab — Claude Code via @uzzaidev

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.

7 participants