@inkeep/agents-ui 0.16.3 → 0.16.5

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