From acf62868a1cb502fb6e62cd03e89d8330825bca7 Mon Sep 17 00:00:00 2001 From: Monica Khoury Date: Wed, 19 Aug 2026 11:53:48 +0300 Subject: [PATCH] fix: sync AI assistant project context for org-view support tickets --- .../ui/AIAssistantPanel/AssistantChat.tsx | 9 +++++++-- .../SupportAssistantSuccessCardContent.tsx | 20 ++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/apps/studio/components/ui/AIAssistantPanel/AssistantChat.tsx b/apps/studio/components/ui/AIAssistantPanel/AssistantChat.tsx index 5bdb8363df2..d22e213052f 100644 --- a/apps/studio/components/ui/AIAssistantPanel/AssistantChat.tsx +++ b/apps/studio/components/ui/AIAssistantPanel/AssistantChat.tsx @@ -168,14 +168,19 @@ export const AssistantChat = ({ const currentTable = tables?.find((t) => t.id.toString() === entityId) const currentSchema = searchParams?.get('schema') ?? 'public' - // Update context in state + // Update context in state. Skip when there's no project in the URL (e.g. org-level + // pages) and the open chat is a support chat that already set its own project + // context (see SupportAssistantSuccessCardContent) — otherwise this would clobber + // that context back to undefined as soon as the panel mounts. useEffect(() => { + if (!project?.ref && currentChat?.supportMetadata?.projectRef) return + state.setContext({ projectRef: project?.ref, orgSlug: selectedOrganization?.slug, connectionString: project?.connectionString ?? '', }) - }, [project?.ref, project?.connectionString, selectedOrganization?.slug, state]) + }, [project?.ref, project?.connectionString, selectedOrganization?.slug, state, currentChat]) const track = useTrack() diff --git a/apps/studio/components/ui/AIAssistantPanel/SupportAssistantSuccessCardContent.tsx b/apps/studio/components/ui/AIAssistantPanel/SupportAssistantSuccessCardContent.tsx index 8438a6d3f34..d0f7c01ea5d 100644 --- a/apps/studio/components/ui/AIAssistantPanel/SupportAssistantSuccessCardContent.tsx +++ b/apps/studio/components/ui/AIAssistantPanel/SupportAssistantSuccessCardContent.tsx @@ -19,6 +19,7 @@ import { buildSupportAssistantPrompt } from '@/components/interfaces/Support/Sup import type { SubmittedSupportRequest } from '@/components/interfaces/Support/SupportForm.state' import { NO_PROJECT_MARKER } from '@/components/interfaces/Support/SupportForm.utils' import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider' +import { useProjectDetailQuery } from '@/data/projects/project-detail-query' import { useTrack } from '@/lib/telemetry/track' import { useAiAssistantState, @@ -60,10 +61,25 @@ export function SupportAssistantSuccessCardContent({ const assistantPrompt = useMemo(() => buildSupportAssistantPrompt(request), [request]) + // The org-view support form resolves projectRef itself (defaulting to the + // first project in the org) rather than reading it from the URL, so the + // assistant's context needs the connection string fetched explicitly too. + const { data: projectDetail } = useProjectDetailQuery( + { ref: request.projectRef }, + { enabled: hasAssistantContext } + ) + useEffect(() => { if (!hasAssistantContext) return + if (!projectDetail?.connectionString) return if (createdChatIdRef.current) return + aiAssistantState.setContext({ + projectRef: request.projectRef, + orgSlug: request.organizationSlug, + connectionString: projectDetail.connectionString, + }) + const newChatId = aiAssistant.newChat({ name: 'Support request', initialMessage: assistantPrompt, @@ -71,7 +87,9 @@ export function SupportAssistantSuccessCardContent({ createdChatIdRef.current = newChatId setChatId(newChatId) - }, [aiAssistant, assistantPrompt, hasAssistantContext]) + // aiAssistantState is a stable context value (same identity across renders) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [aiAssistant, assistantPrompt, hasAssistantContext, projectDetail?.connectionString, request]) const handleOpenAssistant = () => { track(