From 5f431923aa0fb6d96e69d9d39de0ed1eea844509 Mon Sep 17 00:00:00 2001 From: Yaroslav Boiko Date: Fri, 27 Mar 2026 14:52:53 +0100 Subject: [PATCH] [NA] [FE] fix: assistant sidebar dev mode uses unhashed URLs and single source of truth Dev mode detection is now based on VITE_ASSISTANT_SIDEBAR_BASE_URL instead of import.meta.env.DEV. When set, the manifest fetch is skipped entirely and raw file paths are used through the Vite proxy. --- .../src/plugins/comet/AssistantSidebar.tsx | 22 ++++++++++++------- .../src/plugins/comet/constants/assistant.ts | 4 ++++ .../src/plugins/comet/useAssistantBackend.ts | 10 ++++----- 3 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 apps/opik-frontend/src/plugins/comet/constants/assistant.ts diff --git a/apps/opik-frontend/src/plugins/comet/AssistantSidebar.tsx b/apps/opik-frontend/src/plugins/comet/AssistantSidebar.tsx index dde44134d7a..aab8c3f2c69 100644 --- a/apps/opik-frontend/src/plugins/comet/AssistantSidebar.tsx +++ b/apps/opik-frontend/src/plugins/comet/AssistantSidebar.tsx @@ -14,9 +14,8 @@ import useAssistantBackend from "@/plugins/comet/useAssistantBackend"; import useProjectById from "@/api/projects/useProjectById"; import { BASE_API_URL } from "@/api/api"; import useAssistantSidebarConfig from "@/api/assistant-sidebar/useAssistantSidebarConfig"; +import { IS_ASSISTANT_DEV } from "@/plugins/comet/constants/assistant"; -const DEV_BASE_URL = import.meta.env.VITE_ASSISTANT_SIDEBAR_BASE_URL; -const IS_DEV = import.meta.env.DEV; const BRIDGE_PROTOCOL_VERSION = 1; const stopPropagation = (e: Event) => e.stopPropagation(); @@ -90,7 +89,7 @@ const createBridge = (refs: BridgeRefs): AssistantSidebarBridge => ({ refs.onRequestVisibility.current(false); break; default: - if (IS_DEV) { + if (IS_ASSISTANT_DEV) { console.warn( `[AssistantBridge] Unhandled sidebar event: "${event}"`, data, @@ -157,10 +156,8 @@ interface AssistantMeta { function useAssistantMeta(): AssistantMeta | null { const { data: config } = useAssistantSidebarConfig(); - // Local env var overrides the manifest base URL from the config endpoint - const resolvedManifestUrl = DEV_BASE_URL - ? `${DEV_BASE_URL}/manifest.json` - : config?.manifest_url || null; + const resolvedManifestUrl = + !IS_ASSISTANT_DEV && config?.manifest_url ? config.manifest_url : null; const manifestBase = resolvedManifestUrl ? resolvedManifestUrl.substring(0, resolvedManifestUrl.lastIndexOf("/")) @@ -175,7 +172,7 @@ function useAssistantMeta(): AssistantMeta | null { return { scriptUrl: `${manifestBase}/${manifest.js}`, cssUrl: manifest.css ? `${manifestBase}/${manifest.css}` : undefined, - shellUrl: IS_DEV ? "/assistant/shell" : `/assistant/${manifest.shell}`, + shellUrl: `/assistant/${manifest.shell}`, version: manifest.ver, }; }, @@ -184,6 +181,15 @@ function useAssistantMeta(): AssistantMeta | null { retry: 1, }); + if (IS_ASSISTANT_DEV) { + return { + scriptUrl: "/assistant/assistant.js", + cssUrl: "/assistant/assistant.css", + shellUrl: "/assistant/shell", + version: "dev", + }; + } + return data ?? null; } diff --git a/apps/opik-frontend/src/plugins/comet/constants/assistant.ts b/apps/opik-frontend/src/plugins/comet/constants/assistant.ts new file mode 100644 index 00000000000..89b61154abf --- /dev/null +++ b/apps/opik-frontend/src/plugins/comet/constants/assistant.ts @@ -0,0 +1,4 @@ +export const ASSISTANT_DEV_BASE_URL = + (import.meta.env.VITE_ASSISTANT_SIDEBAR_BASE_URL as string) ?? ""; + +export const IS_ASSISTANT_DEV = ASSISTANT_DEV_BASE_URL !== ""; diff --git a/apps/opik-frontend/src/plugins/comet/useAssistantBackend.ts b/apps/opik-frontend/src/plugins/comet/useAssistantBackend.ts index 2d31531f41f..1e002f23e6a 100644 --- a/apps/opik-frontend/src/plugins/comet/useAssistantBackend.ts +++ b/apps/opik-frontend/src/plugins/comet/useAssistantBackend.ts @@ -2,8 +2,8 @@ import { useEffect, useRef, useState } from "react"; import { useQuery } from "@tanstack/react-query"; import cometApi from "@/plugins/comet/api"; import { useActiveWorkspaceName } from "@/store/AppStore"; +import { IS_ASSISTANT_DEV } from "@/plugins/comet/constants/assistant"; -const IS_DEV = import.meta.env.DEV; const HEALTH_POLL_INTERVAL_MS = 5000; const HEALTH_POLL_TIMEOUT_MS = 2 * 60 * 1000; // 2 minutes @@ -69,14 +69,14 @@ export default function useAssistantBackend( ); return { baseUrl, enabled: true }; }, - enabled: !IS_DEV && configEnabled && !!workspaceName, + enabled: !IS_ASSISTANT_DEV && configEnabled && !!workspaceName, staleTime: Infinity, retry: 2, }); const baseUrl = computeResult?.baseUrl ?? null; const computeEnabled = computeResult?.enabled ?? false; - const shouldPollHealth = !IS_DEV && !!baseUrl && computeEnabled; + const shouldPollHealth = !IS_ASSISTANT_DEV && !!baseUrl && computeEnabled; // Track when health polling started — only reset when baseUrl changes // (not on transient shouldPollHealth flickers) @@ -133,8 +133,8 @@ export default function useAssistantBackend( }, }); - // Dev mode — static URL, no network calls (queries are disabled via enabled: !IS_DEV) - if (IS_DEV) return DEV_RESULT; + // Dev mode or local override — static URL, no network calls + if (IS_ASSISTANT_DEV) return DEV_RESULT; if (computeResult && !computeResult.enabled) return notReadyResult(null); if (computeError) return notReadyResult((computeError as Error).message);