Skip to content

Commit a3fc7d3

Browse files
committed
chat: format
1 parent 63e304d commit a3fc7d3

File tree

4 files changed

+189
-144
lines changed

4 files changed

+189
-144
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"editor.formatOnSave": true,
3+
}
Lines changed: 76 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
'use client';
1+
"use client";
22

3-
import { useState, useEffect, useRef } from 'react';
4-
import MessageList from './MessageList';
5-
import MessageInput from './MessageInput';
6-
import { useSearchParams } from 'next/navigation'
3+
import { useState, useEffect, useRef } from "react";
4+
import MessageList from "./MessageList";
5+
import MessageInput from "./MessageInput";
6+
import { useSearchParams } from "next/navigation";
77

88
interface Message {
99
role: string;
@@ -25,10 +25,10 @@ interface StatusChangeEvent {
2525
export default function ChatInterface() {
2626
const [messages, setMessages] = useState<Message[]>([]);
2727
const [loading, setLoading] = useState<boolean>(false);
28-
const [serverStatus, setServerStatus] = useState<string>('unknown');
28+
const [serverStatus, setServerStatus] = useState<string>("unknown");
2929
const searchParams = useSearchParams();
3030
// null port gets converted to NaN
31-
const parsedPort = parseInt(searchParams.get('port') as string);
31+
const parsedPort = parseInt(searchParams.get("port") as string);
3232
const port = isNaN(parsedPort) ? 3284 : parsedPort;
3333
const AgentAPIUrl = `http://localhost:${port}`;
3434
const eventSourceRef = useRef<EventSource | null>(null);
@@ -40,159 +40,177 @@ export default function ChatInterface() {
4040
if (eventSourceRef.current) {
4141
eventSourceRef.current.close();
4242
}
43-
43+
4444
const eventSource = new EventSource(`${AgentAPIUrl}/events`);
4545
eventSourceRef.current = eventSource;
46-
46+
4747
// Handle message updates
48-
eventSource.addEventListener('message_update', (event) => {
48+
eventSource.addEventListener("message_update", (event) => {
4949
const data: MessageUpdateEvent = JSON.parse(event.data);
50-
51-
setMessages(prevMessages => {
50+
51+
setMessages((prevMessages) => {
5252
// Check if message with this ID already exists
53-
const existingIndex = prevMessages.findIndex(m => m.id === data.id);
54-
53+
const existingIndex = prevMessages.findIndex((m) => m.id === data.id);
54+
5555
if (existingIndex !== -1) {
5656
// Update existing message
5757
const updatedMessages = [...prevMessages];
5858
updatedMessages[existingIndex] = {
5959
role: data.role,
6060
content: data.message,
61-
id: data.id
61+
id: data.id,
6262
};
6363
return updatedMessages;
6464
} else {
6565
// Add new message
66-
return [...prevMessages, {
67-
role: data.role,
68-
content: data.message,
69-
id: data.id
70-
}];
66+
return [
67+
...prevMessages,
68+
{
69+
role: data.role,
70+
content: data.message,
71+
id: data.id,
72+
},
73+
];
7174
}
7275
});
7376
});
74-
77+
7578
// Handle status changes
76-
eventSource.addEventListener('status_change', (event) => {
79+
eventSource.addEventListener("status_change", (event) => {
7780
const data: StatusChangeEvent = JSON.parse(event.data);
7881
setServerStatus(data.status);
7982
});
80-
83+
8184
// Handle connection open (server is online)
8285
eventSource.onopen = () => {
8386
// Connection is established, but we'll wait for status_change event
8487
// for the actual server status
8588
};
86-
89+
8790
// Handle connection errors
8891
eventSource.onerror = (error) => {
89-
console.error('EventSource error:', error);
90-
setServerStatus('offline');
91-
92+
console.error("EventSource error:", error);
93+
setServerStatus("offline");
94+
9295
// Try to reconnect after delay
9396
setTimeout(() => {
9497
if (eventSourceRef.current) {
9598
setupEventSource();
9699
}
97100
}, 3000);
98101
};
99-
102+
100103
return eventSource;
101104
};
102-
105+
103106
// Initial setup
104107
const eventSource = setupEventSource();
105-
108+
106109
// Clean up on component unmount
107110
return () => {
108111
eventSource.close();
109112
};
110113
}, [AgentAPIUrl]);
111-
114+
112115
const [error, setError] = useState<string | null>(null);
113116

114117
// Send a new message
115-
const sendMessage = async (content: string, type: 'user' | 'raw' = 'user') => {
118+
const sendMessage = async (
119+
content: string,
120+
type: "user" | "raw" = "user"
121+
) => {
116122
// For user messages, require non-empty content
117-
if (type === 'user' && !content.trim()) return;
118-
123+
if (type === "user" && !content.trim()) return;
124+
119125
// Clear any previous errors
120126
setError(null);
121-
127+
122128
// For raw messages, don't set loading state as it's usually fast
123-
if (type === 'user') {
129+
if (type === "user") {
124130
setLoading(true);
125131
}
126-
132+
127133
try {
128134
const response = await fetch(`${AgentAPIUrl}/message`, {
129-
method: 'POST',
135+
method: "POST",
130136
headers: {
131-
'Content-Type': 'application/json',
137+
"Content-Type": "application/json",
132138
},
133-
body: JSON.stringify({
134-
content: content,
135-
type
139+
body: JSON.stringify({
140+
content: content,
141+
type,
136142
}),
137143
});
138-
144+
139145
if (!response.ok) {
140146
const errorData = await response.json();
141-
console.error('Failed to send message:', errorData);
147+
console.error("Failed to send message:", errorData);
142148
const detail = errorData.detail;
143-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
144-
const messages = "errors" in errorData ? errorData.errors.map((e: any) => e.message).join(", ") : "";
149+
const messages =
150+
"errors" in errorData
151+
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
152+
errorData.errors.map((e: any) => e.message).join(", ")
153+
: "";
145154

146155
const fullDetail = `${detail}: ${messages}`;
147156
setError(`Failed to send message: ${fullDetail}`);
148157
// Auto-clear error after 5 seconds
149158
setTimeout(() => setError(null), 5000);
150159
}
151-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
160+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
152161
} catch (error: any) {
153-
console.error('Error sending message:', error);
162+
console.error("Error sending message:", error);
154163
const detail = error.detail;
155-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
156-
const messages = "errors" in error ? error.errors.map((e: any) => e.message).join("\n") : "";
164+
const messages =
165+
"errors" in error
166+
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
167+
error.errors.map((e: any) => e.message).join("\n")
168+
: "";
157169

158170
const fullDetail = `${detail}: ${messages}`;
159171

160172
setError(`Error sending message: ${fullDetail}`);
161173
// Auto-clear error after 5 seconds
162174
setTimeout(() => setError(null), 5000);
163175
} finally {
164-
if (type === 'user') {
176+
if (type === "user") {
165177
setLoading(false);
166178
}
167179
}
168180
};
169-
181+
170182
return (
171183
<div className="flex flex-col h-[80vh] bg-gray-100 rounded-lg overflow-hidden border border-gray-300 shadow-lg w-full max-w-[95vw]">
172184
<div className="p-3 bg-gray-800 text-white text-sm flex justify-between items-center">
173185
<span>AgentAPI Chat</span>
174186
<span className="flex items-center">
175-
<span className={`w-2 h-2 rounded-full mr-2 ${["offline", "unknown"].includes(serverStatus) ? 'bg-red-500' : 'bg-green-500'}`}></span>
187+
<span
188+
className={`w-2 h-2 rounded-full mr-2 ${
189+
["offline", "unknown"].includes(serverStatus)
190+
? "bg-red-500"
191+
: "bg-green-500"
192+
}`}
193+
></span>
176194
<span>Status: {serverStatus}</span>
177195
<span className="ml-2">Port: {port}</span>
178196
</span>
179197
</div>
180-
198+
181199
{error && (
182200
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-2 text-sm relative">
183201
<span className="block sm:inline">{error}</span>
184-
<button
202+
<button
185203
onClick={() => setError(null)}
186204
className="absolute top-0 bottom-0 right-0 px-4 py-2"
187205
>
188206
×
189207
</button>
190208
</div>
191209
)}
192-
210+
193211
<MessageList messages={messages} />
194-
212+
195213
<MessageInput onSendMessage={sendMessage} disabled={loading} />
196214
</div>
197215
);
198-
}
216+
}

0 commit comments

Comments
 (0)