Commit Graph
2 Commits
Author SHA1 Message Date
e0b115757b fix: route runtime services through server_info (#16090)
Co-authored-by: neubig <398875+neubig@users.noreply.github.com>
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: neubig <neubig@users.noreply.github.com>
2026-08-02 22:39:43 -04:00
7dbe8fd7de fix: populate <RUNTIME_SERVICES> in static builds so automations work (#1125)
* fix: populate <RUNTIME_SERVICES> in static builds so automations work

The agent's <RUNTIME_SERVICES> system-prompt block is built from
VITE_RUNTIME_SERVICES_INFO, which the dev launchers set at build time.
Static builds (the Docker image and the published binary) run
`npm run build` without it, so the block is dropped and the agent does
not know how to reach the local automation backend — it falls back to
the cloud API (app.all-hands.dev) and automation creation fails.

Inject the info at serve time, mirroring the existing --session-api-key
path:

- scripts/static-server.mjs: new --runtime-services-info flag injects
  the JSON as window.__AGENT_CANVAS_RUNTIME_SERVICES_INFO__
- src/api/agent-server-adapter.ts: parseRuntimeServicesInfo() falls back
  to that window global when the env var is empty
- docker/entrypoint.sh: builds the JSON from the sandbox-facing service
  URLs (AGENT_SERVER_URL, AUTOMATION_BASE_URL) and passes it to the
  static server(s)

Refs #1098

* refactor: extract runtime-services-info into a shared module

Replace the inline JSON building in docker/entrypoint.sh with a single
source of truth for the <RUNTIME_SERVICES> shape.

buildRuntimeServicesInfo now lives in scripts/runtime-services-info.mjs
(moved out of dev-safe.mjs, which re-exports it for back-compat) and
gains:
- optional full-URL overrides (agentServerUrl, automation.url) so the
  container can pass its runtime-resolved AGENT_SERVER_URL /
  AUTOMATION_BASE_URL and use 127.0.0.1 (avoiding IPv6 loopback) instead
  of build-time ports, and
- a CLI entrypoint so docker/entrypoint.sh emits the JSON by running the
  same builder the dev stack uses, rather than a hand-rolled node -e blob.

The Dockerfile ships the new dependency-free module into the image.

* fix: pass --runtime-services-info in static mode and verify in automation e2e

- startStaticFrontend() in dev-with-automation.mjs now builds the
  runtime-services info JSON via buildAutomationRuntimeServicesInfo()
  and passes it to static-server.mjs via --runtime-services-info.
  Without this, the npm binary / dev:static path served pre-built
  frontends that never populated the agent's <RUNTIME_SERVICES>
  system-prompt block (the Docker entrypoint already did this).

- The mock-LLM automation e2e test now verifies that the
  <RUNTIME_SERVICES> block is present in the system messages sent
  to the LLM, and that it includes the expected service entries
  (Agent Server, Automation backend, /api/automation).

Co-authored-by: openhands <openhands@all-hands.dev>

* docs: update AGENTS.md with runtime-services-info plumbing changes

Co-authored-by: openhands <openhands@all-hands.dev>

---------

Co-authored-by: Rohit Malhotra <rohitvinodmalhotra@gmail.com>
Co-authored-by: openhands <openhands@all-hands.dev>
2026-06-04 18:28:35 +00:00