From eb48d61dcfd4e6e51cbd46a319ab917582674a5c Mon Sep 17 00:00:00 2001 From: JK-le-dev Date: Sun, 19 Oct 2025 09:22:48 -0500 Subject: [PATCH] feature: chatgpt --- .../src/components/layouts/chat-layout.jsx | 13 ++++- .../src/components/ui/chat/message-input.jsx | 48 ++++++++++++++++++- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/web-app/src/components/layouts/chat-layout.jsx b/web-app/src/components/layouts/chat-layout.jsx index 5439009..da88fd0 100644 --- a/web-app/src/components/layouts/chat-layout.jsx +++ b/web-app/src/components/layouts/chat-layout.jsx @@ -11,6 +11,11 @@ export default function ChatLayout() { }, ]); + function addMessage(role, content) { + const msg = { role, content }; + setMessages((s) => [...s, msg]); + } + function handleSend(text) { const userMsg = { role: "user", content: text }; setMessages((s) => [...s, userMsg]); @@ -31,9 +36,13 @@ export default function ChatLayout() { return (
- + - +
); } diff --git a/web-app/src/components/ui/chat/message-input.jsx b/web-app/src/components/ui/chat/message-input.jsx index 9f0d6d7..4f20709 100644 --- a/web-app/src/components/ui/chat/message-input.jsx +++ b/web-app/src/components/ui/chat/message-input.jsx @@ -3,7 +3,7 @@ import DownButton from "src/components/ui/button/down-button"; import { motion } from "motion/react"; import { BotMessageSquare } from "lucide-react"; -export default function MessageInput({ onSend }) { +export default function MessageInput({ onSend, onMessage }) { const [text, setText] = useState(""); const textareaRef = useRef(null); @@ -12,10 +12,54 @@ export default function MessageInput({ onSend }) { if (textareaRef.current) textareaRef.current.style.height = "auto"; }, []); - function handleSubmit(e) { + async function handleSubmit(e) { e.preventDefault(); if (!text.trim()) return; + + // send user message locally onSend(text.trim()); + + // create query on backend + try { + if (onMessage) + onMessage("assistant", "Queued: sending request to server..."); + const createRes = await fetch(`/api/query/create`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ q: text, top_k: 5 }), + }); + const createJson = await createRes.json(); + const id = createJson.id; + if (!id) throw new Error("no id returned"); + + // poll status + let status = "Queued"; + if (onMessage) onMessage("assistant", `Status: ${status}`); + while (status !== "Completed" && status !== "Failed") { + await new Promise((r) => setTimeout(r, 1000)); + const sRes = await fetch(`/api/query/status?id=${id}`); + const sJson = await sRes.json(); + status = sJson.status; + if (onMessage) onMessage("assistant", `Status: ${status}`); + if (status === "Cancelled") break; + } + + if (status === "Completed") { + const resultRes = await fetch(`/api/query/result?id=${id}`); + const resultJson = await resultRes.json(); + const final = + resultJson?.result?.final_answer || + JSON.stringify(resultJson?.result || {}); + if (onMessage) onMessage("assistant", final); + } else { + if (onMessage) + onMessage("assistant", `Query status ended as: ${status}`); + } + } catch (err) { + console.error(err); + if (onMessage) onMessage("assistant", `Error: ${err.message}`); + } + setText(""); }