// chat.jsx — AI 어시스턴트(채팅). 자연어로 문서 생성·심사·점검을 실제 실행. const { Icon, Pill, Button } = window.RAlly; const SUGGEST = [ '이 트랙 심사해줘', '요건 충족됐어?', '위험관리계획서 다시 써줘', '뭘 만들 수 있어?', 'GMP 갱신심사가 뭐야?', ]; const Chat = ({ go }) => { const trackId = (typeof window !== 'undefined' && window.__RALLY_TRACK) || 1; const [msgs, setMsgs] = React.useState([ { role: 'bot', text: '안녕하세요! RAlly 어시스턴트예요. 문서 생성·가상 심사·요건 점검을 자연어로 시켜보세요.\n예: "이 트랙 심사해줘", "위험관리계획서 다시 써줘", "별표1이 뭐야?"', actions: [] }, ]); const [input, setInput] = React.useState(''); const [busy, setBusy] = React.useState(false); const endRef = React.useRef(null); React.useEffect(() => { if (endRef.current) endRef.current.scrollIntoView({ behavior: 'smooth' }); }, [msgs, busy]); const send = (text) => { const q = (text != null ? text : input).trim(); if (!q || busy) return; setMsgs((m) => [...m, { role: 'me', text: q }]); setInput(''); setBusy(true); fetch('/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: q, track_id: trackId }), }).then((r) => r.json()).then((d) => { setMsgs((m) => [...m, { role: 'bot', text: d.reply || '...', actions: d.actions || [] }]); setBusy(false); }).catch(() => { setMsgs((m) => [...m, { role: 'bot', text: '연결에 문제가 있어요. 다시 시도해 주세요.', actions: [] }]); setBusy(false); }); }; const doAction = (a) => { if (a.track_id) window.__RALLY_TRACK = a.track_id; if (a.doc_id) window.__RALLY_DOC = a.doc_id; if (a.screen) go(a.screen); }; return (