@inkeep/agents-ui 0.15.27 → 0.15.28

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.
@@ -1,4 +1,4 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Ve=require("@ai-sdk/react"),Se=require("./file-upload-input.cjs"),Ze=require("ai"),t=require("react"),Xe=require("../modal/modal-provider.cjs"),Ye=require("../../providers/chat-bubble-provider.cjs"),et=require("../../providers/sidebar-chat-provider.cjs"),tt=require("../../providers/config-provider.cjs"),st=require("./use-captcha.cjs"),rt=require("../../hooks/use-media-query.cjs"),nt=require("../../hooks/use-anonymous-session.cjs"),at=require("../../hooks/use-auth-token.cjs"),ot=require("../../hooks/use-conversation-loader.cjs"),O=require("../../utils/generate-uid.cjs"),it=require("../../providers/base-events-provider.cjs"),ut=require("../../providers/chat-form-provider.cjs"),ct=require("../../providers/widget-provider.cjs"),lt=require("@radix-ui/react-use-controllable-state"),dt=require("../../hooks/use-streaming-events.cjs"),pt=require("../../hooks/use-inkeep-api-client.cjs"),ft=require("../../hooks/use-input-notification.cjs");function ht(g){const m=g.message??"";let r=Number(g.code)||Number(g.statusCode);if(Number.isNaN(r))try{r=Number(JSON.parse(m).status)}catch{}const d=pt.parseAuthError(r,{detail:m});return d!==null?d:r===401?"session":null}const _=`Hmm..
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Ze=require("@ai-sdk/react"),Ae=require("./file-upload-input.cjs"),Xe=require("ai"),t=require("react"),Ye=require("../modal/modal-provider.cjs"),et=require("../../providers/chat-bubble-provider.cjs"),tt=require("../../providers/sidebar-chat-provider.cjs"),st=require("../../providers/config-provider.cjs"),rt=require("./use-captcha.cjs"),nt=require("../../hooks/use-media-query.cjs"),at=require("../../hooks/use-anonymous-session.cjs"),ot=require("../../hooks/use-auth-token.cjs"),it=require("../../hooks/use-conversation-loader.cjs"),ut=require("../../hooks/use-initial-conversation.cjs"),O=require("../../utils/generate-uid.cjs"),ct=require("../../providers/base-events-provider.cjs"),lt=require("../../providers/chat-form-provider.cjs"),dt=require("../../providers/widget-provider.cjs"),ft=require("@radix-ui/react-use-controllable-state"),pt=require("../../hooks/use-streaming-events.cjs"),ht=require("../../hooks/use-inkeep-api-client.cjs"),gt=require("../../hooks/use-input-notification.cjs");function mt(m){const h=m.message??"";let r=Number(m.code)||Number(m.statusCode);if(Number.isNaN(r))try{r=Number(JSON.parse(h).status)}catch{}const d=ht.parseAuthError(r,{detail:h});return d!==null?d:r===401?"session":null}const _=`Hmm..
2
2
 
