import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { FaArrowUpLong } from "react-icons/fa6"; import { useTranslation } from "react-i18next"; import { useState, useCallback } from "react"; import axios from "axios"; import { AssistantMessage } from "@/components/chat/AssistantMessage"; import { ToolCallBubble } from "@/components/chat/ToolCallBubble"; import type { ChatMessage, ToolCall } from "@/types/chat"; export default function ChatPage() { const { t } = useTranslation(["views/chat"]); const [input, setInput] = useState(""); const [messages, setMessages] = useState([]); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const sendMessage = useCallback(async () => { const text = input.trim(); if (!text || isLoading) return; const userMessage: ChatMessage = { role: "user", content: text }; setInput(""); setError(null); setMessages((prev) => [...prev, userMessage]); setIsLoading(true); try { const apiMessages = [...messages, userMessage].map((m) => ({ role: m.role, content: m.content, })); const { data } = await axios.post<{ message: { role: string; content: string | null }; tool_calls?: ToolCall[]; }>("chat/completion", { messages: apiMessages }); const content = data.message?.content ?? ""; setMessages((prev) => [ ...prev, { role: "assistant", content: content || " ", toolCalls: data.tool_calls?.length ? data.tool_calls : undefined, }, ]); } catch { setError(t("error")); } finally { setIsLoading(false); } }, [input, isLoading, messages, t]); return (
{messages.map((msg, i) => (
{msg.role === "assistant" && msg.toolCalls && ( <> {msg.toolCalls.map((tc, tcIdx) => (
{tc.response && ( )}
))} )}
{msg.role === "assistant" ? ( ) : ( msg.content )}
))} {isLoading && (
{t("processing")}
)} {error && (

{error}

)}
); } type ChatEntryProps = { input: string; setInput: (value: string) => void; sendMessage: () => void; isLoading: boolean; placeholder: string; }; function ChatEntry({ input, setInput, sendMessage, isLoading, placeholder, }: ChatEntryProps) { const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); sendMessage(); } }; return (
setInput(e.target.value)} onKeyDown={handleKeyDown} disabled={isLoading} />
); }