fix(ui): keep runtime backend discovery under the UI prefix

This commit is contained in:
Martin Collado 2026-10-15 21:10:50 +02:00
parent e96292479f
commit aa7d2afa66
No known key found for this signature in database
GPG key ID: 566182E0C35B0EC8
2 changed files with 27 additions and 1 deletions

View file

@ -1038,6 +1038,29 @@ describe("getUiConfig runtime backend discovery", () => {
return { networking, mockFetch };
};
it("loads static runtime configuration from the UI prefix independently of the selected worker", async () => {
const mockFetch = vi
.fn()
.mockResolvedValueOnce({
ok: true,
json: async () => ({ backend_url: "https://backend.example.com" }),
} as Response)
.mockResolvedValueOnce({
ok: true,
json: async () => ({ ...discoveryConfig(), server_root_path: "/services/llm" }),
} as Response);
vi.stubGlobal("fetch", mockFetch);
const networking = await loadFreshNetworking();
const { setServerRootPath } = await import("@/lib/serverRootPath");
setServerRootPath("/services/llm");
networking.switchToWorkerUrl("https://worker.example.com/worker-mount");
await networking.getUiConfig();
expect(mockFetch).toHaveBeenNthCalledWith(1, "/services/llm/ui/litellm-runtime-config.json", { cache: "no-store" });
expect(mockFetch.mock.calls[1][0]).toBe("https://backend.example.com/litellm/.well-known/litellm-ui-config");
});
it("uses a normalized runtime backend URL for discovery and the management fallback", async () => {
const mockFetch = vi
.fn()

View file

@ -566,7 +566,10 @@ export const getUiConfig = async () => {
: await (async (): Promise<string | null> => {
try {
// eslint-disable-next-line no-restricted-syntax -- read the UI static config before the API origin is known
const response = await fetch("/ui/litellm-runtime-config.json", { cache: "no-store" });
const response = await fetch(
`${serverRootPath === "/" ? "" : serverRootPath}/ui/litellm-runtime-config.json`,
{ cache: "no-store" },
);
if (!response.ok) return null;
const runtimeConfig: unknown = await response.json();
if (