3
- It seems I might be having some issues right now. Please clear the chat and try again.`,gt=()=>{const{baseSettings:g,aiChatSettings:m}=tt.useInkeepConfig(),[r="",d]=lt.useControllableState({prop:m.conversationId,defaultProp:m.conversationId??""}),Ae=Xe.useModal(),Ie=Ye.useOptionalChatBubble(),we=et.useOptionalSidebarChat(),{logEvent:v}=it.useBaseEvents(),{setConversationId:ke,emitToParent:T}=dt.useStreamingEvents(),Y=t.useRef(r);t.useEffect(()=>{const e=Y.current;Y.current=r,e!==r&&v({eventName:"chat_conversation_changed",properties:{conversationId:r,previousConversationId:e}})},[r,v]);const[C,E]=t.useState(""),Te=e=>E(e.target.value),{shouldBypassCaptcha:ee,filters:te,privacyPreferences:Ee,userProperties:U}=g,{authToken:M,isLoading:Me,refreshToken:se}=at.useAuthToken(),re=!!g.getAuthToken,p=!!M,{onInputMessageChange:qe,filters:ne,baseUrl:q,agentUrl:xe,context:ae,headers:oe,appId:R,apiKey:y,files:S}=m,Fe=Ae?.isOpen??Ie?.isOpen??we?.isOpen??!0,{getCaptchaHeader:A,invalidate:c}=st.useCaptcha({baseUrl:q,shouldBypassCaptcha:ee||!!y,shouldMakeInitialRequest:Fe}),ie=t.useRef(A);ie.current=A;const ue=xe||`${q}/run/api/chat`,{sessionToken:D,refreshSession:L}=nt.useAnonymousSession({baseUrl:q,appId:R,getCaptchaHeader:A,invalidateCaptcha:c,optOutAllAnalytics:Ee?.optOutAllAnalytics,enabled:!p&&!Me}),{loadConversation:ce}=ot.useConversationLoader({baseUrl:q,appId:R,authToken:y??(p?M:D),getCaptchaHeader:A,invalidateCaptcha:c,refreshSession:y||p?void 0:L}),[Pe,le]=t.useState(!1),$=t.useRef(null);$.current=D;const B=t.useRef(null);B.current=M;const z=t.useRef(void 0);z.current=U&&Object.keys(U).length>0?JSON.stringify(U):void 0;const b=t.useRef(0),de=t.useRef(null),H=t.useRef(null),I=t.useRef(void 0),Ne=S?.map(e=>`${e.filename??""}:${e.mediaType}:${e.url.length}:${e.url.slice(0,64)}:${e.url.slice(-32)}`).join(`
4
- `)??"";t.useEffect(()=>{I.current=S?.length?S:void 0},[Ne]);const pe=t.useRef(oe);pe.current=oe;const K=t.useRef(void 0);K.current=te||ne?JSON.stringify({...te,...ne}):void 0;const Oe=e=>{switch(e.code){case 400:return e.message;case 401:return re?"Authentication failed. Please try again.":_;case 403:return`There seems to be a configuration error. Please contact ${g.organizationDisplayName??"Administrator"}`;default:return _}},[x,j]=t.useState([]),_e=t.useMemo(()=>new Ze.DefaultChatTransport({api:ue,headers:()=>{const e=y??B.current??$.current;return{"x-inkeep-client-timezone":Intl.DateTimeFormat().resolvedOptions().timeZone,"x-inkeep-client-timestamp":new Date().toISOString(),...R?{"x-inkeep-app-id":R}:{},...e?{Authorization:`Bearer ${e}`}:{},...K.current?{"inkeep-filters":K.current}:{},...z.current?{"x-inkeep-user-properties":z.current}:{},...pe.current}},prepareSendMessagesRequest:async e=>{const u=await ie.current(),s=e.messages[e.messages.length-1];return s||console.warn("[useInkeepChat] prepareSendMessagesRequest called with empty messages array"),{body:{...e.body,id:e.id,messages:s?[s]:[],trigger:e.trigger,messageId:e.messageId},headers:{...e.headers,...u}}},body:{requestContext:ae}}),[ue,ae,R,y]),{messages:F,sendMessage:J,addToolApprovalResponse:G,status:fe,setMessages:h,stop:P,error:Q}=Ve.useChat({transport:_e,onData(e){T(e.type,e.data)},async onFinish(){T("completion",{conversationId:r}),await v({eventName:"assistant_message_received",properties:{conversationId:r}}),v({eventName:"assistant_answer_displayed",properties:{conversationId:r}})},onError(e){console.error("onError",{code:e.code,message:e.message});const u=ee||y?null:ht(e);if(u!==null&&b.current<1){b.current++;const s=H.current,n=de.current;(async()=>{if(u==="session"&&re){const a=await se();if(!a)throw new Error("Auth token refresh failed");B.current=a}else if(u==="session"){const a=await L();a&&($.current=a)}else c();if(s){G(s);return}n&&(h(a=>{let o=[...a];return o.at(-1)?.role==="assistant"&&(o=o.slice(0,-1)),o.at(-1)?.role==="user"&&(o=o.slice(0,-1)),o}),J(n.files?.length?{parts:[{type:"text",text:n.content},...n.files]}:{text:n.content},{body:n.body}))})().catch(()=>{b.current=0,c(),h(a=>{const o=[...a],f=o[o.length-1];if(!f)return o;const l=_;return f.role==="user"?o.push({id:O.generateUid(16),role:"assistant",parts:[{type:"text",text:l}]}):f.parts=[{type:"text",text:l}],o})});return}b.current=0,u!==null&&c(),v({eventName:"chat_error",properties:{conversationId:r,error:e.message}}),h(s=>{const n=[...s],i=n[n.length-1];if(i){const a=Oe(e);i.role==="user"?n.push({id:O.generateUid(16),role:"assistant",parts:[{type:"text",text:a}]}):i.parts=[{type:"text",text:a}]}return n})}}),he=t.useRef(p);t.useEffect(()=>{const e=he.current;he.current=p,e!==p&&(P(),w(null),h([]),d(""),E(""),j([]),c())},[p,P,h,d,c]);const ge=fe==="submitted",W=fe==="streaming",Ue=t.useMemo(()=>{const e=i=>{if(!i||typeof i!="object")return!1;const a=i;return typeof a.type=="string"&&a.type.startsWith("tool-")},s=[...F??[]].reverse().find(i=>i.role==="assistant");if(!s)return!1;const n=s.parts?.at(-1);return!(!e(n)||n.state!=="output-available"||!n.approval?.id||W)},[F,W]),me=W||Ue,ve=ge||me,De=F.length===0,V=!C.trim()&&x.length===0||ve,Le=rt.useMediaQuery("(max-width: 768px)"),[$e,w]=t.useState(null);t.useEffect(()=>{Q&&w(Q)},[Q]);const Be=()=>w(null),{inputNotification:ze,showInputNotification:ye,clearInputNotification:He}=ft.useInputNotification(),be=t.useRef(null);t.useEffect(()=>{qe?.(C)},[C]);const Ke=e=>{e.key==="Enter"&&!e.shiftKey&&!V&&!e.nativeEvent.isComposing&&(e.preventDefault(),Z())},Z=async(e=C)=>{if(V&&(!e||e.trim().length===0)&&x.length===0)return;const u=x;j([]),E(""),b.current=0,H.current=null,await v({eventName:"user_message_submitted",properties:{conversationId:r}});let s=r;s||(s=`conv_${O.generateUid(16)}`,d(s)),ke(s);const n=I.current;I.current=void 0;let i,a;if(n?.length){let o;try{o=await Promise.all(u.map(f=>{const l=Se.normalizeFileType(f);return new Promise((We,Re)=>{const k=new FileReader;k.onload=()=>{if(typeof k.result!="string"){Re(new Error(`Failed to read file "${l.name}"`));return}We({type:"file",url:k.result,mediaType:l.type,filename:l.name})},k.onerror=()=>Re(new Error(`Failed to read file "${l.name}"`)),k.readAsDataURL(l)})}))}catch{ye({title:"Failed to attach files",message:"Could not read one or more files. Please try again."});return}a=[...o,...n],i=e.trim()?{parts:[{type:"text",text:e},...a]}:{parts:a}}else if(u.length>0){const o=new DataTransfer;for(const l of u)o.items.add(Se.normalizeFileType(l));const f=o.files;i=e.trim()?{text:e,files:f}:{files:f}}else i={text:e};de.current={content:e,body:{conversationId:s},files:a},J(i,{body:{conversationId:s}})},je=t.useCallback(e=>{b.current=0,H.current=e,G(e)},[G]),X=t.useCallback(()=>{P().then(()=>{T("aborted",{conversationId:r})})},[P,r,T]),Ce=()=>{Be(),h([]),d(""),c(),I.current=S?.length?S:void 0,v({eventName:"chat_clear_button_clicked",properties:{conversationId:r}})},N=t.useCallback((e,u)=>{w(null),h(u),d(e),c(),I.current=void 0},[h,d,c]),Je=t.useCallback(async(e,u)=>{X(),N(e,[]),le(!0);try{const s=await ce(e,u),n=s?.[s.length-1],i=s!==null&&n?.role==="user"?[...s,{id:O.generateUid(16),role:"assistant",parts:[{type:"text",text:"This session was interrupted. Please check back in a few minutes or start a new conversation."}]}]:s;i!==null&&N(e,i)}finally{u?.aborted||le(!1)}},[N,ce,X]),{openForm:Ge}=ut.useChatForm(),Qe=ct.useWidget();return t.useImperativeHandle(m.chatFunctionsRef,()=>({submitMessage:Z,updateInputMessage(e){E(e)},clearChat:Ce,openForm:e=>{Qe?.setView("chat"),Ge(e,void 0)},focusInput:()=>{be.current?.focus()}})),{messages:F,sendMessage:J,addToolApprovalResponse:je,isLoading:ge,isStreaming:me,isBusy:ve,error:$e,setError:w,isSubmitDisabled:V,input:C,handleInputChange:Te,handleInputKeyDown:Ke,handleSubmit:Z,stop:X,clear:Ce,inputRef:be,isMobile:Le,files:x,setFiles:j,isNewChat:De,conversationId:r,restoreSession:N,loadAndRestoreSession:Je,isSessionLoading:Pe,authToken:p?M:D,refreshSession:p?se:L,getCaptchaHeader:A,invalidateCaptcha:c,inputNotification:ze,showInputNotification:ye,clearInputNotification:He}};exports.DEFAULT_ERROR_MESSAGE=_;exports.useInkeepChat=gt;
3
+ It seems I might be having some issues right now. Please clear the chat and try again.`,vt=()=>{const{baseSettings:m,aiChatSettings:h}=st.useInkeepConfig(),[r="",d]=ft.useControllableState({prop:h.conversationIdOverride,defaultProp:h.conversationIdOverride??""}),ke=Ye.useModal(),we=et.useOptionalChatBubble(),Te=tt.useOptionalSidebarChat(),{logEvent:v}=ct.useBaseEvents(),{setConversationId:Ee,emitToParent:E}=pt.useStreamingEvents(),Y=t.useRef(r);t.useEffect(()=>{const e=Y.current;Y.current=r,e!==r&&v({eventName:"chat_conversation_changed",properties:{conversationId:r,previousConversationId:e}})},[r,v]);const[C,M]=t.useState(""),Me=e=>M(e.target.value),{shouldBypassCaptcha:ee,filters:te,privacyPreferences:qe,userProperties:U}=m,{authToken:q,isLoading:Fe,refreshToken:se}=ot.useAuthToken(),re=!!m.getAuthToken,f=!!q,{onInputMessageChange:xe,filters:ne,baseUrl:F,agentUrl:Pe,context:ae,headers:oe,appId:R,apiKey:y,files:S}=h,Ne=ke?.isOpen??we?.isOpen??Te?.isOpen??!0,{getCaptchaHeader:I,invalidate:c}=rt.useCaptcha({baseUrl:F,shouldBypassCaptcha:ee||!!y,shouldMakeInitialRequest:Ne}),ie=t.useRef(I);ie.current=I;const ue=Pe||`${F}/run/api/chat`,{sessionToken:D,refreshSession:L}=at.useAnonymousSession({baseUrl:F,appId:R,getCaptchaHeader:I,invalidateCaptcha:c,optOutAllAnalytics:qe?.optOutAllAnalytics,enabled:!f&&!Fe}),ce=y??(f?q:D),{loadConversation:le}=it.useConversationLoader({baseUrl:F,appId:R,authToken:ce,getCaptchaHeader:I,invalidateCaptcha:c,refreshSession:y||f?void 0:L}),[Oe,de]=t.useState(!1),$=t.useRef(null);$.current=D;const B=t.useRef(null);B.current=q;const z=t.useRef(void 0);z.current=U&&Object.keys(U).length>0?JSON.stringify(U):void 0;const b=t.useRef(0),fe=t.useRef(null),H=t.useRef(null),A=t.useRef(void 0),_e=S?.map(e=>`${e.filename??""}:${e.mediaType}:${e.url.length}:${e.url.slice(0,64)}:${e.url.slice(-32)}`).join(`
4
+ `)??"";t.useEffect(()=>{A.current=S?.length?S:void 0},[_e]);const pe=t.useRef(oe);pe.current=oe;const K=t.useRef(void 0);K.current=te||ne?JSON.stringify({...te,...ne}):void 0;const Ue=e=>{switch(e.code){case 400:return e.message;case 401:return re?"Authentication failed. Please try again.":_;case 403:return`There seems to be a configuration error. Please contact ${m.organizationDisplayName??"Administrator"}`;default:return _}},[x,j]=t.useState([]),De=t.useMemo(()=>new Xe.DefaultChatTransport({api:ue,headers:()=>{const e=y??B.current??$.current;return{"x-inkeep-client-timezone":Intl.DateTimeFormat().resolvedOptions().timeZone,"x-inkeep-client-timestamp":new Date().toISOString(),...R?{"x-inkeep-app-id":R}:{},...e?{Authorization:`Bearer ${e}`}:{},...K.current?{"inkeep-filters":K.current}:{},...z.current?{"x-inkeep-user-properties":z.current}:{},...pe.current}},prepareSendMessagesRequest:async e=>{const u=await ie.current(),s=e.messages[e.messages.length-1];return s||console.warn("[useInkeepChat] prepareSendMessagesRequest called with empty messages array"),{body:{...e.body,id:e.id,messages:s?[s]:[],trigger:e.trigger,messageId:e.messageId},headers:{...e.headers,...u}}},body:{requestContext:ae}}),[ue,ae,R,y]),{messages:P,sendMessage:J,addToolApprovalResponse:G,status:he,setMessages:g,stop:N,error:Q}=Ze.useChat({transport:De,onData(e){E(e.type,e.data)},async onFinish(){E("completion",{conversationId:r}),await v({eventName:"assistant_message_received",properties:{conversationId:r}}),v({eventName:"assistant_answer_displayed",properties:{conversationId:r}})},onError(e){console.error("onError",{code:e.code,message:e.message});const u=ee||y?null:mt(e);if(u!==null&&b.current<1){b.current++;const s=H.current,a=fe.current;(async()=>{if(u==="session"&&re){const n=await se();if(!n)throw new Error("Auth token refresh failed");B.current=n}else if(u==="session"){const n=await L();n&&($.current=n)}else c();if(s){G(s);return}a&&(g(n=>{let o=[...n];return o.at(-1)?.role==="assistant"&&(o=o.slice(0,-1)),o.at(-1)?.role==="user"&&(o=o.slice(0,-1)),o}),J(a.files?.length?{parts:[{type:"text",text:a.content},...a.files]}:{text:a.content},{body:a.body}))})().catch(()=>{b.current=0,c(),g(n=>{const o=[...n],p=o[o.length-1];if(!p)return o;const l=_;return p.role==="user"?o.push({id:O.generateUid(16),role:"assistant",parts:[{type:"text",text:l}]}):p.parts=[{type:"text",text:l}],o})});return}b.current=0,u!==null&&c(),v({eventName:"chat_error",properties:{conversationId:r,error:e.message}}),g(s=>{const a=[...s],i=a[a.length-1];if(i){const n=Ue(e);i.role==="user"?a.push({id:O.generateUid(16),role:"assistant",parts:[{type:"text",text:n}]}):i.parts=[{type:"text",text:n}]}return a})}}),ge=t.useRef(f);t.useEffect(()=>{const e=ge.current;ge.current=f,e!==f&&(N(),k(null),g([]),d(""),M(""),j([]),c())},[f,N,g,d,c]);const me=he==="submitted",W=he==="streaming",Le=t.useMemo(()=>{const e=i=>{if(!i||typeof i!="object")return!1;const n=i;return typeof n.type=="string"&&n.type.startsWith("tool-")},s=[...P??[]].reverse().find(i=>i.role==="assistant");if(!s)return!1;const a=s.parts?.at(-1);return!(!e(a)||a.state!=="output-available"||!a.approval?.id||W)},[P,W]),ve=W||Le,ye=me||ve,$e=P.length===0,V=!C.trim()&&x.length===0||ye,Be=nt.useMediaQuery("(max-width: 768px)"),[ze,k]=t.useState(null);t.useEffect(()=>{Q&&k(Q)},[Q]);const He=()=>k(null),{inputNotification:Ke,showInputNotification:be,clearInputNotification:je}=gt.useInputNotification(),Ce=t.useRef(null);t.useEffect(()=>{xe?.(C)},[C]);const Je=e=>{e.key==="Enter"&&!e.shiftKey&&!V&&!e.nativeEvent.isComposing&&(e.preventDefault(),Z())},Z=async(e=C)=>{if(V&&(!e||e.trim().length===0)&&x.length===0)return;const u=x;j([]),M(""),b.current=0,H.current=null,await v({eventName:"user_message_submitted",properties:{conversationId:r}});let s=r;s||(s=`conv_${O.generateUid(16)}`,d(s)),Ee(s);const a=A.current;A.current=void 0;let i,n;if(a?.length){let o;try{o=await Promise.all(u.map(p=>{const l=Ae.normalizeFileType(p);return new Promise((Ve,Ie)=>{const T=new FileReader;T.onload=()=>{if(typeof T.result!="string"){Ie(new Error(`Failed to read file "${l.name}"`));return}Ve({type:"file",url:T.result,mediaType:l.type,filename:l.name})},T.onerror=()=>Ie(new Error(`Failed to read file "${l.name}"`)),T.readAsDataURL(l)})}))}catch{be({title:"Failed to attach files",message:"Could not read one or more files. Please try again."});return}n=[...o,...a],i=e.trim()?{parts:[{type:"text",text:e},...n]}:{parts:n}}else if(u.length>0){const o=new DataTransfer;for(const l of u)o.items.add(Ae.normalizeFileType(l));const p=o.files;i=e.trim()?{text:e,files:p}:{files:p}}else i={text:e};fe.current={content:e,body:{conversationId:s},files:n},J(i,{body:{conversationId:s}})},Ge=t.useCallback(e=>{b.current=0,H.current=e,G(e)},[G]),X=t.useCallback(()=>{N().then(()=>{E("aborted",{conversationId:r})})},[N,r,E]),Re=()=>{He(),g([]),d(""),c(),A.current=S?.length?S:void 0,v({eventName:"chat_clear_button_clicked",properties:{conversationId:r}})},w=t.useCallback((e,u)=>{k(null),g(u),d(e),c(),A.current=void 0},[g,d,c]),Se=t.useCallback(async(e,u)=>{X(),w(e,[]),de(!0);try{const s=await le(e,u);if(s===null)return!1;const i=s[s.length-1]?.role==="user"?[...s,{id:O.generateUid(16),role:"assistant",parts:[{type:"text",text:"This session was interrupted. Please check back in a few minutes or start a new conversation."}]}]:s;return w(e,i),!0}finally{u?.aborted||de(!1)}},[w,le,X]);ut.useInitialConversation({conversationId:h.conversationId,effectiveAuthToken:ce,loadAndRestoreSession:Se,onLoadFailed:()=>w("",[])});const{openForm:Qe}=lt.useChatForm(),We=dt.useWidget();return t.useImperativeHandle(h.chatFunctionsRef,()=>({submitMessage:Z,updateInputMessage(e){M(e)},clearChat:Re,openForm:e=>{We?.setView("chat"),Qe(e,void 0)},focusInput:()=>{Ce.current?.focus()}})),{messages:P,sendMessage:J,addToolApprovalResponse:Ge,isLoading:me,isStreaming:ve,isBusy:ye,error:ze,setError:k,isSubmitDisabled:V,input:C,handleInputChange:Me,handleInputKeyDown:Je,handleSubmit:Z,stop:X,clear:Re,inputRef:Ce,isMobile:Be,files:x,setFiles:j,isNewChat:$e,conversationId:r,restoreSession:w,loadAndRestoreSession:Se,isSessionLoading:Oe,authToken:f?q:D,refreshSession:f?se:L,getCaptchaHeader:I,invalidateCaptcha:c,inputNotification:Ke,showInputNotification:be,clearInputNotification:je}};exports.DEFAULT_ERROR_MESSAGE=_;exports.useInkeepChat=vt;
@@ -47,7 +47,7 @@ export declare const useInkeepChat: () => {
47
47
  isNewChat: boolean;
48
48
  conversationId: string;
49
49
  restoreSession: (sessionId: string, loadedMessages: Message[]) => void;
50
- loadAndRestoreSession: (sessionId: string, signal?: AbortSignal) => Promise<void>;
50
+ loadAndRestoreSession: (sessionId: string, signal?: AbortSignal) => Promise<boolean>;
51
51
  isSessionLoading: boolean;
52
52
  authToken: string | null;
53
53
  refreshSession: () => Promise<string | null>;
@@ -1,122 +1,123 @@
1
1
  "use client";
2
- import { useChat as et } from "@ai-sdk/react";
3
- import { normalizeFileType as Re } from "./file-upload-input.js";
4
- import { DefaultChatTransport as tt } from "ai";
5
- import { useRef as l, useEffect as k, useState as D, useMemo as Te, useCallback as $, useImperativeHandle as st } from "react";
6
- import { useModal as rt } from "../modal/modal-provider.js";
7
- import { useOptionalChatBubble as nt } from "../../providers/chat-bubble-provider.js";
8
- import { useOptionalSidebarChat as ot } from "../../providers/sidebar-chat-provider.js";
9
- import { useInkeepConfig as at } from "../../providers/config-provider.js";
10
- import { useCaptcha as it } from "./use-captcha.js";
11
- import { useMediaQuery as lt } from "../../hooks/use-media-query.js";
12
- import { useAnonymousSession as ct } from "../../hooks/use-anonymous-session.js";
13
- import { useAuthToken as ut } from "../../hooks/use-auth-token.js";
14
- import { useConversationLoader as pt } from "../../hooks/use-conversation-loader.js";
2
+ import { useChat as tt } from "@ai-sdk/react";
3
+ import { normalizeFileType as ke } from "./file-upload-input.js";
4
+ import { DefaultChatTransport as st } from "ai";
5
+ import { useRef as l, useEffect as x, useState as D, useMemo as xe, useCallback as $, useImperativeHandle as rt } from "react";
6
+ import { useModal as nt } from "../modal/modal-provider.js";
7
+ import { useOptionalChatBubble as ot } from "../../providers/chat-bubble-provider.js";
8
+ import { useOptionalSidebarChat as at } from "../../providers/sidebar-chat-provider.js";
9
+ import { useInkeepConfig as it } from "../../providers/config-provider.js";
10
+ import { useCaptcha as lt } from "./use-captcha.js";
11
+ import { useMediaQuery as ct } from "../../hooks/use-media-query.js";
12
+ import { useAnonymousSession as ut } from "../../hooks/use-anonymous-session.js";
13
+ import { useAuthToken as pt } from "../../hooks/use-auth-token.js";
14
+ import { useConversationLoader as dt } from "../../hooks/use-conversation-loader.js";
15
+ import { useInitialConversation as ft } from "../../hooks/use-initial-conversation.js";
15
16
  import { generateUid as L } from "../../utils/generate-uid.js";
16
- import { useBaseEvents as dt } from "../../providers/base-events-provider.js";
17
- import { useChatForm as ft } from "../../providers/chat-form-provider.js";
18
- import { useWidget as mt } from "../../providers/widget-provider.js";
19
- import { useControllableState as ht } from "@radix-ui/react-use-controllable-state";
20
- import { useStreamingEvents as gt } from "../../hooks/use-streaming-events.js";
21
- import { parseAuthError as yt } from "../../hooks/use-inkeep-api-client.js";
22
- import { useInputNotification as vt } from "../../hooks/use-input-notification.js";
23
- function bt(h) {
24
- const g = h.message ?? "";
25
- let s = Number(h.code) || Number(h.statusCode);
17
+ import { useBaseEvents as mt } from "../../providers/base-events-provider.js";
18
+ import { useChatForm as ht } from "../../providers/chat-form-provider.js";
19
+ import { useWidget as gt } from "../../providers/widget-provider.js";
20
+ import { useControllableState as vt } from "@radix-ui/react-use-controllable-state";
21
+ import { useStreamingEvents as yt } from "../../hooks/use-streaming-events.js";
22
+ import { parseAuthError as bt } from "../../hooks/use-inkeep-api-client.js";
23
+ import { useInputNotification as Ct } from "../../hooks/use-input-notification.js";
24
+ function It(g) {
25
+ const m = g.message ?? "";
26
+ let s = Number(g.code) || Number(g.statusCode);
26
27
  if (Number.isNaN(s))
27
28
  try {
28
- s = Number(JSON.parse(g).status);
29
+ s = Number(JSON.parse(m).status);
29
30
  } catch {
30
31
  }
31
- const p = yt(s, { detail: g });
32
+ const p = bt(s, { detail: m });
32
33
  return p !== null ? p : s === 401 ? "session" : null;
33
34
  }
34
35
  const te = `Hmm..
35
36
 
36
- It seems I might be having some issues right now. Please clear the chat and try again.`, zt = () => {
37
- const { baseSettings: h, aiChatSettings: g } = at(), [s = "", p] = ht({
38
- prop: g.conversationId,
39
- defaultProp: g.conversationId ?? ""
40
- }), ke = rt(), xe = nt(), Me = ot(), { logEvent: y } = dt(), { setConversationId: Ee, emitToParent: x } = gt(), se = l(s);
41
- k(() => {
37
+ It seems I might be having some issues right now. Please clear the chat and try again.`, Kt = () => {
38
+ const { baseSettings: g, aiChatSettings: m } = it(), [s = "", p] = vt({
39
+ prop: m.conversationIdOverride,
40
+ defaultProp: m.conversationIdOverride ?? ""
41
+ }), Me = nt(), Fe = ot(), Ee = at(), { logEvent: v } = mt(), { setConversationId: Ne, emitToParent: M } = yt(), se = l(s);
42
+ x(() => {
42
43
  const e = se.current;
43
- se.current = s, e !== s && y({
44
+ se.current = s, e !== s && v({
44
45
  eventName: "chat_conversation_changed",
45
46
  properties: {
46
47
  conversationId: s,
47
48
  previousConversationId: e
48
49
  }
49
50
  });
50
- }, [s, y]);
51
- const [C, M] = D(""), Fe = (e) => M(e.target.value), { shouldBypassCaptcha: re, filters: ne, privacyPreferences: Ne, userProperties: B } = h, { authToken: E, isLoading: Pe, refreshToken: oe } = ut(), ae = !!h.getAuthToken, d = !!E, {
52
- onInputMessageChange: Oe,
51
+ }, [s, v]);
52
+ const [C, F] = D(""), Oe = (e) => F(e.target.value), { shouldBypassCaptcha: re, filters: ne, privacyPreferences: Pe, userProperties: B } = g, { authToken: E, isLoading: _e, refreshToken: oe } = pt(), ae = !!g.getAuthToken, d = !!E, {
53
+ onInputMessageChange: De,
53
54
  filters: ie,
54
- baseUrl: F,
55
- agentUrl: _e,
55
+ baseUrl: N,
56
+ agentUrl: $e,
56
57
  context: le,
57
58
  headers: ce,
58
- appId: w,
59
- apiKey: v,
60
- files: S
61
- } = g, De = ke?.isOpen ?? xe?.isOpen ?? Me?.isOpen ?? !0, { getCaptchaHeader: I, invalidate: c } = it({
62
- baseUrl: F,
63
- shouldBypassCaptcha: re || !!v,
64
- shouldMakeInitialRequest: De
65
- }), ue = l(I);
66
- ue.current = I;
67
- const pe = _e || `${F}/run/api/chat`, { sessionToken: U, refreshSession: z } = ct({
68
- baseUrl: F,
69
- appId: w,
70
- getCaptchaHeader: I,
59
+ appId: I,
60
+ apiKey: y,
61
+ files: w
62
+ } = m, Le = Me?.isOpen ?? Fe?.isOpen ?? Ee?.isOpen ?? !0, { getCaptchaHeader: S, invalidate: c } = lt({
63
+ baseUrl: N,
64
+ shouldBypassCaptcha: re || !!y,
65
+ shouldMakeInitialRequest: Le
66
+ }), ue = l(S);
67
+ ue.current = S;
68
+ const pe = $e || `${N}/run/api/chat`, { sessionToken: U, refreshSession: z } = ut({
69
+ baseUrl: N,
70
+ appId: I,
71
+ getCaptchaHeader: S,
71
72
  invalidateCaptcha: c,
72
- optOutAllAnalytics: Ne?.optOutAllAnalytics,
73
- enabled: !d && !Pe
74
- }), { loadConversation: de } = pt({
75
- baseUrl: F,
76
- appId: w,
77
- authToken: v ?? (d ? E : U),
78
- getCaptchaHeader: I,
73
+ optOutAllAnalytics: Pe?.optOutAllAnalytics,
74
+ enabled: !d && !_e
75
+ }), de = y ?? (d ? E : U), { loadConversation: fe } = dt({
76
+ baseUrl: N,
77
+ appId: I,
78
+ authToken: de,
79
+ getCaptchaHeader: S,
79
80
  invalidateCaptcha: c,
80
- refreshSession: v || d ? void 0 : z
81
- }), [$e, fe] = D(!1), H = l(null);
81
+ refreshSession: y || d ? void 0 : z
82
+ }), [Be, me] = D(!1), H = l(null);
82
83
  H.current = U;
83
84
  const q = l(null);
84
85
  q.current = E;
85
86
  const K = l(void 0);
86
87
  K.current = B && Object.keys(B).length > 0 ? JSON.stringify(B) : void 0;
87
- const b = l(0), me = l(null), J = l(null), A = l(void 0), Le = S?.map((e) => `${e.filename ?? ""}:${e.mediaType}:${e.url.length}:${e.url.slice(0, 64)}:${e.url.slice(-32)}`).join(`
88
+ const b = l(0), he = l(null), J = l(null), A = l(void 0), Ue = w?.map((e) => `${e.filename ?? ""}:${e.mediaType}:${e.url.length}:${e.url.slice(0, 64)}:${e.url.slice(-32)}`).join(`
88
89
  `) ?? "";
89
- k(() => {
90
- A.current = S?.length ? S : void 0;
91
- }, [Le]);
92
- const he = l(ce);
93
- he.current = ce;
90
+ x(() => {
91
+ A.current = w?.length ? w : void 0;
92
+ }, [Ue]);
93
+ const ge = l(ce);
94
+ ge.current = ce;
94
95
  const j = l(void 0);
95
96
  j.current = ne || ie ? JSON.stringify({ ...ne, ...ie }) : void 0;
96
- const Be = (e) => {
97
+ const ze = (e) => {
97
98
  switch (e.code) {
98
99
  case 400:
99
100
  return e.message;
100
101
  case 401:
101
102
  return ae ? "Authentication failed. Please try again." : te;
102
103
  case 403:
103
- return `There seems to be a configuration error. Please contact ${h.organizationDisplayName ?? "Administrator"}`;
104
+ return `There seems to be a configuration error. Please contact ${g.organizationDisplayName ?? "Administrator"}`;
104
105
  default:
105
106
  return te;
106
107
  }
107
- }, [N, W] = D([]), Ue = Te(
108
- () => new tt({
108
+ }, [O, W] = D([]), He = xe(
109
+ () => new st({
109
110
  api: pe,
110
111
  headers: () => {
111
- const e = v ?? q.current ?? H.current;
112
+ const e = y ?? q.current ?? H.current;
112
113
  return {
113
114
  "x-inkeep-client-timezone": Intl.DateTimeFormat().resolvedOptions().timeZone,
114
115
  "x-inkeep-client-timestamp": (/* @__PURE__ */ new Date()).toISOString(),
115
- ...w ? { "x-inkeep-app-id": w } : {},
116
+ ...I ? { "x-inkeep-app-id": I } : {},
116
117
  ...e ? { Authorization: `Bearer ${e}` } : {},
117
118
  ...j.current ? { "inkeep-filters": j.current } : {},
118
119
  ...K.current ? { "x-inkeep-user-properties": K.current } : {},
119
- ...he.current
120
+ ...ge.current
120
121
  };
121
122
  },
122
123
  prepareSendMessagesRequest: async (e) => {
@@ -139,27 +140,27 @@ It seems I might be having some issues right now. Please clear the chat and try
139
140
  requestContext: le
140
141
  }
141
142
  }),
142
- [pe, le, w, v]
143
+ [pe, le, I, y]
143
144
  ), {
144
145
  messages: P,
145
146
  sendMessage: G,
146
147
  addToolApprovalResponse: Q,
147
- status: ge,
148
- setMessages: m,
149
- stop: O,
148
+ status: ve,
149
+ setMessages: h,
150
+ stop: _,
150
151
  error: V
151
- } = et({
152
- transport: Ue,
152
+ } = tt({
153
+ transport: He,
153
154
  onData(e) {
154
- x(e.type, e.data);
155
+ M(e.type, e.data);
155
156
  },
156
157
  async onFinish() {
157
- x("completion", { conversationId: s }), await y({
158
+ M("completion", { conversationId: s }), await v({
158
159
  eventName: "assistant_message_received",
159
160
  properties: {
160
161
  conversationId: s
161
162
  }
162
- }), y({
163
+ }), v({
163
164
  eventName: "assistant_answer_displayed",
164
165
  properties: {
165
166
  conversationId: s
@@ -168,34 +169,34 @@ It seems I might be having some issues right now. Please clear the chat and try
168
169
  },
169
170
  onError(e) {
170
171
  console.error("onError", { code: e.code, message: e.message });
171
- const i = re || v ? null : bt(e);
172
+ const i = re || y ? null : It(e);
172
173
  if (i !== null && b.current < 1) {
173
174
  b.current++;
174
- const t = J.current, r = me.current;
175
+ const t = J.current, n = he.current;
175
176
  (async () => {
176
177
  if (i === "session" && ae) {
177
- const n = await oe();
178
- if (!n) throw new Error("Auth token refresh failed");
179
- q.current = n;
178
+ const r = await oe();
179
+ if (!r) throw new Error("Auth token refresh failed");
180
+ q.current = r;
180
181
  } else if (i === "session") {
181
- const n = await z();
182
- n && (H.current = n);
182
+ const r = await z();
183
+ r && (H.current = r);
183
184
  } else
184
185
  c();
185
186
  if (t) {
186
187
  Q(t);
187
188
  return;
188
189
  }
189
- r && (m((n) => {
190
- let o = [...n];
190
+ n && (h((r) => {
191
+ let o = [...r];
191
192
  return o.at(-1)?.role === "assistant" && (o = o.slice(0, -1)), o.at(-1)?.role === "user" && (o = o.slice(0, -1)), o;
192
193
  }), G(
193
- r.files?.length ? { parts: [{ type: "text", text: r.content }, ...r.files] } : { text: r.content },
194
- { body: r.body }
194
+ n.files?.length ? { parts: [{ type: "text", text: n.content }, ...n.files] } : { text: n.content },
195
+ { body: n.body }
195
196
  ));
196
197
  })().catch(() => {
197
- b.current = 0, c(), m((n) => {
198
- const o = [...n], f = o[o.length - 1];
198
+ b.current = 0, c(), h((r) => {
199
+ const o = [...r], f = o[o.length - 1];
199
200
  if (!f) return o;
200
201
  const u = te;
201
202
  return f.role === "user" ? o.push({
@@ -207,83 +208,83 @@ It seems I might be having some issues right now. Please clear the chat and try
207
208
  });
208
209
  return;
209
210
  }
210
- b.current = 0, i !== null && c(), y({
211
+ b.current = 0, i !== null && c(), v({
211
212
  eventName: "chat_error",
212
213
  properties: {
213
214
  conversationId: s,
214
215
  error: e.message
215
216
  }
216
- }), m((t) => {
217
- const r = [...t], a = r[r.length - 1];
217
+ }), h((t) => {
218
+ const n = [...t], a = n[n.length - 1];
218
219
  if (a) {
219
- const n = Be(e);
220
- a.role === "user" ? r.push({
220
+ const r = ze(e);
221
+ a.role === "user" ? n.push({
221
222
  id: L(16),
222
223
  role: "assistant",
223
- parts: [{ type: "text", text: n }]
224
- }) : a.parts = [{ type: "text", text: n }];
224
+ parts: [{ type: "text", text: r }]
225
+ }) : a.parts = [{ type: "text", text: r }];
225
226
  }
226
- return r;
227
+ return n;
227
228
  });
228
229
  }
229
230
  }), ye = l(d);
230
- k(() => {
231
+ x(() => {
231
232
  const e = ye.current;
232
- ye.current = d, e !== d && (O(), R(null), m([]), p(""), M(""), W([]), c());
233
- }, [d, O, m, p, c]);
234
- const ve = ge === "submitted", Z = ge === "streaming", ze = Te(() => {
233
+ ye.current = d, e !== d && (_(), T(null), h([]), p(""), F(""), W([]), c());
234
+ }, [d, _, h, p, c]);
235
+ const be = ve === "submitted", Z = ve === "streaming", qe = xe(() => {
235
236
  const e = (a) => {
236
237
  if (!a || typeof a != "object") return !1;
237
- const n = a;
238
- return typeof n.type == "string" && n.type.startsWith("tool-");
238
+ const r = a;
239
+ return typeof r.type == "string" && r.type.startsWith("tool-");
239
240
  }, t = [...P ?? []].reverse().find((a) => a.role === "assistant");
240
241
  if (!t) return !1;
241
- const r = t.parts?.at(-1);
242
- return !(!e(r) || r.state !== "output-available" || !r.approval?.id || Z);
243
- }, [P, Z]), be = Z || ze, Ce = ve || be, He = P.length === 0, X = !C.trim() && N.length === 0 || Ce, qe = lt("(max-width: 768px)"), [Ke, R] = D(null);
244
- k(() => {
245
- V && R(V);
242
+ const n = t.parts?.at(-1);
243
+ return !(!e(n) || n.state !== "output-available" || !n.approval?.id || Z);
244
+ }, [P, Z]), Ce = Z || qe, Ie = be || Ce, Ke = P.length === 0, X = !C.trim() && O.length === 0 || Ie, Je = ct("(max-width: 768px)"), [je, T] = D(null);
245
+ x(() => {
246
+ V && T(V);
246
247
  }, [V]);
247
- const Je = () => R(null), { inputNotification: je, showInputNotification: we, clearInputNotification: We } = vt(), Se = l(null);
248
- k(() => {
249
- Oe?.(C);
248
+ const We = () => T(null), { inputNotification: Ge, showInputNotification: we, clearInputNotification: Qe } = Ct(), Se = l(null);
249
+ x(() => {
250
+ De?.(C);
250
251
  }, [C]);
251
- const Ge = (e) => {
252
+ const Ve = (e) => {
252
253
  e.key === "Enter" && !e.shiftKey && !X && !e.nativeEvent.isComposing && (e.preventDefault(), Y());
253
254
  }, Y = async (e = C) => {
254
- if (X && (!e || e.trim().length === 0) && N.length === 0) return;
255
- const i = N;
256
- W([]), M(""), b.current = 0, J.current = null, await y({
255
+ if (X && (!e || e.trim().length === 0) && O.length === 0) return;
256
+ const i = O;
257
+ W([]), F(""), b.current = 0, J.current = null, await v({
257
258
  eventName: "user_message_submitted",
258
259
  properties: {
259
260
  conversationId: s
260
261
  }
261
262
  });
262
263
  let t = s;
263
- t || (t = `conv_${L(16)}`, p(t)), Ee(t);
264
- const r = A.current;
264
+ t || (t = `conv_${L(16)}`, p(t)), Ne(t);
265
+ const n = A.current;
265
266
  A.current = void 0;
266
- let a, n;
267
- if (r?.length) {
267
+ let a, r;
268
+ if (n?.length) {
268
269
  let o;
269
270
  try {
270
271
  o = await Promise.all(
271
272
  i.map((f) => {
272
- const u = Re(f);
273
- return new Promise((Ye, Ae) => {
274
- const T = new FileReader();
275
- T.onload = () => {
276
- if (typeof T.result != "string") {
277
- Ae(new Error(`Failed to read file "${u.name}"`));
273
+ const u = ke(f);
274
+ return new Promise((et, Re) => {
275
+ const k = new FileReader();
276
+ k.onload = () => {
277
+ if (typeof k.result != "string") {
278
+ Re(new Error(`Failed to read file "${u.name}"`));
278
279
  return;
279
280
  }
280
- Ye({
281
+ et({
281
282
  type: "file",
282
- url: T.result,
283
+ url: k.result,
283
284
  mediaType: u.type,
284
285
  filename: u.name
285
286
  });
286
- }, T.onerror = () => Ae(new Error(`Failed to read file "${u.name}"`)), T.readAsDataURL(u);
287
+ }, k.onerror = () => Re(new Error(`Failed to read file "${u.name}"`)), k.readAsDataURL(u);
287
288
  });
288
289
  })
289
290
  );
@@ -294,66 +295,75 @@ It seems I might be having some issues right now. Please clear the chat and try
294
295
  });
295
296
  return;
296
297
  }
297
- n = [...o, ...r], a = e.trim() ? { parts: [{ type: "text", text: e }, ...n] } : { parts: n };
298
+ r = [...o, ...n], a = e.trim() ? { parts: [{ type: "text", text: e }, ...r] } : { parts: r };
298
299
  } else if (i.length > 0) {
299
300
  const o = new DataTransfer();
300
- for (const u of i) o.items.add(Re(u));
301
+ for (const u of i) o.items.add(ke(u));
301
302
  const f = o.files;
302
303
  a = e.trim() ? { text: e, files: f } : { files: f };
303
304
  } else
304
305
  a = { text: e };
305
- me.current = {
306
+ he.current = {
306
307
  content: e,
307
308
  body: { conversationId: t },
308
- files: n
309
+ files: r
309
310
  }, G(a, {
310
311
  body: { conversationId: t }
311
312
  });
312
- }, Qe = $(
313
+ }, Ze = $(
313
314
  (e) => {
314
315
  b.current = 0, J.current = e, Q(e);
315
316
  },
316
317
  [Q]
317
318
  ), ee = $(() => {
318
- O().then(() => {
319
- x("aborted", { conversationId: s });
319
+ _().then(() => {
320
+ M("aborted", { conversationId: s });
320
321
  });
321
- }, [O, s, x]), Ie = () => {
322
- Je(), m([]), p(""), c(), A.current = S?.length ? S : void 0, y({
322
+ }, [_, s, M]), Ae = () => {
323
+ We(), h([]), p(""), c(), A.current = w?.length ? w : void 0, v({
323
324
  eventName: "chat_clear_button_clicked",
324
325
  properties: {
325
326
  conversationId: s
326
327
  }
327
328
  });
328
- }, _ = $(
329
+ }, R = $(
329
330
  (e, i) => {
330
- R(null), m(i), p(e), c(), A.current = void 0;
331
+ T(null), h(i), p(e), c(), A.current = void 0;
331
332
  },
332
- [m, p, c]
333
- ), Ve = $(
333
+ [h, p, c]
334
+ ), Te = $(
334
335
  async (e, i) => {
335
- ee(), _(e, []), fe(!0);
336
+ ee(), R(e, []), me(!0);
336
337
  try {
337
- const t = await de(e, i), r = t?.[t.length - 1], a = t !== null && r?.role === "user" ? [...t, {
338
+ const t = await fe(e, i);
339
+ if (t === null) return !1;
340
+ const a = t[t.length - 1]?.role === "user" ? [...t, {
338
341
  id: L(16),
339
342
  role: "assistant",
340
343
  parts: [{ type: "text", text: "This session was interrupted. Please check back in a few minutes or start a new conversation." }]
341
344
  }] : t;
342
- a !== null && _(e, a);
345
+ return R(e, a), !0;
343
346
  } finally {
344
- i?.aborted || fe(!1);
347
+ i?.aborted || me(!1);
345
348
  }
346
349
  },
347
- [_, de, ee]
348
- ), { openForm: Ze } = ft(), Xe = mt();
349
- return st(g.chatFunctionsRef, () => ({
350
+ [R, fe, ee]
351
+ );
352
+ ft({
353
+ conversationId: m.conversationId,
354
+ effectiveAuthToken: de,
355
+ loadAndRestoreSession: Te,
356
+ onLoadFailed: () => R("", [])
357
+ });
358
+ const { openForm: Xe } = ht(), Ye = gt();
359
+ return rt(m.chatFunctionsRef, () => ({
350
360
  submitMessage: Y,
351
361
  updateInputMessage(e) {
352
- M(e);
362
+ F(e);
353
363
  },
354
- clearChat: Ie,
364
+ clearChat: Ae,
355
365
  openForm: (e) => {
356
- Xe?.setView("chat"), Ze(e, void 0);
366
+ Ye?.setView("chat"), Xe(e, void 0);
357
367
  },
358
368
  focusInput: () => {
359
369
  Se.current?.focus();
@@ -361,38 +371,38 @@ It seems I might be having some issues right now. Please clear the chat and try
361
371
  })), {
362
372
  messages: P,
363
373
  sendMessage: G,
364
- addToolApprovalResponse: Qe,
365
- isLoading: ve,
366
- isStreaming: be,
367
- isBusy: Ce,
368
- error: Ke,
369
- setError: R,
374
+ addToolApprovalResponse: Ze,
375
+ isLoading: be,
376
+ isStreaming: Ce,
377
+ isBusy: Ie,
378
+ error: je,
379
+ setError: T,
370
380
  isSubmitDisabled: X,
371
381
  input: C,
372
- handleInputChange: Fe,
373
- handleInputKeyDown: Ge,
382
+ handleInputChange: Oe,
383
+ handleInputKeyDown: Ve,
374
384
  handleSubmit: Y,
375
385
  stop: ee,
376
- clear: Ie,
386
+ clear: Ae,
377
387
  inputRef: Se,
378
- isMobile: qe,
379
- files: N,
388
+ isMobile: Je,
389
+ files: O,
380
390
  setFiles: W,
381
- isNewChat: He,
391
+ isNewChat: Ke,
382
392
  conversationId: s,
383
- restoreSession: _,
384
- loadAndRestoreSession: Ve,
385
- isSessionLoading: $e,
393
+ restoreSession: R,
394
+ loadAndRestoreSession: Te,
395
+ isSessionLoading: Be,
386
396
  authToken: d ? E : U,
387
397
  refreshSession: d ? oe : z,
388
- getCaptchaHeader: I,
398
+ getCaptchaHeader: S,
389
399
  invalidateCaptcha: c,
390
- inputNotification: je,
400
+ inputNotification: Ge,
391
401
  showInputNotification: we,
392
- clearInputNotification: We
402
+ clearInputNotification: Qe
393
403
  };
394
404
  };
395
405
  export {
396
406
  te as DEFAULT_ERROR_MESSAGE,
397
- zt as useInkeepChat
407
+ Kt as useInkeepChat
398
408
  };
@@ -0,0 +1 @@
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react"),f=({conversationId:e,effectiveAuthToken:s,loadAndRestoreSession:u,onLoadFailed:l})=>{const r=o.useRef(null),c=o.useRef(u);c.current=u;const a=o.useRef(l);a.current=l,o.useEffect(()=>{if(!e||!s||r.current===e)return;r.current=e;const t=new AbortController,i=n=>{r.current=null,console.error("[useInitialConversation] failed to load conversation:",e,n),a.current?.()};return(async()=>{try{!await c.current(e,t.signal)&&!t.signal.aborted&&i()}catch(n){t.signal.aborted||i(n)}})(),()=>{r.current=null,t.abort()}},[e,s])};exports.useInitialConversation=f;
@@ -0,0 +1,16 @@
1
+ interface UseInitialConversationOptions {
2
+ /** The conversationId provided via props to load and restore. */
3
+ conversationId: string | undefined;
4
+ /** Resolved auth token — fetch is skipped until one is available. */
5
+ effectiveAuthToken: string | null;
6
+ /** Returns true if the conversation was loaded successfully, false otherwise. */
7
+ loadAndRestoreSession: (sessionId: string, signal?: AbortSignal) => Promise<boolean>;
8
+ /** Called when the load fails (404 or other error) — use to reset conversation state. */
9
+ onLoadFailed?: () => void;
10
+ }
11
+ /**
12
+ * Loads and restores a conversation by ID once an auth token is available.
13
+ * Calls `onLoadFailed` if the conversation is not found or the fetch fails.
14
+ */
15
+ export declare const useInitialConversation: ({ conversationId, effectiveAuthToken, loadAndRestoreSession, onLoadFailed, }: UseInitialConversationOptions) => void;
16
+ export {};
@@ -0,0 +1,31 @@
1
+ "use client";
2
+ import { useRef as o, useEffect as f } from "react";
3
+ const C = ({
4
+ conversationId: r,
5
+ effectiveAuthToken: l,
6
+ loadAndRestoreSession: s,
7
+ onLoadFailed: c
8
+ }) => {
9
+ const t = o(null), u = o(s);
10
+ u.current = s;
11
+ const a = o(c);
12
+ a.current = c, f(() => {
13
+ if (!r || !l || t.current === r) return;
14
+ t.current = r;
15
+ const e = new AbortController(), i = (n) => {
16
+ t.current = null, console.error("[useInitialConversation] failed to load conversation:", r, n), a.current?.();
17
+ };
18
+ return (async () => {
19
+ try {
20
+ !await u.current(r, e.signal) && !e.signal.aborted && i();
21
+ } catch (n) {
22
+ e.signal.aborted || i(n);
23
+ }
24
+ })(), () => {
25
+ t.current = null, e.abort();
26
+ };
27
+ }, [r, l]);
28
+ };
29
+ export {
30
+ C as useInitialConversation
31
+ };
@@ -1 +1 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("react/jsx-runtime"),t=require("react"),l=require("./config-provider.cjs"),a=t.createContext(void 0),p=({children:e})=>{const{baseSettings:s,componentType:n}=l.useInkeepConfig(),{tags:o,analyticsProperties:r}=s,i=t.useMemo(()=>({widgetLibraryVersion:"0.15.27",componentType:n,tags:o}),[n,o]),u={logEvent:t.useCallback(async c=>{const v={...i,...c.properties,...r},d={eventName:c.eventName,properties:v};return s.onEvent?.(d)},[s,i,r])};return E.jsx(a.Provider,{value:u,children:e})},g=()=>{const e=t.useContext(a);if(!e)throw new Error("useBaseEvents must be used within a BaseEventsProvider");return e};exports.BaseEventsProvider=p;exports.useBaseEvents=g;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("react/jsx-runtime"),t=require("react"),l=require("./config-provider.cjs"),a=t.createContext(void 0),p=({children:e})=>{const{baseSettings:s,componentType:n}=l.useInkeepConfig(),{tags:o,analyticsProperties:r}=s,i=t.useMemo(()=>({widgetLibraryVersion:"0.15.28",componentType:n,tags:o}),[n,o]),u={logEvent:t.useCallback(async c=>{const v={...i,...c.properties,...r},d={eventName:c.eventName,properties:v};return s.onEvent?.(d)},[s,i,r])};return E.jsx(a.Provider,{value:u,children:e})},g=()=>{const e=t.useContext(a);if(!e)throw new Error("useBaseEvents must be used within a BaseEventsProvider");return e};exports.BaseEventsProvider=p;exports.useBaseEvents=g;
@@ -5,7 +5,7 @@ import { useInkeepConfig as g } from "./config-provider.js";
5
5
  const a = d(void 0), P = ({ children: e }) => {
6
6
  const { baseSettings: t, componentType: o } = g(), { tags: s, analyticsProperties: n } = t, r = u(
7
7
  () => ({
8
- widgetLibraryVersion: "0.15.27",
8
+ widgetLibraryVersion: "0.15.28",
9
9
  componentType: o,
10
10
  tags: s
11
11
  }),
@@ -130,8 +130,15 @@ export interface InkeepAIChatSettings {
130
130
  /**
131
131
  * Unique identifier for loading a specific conversation.
132
132
  * Use this to restore a previous conversation state.
133
+ * If the conversation is not found, a new conversation is started.
133
134
  */
134
135
  conversationId?: string;
136
+ /**
137
+ * @deprecated Internal use only. Bypasses conversation loading and sets the
138
+ * conversation ID directly without fetching. Use `conversationId` instead to
139
+ * restore a previous conversation state.
140
+ */
141
+ conversationIdOverride?: string;
135
142
  /**
136
143
  * When enabled, prevents users from sending new messages.
137
144
  * Useful for displaying archived or shared chat sessions.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-ui",
3
- "version": "0.15.27",
3
+ "version": "0.15.28",
4
4
  "description": "",
5
5
  "homepage": "",
6
6
  "repository": {