UNPKG

@embedapi/react

Version:

🚀 Build stunning AI chat interfaces in minutes! Production-ready React components with real-time streaming, Material-UI design, and zero configuration required. Transform your app with powerful, customizable AI chat features.

3 lines (2 loc) • 7.72 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("@embedapi/core"),a=require("@mui/material"),r=require("@mui/material/styles"),n=require("@mui/icons-material/Send"),l=require("@mui/icons-material/SmartToy"),s=require("@mui/icons-material/Person"),o=require("@mui/icons-material/RestartAlt"),i=require("react-markdown");function c(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=c(e),d=c(t),f=c(n),m=c(l),g=c(s),p=c(o),h=c(i);AbortSignal.timeout||(AbortSignal.timeout=function(e){const t=new AbortController;return setTimeout((()=>t.abort()),e),t.signal});const y=new class{constructor(){this.buffer=""}parse(e){this.buffer+=e;try{const e=JSON.parse(this.buffer);return this.buffer="",e}catch(e){return null}}},b="embedapi_chat_",E=10;function x(t){let{agentId:a,service:r="openai",model:n="gpt-4o",initialMessages:l=[],onError:s,enableCache:o=!0,messageLimit:i=E}=t;const c=e.useCallback((()=>{if(!o)return l;try{const e=sessionStorage.getItem(`${b}${a}`);return(e?JSON.parse(e):l).slice(-i)}catch(e){return console.warn("Failed to load cached messages:",e),l}}),[a,l,o,i]),[u,f]=e.useState(c),m=e.useRef(""),[g,p]=e.useState(!1),[h,x]=e.useState(null);e.useEffect((()=>{if(o&&a&&u.length>0)try{const e=u.slice(-i);sessionStorage.setItem(`${b}${a}`,JSON.stringify(e))}catch(e){console.warn("Failed to cache messages:",e)}}),[u,a,o,i]),e.useEffect((()=>{if(!a){const e={role:"system",content:"Error: agentId is required."};f((t=>[...t,e]))}}),[a]);const C=a?new d.default(a,{isAgent:!0}):null,v=e.useCallback((()=>{if(f(l),x(null),p(!1),o&&a)try{sessionStorage.removeItem(`${b}${a}`)}catch(e){console.warn("Failed to clear cached messages:",e)}}),[l,a,o]),k=e.useCallback((e=>{Array.isArray(e)?f(e.slice(-i)):f((t=>("function"==typeof e?e(t):e).slice(-i)))}),[i]),w=e.useCallback((async e=>{if(!a)return;const t={role:"user",content:e};k((e=>[...e,t])),p(!0),x(null);try{const e=await C.generate({service:r,model:n,messages:[...u,t]});f((t=>[...t,{role:"assistant",content:e.content}]))}catch(e){x(e),s?.(e)}finally{p(!1)}}),[u,C,r,n,s,a,k]),S=e.useCallback((async e=>{if(!a)return;p(!0);const t={role:"user",content:e};k((e=>[...e,t])),x(null);const l=new AbortController,o=l.signal;try{const e=await C.stream({service:r,model:n,messages:[...u,t],signal:o}),a=new TextDecoder("utf-8");m.current={role:"assistant",content:""};for await(const t of e.body){if(o.aborted)break;const e=a.decode(t).split(/(\n){2}/).map((e=>e.replace(/(\n)?^data:\s*/,"").trim())).filter((e=>""!==e&&"[DONE]"!==e&&void 0!==e)).map((e=>y.parse(e)));for(const t of e)if("chunk"===t?.type)m.current.content+=t.content;else if("done"===t?.type){m.current.cost=t.cost,m.current.tokenUsage=t.tokenUsage,f((e=>[...e,{...m.current}])),p(!1),m.current={role:"assistant",content:""};break}}e.body?.cancel&&e.body.cancel()}catch(e){s?.(e),o.aborted?console.log("Stream aborted."):(x(e),s?.(e))}finally{p(!1)}return()=>l.abort()}),[u,C,r,n,s,a,k]);return{messages:u,isLoading:g,error:h,currentMessage:m.current,sendMessage:w,streamMessage:S,reset:v,clearCache:e.useCallback((()=>{if(a)try{sessionStorage.removeItem(`${b}${a}`)}catch(e){console.warn("Failed to clear cached messages:",e)}}),[a]),messageCount:u.length}}exports.AgentChat=t=>{let{agentId:n,initialMessages:l=[],className:s="",placeholder:o="Type a message...",onError:i,style:c={},theme:d="light",containerWidth:y="100%",maxHeight:b="600px",customStyles:E={}}=t;const[C,v]=e.useState(""),k=e.useRef(null),w=e.useRef(null),{messages:S,isLoading:I,error:M,currentMessage:T,streamMessage:B,reset:A}=x({agentId:n,initialMessages:l,onError:i}),q=r.createTheme({palette:{mode:d},spacing:8}),G={container:{width:y,maxWidth:"100%",...E.container},messageContainer:{height:b,overflow:"auto",padding:q.spacing(2.5),backgroundColor:"light"===d?"#f5f5f5":"#1a1a1a",scrollBehavior:"smooth",...E.messageContainer},userMessage:{backgroundColor:"light"===d?"#e3f2fd":"#2c387e",color:"light"===d?"#000":"#fff",borderRadius:"10px",padding:q.spacing(1.25,1.875),marginBottom:q.spacing(1.25),boxShadow:"0 1px 2px rgba(0,0,0,0.1)",...E.userMessage},assistantMessage:{backgroundColor:"light"===d?"#fff":"#333",color:"light"===d?"#000":"#fff",borderRadius:"10px",padding:q.spacing(1.25,1.875),marginBottom:q.spacing(1.25),boxShadow:"0 1px 2px rgba(0,0,0,0.1)",...E.assistantMessage},inputContainer:{padding:q.spacing(2.5),backgroundColor:"light"===d?"#fff":"#262626",borderTop:"1px solid "+("light"===d?"#e0e0e0":"#404040"),...E.inputContainer},avatar:{backgroundColor:"light"===d?"#1976d2":"#90caf9",color:"light"===d?"#fff":"#000"},...c};e.useEffect((()=>{k.current?.scrollIntoView({behavior:"smooth"}),w.current?.focus()}),[S]),e.useEffect((()=>{w.current?.focus()}),[]);const R=(e,t)=>u.default.createElement(a.Grid,{item:!0,key:t,container:!0,justifyContent:"user"===e.role?"flex-end":"flex-start"},u.default.createElement(a.Grid,{item:!0,xs:12,sm:8,md:6},u.default.createElement(a.Box,{display:"flex",alignItems:"flex-start",gap:1,style:"user"===e.role?G.userMessage:G.assistantMessage},u.default.createElement(a.Avatar,{style:G.avatar},"user"===e.role?u.default.createElement(g.default,null):u.default.createElement(m.default,null)),u.default.createElement(a.Typography,{style:{wordBreak:"break-word",flex:1}},u.default.createElement(h.default,null,e?.content)))));return u.default.createElement(r.ThemeProvider,{theme:q},u.default.createElement(a.Container,{style:G.container,className:s},u.default.createElement(a.Paper,{elevation:3},u.default.createElement(a.Box,{style:G.messageContainer},u.default.createElement(a.Grid,{container:!0,direction:"column",spacing:2},(()=>{const e=S;return u.default.createElement(u.default.Fragment,null,e.map(R),I&&T&&u.default.createElement(a.Grid,{item:!0,container:!0,justifyContent:"flex-start"},u.default.createElement(a.Grid,{item:!0,xs:12,sm:8,md:6},u.default.createElement(a.Box,{display:"flex",alignItems:"flex-start",gap:1,style:G.assistantMessage},u.default.createElement(a.Avatar,{style:G.avatar},u.default.createElement(m.default,null)),u.default.createElement(a.Box,{style:{flex:1}},u.default.createElement(a.Typography,{style:{wordBreak:"break-word"}},T.content),u.default.createElement(a.Box,{display:"flex",alignItems:"center",mt:1},u.default.createElement(a.CircularProgress,{size:16,style:{marginRight:8}}),u.default.createElement(a.Typography,{variant:"caption",color:"textSecondary"},"Is Typing...")))))),u.default.createElement("div",{ref:k}))})())),u.default.createElement(a.Box,{component:"form",onSubmit:async e=>{if(e.preventDefault(),!C.trim()||I)return;const t=C.trim();v(""),await B(t),w.current?.focus()},style:G.inputContainer},u.default.createElement(a.Grid,{container:!0,spacing:2,alignItems:"center"},u.default.createElement(a.Grid,{item:!0,xs:!0},u.default.createElement(a.TextField,{fullWidth:!0,value:C,onChange:e=>v(e.target.value),placeholder:o,disabled:I,variant:"outlined",size:"small",inputRef:w,InputProps:{style:{backgroundColor:"light"===d?"#fff":"#333",color:"light"===d?"#000":"#fff"}}})),u.default.createElement(a.Grid,{item:!0},u.default.createElement(a.Tooltip,{title:"Reset conversation"},u.default.createElement(a.IconButton,{onClick:()=>{A(),v(""),w.current?.focus()},color:"primary",disabled:I||0===S.length},u.default.createElement(p.default,null)))),u.default.createElement(a.Grid,{item:!0},u.default.createElement(a.Tooltip,{title:"Send message"},u.default.createElement(a.IconButton,{type:"submit",disabled:I||!C.trim(),color:"primary"},u.default.createElement(f.default,null)))))),M&&u.default.createElement(a.Box,{p:2},u.default.createElement(a.Typography,{color:"error"},M.message)))))},exports.useChat=x; //# sourceMappingURL=index.js.map