cawncade-ai / frontend /src /components /TalkToAgent.jsx
Nawaz-khan-droid
build: finalize stratos refactor, textarea hardening, and payload limit alignment
acf82bb
Raw
History Blame Contribute Delete
3.04 kB
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;