()
| 47 | * provider stashes a `pendingSendChat` payload. |
| 48 | */ |
| 49 | export function ChatPanel() { |
| 50 | const currentTab = useCurrentSQLEditorTab(); |
| 51 | const store = useConversationStore(); |
| 52 | const hasCurrentTab = currentTab != null; |
| 53 | |
| 54 | const context = useAIContext(); |
| 55 | const { |
| 56 | aiSetting, |
| 57 | chat, |
| 58 | setShowHistoryDialog, |
| 59 | pendingSendChat, |
| 60 | setPendingSendChat, |
| 61 | events, |
| 62 | } = context; |
| 63 | const { list: conversationList, ready, selected } = chat; |
| 64 | |
| 65 | const [loading, setLoading] = useState(false); |
| 66 | |
| 67 | // Tab/connection signal so we can hide history on (instance, |
| 68 | // database) change — a stable string key the effect can depend on. |
| 69 | const connectionKey = currentTab |
| 70 | ? `${currentTab.connection.instance}|${currentTab.connection.database}` |
| 71 | : ""; |
| 72 | useEffect(() => { |
| 73 | setShowHistoryDialog(false); |
| 74 | }, [connectionKey, setShowHistoryDialog]); |
| 75 | |
| 76 | // Pull the latest `requestAI` into a ref so the pending-send-chat |
| 77 | // effect doesn't need to depend on its identity (the callback closes |
| 78 | // over `selected`, `aiSetting`, etc. — wiring those as effect deps |
| 79 | // would re-run the effect on every conversation tweak). |
| 80 | const requestAIRef = useRef<(query: string) => Promise<void>>(async () => {}); |
| 81 | |
| 82 | const requestAI = useCallback( |
| 83 | async (query: string) => { |
| 84 | const conversation = selected; |
| 85 | if (!conversation) return; |
| 86 | const tab = getCurrentSQLEditorTab(); |
| 87 | if (!tab) return; |
| 88 | |
| 89 | const { messageList } = conversation; |
| 90 | if (messageList.length === 0) { |
| 91 | const engine = context.engine; |
| 92 | const databaseMetadata = context.databaseMetadata; |
| 93 | const schema = context.schema; |
| 94 | const prompts: string[] = [ |
| 95 | promptUtils.declaration(databaseMetadata, engine, schema), |
| 96 | query, |
| 97 | ]; |
| 98 | const prompt = prompts.join("\n"); |
| 99 | await store.createMessage({ |
| 100 | conversation_id: conversation.id, |
| 101 | content: query, |
| 102 | prompt, |
| 103 | author: "USER", |
| 104 | error: "", |
| 105 | status: "DONE", |
| 106 | }); |
nothing calls this directly
no test coverage detected