From ca12f20df79b76cfdbdc1c76ce24809c04f1629a Mon Sep 17 00:00:00 2001 From: ayangweb <75017711+ayangweb@users.noreply.github.com> Date: Thu, 6 Aug 2026 15:18:11 +0800 Subject: [PATCH] fix(search): open deep research panel in quick ai access (#1081) * fix(search): open deep research panel in quick ai access * fix(search): handle quick ai deep research cancellation --- src/components/Search/AskAi.tsx | 101 +++++++++++++++++++++++++++---- src/components/Search/Search.tsx | 10 ++- 2 files changed, 98 insertions(+), 13 deletions(-) diff --git a/src/components/Search/AskAi.tsx b/src/components/Search/AskAi.tsx index 3f52d109..6084f767 100644 --- a/src/components/Search/AskAi.tsx +++ b/src/components/Search/AskAi.tsx @@ -16,10 +16,15 @@ import useMessageChunkData from "@/hooks/useMessageChunkData"; import { useAppStore } from "@/stores/appStore"; import { useExtensionsStore } from "@/stores/extensionsStore"; import { useShortcutsStore } from "@/stores/shortcutsStore"; +import { + DeepResearchPanel, + type DeepResearchPanelPayload, +} from "@/components/ChatMessage/DeepResearch/DeepResearchPanel"; interface AskAiProps { isChatMode: boolean; changeMode?: (isChatMode: boolean) => void; + formatUrl?: (data: any) => string; } const DEEP_RESEARCH_CHUNK_TYPES = [ @@ -34,6 +39,17 @@ const DEEP_RESEARCH_CHUNK_TYPES = [ "research_reporter_end", ]; +const EMPTY_LOADING_STEP: Record = { + query_intent: false, + tools: false, + fetch_source: false, + pick_source: false, + deep_read: false, + think: false, + response: false, + deepResearch: false, +}; + interface State { serverId?: string; assistantId?: string; @@ -42,7 +58,7 @@ interface State { } const AskAi: FC = (props) => { - const { isChatMode, changeMode } = props; + const { isChatMode, changeMode, formatUrl } = props; const { askAiMessage, @@ -77,18 +93,14 @@ const AskAi: FC = (props) => { }); const [isTyping, setIsTyping] = useState(false); - const [loadingStep, setLoadingStep] = useState>({ - query_intent: false, - tools: false, - fetch_source: false, - pick_source: false, - deep_read: false, - think: false, - response: false, - }); + const [deepResearchPanel, setDeepResearchPanel] = + useState(null); + const [loadingStep, setLoadingStep] = + useState>(EMPTY_LOADING_STEP); const unlisten = useRef<() => void>(noop); const sessionIdRef = useRef(""); + const cancelledSessionIdRef = useRef(""); const { quickAiAccessServer, quickAiAccessAssistant } = useExtensionsStore(); @@ -176,6 +188,10 @@ const AskAi: FC = (props) => { return; } + if (cancelledSessionIdRef.current === chunkData.session_id) { + return; + } + setIsTyping(true); setLoadingStep(() => ({ @@ -230,6 +246,9 @@ const AskAi: FC = (props) => { if (!askAiMessage || !state.serverId || !state.assistantId) return; await clearAllChunkData(); + sessionIdRef.current = ""; + cancelledSessionIdRef.current = ""; + setDeepResearchPanel(null); const { serverId, assistantId } = state; @@ -250,6 +269,43 @@ const AskAi: FC = (props) => { } }, [askAiMessage]); + const cancelQuickAiResearch = useCallback(async () => { + const sessionId = sessionIdRef.current || deepResearch[0]?.session_id; + const messageId = deepResearch[0]?.message_id || state.messageId; + const serverId = state.serverId; + const cancelledPayload = { reason: "user_cancelled" }; + + if (sessionId) { + cancelledSessionIdRef.current = sessionId; + } + + handlers.deal_reply_end({ + session_id: sessionId || "", + message_id: messageId, + message_type: "assistant", + reply_to_message: deepResearch[0]?.reply_to_message || state.messageId, + chunk_sequence: Date.now(), + chunk_type: "reply_end", + message_chunk: JSON.stringify(cancelledPayload), + }); + setIsTyping(false); + setLoadingStep(EMPTY_LOADING_STEP); + + if (!serverId || !sessionId) return; + + try { + await platformAdapter.commands("cancel_session_chat", { + serverId, + sessionId, + queryParams: { + message_id: messageId, + }, + }); + } catch (error) { + addError(String(error)); + } + }, [addError, deepResearch, handlers, state.messageId, state.serverId]); + useKeyPress( "enter", () => { @@ -266,7 +322,7 @@ const AskAi: FC = (props) => { return ( askAiMessage && ( -
+
{askAiMessage} @@ -281,7 +337,8 @@ const AskAi: FC = (props) => { _source: { type: "assistant", message: "", - question: "", + question: askAiMessage, + session_id: sessionIdRef.current, }, }} isTyping={isTyping} @@ -296,9 +353,29 @@ const AskAi: FC = (props) => { replyEnd={replyEnd} loadingStep={loadingStep} copyButtonId={state.copyButtonId} + formatUrl={formatUrl} + onCancel={cancelQuickAiResearch} + activeDeepResearchViewKey={deepResearchPanel?.viewKey} + onOpenDeepResearch={setDeepResearchPanel} + onUpdateDeepResearch={(payload) => { + setDeepResearchPanel((current) => { + return current?.viewKey === payload.viewKey + ? payload + : current; + }); + }} />
+ + {deepResearchPanel && ( +
+ setDeepResearchPanel(null)} + /> +
+ )}
) ); diff --git a/src/components/Search/Search.tsx b/src/components/Search/Search.tsx index 5875ecfa..7b248959 100644 --- a/src/components/Search/Search.tsx +++ b/src/components/Search/Search.tsx @@ -141,7 +141,15 @@ const SearchResultsPanel = memo<{ return ; } - if (goAskAi) return ; + if (goAskAi) { + return ( + + ); + } if (sourceData) { return ;