Download web/src/components/ChatPanel.jsx from kphani007/Aegis: direct link, hf CLI and curl.
- Browser
- Download file 2.82 kB
-
https://huggingface.co/spaces/kphani007/Aegis/resolve/main/web/src/components/ChatPanel.jsx
- Command line
-
hf download hf://spaces/kphani007/Aegis/web/src/components/ChatPanel.jsx
-
curl -L -o ChatPanel.jsx https://huggingface.co/spaces/kphani007/Aegis/resolve/main/web/src/components/ChatPanel.jsx
2.82 kB
| import { useEffect, useRef, useState } from 'react' | |
| import DomainButtons from './DomainButtons' | |
| import MessageBubble from './MessageBubble' | |
| export default function ChatPanel({ | |
| conversation, | |
| categories, | |
| loading, | |
| onSend, | |
| }) { | |
| const [draft, setDraft] = useState('') | |
| const messagesEndRef = useRef(null) | |
| const textareaRef = useRef(null) | |
| const messages = conversation?.messages || [] | |
| useEffect(() => { | |
| messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }) | |
| }, [messages.length, loading]) | |
| function handleSubmit(event) { | |
| event.preventDefault() | |
| const trimmed = draft.trim() | |
| if (!trimmed || loading) return | |
| onSend(trimmed) | |
| setDraft('') | |
| } | |
| function handleKeyDown(event) { | |
| if (event.key === 'Enter' && !event.shiftKey) { | |
| event.preventDefault() | |
| handleSubmit(event) | |
| } | |
| } | |
| function handlePick(question) { | |
| setDraft(question) | |
| textareaRef.current?.focus() | |
| } | |
| return ( | |
| <div className="chat-panel"> | |
| <div className="chat-header"> | |
| <h1>{conversation ? conversation.title : 'Aegis'}</h1> | |
| <p className="chat-subtitle"> | |
| Local instruction-tuned model · LOS + Guidewire + Duck Creek | |
| + general insurance · retrieval augmented | |
| </p> | |
| </div> | |
| <div className="messages"> | |
| {messages.length === 0 && ( | |
| <div className="welcome"> | |
| <div className="welcome-icon">Æ</div> | |
| <h2>Ask Aegis something</h2> | |
| <p> | |
| Pick a domain below or type your own question. Experimental | |
| model — do not rely on it for real loan, underwriting, claims, | |
| or financial decisions. | |
| </p> | |
| </div> | |
| )} | |
| {messages.map((message, index) => ( | |
| <MessageBubble key={index} message={message} /> | |
| ))} | |
| {loading && ( | |
| <div className="message-row"> | |
| <div className="bubble bubble--assistant bubble--typing"> | |
| <span className="dot" /> | |
| <span className="dot" /> | |
| <span className="dot" /> | |
| </div> | |
| </div> | |
| )} | |
| <div ref={messagesEndRef} /> | |
| </div> | |
| <div className="composer"> | |
| <DomainButtons categories={categories} onPick={handlePick} /> | |
| <form className="composer-form" onSubmit={handleSubmit}> | |
| <textarea | |
| ref={textareaRef} | |
| value={draft} | |
| onChange={(event) => setDraft(event.target.value)} | |
| onKeyDown={handleKeyDown} | |
| placeholder="Ask about LOS, Guidewire, Duck Creek, or general insurance..." | |
| rows={1} | |
| /> | |
| <button type="submit" disabled={loading || !draft.trim()}> | |
| Send | |
| </button> | |
| </form> | |
| </div> | |
| </div> | |
| ) | |
| } | |