import React, { useState } from 'react'; import { MessageSquare, Activity, Terminal, ChevronRight, Plus } from 'lucide-react'; import apiClient from '../../api/client'; interface ChatMessage { id: string; sender: 'user' | 'ai'; text: string; timestamp: Date; eventId?: string; } export function ChatPanel() { const [messages, setMessages] = useState([ { id: '1', sender: 'ai', text: "Hello! I am Pretor Assistant. How can I help you today?", timestamp: new Date() } ]); const [input, setInput] = useState(''); const [loading, setLoading] = useState(false); const fileInputRef = React.useRef(null); const handleFileUpload = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; const formData = new FormData(); formData.append('file', file); setLoading(true); try { const response = await apiClient.post('/api/v1/adapter/client/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }); const aiMessage: ChatMessage = { id: Date.now().toString(), sender: 'ai', text: `已上传文件: ${response.data.filename}`, timestamp: new Date() }; setMessages(prev => [...prev, aiMessage]); } catch (error) { console.error("Error uploading file", error); const errorMessage: ChatMessage = { id: Date.now().toString(), sender: 'ai', text: "文件上传失败。", timestamp: new Date() }; setMessages(prev => [...prev, errorMessage]); } finally { setLoading(false); if (fileInputRef.current) { fileInputRef.current.value = ''; } } }; const handleSendMessage = async () => { if (!input.trim()) return; const userMessage: ChatMessage = { id: Date.now().toString(), sender: 'user', text: input, timestamp: new Date() }; setMessages(prev => [...prev, userMessage]); setInput(''); setLoading(true); try { // Assuming a token might be needed, apiClient should handle it if set const promptModifier = mode === 'deploy' ? '[DEPLOY TASK] ' : ''; const response = await apiClient.post('/api/v1/adapter/client', { message: promptModifier + userMessage.text }); const aiMessage: ChatMessage = { id: (Date.now() + 1).toString(), sender: 'ai', text: typeof response.data.message === 'string' && response.data.message.includes('-') ? "Task has been created." // It's an event ID : response.data.message || "I received your message.", eventId: typeof response.data.message === 'string' && response.data.message.includes('-') ? response.data.message : undefined, timestamp: new Date() }; setMessages(prev => [...prev, aiMessage]); // If we got an event_id, we could potentially open a websocket to listen to its stream if (aiMessage.eventId) { console.log(`Open WS to track event: ${aiMessage.eventId}`); // Implement WS tracking if needed } } catch (error) { console.error("Error sending message", error); const errorMessage: ChatMessage = { id: (Date.now() + 1).toString(), sender: 'ai', text: "Sorry, I encountered an error communicating with the server.", timestamp: new Date() }; setMessages(prev => [...prev, errorMessage]); } finally { setLoading(false); } }; const [mode, setMode] = useState<'chat' | 'deploy'>('chat'); return (

Pretor Assistant

{/* Chat History */}
Today
{messages.map((msg) => (
{msg.sender === 'ai' && (
)}

{msg.text}

{msg.eventId && (
Task ID: {msg.eventId}
)}
))} {loading && (
)}
{/* Chat Input */}
setInput(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleSendMessage()} placeholder="Ask Pretor to do something..." className="w-full bg-slate-50 border border-slate-200 text-sm rounded-xl pl-12 pr-12 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all shadow-inner" />
); }