Description
URLUtil.getApiServerBaseUrl() (src/utils/url-util.ts) returns runtimeConfig.backendUrl || ''. When no backendUrl is configured, the app falls back to root-relative API calls (e.g. GET /list-apps).
This breaks any deployment where the built adk-web bundle is served behind a path-prefixing reverse proxy that strips its prefix before forwarding to the backend — e.g. a proxy routing /agents/my-agent/* -> container (prefix stripped on the way in). The dev-ui itself loads fine at /agents/my-agent/dev-ui/, but its API calls go out root-relative to /list-apps, which the proxy has no route for → 404.
runtime-config.json is meant to be customized via set-backend.js, but that's a build-time script (npm run serve --backend=...) run against the source before ng build. Backends that embed an already-built adk-web bundle as a dependency artifact (e.g. adk-java's AdkWebServer, which serves classpath:/browser/** straight out of the google-adk-dev jar) have no build step to run this against and can't easily rewrite a file sealed inside a jar at runtime. So today there's no way for such a backend to get a correct backendUrl without patching the frontend itself.
This also affects getBaseUrlWithoutPath(), which hardcodes origin + '/dev-ui/' and drops any proxy prefix the same way (used as the OAuth redirectUri).
Proposed fix
When runtimeConfig.backendUrl isn't set, derive a same-origin default from window.location instead of defaulting to root-relative — specifically, preserve whatever path prefix the app was itself loaded under (i.e. strip the /dev-ui... suffix off location.pathname to recover the mount root, then default backendUrl to origin + mountRoot). This makes the bundle work behind any path-prefixing reverse proxy out of the box, for any backend embedding it, with no change needed on the backend side — while an explicit runtimeConfig.backendUrl (e.g. from set-backend.js in local dev) still takes precedence.
I have a fix + tests ready and will open a PR referencing this issue.
Description
URLUtil.getApiServerBaseUrl()(src/utils/url-util.ts) returnsruntimeConfig.backendUrl || ''. When nobackendUrlis configured, the app falls back to root-relative API calls (e.g.GET /list-apps).This breaks any deployment where the built
adk-webbundle is served behind a path-prefixing reverse proxy that strips its prefix before forwarding to the backend — e.g. a proxy routing/agents/my-agent/* -> container(prefix stripped on the way in). The dev-ui itself loads fine at/agents/my-agent/dev-ui/, but its API calls go out root-relative to/list-apps, which the proxy has no route for → 404.runtime-config.jsonis meant to be customized viaset-backend.js, but that's a build-time script (npm run serve --backend=...) run against the source beforeng build. Backends that embed an already-builtadk-webbundle as a dependency artifact (e.g.adk-java'sAdkWebServer, which servesclasspath:/browser/**straight out of thegoogle-adk-devjar) have no build step to run this against and can't easily rewrite a file sealed inside a jar at runtime. So today there's no way for such a backend to get a correctbackendUrlwithout patching the frontend itself.This also affects
getBaseUrlWithoutPath(), which hardcodesorigin + '/dev-ui/'and drops any proxy prefix the same way (used as the OAuthredirectUri).Proposed fix
When
runtimeConfig.backendUrlisn't set, derive a same-origin default fromwindow.locationinstead of defaulting to root-relative — specifically, preserve whatever path prefix the app was itself loaded under (i.e. strip the/dev-ui...suffix offlocation.pathnameto recover the mount root, then defaultbackendUrltoorigin + mountRoot). This makes the bundle work behind any path-prefixing reverse proxy out of the box, for any backend embedding it, with no change needed on the backend side — while an explicitruntimeConfig.backendUrl(e.g. fromset-backend.jsin local dev) still takes precedence.I have a fix + tests ready and will open a PR referencing this issue.