From 099d26204f1998f3c8181e7eb3581ac097a59d38 Mon Sep 17 00:00:00 2001 From: Tin Chi Lo Date: Wed, 2 Sep 2026 19:54:09 -0700 Subject: [PATCH 1/3] fix(ui): read the preset catalog at runtime in the vitest mock The autoRouterPresets mock imported litellm/proxy/public_endpoints/autorouter_presets.json as a module. That path sits outside ui/litellm-dashboard, the only directory the UI Dockerfile copies, so `next build` type-checking inside the image failed with "Cannot find module" and the ui-image job went red on every PR that touched an image-scan path. Read the file with fs at runtime instead; vitest still derives expectations from the real bundled catalog. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01HqEPCNLDrssxsuezhAaL4j --- .../tests/mocks/autoRouterPresets.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts b/ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts index f73faaa70fe..7356d92d99e 100644 --- a/ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts +++ b/ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts @@ -1,10 +1,18 @@ +import { readFileSync } from "fs"; +import { resolve } from "path"; import { vi } from "vitest"; -import bundledPresets from "../../../../litellm/proxy/public_endpoints/autorouter_presets.json"; import { hydratePresets, type AutoRouterPresetsResponse } from "@/lib/autorouter_presets"; // Derived from the real bundled catalog so a preset edit there flows into test expectations -// instead of redding on a stale copy. Exported as vi.fn so a test can override the query state. -export const BUNDLED_PRESETS = hydratePresets(bundledPresets as AutoRouterPresetsResponse); +// instead of redding on a stale copy. Read at runtime rather than imported as a module: the +// catalog lives outside ui/litellm-dashboard, so a module import fails `next build`'s type +// check inside the UI Docker image, whose build context is only this package. +// Exported as vi.fn so a test can override the query state. +const CATALOG_PATH = resolve(process.cwd(), "../../litellm/proxy/public_endpoints/autorouter_presets.json"); + +export const BUNDLED_PRESETS = hydratePresets( + JSON.parse(readFileSync(CATALOG_PATH, "utf8")) as AutoRouterPresetsResponse, +); export const LOADED_PRESETS_QUERY = { data: BUNDLED_PRESETS, From fcc9b813afcc8faece3dd44d3acfc59b0f503456 Mon Sep 17 00:00:00 2001 From: Tin Chi Lo Date: Wed, 2 Sep 2026 20:01:35 -0700 Subject: [PATCH 2/3] fix(ui): resolve the preset catalog relative to the mock, not cwd Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01HqEPCNLDrssxsuezhAaL4j --- ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts b/ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts index 7356d92d99e..cff417e6bfa 100644 --- a/ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts +++ b/ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts @@ -4,11 +4,8 @@ import { vi } from "vitest"; import { hydratePresets, type AutoRouterPresetsResponse } from "@/lib/autorouter_presets"; // Derived from the real bundled catalog so a preset edit there flows into test expectations -// instead of redding on a stale copy. Read at runtime rather than imported as a module: the -// catalog lives outside ui/litellm-dashboard, so a module import fails `next build`'s type -// check inside the UI Docker image, whose build context is only this package. -// Exported as vi.fn so a test can override the query state. -const CATALOG_PATH = resolve(process.cwd(), "../../litellm/proxy/public_endpoints/autorouter_presets.json"); +// instead of redding on a stale copy. Exported as vi.fn so a test can override the query state. +const CATALOG_PATH = resolve(__dirname, "../../../../litellm/proxy/public_endpoints/autorouter_presets.json"); export const BUNDLED_PRESETS = hydratePresets( JSON.parse(readFileSync(CATALOG_PATH, "utf8")) as AutoRouterPresetsResponse, From f62e87d28c0bd82da95479db188aa2309384583d Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Wed, 2 Sep 2026 21:42:47 -0700 Subject: [PATCH 3/3] fix(ui): read the preset catalog through the shared mock in the lib test --- ui/litellm-dashboard/src/lib/autorouter_presets.test.ts | 5 ++--- ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ui/litellm-dashboard/src/lib/autorouter_presets.test.ts b/ui/litellm-dashboard/src/lib/autorouter_presets.test.ts index 44ac6973a1c..76996447ac8 100644 --- a/ui/litellm-dashboard/src/lib/autorouter_presets.test.ts +++ b/ui/litellm-dashboard/src/lib/autorouter_presets.test.ts @@ -1,9 +1,8 @@ import { describe, it, expect } from "vitest"; -import bundledPresets from "../../../../litellm/proxy/public_endpoints/autorouter_presets.json"; +import { BUNDLED_PRESETS_RESPONSE } from "../../tests/mocks/autoRouterPresets"; import { hydratePresets, AutoRouterPreset, - AutoRouterPresetsResponse, getRequiredModelsInPreset, getMissingModelsInPreset, getRequiredModels, @@ -21,7 +20,7 @@ import { DEFAULT_ESCALATION_KEYWORDS } from "@/components/add_model/EscalationKe const groupsOnly = (models: Iterable) => buildModelAvailability(models, []); // Hydrated from the real bundled catalog so a catalog edit flows into these expectations. -const PRESETS = hydratePresets(bundledPresets as AutoRouterPresetsResponse); +const PRESETS = hydratePresets(BUNDLED_PRESETS_RESPONSE); const getAllPresets = (): AutoRouterPreset[] => PRESETS; const getPresetByKey = (key: string): AutoRouterPreset | undefined => PRESETS.find((p) => p.key === key); diff --git a/ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts b/ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts index cff417e6bfa..ac6da9bceba 100644 --- a/ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts +++ b/ui/litellm-dashboard/tests/mocks/autoRouterPresets.ts @@ -7,9 +7,9 @@ import { hydratePresets, type AutoRouterPresetsResponse } from "@/lib/autorouter // instead of redding on a stale copy. Exported as vi.fn so a test can override the query state. const CATALOG_PATH = resolve(__dirname, "../../../../litellm/proxy/public_endpoints/autorouter_presets.json"); -export const BUNDLED_PRESETS = hydratePresets( - JSON.parse(readFileSync(CATALOG_PATH, "utf8")) as AutoRouterPresetsResponse, -); +export const BUNDLED_PRESETS_RESPONSE = JSON.parse(readFileSync(CATALOG_PATH, "utf8")) as AutoRouterPresetsResponse; + +export const BUNDLED_PRESETS = hydratePresets(BUNDLED_PRESETS_RESPONSE); export const LOADED_PRESETS_QUERY = { data: BUNDLED_PRESETS,