Spaces:
Paused
Paused
Nawaz-khan-droid
build: finalize stratos refactor, textarea hardening, and payload limit alignment
acf82bb | import React, { useState } from 'react'; | |
| import { Send } from 'lucide-react'; | |
| const TalkToAgent = () => { | |
| const [messages, setMessages] = useState([ | |
| { role: 'bot', content: "I'm CAWNCADE's internal agent. I have access to Serper and Tavily. How can I help you research today?" } | |
| ]); | |
| const [input, setInput] = useState(""); | |
| const [isTyping, setIsTyping] = useState(false); | |
| const handleSend = async () => { | |
| if (!input.trim()) return; | |
| const newMsg = { role: 'user', content: input }; | |
| setMessages([...messages, newMsg]); | |
| setInput(""); | |
| setIsTyping(true); | |
| try { | |
| // Call your new /api/v1/chat endpoint | |
| const response = await fetch('/api/v1/chat', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ message: input, session_id: 'default' }) | |
| }); | |
| const data = await response.json(); | |
| setMessages(prev => [...prev, { role: 'bot', content: data.output }]); | |
| } catch (e) { | |
| setMessages(prev => [...prev, { role: 'bot', content: "Chat service unavailable." }]); | |
| } finally { | |
| setIsTyping(false); | |
| } | |
| }; | |
| return ( | |
| <div className="glass-card flex h-[500px] max-h-[70vh] w-full max-w-full shrink-0 flex-col overflow-hidden bg-slate-900/50"> | |
| <div className="border-b border-white/10 px-4 py-3"> | |
| <h3 className="text-sm font-semibold uppercase tracking-wider text-sky-300">Agent Console</h3> | |
| <p className="mt-1 text-xs text-slate-500">Follow-up research and conversational investigation.</p> | |
| </div> | |
| <div className="flex-1 space-y-4 overflow-y-auto p-4"> | |
| {messages.map((m, i) => ( | |
| <div key={i} className={`flex ${m.role === 'user' ? 'justify-end' : 'justify-start'}`}> | |
| <div className={`max-w-[85%] rounded-2xl p-3 sm:max-w-[80%] ${m.role === 'user' ? 'bg-sky-600 text-white shadow-lg shadow-sky-900/20' : 'border border-slate-700 bg-slate-800 text-slate-100'}`}> | |
| <p className="text-sm text-white" style={{ overflowWrap: 'break-word', wordBreak: 'break-word' }}>{m.content}</p> | |
| </div> | |
| </div> | |
| ))} | |
| {isTyping && <div className="animate-pulse text-xs font-medium text-emerald-400">Agent is thinking and researching...</div>} | |
| </div> | |
| <div className="flex gap-2 border-t border-white/10 p-4"> | |
| <input | |
| value={input} | |
| onChange={(e) => setInput(e.target.value)} | |
| onKeyDown={(e) => e.key === 'Enter' && handleSend()} | |
| className="min-h-[44px] flex-1 rounded-xl border border-sky-500/30 bg-slate-900/70 p-3 text-white outline-none transition-colors focus:border-emerald-500/50" | |
| placeholder="Ask a follow-up question..." | |
| /> | |
| <button onClick={handleSend} className="flex min-h-[44px] items-center justify-center rounded-xl bg-sky-500 px-4 py-2 text-slate-950 transition-colors hover:bg-sky-400"> | |
| <Send size={20} /> | |
| </button> | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| export default TalkToAgent; | |