import { useState, useRef, useEffect } from "react"; import { invoke } from "@tauri-apps/api/core"; import Markdown from "react-markdown"; import { Message, ProviderConfig } from "../types"; export function Chat() { const [messages, setMessages] = useState([]); const [input, setInput] = useState(""); const [loading, setLoading] = useState(false); const [model, setModel] = useState("llama3.1"); // Default local model const messagesEndRef = useRef(null); const scrollToBottom = () => { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); }; useEffect(scrollToBottom, [messages]); const sendMessage = async () => { if (!input.trim() || loading) return; const userMsg: Message = { role: "user", content: input }; const newHistory = [...messages, userMsg]; setMessages(newHistory); setInput(""); setLoading(true); try { const config: ProviderConfig = { provider: "ollama", model: model, base_url: "http://localhost:11434", }; // Invoke backend chat command // The backend returns the *new* messages (assistant response + tool outputs) const response = await invoke("chat", { messages: newHistory, config: config, }); setMessages((prev) => [...prev, ...response]); } catch (e) { console.error(e); setMessages((prev) => [ ...prev, { role: "assistant", content: `**Error:** ${e}` }, ]); } finally { setLoading(false); } }; return (
{/* Settings Bar */}
setModel(e.target.value)} placeholder="e.g. llama3, mistral" style={{ padding: "5px" }} />
{/* Messages Area */}
{messages.map((msg, idx) => (
{msg.role === "user" ? "You" : msg.role === "tool" ? "Tool Output" : "Agent"} {msg.role === "tool" ? (
{msg.content}
) : ( {msg.content} )} {/* Show Tool Calls if present */} {msg.tool_calls && (
{msg.tool_calls.map((tc, i) => (
🛠 {tc.function.name}({tc.function.arguments})
))}
)}
))} {loading &&
Thinking...
}
{/* Input Area */}
setInput(e.target.value)} onKeyDown={(e) => e.key === "Enter" && sendMessage()} placeholder="Ask the agent to do something..." style={{ flex: 1, padding: "10px", borderRadius: "4px", border: "1px solid #ccc" }} disabled={loading} />
); }