@namiruai/chat 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,14 +2,15 @@ export interface NamiruChatConfig {
2
2
  agentId: string;
3
3
  /** @internal */ serverUrl?: string;
4
4
  /** @internal */ wsUrl?: string;
5
- /** @internal */ mode?: "button" | "inline";
5
+ mode?: "button" | "inline";
6
+ position?: "bottom-right" | "bottom-left";
7
+ width?: string;
8
+ height?: string;
6
9
  /** @internal */ container?: HTMLElement;
7
10
  /** @internal */ preChatEnabled?: boolean;
8
11
  /** @internal */ preChatTemplate?: "ecommerce" | "saas" | "services" | "custom" | null;
9
12
  /** @internal */ preChatCustom?: PreChatCustomConfig;
10
13
  /** @internal */ greetingDelay?: number;
11
- /** @internal */ width?: string;
12
- /** @internal */ height?: string;
13
14
  /** @internal */ suggestedQuestions?: string[];
14
15
  onLeadCapture?: (lead: LeadCaptureData) => void;
15
16
  onFeedback?: (rating: "up" | "down") => void;
@@ -1088,5 +1088,5 @@ function he(){return{state:"idle",messages:[],isOpen:!1,isLoading:!1,streamingCo
1088
1088
  font-size: 14px; font-weight: 500; line-height: 1; box-sizing: border-box;
1089
1089
  background: transparent; color: ${t.textColor||"#1f2937"};
1090
1090
  border: 1px solid ${t.textColor?t.textColor+"33":"#e5e7eb"};
1091
- `,Q.textContent="Reload",Q.addEventListener("click",()=>window.location.reload()),H.appendChild(Q),m.appendChild(H),y.appendChild(m)}function pe(m){_||(_=Ie({onFeedback:v=>{s(v),i==="button"&&setTimeout(()=>{e.dispatch({type:"RESET"}),e.dispatch({type:"SET_OPEN",isOpen:!1})},800)},softPrompt:m}),y.appendChild(_),Z())}function Z(){requestAnimationFrame(()=>{y.scrollTop=y.scrollHeight})}function Ze(m){A&&m.some(v=>v.role==="user")&&(A.remove(),A=null);for(let v=O;v<m.length;v++){let S=f.createBubble(m[v]);y.appendChild(S)}O=m.length,Z()}function Ue(m){if(m){L||(u&&(u.remove(),u=null),L=f.createStreaming(),y.appendChild(L));let v=L._namiruTextEl,S=ne(m);v?v.innerHTML=S:L.innerHTML=S,Z()}else L&&(L.remove(),L=null)}function qe(m){m&&!u&&!L?(u=f.createLoading(),y.appendChild(u),Z()):!m&&u&&(u.remove(),u=null)}let z=null;return e.subscribe(m=>{if(console.log("[ChatWindow] subscriber:","state="+m.state,"msgs="+m.messages.length,"open="+m.isOpen,"input="+T?.style.display,"prev="+(z?.state||"null")),i==="button"&&(m.isOpen?x.classList.add("namiru-popup--open"):x.classList.remove("namiru-popup--open")),!z||z.state!==m.state)switch(m.state){case"idle":j(),T.style.display="none",q();break;case"connecting":T.style.display="none",Re();break;case"pre_chat":Ge();break;case"chatting":q(),z?.state==="pre_chat"&&j(),T.style.display="",ze();break;case"feedback":pe(!0);break;case"escalation":de();break;case"email_fallback":me();break;case"conversation_limit":q(),T.style.display="none",ue();break;case"domain_error":q(),T.style.display="none",We();break;case"error":q(),T.style.display="none";break}m.messages.length>O&&m.state!=="pre_chat"&&Ze(m.messages),m.state==="chatting"&&m.messages.length>=W&&e.dispatch({type:"SET_STATE",state:"conversation_limit"}),z?.streamingContent!==m.streamingContent&&Ue(m.streamingContent),z?.isLoading!==m.isLoading&&qe(m.isLoading),z=m}),x._namiruShowEscalation=de,x._namiruShowFeedback=pe,x._namiruShowTranscript=ce,x._namiruShowContactForm=me,x._namiruShowLimitOverlay=ue,x._namiruShowCloseConfirmation=()=>re(N,e),x}function Pe(n){let{position:e,store:t,welcomeMessage:a,greetingDelay:i,bubbleStyle:r,onCloseRequest:l}=n,o=document.createElement("div"),s=document.createElement("button");s.className=`namiru-button namiru-button--${e}`,r==="classic"&&s.classList.add("namiru-button--classic"),s.setAttribute("aria-label","Open chat");let c=Ee(),d=ae();d.style.display="none",s.appendChild(c),s.appendChild(d),s.addEventListener("click",()=>{let E=t.getState().isOpen;E&&l?l():t.dispatch({type:"SET_OPEN",isOpen:!E})}),o.appendChild(s);let p=null,k=!1,h=null;if(a){p=document.createElement("div"),p.className=`namiru-greeting namiru-greeting--${e} namiru-greeting--hidden`;let E=document.createTextNode(a);p.appendChild(E);let f=document.createElement("button");f.className="namiru-greeting-close",f.setAttribute("aria-label","Dismiss"),f.textContent="\xD7",f.addEventListener("click",N=>{N.stopPropagation(),C()}),p.appendChild(f),p.addEventListener("click",()=>{C(),t.dispatch({type:"SET_OPEN",isOpen:!0})}),o.appendChild(p),h=setTimeout(()=>{!t.getState().isOpen&&p&&(p.classList.remove("namiru-greeting--hidden"),k=!0,setTimeout(()=>C(),3e4))},i??3e3)}function C(){k&&p&&(p.classList.add("namiru-greeting--hidden"),k=!1),h&&(clearTimeout(h),h=null)}return t.subscribe(E=>{E.isOpen?(c.style.display="none",d.style.display="",s.setAttribute("aria-label","Close chat"),C()):(c.style.display="",d.style.display="none",s.setAttribute("aria-label","Open chat"))}),o}function ht(n){try{let e=new URL(n),t=e.protocol==="https:"?"wss:":"ws:";return e.hostname==="localhost"||e.hostname==="127.0.0.1"?(e.port="3423",e.protocol=t,e.origin):e.hostname==="test.namiru.ai"?`${t}//ai-test.namiru.ai`:e.hostname==="namiru.ai"||e.hostname==="app.namiru.ai"||e.hostname==="api.namiru.ai"?`${t}//ai.namiru.ai`:(e.protocol=t,e.origin)}catch{let e=n.startsWith("https")?"wss":"ws",t=n.replace(/^https?:\/\//,"");return`${e}://${t}`}}function ft(n){try{let e=new URL(n);return e.hostname.startsWith("app.")?(e.hostname=e.hostname.replace("app.","api."),e.origin):e.hostname==="test.namiru.ai"?(e.hostname="api-test.namiru.ai",e.origin):e.hostname==="namiru.ai"?(e.hostname="api.namiru.ai",e.origin):((e.hostname==="localhost"||e.hostname==="127.0.0.1")&&(e.port="3001"),e.origin)}catch{return n}}function bt(n){let e,t=null;if(n.serverUrl)e=n.serverUrl.replace(/\/$/,"");else{let a=document.querySelectorAll("script[src]");for(let i=a.length-1;i>=0;i--){let r=a[i].src;if(r.includes("namiru-chat")||r.includes("namiru"))try{t=new URL(r).origin;break}catch{}}e=ft(t||location.origin)}return{apiBase:e,wsUrl:n.wsUrl||ht(t||e)}}var Be="namiru_visitor_id";function le(){try{let n=localStorage.getItem(Be);if(n)return n;let e=`v_${Date.now()}_${Math.random().toString(36).substring(2,11)}`;return localStorage.setItem(Be,e),e}catch{return`v_${Date.now()}_${Math.random().toString(36).substring(2,11)}`}}var Ve=0;function ie(){return Ve++,`msg-${Date.now()}-${Ve}`}function Fe(n){if(!n||n.length===0)return!1;let e=window.location.pathname;return n.some(t=>{if(t.endsWith("/*")){let a=t.slice(0,-1);return e.startsWith(a)||e===a.slice(0,-1)}if(t.endsWith("*")){let a=t.slice(0,-1);return e.startsWith(a)}return e===t})}function xt(n,e){if(!e)return()=>{};let t="namiru:locationchange",a=history.pushState.bind(history),i=history.replaceState.bind(history);history.pushState=function(...l){a(...l),window.dispatchEvent(new Event(t))},history.replaceState=function(...l){i(...l),window.dispatchEvent(new Event(t))};function r(){Fe(n)?e.style.display="none":e.style.display=""}return window.addEventListener(t,r),window.addEventListener("popstate",r),()=>{history.pushState=a,history.replaceState=i,window.removeEventListener(t,r),window.removeEventListener("popstate",r)}}function yt(n){if(!n||n.length===0)return!0;let e=window.location.hostname.toLowerCase();return e==="localhost"||e==="127.0.0.1"||e==="namiru.ai"||e.endsWith(".namiru.ai")?!0:n.some(t=>{let a=t.toLowerCase();return e===a||e.endsWith("."+a)})}function vt(n){if(!n.agentId)throw new Error("NamiruChat: agentId is required");let e=n.mode||"button",t="bottom-right",{apiBase:a,wsUrl:i}=bt(n),r=new Y,l=new J({baseUrl:a}),o=null,s=null,c=null,d=null,p=null,k=null,h=!1,C="handoff_accepted",E=!1,f=null,x=!1,N=null;s=document.createElement("div"),s.id="namiru-widget-host";let y=typeof s.attachShadow=="function";fe(y),y&&(s.style.cssText="all:initial;position:fixed;top:0;left:0;width:0;height:0;overflow:visible;z-index:2147483646;pointer-events:none;",c=s.attachShadow({mode:"open"})),d=document.createElement("div"),d.className="namiru-widget-root";let T=c||s;y&&(d.style.pointerEvents="auto"),T.appendChild(d);async function G(){try{let u=await l.fetchBranding(n.agentId);if(h)return;if(!yt(u.allowedDomains)){console.warn(`[Namiru Widget] Domain "${window.location.hostname}" is not allowed for this agent. Allowed: ${JSON.stringify(u.allowedDomains)}`);return}if(Fe(u.excludedRoutes)){console.info(`[Namiru Widget] Widget hidden on excluded route "${window.location.pathname}"`);return}xe({primaryColor:u.primaryColor,accentColor:u.accentColor,headerColor:u.headerColor,fontFamily:u.fontFamily,presetTheme:u.presetTheme,backgroundColor:u.backgroundColor,textColor:u.textColor,fontSize:u.fontSize,userMessageColor:u.userMessageColor,agentMessageColor:u.agentMessageColor,borderColor:u.borderColor,inputColor:u.inputColor,buttonColor:u.buttonColor},T,!y),n.suggestedQuestions&&n.suggestedQuestions.length>0&&(u.suggestedQuestions=n.suggestedQuestions),console.log("[NamiruChat] suggestedQuestions:",u.suggestedQuestions);let b=n.preChatEnabled??u.preChatConfig?.enabled??!1;b&&(u.preChatConfig?(u.preChatConfig.enabled=!0,n.preChatTemplate!==void 0&&(u.preChatConfig.template=n.preChatTemplate),n.preChatCustom&&(u.preChatConfig.custom=n.preChatCustom)):u.preChatConfig={enabled:!0,template:n.preChatTemplate??null,custom:n.preChatCustom}),x=u.feedbackConfig?.enabled??!1;let _=u.feedbackConfig?.inactivityMinutes??3;if(x&&(f=new X(_,()=>{let g=r.getState();!g.feedbackGiven&&g.state==="chatting"&&g.messages.length>0&&r.dispatch({type:"SET_STATE",state:"feedback"})})),p=De({store:r,branding:u,agentId:n.agentId,mode:e,position:t,onSendMessage:g=>{let w={id:ie(),role:"user",content:g,timestamp:Date.now()};r.dispatch({type:"ADD_MESSAGE",message:w}),r.dispatch({type:"SET_LOADING",isLoading:!0}),o&&o.sendMessage(g)},onPreChatSelect:g=>{r.dispatch({type:"SET_QUALIFICATION",qualification:g}),r.dispatch({type:"SET_STATE",state:"connecting"}),W(g)},onFeedback:g=>{let w=r.getState().sessionId;w&&l.submitFeedback(n.agentId,{sessionId:w,rating:g}).catch(A=>console.error("NamiruChat: feedback submit failed",A)),r.dispatch({type:"SET_FEEDBACK_GIVEN"}),f?.stop(),n.onFeedback?.(g)},onEscalationEmail:g=>{let w=r.getState().sessionId;w&&l.submitEscalation(n.agentId,{sessionId:w,userEmail:g}).catch(A=>console.error("NamiruChat: escalation submit failed",A)),o&&o.sendEscalationEmail(g),n.onLeadCapture?.({email:g,sessionId:w||"",source:"email_fallback",qualification:r.getState().qualification||void 0})},onTranscriptEmail:g=>{let w=r.getState().sessionId;w&&l.requestTranscript(n.agentId,w,{email:g}).catch(A=>console.error("NamiruChat: transcript request failed",A))},onContactFormSubmit:g=>{let w=le(),A=r.getState().sessionId;l.submitLead({agentId:n.agentId,name:g.name||void 0,email:g.email,message:g.message,visitorId:w,fallbackReason:C,conversationId:A||void 0}).catch(R=>console.error("NamiruChat: lead submit failed",R)),o&&o.sendHandoffComplete({email:g.email,name:g.name||void 0,reason:C}),n.onLeadCapture?.({email:g.email,sessionId:A||"",source:"email_fallback",qualification:r.getState().qualification||void 0})},onLimitMessage:g=>{g.visitorEmail?l.submitContactMessage(n.agentId,{email:g.visitorEmail,message:g.message,visitorId:le()}).catch(w=>console.error("NamiruChat: contact message submit failed",w)):l.submitLimitMessage({agentId:n.agentId,message:g.message}).catch(w=>console.error("NamiruChat: limit message submit failed",w))},feedbackEnabled:x,onNewChat:()=>{o&&(o.disconnect(),o=null),f?.stop(),r.dispatch({type:"RESET"}),r.dispatch({type:"SET_OPEN",isOpen:!0}),r.dispatch({type:"SET_STATE",state:"connecting"}),W()}}),d.appendChild(p),e==="button"&&(k=Pe({position:t,store:r,welcomeMessage:u.bubbleGreeting||void 0,greetingDelay:n.greetingDelay,bubbleStyle:u.bubbleStyle,onCloseRequest:()=>{let g=r.getState();if(x&&!g.feedbackGiven&&g.state==="chatting"&&g.messages.length>0){r.dispatch({type:"SET_STATE",state:"feedback"});return}if(g.messages.length===0){r.dispatch({type:"SET_OPEN",isOpen:!1});return}let w=p?._namiruShowCloseConfirmation;typeof w=="function"?w():r.dispatch({type:"SET_OPEN",isOpen:!1})}}),d.appendChild(k)),e==="inline"&&p){let g=n.width||"100%",w=n.height||"100%";p.style.width=g,p.style.height=w,p.style.maxHeight=w,d.style.height="100%"}if(y?e==="inline"&&n.container?(s.style.cssText="all:initial;display:block;height:100%;",n.container.appendChild(s)):document.body.appendChild(s):e==="inline"&&n.container?n.container.appendChild(d):document.body.appendChild(d),b?r.dispatch({type:"SET_STATE",state:"pre_chat"}):(r.dispatch({type:"SET_STATE",state:"connecting"}),W()),e==="inline"&&r.dispatch({type:"SET_OPEN",isOpen:!0}),u.excludedRoutes&&u.excludedRoutes.length>0){let g=y?s:d;N=xt(u.excludedRoutes,g)}}catch(u){console.error("NamiruChat: initialization failed",u),r.dispatch({type:"SET_ERROR",error:"Failed to load chat. Please try again later."})}}function F(){E&&(E=!1,p&&setTimeout(()=>{let u=p?._namiruShowEscalation;typeof u=="function"&&u()},100))}function W(u){o||h||(o=new K({url:i,agentId:n.agentId,visitorId:le()}),o.on("connected",()=>{}),o.on("agent_initialized",b=>{r.dispatch({type:"SET_STATE",state:"chatting"}),r.dispatch({type:"SET_LOADING",isLoading:!1}),b.data.sessionId&&(r.dispatch({type:"SET_SESSION_ID",sessionId:b.data.sessionId}),n.onSessionStart?.(b.data.sessionId)),u&&o?.sendMessage(`[User selected: ${u}]`)}),o.on("stream_token",b=>{r.dispatch({type:"APPEND_STREAMING",token:b.data.token})}),o.on("final_response",b=>{r.dispatch({type:"CLEAR_STREAMING"});let _={id:ie(),role:"assistant",content:b.data.content||b.data.response||"",timestamp:Date.now()};r.dispatch({type:"ADD_MESSAGE",message:_}),r.dispatch({type:"SET_LOADING",isLoading:!1}),F(),x&&b.data.conversationMayHaveEnded&&!r.getState().feedbackGiven?(setTimeout(()=>{let g=r.getState();!g.feedbackGiven&&g.state==="chatting"&&g.messages.length>0&&r.dispatch({type:"SET_STATE",state:"feedback"})},800),f?.stop()):f&&!r.getState().feedbackGiven&&f.reset()}),o.on("stream_end",()=>{let b=r.getState().streamingContent;if(b){r.dispatch({type:"CLEAR_STREAMING"});let _={id:ie(),role:"assistant",content:b,timestamp:Date.now()};r.dispatch({type:"ADD_MESSAGE",message:_})}r.dispatch({type:"SET_LOADING",isLoading:!1}),F(),f&&!r.getState().feedbackGiven&&f.reset()}),o.on("tool_start",()=>{r.dispatch({type:"SET_LOADING",isLoading:!0})}),o.on("tool_end",()=>{}),o.on("kit_trigger",b=>{let _=b.data;(_==="escalation_email_form"||_?.type==="escalation_email_form")&&(E=!0)}),o.on("handoff_active",b=>{let _={id:ie(),role:"assistant",content:b.data?.message||"A human operator is currently handling this conversation. Please wait for their response.",timestamp:Date.now()};r.dispatch({type:"ADD_MESSAGE",message:_}),r.dispatch({type:"SET_LOADING",isLoading:!1})}),o.on("show_handoff_form",b=>{C=b.data?.reason||"handoff_accepted",r.dispatch({type:"SET_STATE",state:"email_fallback"}),r.dispatch({type:"SET_LOADING",isLoading:!1})}),o.on("error",b=>{if(b.data?.type==="usage_limit"||b.data?.usage_limit){r.dispatch({type:"SET_STATE",state:"conversation_limit"}),r.dispatch({type:"SET_LOADING",isLoading:!1});return}if(b.data?.message==="Domain not authorized"){r.dispatch({type:"SET_STATE",state:"domain_error"}),r.dispatch({type:"SET_LOADING",isLoading:!1});return}console.error("NamiruChat: WebSocket error",b.data),r.dispatch({type:"SET_ERROR",error:b.data?.message||"Connection error. Please try again."}),r.dispatch({type:"SET_LOADING",isLoading:!1})}),o.on("disconnected",()=>{}),o.connect())}G();let O=!1,L=!1;return r.subscribe(u=>{if(!(h||L)){if(O&&!u.isOpen){O=!1,L=!0,o&&(o.disconnect(),o=null),f?.stop(),L=!1;return}if(!O&&u.isOpen&&!o){O=!0,L=!0,r.dispatch({type:"SET_STATE",state:"connecting"}),W(),L=!1;return}O=u.isOpen}}),{open:()=>{h||r.dispatch({type:"SET_OPEN",isOpen:!0})},close:()=>{h||r.dispatch({type:"SET_OPEN",isOpen:!1})},toggle:()=>{if(!h){let u=r.getState().isOpen;r.dispatch({type:"SET_OPEN",isOpen:!u})}},destroy:()=>{if(h)return;h=!0,N?.(),N=null,o?.disconnect(),f?.stop(),ye();let u=y?s:d;u&&u.parentNode&&u.parentNode.removeChild(u);let b=r.getState().sessionId;b&&n.onSessionEnd?.(b),r.dispatch({type:"RESET"}),s=null,c=null,d=null,p=null,k=null,o=null},updateConfig:u=>{h||Object.assign(n,u)}}}if(typeof document<"u"&&document.currentScript){let n=document.currentScript,e=n.getAttribute("data-agent-id");if(e){let t=n.getAttribute("data-mode")||"button",a=n.getAttribute("data-server-url")||void 0,i=n.getAttribute("data-container-id");vt({agentId:e,mode:t,serverUrl:a,container:i&&document.getElementById(i)||void 0})}}export{vt as init};
1091
+ `,Q.textContent="Reload",Q.addEventListener("click",()=>window.location.reload()),H.appendChild(Q),m.appendChild(H),y.appendChild(m)}function pe(m){_||(_=Ie({onFeedback:v=>{s(v),i==="button"&&setTimeout(()=>{e.dispatch({type:"RESET"}),e.dispatch({type:"SET_OPEN",isOpen:!1})},800)},softPrompt:m}),y.appendChild(_),Z())}function Z(){requestAnimationFrame(()=>{y.scrollTop=y.scrollHeight})}function Ze(m){A&&m.some(v=>v.role==="user")&&(A.remove(),A=null);for(let v=O;v<m.length;v++){let S=f.createBubble(m[v]);y.appendChild(S)}O=m.length,Z()}function Ue(m){if(m){L||(u&&(u.remove(),u=null),L=f.createStreaming(),y.appendChild(L));let v=L._namiruTextEl,S=ne(m);v?v.innerHTML=S:L.innerHTML=S,Z()}else L&&(L.remove(),L=null)}function qe(m){m&&!u&&!L?(u=f.createLoading(),y.appendChild(u),Z()):!m&&u&&(u.remove(),u=null)}let z=null;return e.subscribe(m=>{if(console.log("[ChatWindow] subscriber:","state="+m.state,"msgs="+m.messages.length,"open="+m.isOpen,"input="+T?.style.display,"prev="+(z?.state||"null")),i==="button"&&(m.isOpen?x.classList.add("namiru-popup--open"):x.classList.remove("namiru-popup--open")),!z||z.state!==m.state)switch(m.state){case"idle":j(),T.style.display="none",q();break;case"connecting":T.style.display="none",Re();break;case"pre_chat":Ge();break;case"chatting":q(),z?.state==="pre_chat"&&j(),T.style.display="",ze();break;case"feedback":pe(!0);break;case"escalation":de();break;case"email_fallback":me();break;case"conversation_limit":q(),T.style.display="none",ue();break;case"domain_error":q(),T.style.display="none",We();break;case"error":q(),T.style.display="none";break}m.messages.length>O&&m.state!=="pre_chat"&&Ze(m.messages),m.state==="chatting"&&m.messages.length>=W&&e.dispatch({type:"SET_STATE",state:"conversation_limit"}),z?.streamingContent!==m.streamingContent&&Ue(m.streamingContent),z?.isLoading!==m.isLoading&&qe(m.isLoading),z=m}),x._namiruShowEscalation=de,x._namiruShowFeedback=pe,x._namiruShowTranscript=ce,x._namiruShowContactForm=me,x._namiruShowLimitOverlay=ue,x._namiruShowCloseConfirmation=()=>re(N,e),x}function Pe(n){let{position:e,store:t,welcomeMessage:a,greetingDelay:i,bubbleStyle:r,onCloseRequest:l}=n,o=document.createElement("div"),s=document.createElement("button");s.className=`namiru-button namiru-button--${e}`,r==="classic"&&s.classList.add("namiru-button--classic"),s.setAttribute("aria-label","Open chat");let c=Ee(),d=ae();d.style.display="none",s.appendChild(c),s.appendChild(d),s.addEventListener("click",()=>{let E=t.getState().isOpen;E&&l?l():t.dispatch({type:"SET_OPEN",isOpen:!E})}),o.appendChild(s);let p=null,k=!1,h=null;if(a){p=document.createElement("div"),p.className=`namiru-greeting namiru-greeting--${e} namiru-greeting--hidden`;let E=document.createTextNode(a);p.appendChild(E);let f=document.createElement("button");f.className="namiru-greeting-close",f.setAttribute("aria-label","Dismiss"),f.textContent="\xD7",f.addEventListener("click",N=>{N.stopPropagation(),C()}),p.appendChild(f),p.addEventListener("click",()=>{C(),t.dispatch({type:"SET_OPEN",isOpen:!0})}),o.appendChild(p),h=setTimeout(()=>{!t.getState().isOpen&&p&&(p.classList.remove("namiru-greeting--hidden"),k=!0,setTimeout(()=>C(),3e4))},i??3e3)}function C(){k&&p&&(p.classList.add("namiru-greeting--hidden"),k=!1),h&&(clearTimeout(h),h=null)}return t.subscribe(E=>{E.isOpen?(c.style.display="none",d.style.display="",s.setAttribute("aria-label","Close chat"),C()):(c.style.display="",d.style.display="none",s.setAttribute("aria-label","Open chat"))}),o}function ht(n){try{let e=new URL(n),t=e.protocol==="https:"?"wss:":"ws:";return e.hostname==="localhost"||e.hostname==="127.0.0.1"?(e.port="3423",e.protocol=t,e.origin):e.hostname==="test.namiru.ai"?`${t}//ai-test.namiru.ai`:e.hostname==="namiru.ai"||e.hostname==="app.namiru.ai"||e.hostname==="api.namiru.ai"?`${t}//ai.namiru.ai`:(e.protocol=t,e.origin)}catch{let e=n.startsWith("https")?"wss":"ws",t=n.replace(/^https?:\/\//,"");return`${e}://${t}`}}function ft(n){try{let e=new URL(n);return e.hostname.startsWith("app.")?(e.hostname=e.hostname.replace("app.","api."),e.origin):e.hostname==="test.namiru.ai"?(e.hostname="api-test.namiru.ai",e.origin):e.hostname==="namiru.ai"?(e.hostname="api.namiru.ai",e.origin):((e.hostname==="localhost"||e.hostname==="127.0.0.1")&&(e.port="3001"),e.origin)}catch{return n}}function bt(n){let e,t=null;if(n.serverUrl)e=n.serverUrl.replace(/\/$/,"");else{let a=document.querySelectorAll("script[src]");for(let i=a.length-1;i>=0;i--){let r=a[i].src;if(r.includes("namiru-chat")||r.includes("namiru"))try{t=new URL(r).origin;break}catch{}}e=ft(t||location.origin)}return{apiBase:e,wsUrl:n.wsUrl||ht(t||e)}}var Be="namiru_visitor_id";function le(){try{let n=localStorage.getItem(Be);if(n)return n;let e=`v_${Date.now()}_${Math.random().toString(36).substring(2,11)}`;return localStorage.setItem(Be,e),e}catch{return`v_${Date.now()}_${Math.random().toString(36).substring(2,11)}`}}var Ve=0;function ie(){return Ve++,`msg-${Date.now()}-${Ve}`}function Fe(n){if(!n||n.length===0)return!1;let e=window.location.pathname;return n.some(t=>{if(t.endsWith("/*")){let a=t.slice(0,-1);return e.startsWith(a)||e===a.slice(0,-1)}if(t.endsWith("*")){let a=t.slice(0,-1);return e.startsWith(a)}return e===t})}function xt(n,e){if(!e)return()=>{};let t="namiru:locationchange",a=history.pushState.bind(history),i=history.replaceState.bind(history);history.pushState=function(...l){a(...l),window.dispatchEvent(new Event(t))},history.replaceState=function(...l){i(...l),window.dispatchEvent(new Event(t))};function r(){Fe(n)?e.style.display="none":e.style.display=""}return window.addEventListener(t,r),window.addEventListener("popstate",r),()=>{history.pushState=a,history.replaceState=i,window.removeEventListener(t,r),window.removeEventListener("popstate",r)}}function yt(n){if(!n||n.length===0)return!0;let e=window.location.hostname.toLowerCase();return e==="localhost"||e==="127.0.0.1"||e==="namiru.ai"||e.endsWith(".namiru.ai")?!0:n.some(t=>{let a=t.toLowerCase();return e===a||e.endsWith("."+a)})}function vt(n){if(!n.agentId)throw new Error("NamiruChat: agentId is required");let e=n.mode||"button",t=n.position||"bottom-right",{apiBase:a,wsUrl:i}=bt(n),r=new Y,l=new J({baseUrl:a}),o=null,s=null,c=null,d=null,p=null,k=null,h=!1,C="handoff_accepted",E=!1,f=null,x=!1,N=null;s=document.createElement("div"),s.id="namiru-widget-host";let y=typeof s.attachShadow=="function";fe(y),y&&(s.style.cssText="all:initial;position:fixed;top:0;left:0;width:0;height:0;overflow:visible;z-index:2147483646;pointer-events:none;",c=s.attachShadow({mode:"open"})),d=document.createElement("div"),d.className="namiru-widget-root";let T=c||s;y&&(d.style.pointerEvents="auto"),T.appendChild(d);async function G(){try{let u=await l.fetchBranding(n.agentId);if(h)return;if(!yt(u.allowedDomains)){console.warn(`[Namiru Widget] Domain "${window.location.hostname}" is not allowed for this agent. Allowed: ${JSON.stringify(u.allowedDomains)}`);return}if(Fe(u.excludedRoutes)){console.info(`[Namiru Widget] Widget hidden on excluded route "${window.location.pathname}"`);return}xe({primaryColor:u.primaryColor,accentColor:u.accentColor,headerColor:u.headerColor,fontFamily:u.fontFamily,presetTheme:u.presetTheme,backgroundColor:u.backgroundColor,textColor:u.textColor,fontSize:u.fontSize,userMessageColor:u.userMessageColor,agentMessageColor:u.agentMessageColor,borderColor:u.borderColor,inputColor:u.inputColor,buttonColor:u.buttonColor},T,!y),n.suggestedQuestions&&n.suggestedQuestions.length>0&&(u.suggestedQuestions=n.suggestedQuestions),console.log("[NamiruChat] suggestedQuestions:",u.suggestedQuestions);let b=n.preChatEnabled??u.preChatConfig?.enabled??!1;b&&(u.preChatConfig?(u.preChatConfig.enabled=!0,n.preChatTemplate!==void 0&&(u.preChatConfig.template=n.preChatTemplate),n.preChatCustom&&(u.preChatConfig.custom=n.preChatCustom)):u.preChatConfig={enabled:!0,template:n.preChatTemplate??null,custom:n.preChatCustom}),x=u.feedbackConfig?.enabled??!1;let _=u.feedbackConfig?.inactivityMinutes??3;if(x&&(f=new X(_,()=>{let g=r.getState();!g.feedbackGiven&&g.state==="chatting"&&g.messages.length>0&&r.dispatch({type:"SET_STATE",state:"feedback"})})),p=De({store:r,branding:u,agentId:n.agentId,mode:e,position:t,onSendMessage:g=>{let w={id:ie(),role:"user",content:g,timestamp:Date.now()};r.dispatch({type:"ADD_MESSAGE",message:w}),r.dispatch({type:"SET_LOADING",isLoading:!0}),o&&o.sendMessage(g)},onPreChatSelect:g=>{r.dispatch({type:"SET_QUALIFICATION",qualification:g}),r.dispatch({type:"SET_STATE",state:"connecting"}),W(g)},onFeedback:g=>{let w=r.getState().sessionId;w&&l.submitFeedback(n.agentId,{sessionId:w,rating:g}).catch(A=>console.error("NamiruChat: feedback submit failed",A)),r.dispatch({type:"SET_FEEDBACK_GIVEN"}),f?.stop(),n.onFeedback?.(g)},onEscalationEmail:g=>{let w=r.getState().sessionId;w&&l.submitEscalation(n.agentId,{sessionId:w,userEmail:g}).catch(A=>console.error("NamiruChat: escalation submit failed",A)),o&&o.sendEscalationEmail(g),n.onLeadCapture?.({email:g,sessionId:w||"",source:"email_fallback",qualification:r.getState().qualification||void 0})},onTranscriptEmail:g=>{let w=r.getState().sessionId;w&&l.requestTranscript(n.agentId,w,{email:g}).catch(A=>console.error("NamiruChat: transcript request failed",A))},onContactFormSubmit:g=>{let w=le(),A=r.getState().sessionId;l.submitLead({agentId:n.agentId,name:g.name||void 0,email:g.email,message:g.message,visitorId:w,fallbackReason:C,conversationId:A||void 0}).catch(R=>console.error("NamiruChat: lead submit failed",R)),o&&o.sendHandoffComplete({email:g.email,name:g.name||void 0,reason:C}),n.onLeadCapture?.({email:g.email,sessionId:A||"",source:"email_fallback",qualification:r.getState().qualification||void 0})},onLimitMessage:g=>{g.visitorEmail?l.submitContactMessage(n.agentId,{email:g.visitorEmail,message:g.message,visitorId:le()}).catch(w=>console.error("NamiruChat: contact message submit failed",w)):l.submitLimitMessage({agentId:n.agentId,message:g.message}).catch(w=>console.error("NamiruChat: limit message submit failed",w))},feedbackEnabled:x,onNewChat:()=>{o&&(o.disconnect(),o=null),f?.stop(),r.dispatch({type:"RESET"}),r.dispatch({type:"SET_OPEN",isOpen:!0}),r.dispatch({type:"SET_STATE",state:"connecting"}),W()}}),d.appendChild(p),e==="button"&&(k=Pe({position:t,store:r,welcomeMessage:u.bubbleGreeting||void 0,greetingDelay:n.greetingDelay,bubbleStyle:u.bubbleStyle,onCloseRequest:()=>{let g=r.getState();if(x&&!g.feedbackGiven&&g.state==="chatting"&&g.messages.length>0){r.dispatch({type:"SET_STATE",state:"feedback"});return}if(g.messages.length===0){r.dispatch({type:"SET_OPEN",isOpen:!1});return}let w=p?._namiruShowCloseConfirmation;typeof w=="function"?w():r.dispatch({type:"SET_OPEN",isOpen:!1})}}),d.appendChild(k)),e==="inline"&&p){let g=n.width||"100%",w=n.height||"100%";p.style.width=g,p.style.height=w,p.style.maxHeight=w,d.style.height="100%"}if(y?e==="inline"&&n.container?(s.style.cssText="all:initial;display:block;height:100%;",n.container.appendChild(s)):document.body.appendChild(s):e==="inline"&&n.container?n.container.appendChild(d):document.body.appendChild(d),b?r.dispatch({type:"SET_STATE",state:"pre_chat"}):(r.dispatch({type:"SET_STATE",state:"connecting"}),W()),e==="inline"&&r.dispatch({type:"SET_OPEN",isOpen:!0}),u.excludedRoutes&&u.excludedRoutes.length>0){let g=y?s:d;N=xt(u.excludedRoutes,g)}}catch(u){console.error("NamiruChat: initialization failed",u),r.dispatch({type:"SET_ERROR",error:"Failed to load chat. Please try again later."})}}function F(){E&&(E=!1,p&&setTimeout(()=>{let u=p?._namiruShowEscalation;typeof u=="function"&&u()},100))}function W(u){o||h||(o=new K({url:i,agentId:n.agentId,visitorId:le()}),o.on("connected",()=>{}),o.on("agent_initialized",b=>{r.dispatch({type:"SET_STATE",state:"chatting"}),r.dispatch({type:"SET_LOADING",isLoading:!1}),b.data.sessionId&&(r.dispatch({type:"SET_SESSION_ID",sessionId:b.data.sessionId}),n.onSessionStart?.(b.data.sessionId)),u&&o?.sendMessage(`[User selected: ${u}]`)}),o.on("stream_token",b=>{r.dispatch({type:"APPEND_STREAMING",token:b.data.token})}),o.on("final_response",b=>{r.dispatch({type:"CLEAR_STREAMING"});let _={id:ie(),role:"assistant",content:b.data.content||b.data.response||"",timestamp:Date.now()};r.dispatch({type:"ADD_MESSAGE",message:_}),r.dispatch({type:"SET_LOADING",isLoading:!1}),F(),x&&b.data.conversationMayHaveEnded&&!r.getState().feedbackGiven?(setTimeout(()=>{let g=r.getState();!g.feedbackGiven&&g.state==="chatting"&&g.messages.length>0&&r.dispatch({type:"SET_STATE",state:"feedback"})},800),f?.stop()):f&&!r.getState().feedbackGiven&&f.reset()}),o.on("stream_end",()=>{let b=r.getState().streamingContent;if(b){r.dispatch({type:"CLEAR_STREAMING"});let _={id:ie(),role:"assistant",content:b,timestamp:Date.now()};r.dispatch({type:"ADD_MESSAGE",message:_})}r.dispatch({type:"SET_LOADING",isLoading:!1}),F(),f&&!r.getState().feedbackGiven&&f.reset()}),o.on("tool_start",()=>{r.dispatch({type:"SET_LOADING",isLoading:!0})}),o.on("tool_end",()=>{}),o.on("kit_trigger",b=>{let _=b.data;(_==="escalation_email_form"||_?.type==="escalation_email_form")&&(E=!0)}),o.on("handoff_active",b=>{let _={id:ie(),role:"assistant",content:b.data?.message||"A human operator is currently handling this conversation. Please wait for their response.",timestamp:Date.now()};r.dispatch({type:"ADD_MESSAGE",message:_}),r.dispatch({type:"SET_LOADING",isLoading:!1})}),o.on("show_handoff_form",b=>{C=b.data?.reason||"handoff_accepted",r.dispatch({type:"SET_STATE",state:"email_fallback"}),r.dispatch({type:"SET_LOADING",isLoading:!1})}),o.on("error",b=>{if(b.data?.type==="usage_limit"||b.data?.usage_limit){r.dispatch({type:"SET_STATE",state:"conversation_limit"}),r.dispatch({type:"SET_LOADING",isLoading:!1});return}if(b.data?.message==="Domain not authorized"){r.dispatch({type:"SET_STATE",state:"domain_error"}),r.dispatch({type:"SET_LOADING",isLoading:!1});return}console.error("NamiruChat: WebSocket error",b.data),r.dispatch({type:"SET_ERROR",error:b.data?.message||"Connection error. Please try again."}),r.dispatch({type:"SET_LOADING",isLoading:!1})}),o.on("disconnected",()=>{}),o.connect())}G();let O=!1,L=!1;return r.subscribe(u=>{if(!(h||L)){if(O&&!u.isOpen){O=!1,L=!0,o&&(o.disconnect(),o=null),f?.stop(),L=!1;return}if(!O&&u.isOpen&&!o){O=!0,L=!0,r.dispatch({type:"SET_STATE",state:"connecting"}),W(),L=!1;return}O=u.isOpen}}),{open:()=>{h||r.dispatch({type:"SET_OPEN",isOpen:!0})},close:()=>{h||r.dispatch({type:"SET_OPEN",isOpen:!1})},toggle:()=>{if(!h){let u=r.getState().isOpen;r.dispatch({type:"SET_OPEN",isOpen:!u})}},destroy:()=>{if(h)return;h=!0,N?.(),N=null,o?.disconnect(),f?.stop(),ye();let u=y?s:d;u&&u.parentNode&&u.parentNode.removeChild(u);let b=r.getState().sessionId;b&&n.onSessionEnd?.(b),r.dispatch({type:"RESET"}),s=null,c=null,d=null,p=null,k=null,o=null},updateConfig:u=>{h||Object.assign(n,u)}}}if(typeof document<"u"&&document.currentScript){let n=document.currentScript,e=n.getAttribute("data-agent-id");if(e){let t=n.getAttribute("data-mode")||"button",a=n.getAttribute("data-server-url")||void 0,i=n.getAttribute("data-container-id");vt({agentId:e,mode:t,serverUrl:a,container:i&&document.getElementById(i)||void 0})}}export{vt as init};
1092
1092
  //# sourceMappingURL=namiru-chat.esm.js.map