From 909cc5161b483aa3d26fe2d863dac3e1b26fe575 Mon Sep 17 00:00:00 2001 From: S Kumar Dhananjaya Date: Wed, 7 Jan 2026 02:23:41 +0530 Subject: [PATCH 1/2] fix(web): improve citation click reliability during streaming - Switch citation wrapper from `` to `` to leverage native link behavior, which is more robust during DOM churn. - Memoize props in `MemoizedTextComponents` to stabilize the Virtual DOM and prevent unnecessary re-renders of citations as message chunks arrive. - Add `stopPropagation` and `preventDefault` to citation click handlers to ensure consistent behavior across a " --- .../chat/message/MemoizedTextComponents.tsx | 42 ++++++++++++------- .../components/search/results/Citation.tsx | 15 ++++--- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/web/src/app/chat/message/MemoizedTextComponents.tsx b/web/src/app/chat/message/MemoizedTextComponents.tsx index 2c93124edec..946d7560d7e 100644 --- a/web/src/app/chat/message/MemoizedTextComponents.tsx +++ b/web/src/app/chat/message/MemoizedTextComponents.tsx @@ -4,7 +4,7 @@ import { DocumentCardProps, } from "@/components/search/results/Citation"; import { LoadedOnyxDocument, OnyxDocument } from "@/lib/search/interfaces"; -import React, { memo, JSX } from "react"; +import React, { memo, JSX, useMemo } from "react"; import isEqual from "lodash/isEqual"; import { SourceIcon } from "@/components/SourceIcon"; import { WebResultIcon } from "@/components/WebResultIcon"; @@ -78,13 +78,17 @@ export const MemoizedAnchor = memo( /> ); } - const associatedDocInfo = associatedDoc - ? { - ...associatedDoc, - icon: icon as any, - link: associatedDoc.link, - } - : undefined; + const associatedDocInfo = useMemo( + () => + associatedDoc + ? { + ...associatedDoc, + icon: icon as any, + link: associatedDoc.link, + } + : undefined, + [associatedDoc, icon] + ); return ( { const value = rest.children; - const questionCardProps: QuestionCardProps | undefined = - question && openQuestion - ? { + const questionCardProps: QuestionCardProps | undefined = useMemo( + () => + question && openQuestion + ? { question: question, openQuestion: openQuestion, } - : undefined; + : undefined, + [question, openQuestion] + ); - const documentCardProps: DocumentCardProps | undefined = - document && updatePresentingDocument - ? { + const documentCardProps: DocumentCardProps | undefined = useMemo( + () => + document && updatePresentingDocument + ? { url: document.link, document: document as LoadedOnyxDocument, updatePresentingDocument: updatePresentingDocument!, } - : undefined; + : undefined, + [document, updatePresentingDocument] + ); if (value?.toString().startsWith("*")) { return ; diff --git a/web/src/components/search/results/Citation.tsx b/web/src/components/search/results/Citation.tsx index 5b949b60d24..a59dbf1a38a 100644 --- a/web/src/components/search/results/Citation.tsx +++ b/web/src/components/search/results/Citation.tsx @@ -71,13 +71,16 @@ export function Citation({ - { + { + e.preventDefault(); + e.stopPropagation(); document_info?.document ? openDocument( - document_info.document, - document_info.updatePresentingDocument - ) + document_info.document, + document_info.updatePresentingDocument + ) : question_info?.question ? question_info.openQuestion(question_info.question) : null; @@ -94,7 +97,7 @@ export function Citation({ {citationText} - + Date: Wed, 7 Jan 2026 02:37:09 +0530 Subject: [PATCH 2/2] fix(web): ensure assistant tool states are correctly initialized on refresh (#7207) - Enable in to allow form values to update once asynchronous tool data is available. - Add a loading overlay to [AgentEditorPage](cci:1://file:///Users/kumardhananjaya/Desktop/Projects/onyx/web/src/refresh-pages/AgentEditorPage.tsx:446:0-1440:1) to prevent interaction before tools are fully synchronized. - Update tool fetching hooks to expose status to the editor page. --- web/src/refresh-pages/AgentEditorPage.tsx | 57 ++++++++++++++--------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/web/src/refresh-pages/AgentEditorPage.tsx b/web/src/refresh-pages/AgentEditorPage.tsx index f3ac547f0ea..55b8f9ed86d 100644 --- a/web/src/refresh-pages/AgentEditorPage.tsx +++ b/web/src/refresh-pages/AgentEditorPage.tsx @@ -458,15 +458,15 @@ export default function AgentEditorPage({ (values: any, llmProviders: any) => values.llm_model_version_override && values.llm_model_provider_override ? (() => { - const provider = llmProviders?.find( - (p: any) => p.name === values.llm_model_provider_override - ); - return structureValue( - values.llm_model_provider_override, - provider?.provider || "", - values.llm_model_version_override - ); - })() + const provider = llmProviders?.find( + (p: any) => p.name === values.llm_model_provider_override + ); + return structureValue( + values.llm_model_provider_override, + provider?.provider || "", + values.llm_model_version_override + ); + })() : null, [] ); @@ -496,8 +496,9 @@ export default function AgentEditorPage({ semantic_identifier: string; } | null>(null); - const { mcpData } = useMcpServers(); - const { openApiTools: openApiToolsRaw } = useOpenApiTools(); + const { mcpData, isLoading: isMcpLoading } = useMcpServers(); + const { openApiTools: openApiToolsRaw, isLoading: isOpenApiLoading } = + useOpenApiTools(); const { llmProviders } = useLLMProviders(existingAgent?.id); const mcpServers = mcpData?.mcp_servers ?? []; const openApiTools = openApiToolsRaw ?? []; @@ -507,7 +508,10 @@ export default function AgentEditorPage({ // - image-gen // - web-search // - code-interpreter - const { tools: availableTools } = useAvailableTools(); + const { tools: availableTools, isLoading: isToolsLoading } = + useAvailableTools(); + + const isPageLoading = isMcpLoading || isOpenApiLoading || isToolsLoading; const searchTool = availableTools?.find( (t) => t.in_code_tool_id === SEARCH_TOOL_ID ); @@ -827,9 +831,8 @@ export default function AgentEditorPage({ : "No response received"; setPopup({ type: "error", - message: `Failed to ${ - existingAgent ? "update" : "create" - } agent - ${error}`, + message: `Failed to ${existingAgent ? "update" : "create" + } agent - ${error}`, }); return; } @@ -838,9 +841,8 @@ export default function AgentEditorPage({ const agent = await personaResponse.json(); setPopup({ type: "success", - message: `Agent "${agent.name}" ${ - existingAgent ? "updated" : "created" - } successfully`, + message: `Agent "${agent.name}" ${existingAgent ? "updated" : "created" + } successfully`, }); // Refresh agents list and the specific agent @@ -936,10 +938,21 @@ export default function AgentEditorPage({ aria-label="Agents Editor Page" className="h-full w-full" > + {isPageLoading && ( +
+ +
+
+ Loading tools... +
+ +
+ )}
@@ -1323,8 +1336,8 @@ export default function AgentEditorPage({ {/* render the separator if there is at least one mcp-server or open-api-tool */} {(mcpServers.length > 0 || openApiTools.length > 0) && ( - - )} + + )} {/* MCP tools */} {mcpServersWithTools.length > 0 && (