|
1 | 1 | "use client"; |
2 | 2 |
|
3 | | -import { useCallback, useEffect, useState, useRef } from "react"; |
| 3 | +import { useCallback, useEffect, useMemo } from "react"; |
4 | 4 |
|
5 | 5 | import { AssistantRuntimeProvider } from "@assistant-ui/react"; |
6 | 6 | import { useAISDKRuntime } from "@assistant-ui/react-ai-sdk"; |
@@ -34,69 +34,44 @@ export function DocsAssistant({ pageContext }: DocsAssistantProps) { |
34 | 34 | function DocsAssistantInner({ pageContext }: DocsAssistantProps) { |
35 | 35 | const { provider, openaiApiKey, geminiApiKey } = useAssistantSettings(); |
36 | 36 |
|
37 | | - // Use refs to ensure we always get the latest values |
38 | | - const providerRef = useRef(provider); |
39 | | - const openaiApiKeyRef = useRef(openaiApiKey); |
40 | | - const geminiApiKeyRef = useRef(geminiApiKey); |
41 | | - |
42 | | - // Update refs whenever the values change |
43 | | - providerRef.current = provider; |
44 | | - openaiApiKeyRef.current = openaiApiKey; |
45 | | - geminiApiKeyRef.current = geminiApiKey; |
46 | | - |
47 | | - const chat = useChat({ |
48 | | - transport: new DefaultChatTransport({ |
49 | | - api: "/api/chat", |
50 | | - body: () => { |
51 | | - // Use refs to get the current values at request time |
52 | | - const currentProvider = providerRef.current; |
53 | | - const currentApiKey = |
54 | | - currentProvider === "openai" |
55 | | - ? openaiApiKeyRef.current |
56 | | - : currentProvider === "gemini" |
57 | | - ? geminiApiKeyRef.current |
58 | | - : ""; // intern provider doesn't need API key |
59 | | - |
60 | | - console.log("[DocsAssistant] useChat body function called with:", { |
61 | | - provider: currentProvider, |
62 | | - apiKeyLength: currentApiKey.length, |
63 | | - hasApiKey: currentApiKey.trim().length > 0, |
64 | | - }); |
65 | | - |
66 | | - return { |
67 | | - pageContext, |
68 | | - provider: currentProvider, |
69 | | - apiKey: currentApiKey, |
70 | | - }; |
71 | | - }, |
72 | | - }), |
73 | | - }); |
| 37 | + const transport = useMemo( |
| 38 | + () => |
| 39 | + new DefaultChatTransport({ |
| 40 | + api: "/api/chat", |
| 41 | + body: () => { |
| 42 | + const apiKey = |
| 43 | + provider === "openai" |
| 44 | + ? openaiApiKey |
| 45 | + : provider === "gemini" |
| 46 | + ? geminiApiKey |
| 47 | + : ""; // intern provider doesn't need API key |
| 48 | + |
| 49 | + return { pageContext, provider, apiKey }; |
| 50 | + }, |
| 51 | + }), |
| 52 | + [geminiApiKey, openaiApiKey, pageContext, provider], |
| 53 | + ); |
| 54 | + |
| 55 | + const chat = useChat({ transport }); |
74 | 56 |
|
75 | 57 | const { |
76 | 58 | error: chatError, |
77 | 59 | status: chatStatus, |
78 | 60 | clearError: clearChatError, |
79 | 61 | } = chat; |
80 | | - const [assistantError, setAssistantError] = |
81 | | - useState<AssistantErrorState | null>(null); |
82 | | - |
83 | | - useEffect(() => { |
84 | | - if (!chatError) { |
85 | | - return; |
86 | | - } |
87 | | - |
88 | | - setAssistantError(deriveAssistantError(chatError, provider)); |
89 | | - clearChatError(); |
90 | | - }, [chatError, clearChatError, provider]); |
91 | 62 |
|
92 | 63 | useEffect(() => { |
93 | 64 | if (chatStatus === "submitted" || chatStatus === "streaming") { |
94 | | - setAssistantError(null); |
| 65 | + clearChatError(); |
95 | 66 | } |
96 | | - }, [chatStatus]); |
| 67 | + }, [chatStatus, clearChatError]); |
| 68 | + |
| 69 | + const assistantError = |
| 70 | + chatError && chatStatus !== "submitted" && chatStatus !== "streaming" |
| 71 | + ? deriveAssistantError(chatError, provider) |
| 72 | + : null; |
97 | 73 |
|
98 | 74 | const handleClearError = useCallback(() => { |
99 | | - setAssistantError(null); |
100 | 75 | clearChatError(); |
101 | 76 | }, [clearChatError]); |
102 | 77 |
|
|
0 commit comments