diff options
| author | soryu <soryu@soryu.co> | 2026-01-06 04:08:11 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-01-11 03:01:13 +0000 |
| commit | 8b17a175c3e7e27b789812eba4e3cd760beadb10 (patch) | |
| tree | 7864dcaa2fa9db47fdfd4e8bfdb0b1dde832aa33 /makima/frontend/src/hooks/useMeshChatHistory.ts | |
| parent | f79c416c58557d2f946aa5332989afdfa8c021cd (diff) | |
| download | soryu-8b17a175c3e7e27b789812eba4e3cd760beadb10.tar.gz soryu-8b17a175c3e7e27b789812eba4e3cd760beadb10.zip | |
Initial Control system
Diffstat (limited to 'makima/frontend/src/hooks/useMeshChatHistory.ts')
| -rw-r--r-- | makima/frontend/src/hooks/useMeshChatHistory.ts | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/makima/frontend/src/hooks/useMeshChatHistory.ts b/makima/frontend/src/hooks/useMeshChatHistory.ts new file mode 100644 index 0000000..82c576d --- /dev/null +++ b/makima/frontend/src/hooks/useMeshChatHistory.ts @@ -0,0 +1,133 @@ +import { useState, useCallback, useEffect } from "react"; +import { + getMeshChatHistory, + clearMeshChatHistory, + chatWithMeshContext, + type MeshChatMessageRecord, + type MeshChatContext, + type MeshChatResponse, + type LlmModel, +} from "../lib/api"; + +export interface MeshChatState { + conversationId: string | null; + messages: MeshChatMessageRecord[]; + loading: boolean; + error: string | null; + sending: boolean; +} + +export function useMeshChatHistory() { + const [state, setState] = useState<MeshChatState>({ + conversationId: null, + messages: [], + loading: true, + error: null, + sending: false, + }); + + const fetchHistory = useCallback(async () => { + setState((prev) => ({ ...prev, loading: true, error: null })); + try { + const response = await getMeshChatHistory(); + setState((prev) => ({ + ...prev, + conversationId: response.conversationId, + messages: response.messages, + loading: false, + })); + } catch (e) { + setState((prev) => ({ + ...prev, + error: e instanceof Error ? e.message : "Failed to fetch chat history", + loading: false, + })); + } + }, []); + + const clearHistory = useCallback(async (): Promise<boolean> => { + setState((prev) => ({ ...prev, loading: true, error: null })); + try { + const response = await clearMeshChatHistory(); + setState({ + conversationId: response.conversationId, + messages: [], + loading: false, + error: null, + sending: false, + }); + return true; + } catch (e) { + setState((prev) => ({ + ...prev, + error: e instanceof Error ? e.message : "Failed to clear chat history", + loading: false, + })); + return false; + } + }, []); + + const sendMessage = useCallback( + async ( + message: string, + context: MeshChatContext, + model?: LlmModel + ): Promise<MeshChatResponse | null> => { + setState((prev) => ({ ...prev, sending: true, error: null })); + + // Optimistically add user message (will be refetched after response) + const tempUserMessage: MeshChatMessageRecord = { + id: `temp-${Date.now()}`, + conversationId: state.conversationId || "", + role: "user", + content: message, + contextType: context.type, + contextTaskId: context.taskId || null, + toolCalls: null, + pendingQuestions: null, + createdAt: new Date().toISOString(), + }; + + setState((prev) => ({ + ...prev, + messages: [...prev.messages, tempUserMessage], + })); + + try { + const response = await chatWithMeshContext(message, context, model); + + // Refetch to get the actual saved messages (with proper IDs) + await fetchHistory(); + + setState((prev) => ({ ...prev, sending: false })); + return response; + } catch (e) { + // Remove optimistic message on error + setState((prev) => ({ + ...prev, + messages: prev.messages.filter((m) => m.id !== tempUserMessage.id), + error: e instanceof Error ? e.message : "Failed to send message", + sending: false, + })); + return null; + } + }, + [state.conversationId, fetchHistory] + ); + + // Initial fetch on mount + useEffect(() => { + fetchHistory(); + }, [fetchHistory]); + + return { + conversationId: state.conversationId, + messages: state.messages, + loading: state.loading, + error: state.error, + sending: state.sending, + fetchHistory, + clearHistory, + sendMessage, + }; +} |
