diff --git a/client/src/Agents.tsx b/client/src/Agents.tsx
index 06e2c56b49..90de2fca66 100644
--- a/client/src/Agents.tsx
+++ b/client/src/Agents.tsx
@@ -1,23 +1,11 @@
-import { useQuery } from "@tanstack/react-query";
import { Button } from "@/components/ui/button";
import { useNavigate } from "react-router-dom";
+import { useGetAgentsQuery } from "@/api";
import "./App.css";
-type Agent = {
- id: string;
- name: string;
-};
-
function Agents() {
const navigate = useNavigate();
- const { data: agents, isLoading } = useQuery({
- queryKey: ["agents"],
- queryFn: async () => {
- const res = await fetch("/api/agents");
- const data = await res.json();
- return data.agents as Agent[];
- },
- });
+ const { data: agents, isLoading } = useGetAgentsQuery()
return (
diff --git a/client/src/Chat.tsx b/client/src/Chat.tsx
index c699692ddc..b9959f6a40 100644
--- a/client/src/Chat.tsx
+++ b/client/src/Chat.tsx
@@ -1,17 +1,12 @@
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
-import { useMutation } from "@tanstack/react-query";
+import type { TextResponse } from "@/api";
+import { useSendMessageMutation } from "@/api";
import { ImageIcon } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { useParams } from "react-router-dom";
import "./App.css";
-type TextResponse = {
- text: string;
- user: string;
- attachments?: { url: string; contentType: string; title: string }[];
-};
-
export default function Chat() {
const { agentId } = useParams();
const [input, setInput] = useState("");
@@ -19,6 +14,7 @@ export default function Chat() {
const [selectedFile, setSelectedFile] = useState
(null);
const fileInputRef = useRef(null);
const messagesEndRef = useRef(null);
+ const { mutate: sendMessage, isPending } = useSendMessageMutation({ setMessages, setSelectedFile });
const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
@@ -28,32 +24,9 @@ export default function Chat() {
scrollToBottom();
}, [messages]);
- const mutation = useMutation({
- mutationFn: async (text: string) => {
- const formData = new FormData();
- formData.append("text", text);
- formData.append("userId", "user");
- formData.append("roomId", `default-room-${agentId}`);
-
- if (selectedFile) {
- formData.append("file", selectedFile);
- }
-
- const res = await fetch(`/api/${agentId}/message`, {
- method: "POST",
- body: formData,
- });
- return res.json() as Promise;
- },
- onSuccess: (data) => {
- setMessages((prev) => [...prev, ...data]);
- setSelectedFile(null);
- },
- });
-
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
- if (!input.trim() && !selectedFile) return;
+ if ((!input.trim() && !selectedFile) || !agentId) return;
// Add user message immediately to state
const userMessage: TextResponse = {
@@ -63,7 +36,7 @@ export default function Chat() {
};
setMessages((prev) => [...prev, userMessage]);
- mutation.mutate(input);
+ sendMessage({ text: input, agentId, selectedFile });
setInput("");
};
@@ -142,19 +115,19 @@ export default function Chat() {
onChange={(e) => setInput(e.target.value)}
placeholder="Type a message..."
className="flex-1"
- disabled={mutation.isPending}
+ disabled={isPending}
/>
-