samples updating with AgentScope-Runtime 1.0.0 (#43)

This commit is contained in:
Zhiling (Bruce) Luo
2025-12-09 21:19:33 +08:00
committed by GitHub
parent 67469f1caa
commit 68450961bb
10 changed files with 353 additions and 271 deletions

View File

@@ -1,24 +1,24 @@
import React, { useState, useEffect, useRef } from 'react';
import { MessageCircle, User, Send, Plus, LogOut, Menu, X, Bot } from 'lucide-react';
import React, { useState, useEffect, useRef } from "react";
import { MessageCircle, User, Send, Plus, LogOut, Menu, X, Bot } from "lucide-react";
const App = () => {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [currentUser, setCurrentUser] = useState(null);
const [conversations, setConversations] = useState([]);
const [activeConversation, setActiveConversation] = useState(null);
const [message, setMessage] = useState('');
const [message, setMessage] = useState("");
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [loading, setLoading] = useState(false);
const messagesEndRef = useRef(null);
// API base URL
const API_BASE = 'http://localhost:5100/api';
const API_BASE = "http://localhost:5100/api";
// Auto scroll to bottom of messages
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
}, [activeConversation?.messages]);
// Fetch user conversations
@@ -34,7 +34,7 @@ const App = () => {
}
}
} catch (error) {
console.error('Error fetching conversations:', error);
console.error("Error fetching conversations:", error);
}
};
@@ -47,7 +47,7 @@ const App = () => {
setActiveConversation(data);
}
} catch (error) {
console.error('Error loading conversation:', error);
console.error("Error loading conversation:", error);
}
};
@@ -58,9 +58,9 @@ const App = () => {
try {
const response = await fetch(`${API_BASE}/login`, {
method: 'POST',
method: "POST",
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
body: JSON.stringify({ username, password }),
});
@@ -72,11 +72,11 @@ const App = () => {
await fetchConversations(userData.id);
} else {
const errorData = await response.json();
alert(errorData.error || 'Login failed');
alert(errorData.error || "Login failed");
}
} catch (error) {
console.error('Login error:', error);
alert('Network error. Please try again.');
console.error("Login error:", error);
alert("Network error. Please try again.");
} finally {
setLoading(false);
}
@@ -86,8 +86,8 @@ const App = () => {
const handleLogout = () => {
setIsLoggedIn(false);
setCurrentUser(null);
setUsername('');
setPassword('');
setUsername("");
setPassword("");
setConversations([]);
setActiveConversation(null);
setIsMenuOpen(false);
@@ -95,16 +95,18 @@ const App = () => {
// Create new conversation
const createNewConversation = async () => {
if (!currentUser) return;
if (!currentUser) {
return;
}
setLoading(true);
try {
const response = await fetch(`${API_BASE}/users/${currentUser.id}/conversations`, {
method: 'POST',
method: "POST",
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
body: JSON.stringify({ title: 'New Conversation' }),
body: JSON.stringify({ title: "New Conversation" }),
});
if (response.ok) {
@@ -113,7 +115,7 @@ const App = () => {
await loadConversation(newConversation.id);
}
} catch (error) {
console.error('Error creating conversation:', error);
console.error("Error creating conversation:", error);
} finally {
setLoading(false);
setIsMenuOpen(false);
@@ -122,17 +124,19 @@ const App = () => {
// Send message
const sendMessage = async () => {
if (!message.trim() || !activeConversation) return;
if (!message.trim() || !activeConversation) {
return;
}
setLoading(true);
try {
// Send user message
const userMessageResponse = await fetch(`${API_BASE}/conversations/${activeConversation.id}/messages`, {
method: 'POST',
method: "POST",
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
body: JSON.stringify({ text: message, sender: 'user' }),
body: JSON.stringify({ text: message, sender: "user" }),
});
if (userMessageResponse.ok) {
@@ -142,16 +146,16 @@ const App = () => {
const updatedConversation = {
...activeConversation,
messages: [...activeConversation.messages, userMessage],
title: activeConversation.messages.length === 1 ? message.slice(0, 20) + (message.length > 20 ? '...' : '') : activeConversation.title
title: activeConversation.messages.length === 1 ? message.slice(0, 20) + (message.length > 20 ? "..." : "") : activeConversation.title
};
setActiveConversation(updatedConversation);
setMessage('');
setMessage("");
// Fetch updated conversation to get AI response
await loadConversation(activeConversation.id);
}
} catch (error) {
console.error('Error sending message:', error);
console.error("Error sending message:", error);
} finally {
setLoading(false);
}
@@ -159,9 +163,9 @@ const App = () => {
// Format timestamp
const formatTime = (timestamp) => {
return new Date(timestamp).toLocaleTimeString('en-US', {
hour: '2-digit',
minute: '2-digit'
return new Date(timestamp).toLocaleTimeString("en-US", {
hour: "2-digit",
minute: "2-digit"
});
};
@@ -206,7 +210,7 @@ const App = () => {
disabled={loading}
className="w-full bg-indigo-600 text-white py-3 rounded-lg font-medium hover:bg-indigo-700 transition-colors focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-50"
>
{loading ? 'Logging in...' : 'Login'}
{loading ? "Logging in..." : "Login"}
</button>
</form>
@@ -283,7 +287,7 @@ const App = () => {
setIsMenuOpen(false);
}}
className={`p-4 border-b border-gray-100 cursor-pointer hover:bg-gray-50 transition-colors ${
activeConversation?.id === conversation.id ? 'bg-indigo-50 border-l-4 border-l-indigo-500' : ''
activeConversation?.id === conversation.id ? "bg-indigo-50 border-l-4 border-l-indigo-500" : ""
}`}
>
<div className="flex items-start space-x-3">
@@ -291,7 +295,7 @@ const App = () => {
<div className="flex-1 min-w-0">
<h3 className="font-medium text-gray-900 truncate">{conversation.title}</h3>
<p className="text-sm text-gray-500 truncate">
{conversation.preview || 'New conversation'}
{conversation.preview || "New conversation"}
</p>
</div>
</div>
@@ -328,17 +332,17 @@ const App = () => {
{activeConversation.messages.map((msg) => (
<div
key={msg.id}
className={`flex ${msg.sender === 'user' ? 'justify-end' : 'justify-start'}`}
className={`flex ${msg.sender === "user" ? "justify-end" : "justify-start"}`}
>
<div
className={`max-w-xs lg:max-w-md px-4 py-3 rounded-2xl ${
msg.sender === 'user'
? 'bg-indigo-600 text-white rounded-br-md'
: 'bg-white text-gray-800 border border-gray-200 rounded-bl-md shadow-sm'
msg.sender === "user"
? "bg-indigo-600 text-white rounded-br-md"
: "bg-white text-gray-800 border border-gray-200 rounded-bl-md shadow-sm"
}`}
>
<p className="text-sm">{msg.text}</p>
<p className={`text-xs mt-1 ${msg.sender === 'user' ? 'text-indigo-100' : 'text-gray-500'}`}>
<p className={`text-xs mt-1 ${msg.sender === "user" ? "text-indigo-100" : "text-gray-500"}`}>
{formatTime(msg.created_at)}
</p>
</div>
@@ -354,7 +358,7 @@ const App = () => {
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && !loading && sendMessage()}
onKeyPress={(e) => e.key === "Enter" && !loading && sendMessage()}
disabled={loading}
className="flex-1 px-4 py-3 border border-gray-300 rounded-full focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all disabled:opacity-50"
placeholder="Type a message..."