@inkeep/agents-ui 0.15.22 → 0.15.24

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,3 +1,4 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const He=require("@ai-sdk/react"),We=require("ai"),t=require("react"),$e=require("../modal/modal-provider.cjs"),je=require("../../providers/chat-bubble-provider.cjs"),ze=require("../../providers/sidebar-chat-provider.cjs"),Je=require("../../providers/config-provider.cjs"),Ke=require("./use-captcha.cjs"),Ge=require("../../hooks/use-media-query.cjs"),Qe=require("../../hooks/use-anonymous-session.cjs"),Ve=require("../../hooks/use-auth-token.cjs"),Ze=require("../../hooks/use-conversation-loader.cjs"),x=require("../../utils/generate-uid.cjs"),Xe=require("../../providers/base-events-provider.cjs"),Ye=require("../../providers/chat-form-provider.cjs"),et=require("../../providers/widget-provider.cjs"),tt=require("@radix-ui/react-use-controllable-state"),st=require("../../hooks/use-streaming-events.cjs"),rt=require("../../hooks/use-inkeep-api-client.cjs");function nt(f){const h=f.message??"";let s=Number(f.code)||Number(f.statusCode);if(Number.isNaN(s))try{s=Number(JSON.parse(h).status)}catch{}const l=rt.parseAuthError(s,{detail:h});return l!==null?l:s===401?"session":null}const P=`Hmm..
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const We=require("@ai-sdk/react"),ze=require("ai"),t=require("react"),Je=require("../modal/modal-provider.cjs"),Ge=require("../../providers/chat-bubble-provider.cjs"),Qe=require("../../providers/sidebar-chat-provider.cjs"),Ve=require("../../providers/config-provider.cjs"),Ze=require("./use-captcha.cjs"),Xe=require("../../hooks/use-media-query.cjs"),Ye=require("../../hooks/use-anonymous-session.cjs"),et=require("../../hooks/use-auth-token.cjs"),tt=require("../../hooks/use-conversation-loader.cjs"),N=require("../../utils/generate-uid.cjs"),st=require("../../providers/base-events-provider.cjs"),nt=require("../../providers/chat-form-provider.cjs"),rt=require("../../providers/widget-provider.cjs"),at=require("@radix-ui/react-use-controllable-state"),ot=require("../../hooks/use-streaming-events.cjs"),it=require("../../hooks/use-inkeep-api-client.cjs");function ut(f){const h=f.message??"";let s=Number(f.code)||Number(f.statusCode);if(Number.isNaN(s))try{s=Number(JSON.parse(h).status)}catch{}const l=it.parseAuthError(s,{detail:h});return l!==null?l:s===401?"session":null}const O=`Hmm..
2
2
 
3
- It seems I might be having some issues right now. Please clear the chat and try again.`,at=()=>{const{baseSettings:f,aiChatSettings:h}=Je.useInkeepConfig(),[s="",l]=tt.useControllableState({prop:h.conversationId,defaultProp:h.conversationId??""}),ve=$e.useModal(),ye=je.useOptionalChatBubble(),be=ze.useOptionalSidebarChat(),{logEvent:g}=Xe.useBaseEvents(),{setConversationId:Ce,emitToParent:k}=st.useStreamingEvents(),Q=t.useRef(s);t.useEffect(()=>{const e=Q.current;Q.current=s,e!==s&&g({eventName:"chat_conversation_changed",properties:{conversationId:s,previousConversationId:e}})},[s,g]);const[y,A]=t.useState(""),Se=e=>A(e.target.value),{shouldBypassCaptcha:V,filters:Z,privacyPreferences:Re,userProperties:N}=f,{authToken:I,refreshToken:X}=Ve.useAuthToken(),Y=!!f.getAuthToken,d=!!I,{onInputMessageChange:ke,filters:ee,baseUrl:E,agentUrl:Ae,context:te,headers:se,appId:b,apiKey:m}=h,Ie=ve?.isOpen??ye?.isOpen??be?.isOpen??!0,{getCaptchaHeader:C,invalidate:c}=Ke.useCaptcha({baseUrl:E,shouldBypassCaptcha:V||!!m,shouldMakeInitialRequest:Ie}),re=t.useRef(C);re.current=C;const ne=Ae||`${E}/run/api/chat`,{sessionToken:O,refreshSession:_}=Qe.useAnonymousSession({baseUrl:E,appId:b,getCaptchaHeader:C,invalidateCaptcha:c,optOutAllAnalytics:Re?.optOutAllAnalytics,enabled:!d}),{loadConversation:ae}=Ze.useConversationLoader({baseUrl:E,appId:b,authToken:m??(d?I:O),getCaptchaHeader:C,invalidateCaptcha:c,refreshSession:m||d?void 0:_}),[Ee,oe]=t.useState(!1),F=t.useRef(null);F.current=O;const U=t.useRef(null);U.current=I;const D=t.useRef(void 0);D.current=N&&Object.keys(N).length>0?JSON.stringify(N):void 0;const v=t.useRef(0),ie=t.useRef(null),B=t.useRef(null),ue=t.useRef(se);ue.current=se;const L=t.useRef(void 0);L.current=Z||ee?JSON.stringify({...Z,...ee}):void 0;const we=e=>{switch(e.code){case 400:return e.message;case 401:return Y?"Authentication failed. Please try again.":P;case 403:return`There seems to be a configuration error. Please contact ${f.organizationDisplayName??"Administrator"}`;default:return P}},[Te,S]=t.useState([]),[Me,w]=t.useState(null),qe=t.useMemo(()=>new We.DefaultChatTransport({api:ne,headers:()=>{const e=m??U.current??F.current;return{"x-inkeep-client-timezone":Intl.DateTimeFormat().resolvedOptions().timeZone,"x-inkeep-client-timestamp":new Date().toISOString(),...b?{"x-inkeep-app-id":b}:{},...e?{Authorization:`Bearer ${e}`}:{},...L.current?{"inkeep-filters":L.current}:{},...D.current?{"x-inkeep-user-properties":D.current}:{},...ue.current}},prepareSendMessagesRequest:async e=>{const r=await re.current();return{body:{...e.body,id:e.id,messages:e.messages,trigger:e.trigger,messageId:e.messageId},headers:{...e.headers,...r}}},body:{requestContext:te}}),[ne,te,b,m]),{messages:T,sendMessage:H,addToolApprovalResponse:W,status:ce,setMessages:p,stop:M,error:$}=He.useChat({transport:qe,onData(e){k(e.type,e.data)},async onFinish(){k("completion",{conversationId:s}),await g({eventName:"assistant_message_received",properties:{conversationId:s}}),g({eventName:"assistant_answer_displayed",properties:{conversationId:s}})},onError(e){console.error("onError",{code:e.code,message:e.message});const r=V||m?null:nt(e);if(r!==null&&v.current<1){v.current++;const o=B.current,a=ie.current;(async()=>{if(r==="session"&&Y){const n=await X();if(!n)throw new Error("Auth token refresh failed");U.current=n}else if(r==="session"){const n=await _();n&&(F.current=n)}else c();if(o){W(o);return}a&&(p(n=>{let u=[...n];return u.at(-1)?.role==="assistant"&&(u=u.slice(0,-1)),u.at(-1)?.role==="user"&&(u=u.slice(0,-1)),u}),H({text:a.content},{body:a.body}))})().catch(()=>{v.current=0,c(),p(n=>{const u=[...n],G=u[u.length-1];if(!G)return u;const me=P;return G.role==="user"?u.push({id:x.generateUid(16),role:"assistant",parts:[{type:"text",text:me}]}):G.parts=[{type:"text",text:me}],u})});return}v.current=0,r!==null&&c(),g({eventName:"chat_error",properties:{conversationId:s,error:e.message}}),p(o=>{const a=[...o],i=a[a.length-1];if(i){const n=we(e);i.role==="user"?a.push({id:x.generateUid(16),role:"assistant",parts:[{type:"text",text:n}]}):i.parts=[{type:"text",text:n}]}return a})}}),le=t.useRef(d);t.useEffect(()=>{const e=le.current;le.current=d,e!==d&&(M(),R(null),p([]),l(""),A(""),S([]),w(null),c())},[d,M,p,l,c]);const de=ce==="submitted",j=ce==="streaming",xe=t.useMemo(()=>{const e=i=>{if(!i||typeof i!="object")return!1;const n=i;return typeof n.type=="string"&&n.type.startsWith("tool-")},o=[...T??[]].reverse().find(i=>i.role==="assistant");if(!o)return!1;const a=o.parts?.at(-1);return!(!e(a)||a.state!=="output-available"||!a.approval?.id||j)},[T,j]),pe=j||xe,fe=de||pe,Pe=T.length===0,z=!y.trim()||fe,Ne=Ge.useMediaQuery("(max-width: 768px)"),[Oe,R]=t.useState(null);t.useEffect(()=>{$&&R($)},[$]);const _e=()=>R(null),he=t.useRef(null);t.useEffect(()=>{ke?.(y)},[y]);const Fe=e=>{e.key==="Enter"&&!e.shiftKey&&!z&&!e.nativeEvent.isComposing&&(e.preventDefault(),J())},J=async(e=y)=>{if(z&&(!e||e.trim().length===0))return;S([]),A(""),v.current=0,B.current=null,await g({eventName:"user_message_submitted",properties:{conversationId:s}});let r=s;r||(r=`conv_${x.generateUid(16)}`,l(r)),Ce(r),ie.current={content:e,body:{conversationId:r}},H({text:e},{body:{conversationId:r}})},Ue=t.useCallback(e=>{v.current=0,B.current=e,W(e)},[W]),K=t.useCallback(()=>{M().then(()=>{k("aborted",{conversationId:s})})},[M,s,k]),ge=()=>{_e(),p([]),l(""),S([]),w(null),c(),g({eventName:"chat_clear_button_clicked",properties:{conversationId:s}})},q=t.useCallback((e,r)=>{R(null),p(r),l(e),S([]),w(null),c()},[p,l,c]),De=t.useCallback(async(e,r)=>{K(),q(e,[]),oe(!0);try{const o=await ae(e,r),a=o?.[o.length-1],i=o!==null&&a?.role==="user"?[...o,{id:x.generateUid(16),role:"assistant",parts:[{type:"text",text:"This session was interrupted. Please check back in a few minutes or start a new conversation."}]}]:o;i!==null&&q(e,i)}finally{r?.aborted||oe(!1)}},[q,ae,K]),{openForm:Be}=Ye.useChatForm(),Le=et.useWidget();return t.useImperativeHandle(h.chatFunctionsRef,()=>({submitMessage:J,updateInputMessage(e){A(e)},clearChat:ge,openForm:e=>{Le?.setView("chat"),Be(e,void 0)},focusInput:()=>{he.current?.focus()}})),{messages:T,sendMessage:H,addToolApprovalResponse:Ue,isLoading:de,isStreaming:pe,isBusy:fe,error:Oe,setError:R,isSubmitDisabled:z,input:y,handleInputChange:Se,handleInputKeyDown:Fe,handleSubmit:J,stop:K,clear:ge,inputRef:he,isMobile:Ne,messageAttachments:Te,setMessageAttachments:S,selectedWorkflow:Me,setSelectedWorkflow:w,isNewChat:Pe,conversationId:s,restoreSession:q,loadAndRestoreSession:De,isSessionLoading:Ee,sessionToken:d?I:O,refreshSession:d?X:_,getCaptchaHeader:C,invalidateCaptcha:c}};exports.DEFAULT_ERROR_MESSAGE=P;exports.useInkeepChat=at;
3
+ It seems I might be having some issues right now. Please clear the chat and try again.`,ct=()=>{const{baseSettings:f,aiChatSettings:h}=Ve.useInkeepConfig(),[s="",l]=at.useControllableState({prop:h.conversationId,defaultProp:h.conversationId??""}),be=Je.useModal(),Ce=Ge.useOptionalChatBubble(),Se=Qe.useOptionalSidebarChat(),{logEvent:g}=st.useBaseEvents(),{setConversationId:Re,emitToParent:I}=ot.useStreamingEvents(),Z=t.useRef(s);t.useEffect(()=>{const e=Z.current;Z.current=s,e!==s&&g({eventName:"chat_conversation_changed",properties:{conversationId:s,previousConversationId:e}})},[s,g]);const[y,E]=t.useState(""),Ae=e=>E(e.target.value),{shouldBypassCaptcha:X,filters:Y,privacyPreferences:ke,userProperties:_}=f,{authToken:T,isLoading:Ie,refreshToken:ee}=et.useAuthToken(),te=!!f.getAuthToken,d=!!T,{onInputMessageChange:Ee,filters:se,baseUrl:w,agentUrl:Te,context:ne,headers:re,appId:b,apiKey:m,files:C}=h,we=be?.isOpen??Ce?.isOpen??Se?.isOpen??!0,{getCaptchaHeader:S,invalidate:c}=Ze.useCaptcha({baseUrl:w,shouldBypassCaptcha:X||!!m,shouldMakeInitialRequest:we}),ae=t.useRef(S);ae.current=S;const oe=Te||`${w}/run/api/chat`,{sessionToken:F,refreshSession:U}=Ye.useAnonymousSession({baseUrl:w,appId:b,getCaptchaHeader:S,invalidateCaptcha:c,optOutAllAnalytics:ke?.optOutAllAnalytics,enabled:!d&&!Ie}),{loadConversation:ie}=tt.useConversationLoader({baseUrl:w,appId:b,authToken:m??(d?T:F),getCaptchaHeader:S,invalidateCaptcha:c,refreshSession:m||d?void 0:U}),[Me,ue]=t.useState(!1),D=t.useRef(null);D.current=F;const B=t.useRef(null);B.current=T;const L=t.useRef(void 0);L.current=_&&Object.keys(_).length>0?JSON.stringify(_):void 0;const v=t.useRef(0),ce=t.useRef(null),$=t.useRef(null),R=t.useRef(void 0),xe=C?.map(e=>`${e.filename??""}:${e.mediaType}:${e.url.length}:${e.url.slice(0,64)}:${e.url.slice(-32)}`).join(`
4
+ `)??"";t.useEffect(()=>{R.current=C?.length?C:void 0},[xe]);const le=t.useRef(re);le.current=re;const H=t.useRef(void 0);H.current=Y||se?JSON.stringify({...Y,...se}):void 0;const qe=e=>{switch(e.code){case 400:return e.message;case 401:return te?"Authentication failed. Please try again.":O;case 403:return`There seems to be a configuration error. Please contact ${f.organizationDisplayName??"Administrator"}`;default:return O}},[Pe,A]=t.useState([]),[Ne,M]=t.useState(null),Oe=t.useMemo(()=>new ze.DefaultChatTransport({api:oe,headers:()=>{const e=m??B.current??D.current;return{"x-inkeep-client-timezone":Intl.DateTimeFormat().resolvedOptions().timeZone,"x-inkeep-client-timestamp":new Date().toISOString(),...b?{"x-inkeep-app-id":b}:{},...e?{Authorization:`Bearer ${e}`}:{},...H.current?{"inkeep-filters":H.current}:{},...L.current?{"x-inkeep-user-properties":L.current}:{},...le.current}},prepareSendMessagesRequest:async e=>{const n=await ae.current();return{body:{...e.body,id:e.id,messages:e.messages,trigger:e.trigger,messageId:e.messageId},headers:{...e.headers,...n}}},body:{requestContext:ne}}),[oe,ne,b,m]),{messages:x,sendMessage:j,addToolApprovalResponse:K,status:de,setMessages:p,stop:q,error:W}=We.useChat({transport:Oe,onData(e){I(e.type,e.data)},async onFinish(){I("completion",{conversationId:s}),await g({eventName:"assistant_message_received",properties:{conversationId:s}}),g({eventName:"assistant_answer_displayed",properties:{conversationId:s}})},onError(e){console.error("onError",{code:e.code,message:e.message});const n=X||m?null:ut(e);if(n!==null&&v.current<1){v.current++;const r=$.current,a=ce.current;(async()=>{if(n==="session"&&te){const o=await ee();if(!o)throw new Error("Auth token refresh failed");B.current=o}else if(n==="session"){const o=await U();o&&(D.current=o)}else c();if(r){K(r);return}a&&(p(o=>{let u=[...o];return u.at(-1)?.role==="assistant"&&(u=u.slice(0,-1)),u.at(-1)?.role==="user"&&(u=u.slice(0,-1)),u}),j(a.files?.length?{parts:[{type:"text",text:a.content},...a.files]}:{text:a.content},{body:a.body}))})().catch(()=>{v.current=0,c(),p(o=>{const u=[...o],V=u[u.length-1];if(!V)return u;const ye=O;return V.role==="user"?u.push({id:N.generateUid(16),role:"assistant",parts:[{type:"text",text:ye}]}):V.parts=[{type:"text",text:ye}],u})});return}v.current=0,n!==null&&c(),g({eventName:"chat_error",properties:{conversationId:s,error:e.message}}),p(r=>{const a=[...r],i=a[a.length-1];if(i){const o=qe(e);i.role==="user"?a.push({id:N.generateUid(16),role:"assistant",parts:[{type:"text",text:o}]}):i.parts=[{type:"text",text:o}]}return a})}}),pe=t.useRef(d);t.useEffect(()=>{const e=pe.current;pe.current=d,e!==d&&(q(),k(null),p([]),l(""),E(""),A([]),M(null),c())},[d,q,p,l,c]);const fe=de==="submitted",z=de==="streaming",_e=t.useMemo(()=>{const e=i=>{if(!i||typeof i!="object")return!1;const o=i;return typeof o.type=="string"&&o.type.startsWith("tool-")},r=[...x??[]].reverse().find(i=>i.role==="assistant");if(!r)return!1;const a=r.parts?.at(-1);return!(!e(a)||a.state!=="output-available"||!a.approval?.id||z)},[x,z]),he=z||_e,ge=fe||he,Fe=x.length===0,J=!y.trim()||ge,Ue=Xe.useMediaQuery("(max-width: 768px)"),[De,k]=t.useState(null);t.useEffect(()=>{W&&k(W)},[W]);const Be=()=>k(null),me=t.useRef(null);t.useEffect(()=>{Ee?.(y)},[y]);const Le=e=>{e.key==="Enter"&&!e.shiftKey&&!J&&!e.nativeEvent.isComposing&&(e.preventDefault(),G())},G=async(e=y)=>{if(J&&(!e||e.trim().length===0))return;A([]),E(""),v.current=0,$.current=null,await g({eventName:"user_message_submitted",properties:{conversationId:s}});let n=s;n||(n=`conv_${N.generateUid(16)}`,l(n)),Re(n);const r=R.current;R.current=void 0,ce.current={content:e,body:{conversationId:n},files:r},j(r?{parts:[{type:"text",text:e},...r]}:{text:e},{body:{conversationId:n}})},$e=t.useCallback(e=>{v.current=0,$.current=e,K(e)},[K]),Q=t.useCallback(()=>{q().then(()=>{I("aborted",{conversationId:s})})},[q,s,I]),ve=()=>{Be(),p([]),l(""),A([]),M(null),c(),R.current=C?.length?C:void 0,g({eventName:"chat_clear_button_clicked",properties:{conversationId:s}})},P=t.useCallback((e,n)=>{k(null),p(n),l(e),A([]),M(null),c(),R.current=void 0},[p,l,c]),He=t.useCallback(async(e,n)=>{Q(),P(e,[]),ue(!0);try{const r=await ie(e,n),a=r?.[r.length-1],i=r!==null&&a?.role==="user"?[...r,{id:N.generateUid(16),role:"assistant",parts:[{type:"text",text:"This session was interrupted. Please check back in a few minutes or start a new conversation."}]}]:r;i!==null&&P(e,i)}finally{n?.aborted||ue(!1)}},[P,ie,Q]),{openForm:je}=nt.useChatForm(),Ke=rt.useWidget();return t.useImperativeHandle(h.chatFunctionsRef,()=>({submitMessage:G,updateInputMessage(e){E(e)},clearChat:ve,openForm:e=>{Ke?.setView("chat"),je(e,void 0)},focusInput:()=>{me.current?.focus()}})),{messages:x,sendMessage:j,addToolApprovalResponse:$e,isLoading:fe,isStreaming:he,isBusy:ge,error:De,setError:k,isSubmitDisabled:J,input:y,handleInputChange:Ae,handleInputKeyDown:Le,handleSubmit:G,stop:Q,clear:ve,inputRef:me,isMobile:Ue,messageAttachments:Pe,setMessageAttachments:A,selectedWorkflow:Ne,setSelectedWorkflow:M,isNewChat:Fe,conversationId:s,restoreSession:P,loadAndRestoreSession:He,isSessionLoading:Me,authToken:d?T:F,refreshSession:d?ee:U,getCaptchaHeader:S,invalidateCaptcha:c}};exports.DEFAULT_ERROR_MESSAGE=O;exports.useInkeepChat=ct;
@@ -1,6 +1,6 @@
1
1
  import { KeyboardEvent, Dispatch, SetStateAction, RefObject } from 'react';
2
- import { Message, MessageAttachment, Workflow } from '../../../types/index.ts';
3
2
  import { FileUIPart, ChatRequestOptions } from 'ai';
3
+ import { Message, MessageAttachment, Workflow } from '../../../types/index.ts';
4
4
  export declare const DEFAULT_ERROR_MESSAGE = "Hmm.. \n\nIt seems I might be having some issues right now. Please clear the chat and try again.";
5
5
  export declare const useInkeepChat: () => {
6
6
  messages: Message[];
@@ -50,7 +50,7 @@ export declare const useInkeepChat: () => {
50
50
  restoreSession: (sessionId: string, loadedMessages: Message[]) => void;
51
51
  loadAndRestoreSession: (sessionId: string, signal?: AbortSignal) => Promise<void>;
52
52
  isSessionLoading: boolean;
53
- sessionToken: string | null;
53
+ authToken: string | null;
54
54
  refreshSession: () => Promise<string | null>;
55
55
  getCaptchaHeader: () => Promise<Record<string, string>>;
56
56
  invalidateCaptcha: () => void;
@@ -1,24 +1,24 @@
1
1
  "use client";
2
- import { useChat as Je } from "@ai-sdk/react";
3
- import { DefaultChatTransport as Ke } from "ai";
4
- import { useRef as c, useEffect as O, useState as A, useMemo as Ce, useCallback as _, useImperativeHandle as je } from "react";
5
- import { useModal as Ge } from "../modal/modal-provider.js";
6
- import { useOptionalChatBubble as Qe } from "../../providers/chat-bubble-provider.js";
7
- import { useOptionalSidebarChat as Ve } from "../../providers/sidebar-chat-provider.js";
8
- import { useInkeepConfig as Ze } from "../../providers/config-provider.js";
9
- import { useCaptcha as Xe } from "./use-captcha.js";
10
- import { useMediaQuery as Ye } from "../../hooks/use-media-query.js";
11
- import { useAnonymousSession as et } from "../../hooks/use-anonymous-session.js";
12
- import { useAuthToken as tt } from "../../hooks/use-auth-token.js";
13
- import { useConversationLoader as st } from "../../hooks/use-conversation-loader.js";
14
- import { generateUid as F } from "../../utils/generate-uid.js";
15
- import { useBaseEvents as rt } from "../../providers/base-events-provider.js";
16
- import { useChatForm as nt } from "../../providers/chat-form-provider.js";
17
- import { useWidget as ot } from "../../providers/widget-provider.js";
18
- import { useControllableState as at } from "@radix-ui/react-use-controllable-state";
19
- import { useStreamingEvents as it } from "../../hooks/use-streaming-events.js";
20
- import { parseAuthError as ct } from "../../hooks/use-inkeep-api-client.js";
21
- function ut(m) {
2
+ import { useChat as Qe } from "@ai-sdk/react";
3
+ import { DefaultChatTransport as Ve } from "ai";
4
+ import { useRef as c, useEffect as w, useState as R, useMemo as Se, useCallback as P, useImperativeHandle as Ze } from "react";
5
+ import { useModal as Xe } from "../modal/modal-provider.js";
6
+ import { useOptionalChatBubble as Ye } from "../../providers/chat-bubble-provider.js";
7
+ import { useOptionalSidebarChat as et } from "../../providers/sidebar-chat-provider.js";
8
+ import { useInkeepConfig as tt } from "../../providers/config-provider.js";
9
+ import { useCaptcha as st } from "./use-captcha.js";
10
+ import { useMediaQuery as rt } from "../../hooks/use-media-query.js";
11
+ import { useAnonymousSession as nt } from "../../hooks/use-anonymous-session.js";
12
+ import { useAuthToken as ot } from "../../hooks/use-auth-token.js";
13
+ import { useConversationLoader as at } from "../../hooks/use-conversation-loader.js";
14
+ import { generateUid as D } from "../../utils/generate-uid.js";
15
+ import { useBaseEvents as it } from "../../providers/base-events-provider.js";
16
+ import { useChatForm as ct } from "../../providers/chat-form-provider.js";
17
+ import { useWidget as lt } from "../../providers/widget-provider.js";
18
+ import { useControllableState as ut } from "@radix-ui/react-use-controllable-state";
19
+ import { useStreamingEvents as pt } from "../../hooks/use-streaming-events.js";
20
+ import { parseAuthError as dt } from "../../hooks/use-inkeep-api-client.js";
21
+ function mt(m) {
22
22
  const f = m.message ?? "";
23
23
  let t = Number(m.code) || Number(m.statusCode);
24
24
  if (Number.isNaN(t))
@@ -26,19 +26,19 @@ function ut(m) {
26
26
  t = Number(JSON.parse(f).status);
27
27
  } catch {
28
28
  }
29
- const l = ct(t, { detail: f });
30
- return l !== null ? l : t === 401 ? "session" : null;
29
+ const u = dt(t, { detail: f });
30
+ return u !== null ? u : t === 401 ? "session" : null;
31
31
  }
32
- const Z = `Hmm..
32
+ const Y = `Hmm..
33
33
 
34
- It seems I might be having some issues right now. Please clear the chat and try again.`, xt = () => {
35
- const { baseSettings: m, aiChatSettings: f } = Ze(), [t = "", l] = at({
34
+ It seems I might be having some issues right now. Please clear the chat and try again.`, _t = () => {
35
+ const { baseSettings: m, aiChatSettings: f } = tt(), [t = "", u] = ut({
36
36
  prop: f.conversationId,
37
37
  defaultProp: f.conversationId ?? ""
38
- }), Se = Ge(), ke = Qe(), Ae = Ve(), { logEvent: h } = rt(), { setConversationId: Ie, emitToParent: I } = it(), X = c(t);
39
- O(() => {
40
- const e = X.current;
41
- X.current = t, e !== t && h({
38
+ }), ke = Xe(), Ie = Ye(), we = et(), { logEvent: h } = it(), { setConversationId: Re, emitToParent: T } = pt(), ee = c(t);
39
+ w(() => {
40
+ const e = ee.current;
41
+ ee.current = t, e !== t && h({
42
42
  eventName: "chat_conversation_changed",
43
43
  properties: {
44
44
  conversationId: t,
@@ -46,73 +46,79 @@ It seems I might be having some issues right now. Please clear the chat and try
46
46
  }
47
47
  });
48
48
  }, [t, h]);
49
- const [y, w] = A(""), we = (e) => w(e.target.value), { shouldBypassCaptcha: Y, filters: ee, privacyPreferences: Re, userProperties: P } = m, { authToken: R, refreshToken: te } = tt(), se = !!m.getAuthToken, p = !!R, {
50
- onInputMessageChange: Te,
51
- filters: re,
52
- baseUrl: T,
53
- agentUrl: Me,
54
- context: ne,
55
- headers: oe,
49
+ const [y, x] = R(""), Te = (e) => x(e.target.value), { shouldBypassCaptcha: te, filters: se, privacyPreferences: xe, userProperties: $ } = m, { authToken: M, isLoading: Me, refreshToken: re } = ot(), ne = !!m.getAuthToken, p = !!M, {
50
+ onInputMessageChange: Ee,
51
+ filters: oe,
52
+ baseUrl: E,
53
+ agentUrl: Ne,
54
+ context: ae,
55
+ headers: ie,
56
56
  appId: b,
57
- apiKey: g
58
- } = f, xe = Se?.isOpen ?? ke?.isOpen ?? Ae?.isOpen ?? !0, { getCaptchaHeader: C, invalidate: u } = Xe({
59
- baseUrl: T,
60
- shouldBypassCaptcha: Y || !!g,
61
- shouldMakeInitialRequest: xe
62
- }), ae = c(C);
63
- ae.current = C;
64
- const ie = Me || `${T}/run/api/chat`, { sessionToken: D, refreshSession: B } = et({
65
- baseUrl: T,
57
+ apiKey: g,
58
+ files: C
59
+ } = f, Oe = ke?.isOpen ?? Ie?.isOpen ?? we?.isOpen ?? !0, { getCaptchaHeader: A, invalidate: l } = st({
60
+ baseUrl: E,
61
+ shouldBypassCaptcha: te || !!g,
62
+ shouldMakeInitialRequest: Oe
63
+ }), ce = c(A);
64
+ ce.current = A;
65
+ const le = Ne || `${E}/run/api/chat`, { sessionToken: B, refreshSession: L } = nt({
66
+ baseUrl: E,
66
67
  appId: b,
67
- getCaptchaHeader: C,
68
- invalidateCaptcha: u,
69
- optOutAllAnalytics: Re?.optOutAllAnalytics,
70
- enabled: !p
71
- }), { loadConversation: ce } = st({
72
- baseUrl: T,
68
+ getCaptchaHeader: A,
69
+ invalidateCaptcha: l,
70
+ optOutAllAnalytics: xe?.optOutAllAnalytics,
71
+ enabled: !p && !Me
72
+ }), { loadConversation: ue } = at({
73
+ baseUrl: E,
73
74
  appId: b,
74
- authToken: g ?? (p ? R : D),
75
- getCaptchaHeader: C,
76
- invalidateCaptcha: u,
77
- refreshSession: g || p ? void 0 : B
78
- }), [Ee, ue] = A(!1), H = c(null);
79
- H.current = D;
80
- const L = c(null);
81
- L.current = R;
82
- const U = c(void 0);
83
- U.current = P && Object.keys(P).length > 0 ? JSON.stringify(P) : void 0;
84
- const v = c(0), le = c(null), W = c(null), pe = c(oe);
85
- pe.current = oe;
86
- const $ = c(void 0);
87
- $.current = ee || re ? JSON.stringify({ ...ee, ...re }) : void 0;
88
- const Ne = (e) => {
75
+ authToken: g ?? (p ? M : B),
76
+ getCaptchaHeader: A,
77
+ invalidateCaptcha: l,
78
+ refreshSession: g || p ? void 0 : L
79
+ }), [_e, pe] = R(!1), H = c(null);
80
+ H.current = B;
81
+ const U = c(null);
82
+ U.current = M;
83
+ const K = c(void 0);
84
+ K.current = $ && Object.keys($).length > 0 ? JSON.stringify($) : void 0;
85
+ const v = c(0), de = c(null), W = c(null), S = c(void 0), Fe = C?.map((e) => `${e.filename ?? ""}:${e.mediaType}:${e.url.length}:${e.url.slice(0, 64)}:${e.url.slice(-32)}`).join(`
86
+ `) ?? "";
87
+ w(() => {
88
+ S.current = C?.length ? C : void 0;
89
+ }, [Fe]);
90
+ const me = c(ie);
91
+ me.current = ie;
92
+ const j = c(void 0);
93
+ j.current = se || oe ? JSON.stringify({ ...se, ...oe }) : void 0;
94
+ const Pe = (e) => {
89
95
  switch (e.code) {
90
96
  case 400:
91
97
  return e.message;
92
98
  case 401:
93
- return se ? "Authentication failed. Please try again." : Z;
99
+ return ne ? "Authentication failed. Please try again." : Y;
94
100
  case 403:
95
101
  return `There seems to be a configuration error. Please contact ${m.organizationDisplayName ?? "Administrator"}`;
96
102
  default:
97
- return Z;
103
+ return Y;
98
104
  }
99
- }, [Oe, S] = A([]), [_e, M] = A(null), Fe = Ce(
100
- () => new Ke({
101
- api: ie,
105
+ }, [De, k] = R([]), [$e, N] = R(null), Be = Se(
106
+ () => new Ve({
107
+ api: le,
102
108
  headers: () => {
103
- const e = g ?? L.current ?? H.current;
109
+ const e = g ?? U.current ?? H.current;
104
110
  return {
105
111
  "x-inkeep-client-timezone": Intl.DateTimeFormat().resolvedOptions().timeZone,
106
112
  "x-inkeep-client-timestamp": (/* @__PURE__ */ new Date()).toISOString(),
107
113
  ...b ? { "x-inkeep-app-id": b } : {},
108
114
  ...e ? { Authorization: `Bearer ${e}` } : {},
109
- ...$.current ? { "inkeep-filters": $.current } : {},
110
- ...U.current ? { "x-inkeep-user-properties": U.current } : {},
111
- ...pe.current
115
+ ...j.current ? { "inkeep-filters": j.current } : {},
116
+ ...K.current ? { "x-inkeep-user-properties": K.current } : {},
117
+ ...me.current
112
118
  };
113
119
  },
114
120
  prepareSendMessagesRequest: async (e) => {
115
- const s = await ae.current();
121
+ const s = await ce.current();
116
122
  return {
117
123
  body: {
118
124
  ...e.body,
@@ -128,25 +134,25 @@ It seems I might be having some issues right now. Please clear the chat and try
128
134
  };
129
135
  },
130
136
  body: {
131
- requestContext: ne
137
+ requestContext: ae
132
138
  }
133
139
  }),
134
- [ie, ne, b, g]
140
+ [le, ae, b, g]
135
141
  ), {
136
- messages: x,
142
+ messages: O,
137
143
  sendMessage: q,
138
144
  addToolApprovalResponse: z,
139
- status: de,
145
+ status: fe,
140
146
  setMessages: d,
141
- stop: E,
147
+ stop: _,
142
148
  error: J
143
- } = Je({
144
- transport: Fe,
149
+ } = Qe({
150
+ transport: Be,
145
151
  onData(e) {
146
- I(e.type, e.data);
152
+ T(e.type, e.data);
147
153
  },
148
154
  async onFinish() {
149
- I("completion", { conversationId: t }), await h({
155
+ T("completion", { conversationId: t }), await h({
150
156
  eventName: "assistant_message_received",
151
157
  properties: {
152
158
  conversationId: t
@@ -160,187 +166,193 @@ It seems I might be having some issues right now. Please clear the chat and try
160
166
  },
161
167
  onError(e) {
162
168
  console.error("onError", { code: e.code, message: e.message });
163
- const s = Y || g ? null : ut(e);
169
+ const s = te || g ? null : mt(e);
164
170
  if (s !== null && v.current < 1) {
165
171
  v.current++;
166
- const o = W.current, n = le.current;
172
+ const r = W.current, n = de.current;
167
173
  (async () => {
168
- if (s === "session" && se) {
169
- const r = await te();
170
- if (!r) throw new Error("Auth token refresh failed");
171
- L.current = r;
174
+ if (s === "session" && ne) {
175
+ const o = await re();
176
+ if (!o) throw new Error("Auth token refresh failed");
177
+ U.current = o;
172
178
  } else if (s === "session") {
173
- const r = await B();
174
- r && (H.current = r);
179
+ const o = await L();
180
+ o && (H.current = o);
175
181
  } else
176
- u();
177
- if (o) {
178
- z(o);
182
+ l();
183
+ if (r) {
184
+ z(r);
179
185
  return;
180
186
  }
181
- n && (d((r) => {
182
- let i = [...r];
187
+ n && (d((o) => {
188
+ let i = [...o];
183
189
  return i.at(-1)?.role === "assistant" && (i = i.slice(0, -1)), i.at(-1)?.role === "user" && (i = i.slice(0, -1)), i;
184
- }), q({ text: n.content }, { body: n.body }));
190
+ }), q(
191
+ n.files?.length ? { parts: [{ type: "text", text: n.content }, ...n.files] } : { text: n.content },
192
+ { body: n.body }
193
+ ));
185
194
  })().catch(() => {
186
- v.current = 0, u(), d((r) => {
187
- const i = [...r], V = i[i.length - 1];
188
- if (!V) return i;
189
- const be = Z;
190
- return V.role === "user" ? i.push({
191
- id: F(16),
195
+ v.current = 0, l(), d((o) => {
196
+ const i = [...o], X = i[i.length - 1];
197
+ if (!X) return i;
198
+ const Ae = Y;
199
+ return X.role === "user" ? i.push({
200
+ id: D(16),
192
201
  role: "assistant",
193
- parts: [{ type: "text", text: be }]
194
- }) : V.parts = [{ type: "text", text: be }], i;
202
+ parts: [{ type: "text", text: Ae }]
203
+ }) : X.parts = [{ type: "text", text: Ae }], i;
195
204
  });
196
205
  });
197
206
  return;
198
207
  }
199
- v.current = 0, s !== null && u(), h({
208
+ v.current = 0, s !== null && l(), h({
200
209
  eventName: "chat_error",
201
210
  properties: {
202
211
  conversationId: t,
203
212
  error: e.message
204
213
  }
205
- }), d((o) => {
206
- const n = [...o], a = n[n.length - 1];
214
+ }), d((r) => {
215
+ const n = [...r], a = n[n.length - 1];
207
216
  if (a) {
208
- const r = Ne(e);
217
+ const o = Pe(e);
209
218
  a.role === "user" ? n.push({
210
- id: F(16),
219
+ id: D(16),
211
220
  role: "assistant",
212
- parts: [{ type: "text", text: r }]
213
- }) : a.parts = [{ type: "text", text: r }];
221
+ parts: [{ type: "text", text: o }]
222
+ }) : a.parts = [{ type: "text", text: o }];
214
223
  }
215
224
  return n;
216
225
  });
217
226
  }
218
- }), me = c(p);
219
- O(() => {
220
- const e = me.current;
221
- me.current = p, e !== p && (E(), k(null), d([]), l(""), w(""), S([]), M(null), u());
222
- }, [p, E, d, l, u]);
223
- const fe = de === "submitted", K = de === "streaming", Pe = Ce(() => {
227
+ }), he = c(p);
228
+ w(() => {
229
+ const e = he.current;
230
+ he.current = p, e !== p && (_(), I(null), d([]), u(""), x(""), k([]), N(null), l());
231
+ }, [p, _, d, u, l]);
232
+ const ge = fe === "submitted", G = fe === "streaming", Le = Se(() => {
224
233
  const e = (a) => {
225
234
  if (!a || typeof a != "object") return !1;
226
- const r = a;
227
- return typeof r.type == "string" && r.type.startsWith("tool-");
228
- }, o = [...x ?? []].reverse().find((a) => a.role === "assistant");
229
- if (!o) return !1;
230
- const n = o.parts?.at(-1);
231
- return !(!e(n) || n.state !== "output-available" || !n.approval?.id || K);
232
- }, [x, K]), he = K || Pe, ge = fe || he, De = x.length === 0, j = !y.trim() || ge, Be = Ye("(max-width: 768px)"), [He, k] = A(null);
233
- O(() => {
234
- J && k(J);
235
+ const o = a;
236
+ return typeof o.type == "string" && o.type.startsWith("tool-");
237
+ }, r = [...O ?? []].reverse().find((a) => a.role === "assistant");
238
+ if (!r) return !1;
239
+ const n = r.parts?.at(-1);
240
+ return !(!e(n) || n.state !== "output-available" || !n.approval?.id || G);
241
+ }, [O, G]), ve = G || Le, ye = ge || ve, He = O.length === 0, Q = !y.trim() || ye, Ue = rt("(max-width: 768px)"), [Ke, I] = R(null);
242
+ w(() => {
243
+ J && I(J);
235
244
  }, [J]);
236
- const Le = () => k(null), ve = c(null);
237
- O(() => {
238
- Te?.(y);
245
+ const We = () => I(null), be = c(null);
246
+ w(() => {
247
+ Ee?.(y);
239
248
  }, [y]);
240
- const Ue = (e) => {
241
- e.key === "Enter" && !e.shiftKey && !j && !e.nativeEvent.isComposing && (e.preventDefault(), G());
242
- }, G = async (e = y) => {
243
- if (j && (!e || e.trim().length === 0)) return;
244
- S([]), w(""), v.current = 0, W.current = null, await h({
249
+ const je = (e) => {
250
+ e.key === "Enter" && !e.shiftKey && !Q && !e.nativeEvent.isComposing && (e.preventDefault(), V());
251
+ }, V = async (e = y) => {
252
+ if (Q && (!e || e.trim().length === 0)) return;
253
+ k([]), x(""), v.current = 0, W.current = null, await h({
245
254
  eventName: "user_message_submitted",
246
255
  properties: {
247
256
  conversationId: t
248
257
  }
249
258
  });
250
259
  let s = t;
251
- s || (s = `conv_${F(16)}`, l(s)), Ie(s), le.current = {
260
+ s || (s = `conv_${D(16)}`, u(s)), Re(s);
261
+ const r = S.current;
262
+ S.current = void 0, de.current = {
252
263
  content: e,
253
- body: { conversationId: s }
264
+ body: { conversationId: s },
265
+ files: r
254
266
  }, q(
255
- { text: e },
267
+ r ? { parts: [{ type: "text", text: e }, ...r] } : { text: e },
256
268
  {
257
269
  body: { conversationId: s }
258
270
  }
259
271
  );
260
- }, We = _(
272
+ }, qe = P(
261
273
  (e) => {
262
274
  v.current = 0, W.current = e, z(e);
263
275
  },
264
276
  [z]
265
- ), Q = _(() => {
266
- E().then(() => {
267
- I("aborted", { conversationId: t });
277
+ ), Z = P(() => {
278
+ _().then(() => {
279
+ T("aborted", { conversationId: t });
268
280
  });
269
- }, [E, t, I]), ye = () => {
270
- Le(), d([]), l(""), S([]), M(null), u(), h({
281
+ }, [_, t, T]), Ce = () => {
282
+ We(), d([]), u(""), k([]), N(null), l(), S.current = C?.length ? C : void 0, h({
271
283
  eventName: "chat_clear_button_clicked",
272
284
  properties: {
273
285
  conversationId: t
274
286
  }
275
287
  });
276
- }, N = _(
288
+ }, F = P(
277
289
  (e, s) => {
278
- k(null), d(s), l(e), S([]), M(null), u();
290
+ I(null), d(s), u(e), k([]), N(null), l(), S.current = void 0;
279
291
  },
280
- [d, l, u]
281
- ), $e = _(
292
+ [d, u, l]
293
+ ), ze = P(
282
294
  async (e, s) => {
283
- Q(), N(e, []), ue(!0);
295
+ Z(), F(e, []), pe(!0);
284
296
  try {
285
- const o = await ce(e, s), n = o?.[o.length - 1], a = o !== null && n?.role === "user" ? [...o, {
286
- id: F(16),
297
+ const r = await ue(e, s), n = r?.[r.length - 1], a = r !== null && n?.role === "user" ? [...r, {
298
+ id: D(16),
287
299
  role: "assistant",
288
300
  parts: [{ type: "text", text: "This session was interrupted. Please check back in a few minutes or start a new conversation." }]
289
- }] : o;
290
- a !== null && N(e, a);
301
+ }] : r;
302
+ a !== null && F(e, a);
291
303
  } finally {
292
- s?.aborted || ue(!1);
304
+ s?.aborted || pe(!1);
293
305
  }
294
306
  },
295
- [N, ce, Q]
296
- ), { openForm: qe } = nt(), ze = ot();
297
- return je(f.chatFunctionsRef, () => ({
298
- submitMessage: G,
307
+ [F, ue, Z]
308
+ ), { openForm: Je } = ct(), Ge = lt();
309
+ return Ze(f.chatFunctionsRef, () => ({
310
+ submitMessage: V,
299
311
  updateInputMessage(e) {
300
- w(e);
312
+ x(e);
301
313
  },
302
- clearChat: ye,
314
+ clearChat: Ce,
303
315
  openForm: (e) => {
304
- ze?.setView("chat"), qe(e, void 0);
316
+ Ge?.setView("chat"), Je(e, void 0);
305
317
  },
306
318
  focusInput: () => {
307
- ve.current?.focus();
319
+ be.current?.focus();
308
320
  }
309
321
  })), {
310
- messages: x,
322
+ messages: O,
311
323
  sendMessage: q,
312
- addToolApprovalResponse: We,
313
- isLoading: fe,
314
- isStreaming: he,
315
- isBusy: ge,
316
- error: He,
317
- setError: k,
318
- isSubmitDisabled: j,
324
+ addToolApprovalResponse: qe,
325
+ isLoading: ge,
326
+ isStreaming: ve,
327
+ isBusy: ye,
328
+ error: Ke,
329
+ setError: I,
330
+ isSubmitDisabled: Q,
319
331
  input: y,
320
- handleInputChange: we,
321
- handleInputKeyDown: Ue,
322
- handleSubmit: G,
323
- stop: Q,
324
- clear: ye,
325
- inputRef: ve,
326
- isMobile: Be,
332
+ handleInputChange: Te,
333
+ handleInputKeyDown: je,
334
+ handleSubmit: V,
335
+ stop: Z,
336
+ clear: Ce,
337
+ inputRef: be,
338
+ isMobile: Ue,
327
339
  // Additional state for attachments and workflow
328
- messageAttachments: Oe,
329
- setMessageAttachments: S,
330
- selectedWorkflow: _e,
331
- setSelectedWorkflow: M,
332
- isNewChat: De,
340
+ messageAttachments: De,
341
+ setMessageAttachments: k,
342
+ selectedWorkflow: $e,
343
+ setSelectedWorkflow: N,
344
+ isNewChat: He,
333
345
  conversationId: t,
334
- restoreSession: N,
335
- loadAndRestoreSession: $e,
336
- isSessionLoading: Ee,
337
- sessionToken: p ? R : D,
338
- refreshSession: p ? te : B,
339
- getCaptchaHeader: C,
340
- invalidateCaptcha: u
346
+ restoreSession: F,
347
+ loadAndRestoreSession: ze,
348
+ isSessionLoading: _e,
349
+ authToken: p ? M : B,
350
+ refreshSession: p ? re : L,
351
+ getCaptchaHeader: A,
352
+ invalidateCaptcha: l
341
353
  };
342
354
  };
343
355
  export {
344
- Z as DEFAULT_ERROR_MESSAGE,
345
- xt as useInkeepChat
356
+ Y as DEFAULT_ERROR_MESSAGE,
357
+ _t as useInkeepChat
346
358
  };
@@ -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.22",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.24",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.22",
8
+ widgetLibraryVersion: "0.15.24",
9
9
  componentType: o,
10
10
  tags: s
11
11
  }),
@@ -1 +1 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const te=require("react/jsx-runtime"),e=require("react"),se=require("../components/embedded-chat/chat-provider.cjs"),ne=require("./config-provider.cjs"),re=require("../hooks/use-inkeep-api-client.cjs"),Z=e.createContext(void 0),U=25;function oe(t){const{stop:u,clear:f,conversationId:l,isStreaming:R,loadAndRestoreSession:H,sessionToken:r,refreshSession:_,getCaptchaHeader:z,invalidateCaptcha:B}=se.useChat(),{aiChatSettings:J,baseSettings:Q}=ne.useInkeepConfig(),{baseUrl:S,appId:I,apiKey:V}=J,i=!!Q.getAuthToken,a=!V&&!!I&&(!!r||i),v=r,{fetchWithAuth:P}=re.useInkeepApiClient({appId:I,authToken:v,getCaptchaHeader:z,invalidateCaptcha:B,refreshSession:_}),[b,k]=e.useState(!1),[E,x]=e.useState([]),[w,m]=e.useState(!1),[T,q]=e.useState(0),[A,j]=e.useState(!1),h=e.useRef(!1),M=e.useRef(null),$=e.useRef(i),L=e.useRef(r);e.useEffect(()=>{const n=$.current,s=L.current;$.current=i,L.current=r,(n!==i||s!==null&&r!==null&&s!==r)&&(x([]),q(0),j(!1),h.current=!1)},[i,r]);const O=e.useRef([]);O.current=E;const D=e.useRef(P);D.current=P;const c=e.useCallback(async(n,s=!1)=>{if(!(!S||!v||!a)){s||m(!0);try{const C=`${S}/run/v1/conversations?page=${n+1}&limit=${U}`,g=await D.current(C);if(!g.ok)throw new Error(`Failed to fetch conversations: ${g.status}`);const W=await g.json(),p=(W.data??[]).map(o=>({id:o.id,title:o.title??"",createdAt:new Date(o.createdAt),updatedAt:new Date(o.updatedAt)}));x(o=>{if(n===0&&!s)return p;if(n===0&&s){const d=new Set(p.map(y=>y.id));return[...p,...o.slice(U).filter(y=>!d.has(y.id))]}const ee=new Set(o.map(d=>d.id));return[...o,...p.filter(d=>!ee.has(d.id))]});const{page:G,pages:K}=W.pagination??{};j(G!=null&&K!=null?G<K:!1),s||q(n)}catch(C){console.error("[useChatHistory] Failed to load conversations:",C)}finally{m(!1)}}},[S,v,a]);e.useEffect(()=>{!b||!r&&!i||!a||(t==="stack"?c(0):h.current||(h.current=!0,c(0)))},[b,r,i,a,t,c]);const F=e.useRef("");e.useEffect(()=>{a&&t==="sidepane"&&(!l||!R||h.current&&F.current!==l&&(O.current.some(n=>n.id===l)||(F.current=l,c(0,!0))))},[l,a,t,c,R]);const X=e.useCallback(()=>{!w&&A&&c(T+1)},[w,A,T,c]),Y=e.useCallback(()=>{u(),f(),t!=="sidepane"&&k(!1)},[t,u,f]),N=e.useCallback(async n=>{M.current?.abort();const s=new AbortController;M.current=s,await H(n,s.signal),!s.signal.aborted&&t!=="sidepane"&&k(!1)},[t,H]);return{isEnabled:a,isOpen:b,setIsOpen:k,sessions:E,isLoading:w,hasMore:A,loadMore:X,startNewConversation:Y,loadSession:N}}const ie=({layout:t,children:u})=>{const f=oe(t);return te.jsx(Z.Provider,{value:f,children:typeof u=="function"?u(f):u})},ae=()=>{const t=e.useContext(Z);if(!t)throw new Error("useChatHistory must be used within a ChatHistoryProvider");return t};exports.ChatHistoryProvider=ie;exports.useChatHistory=ae;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ee=require("react/jsx-runtime"),e=require("react"),te=require("../components/embedded-chat/chat-provider.cjs"),se=require("./config-provider.cjs"),ne=require("../hooks/use-inkeep-api-client.cjs"),U=e.createContext(void 0),K=25;function re(t){const{stop:u,clear:f,conversationId:l,isStreaming:y,loadAndRestoreSession:R,authToken:s,refreshSession:Z,getCaptchaHeader:_,invalidateCaptcha:z}=te.useChat(),{aiChatSettings:B,baseSettings:J}=se.useInkeepConfig(),{baseUrl:S,appId:H,apiKey:Q}=B,a=!!J.getAuthToken,o=!Q&&!!H&&(!!s||a),{fetchWithAuth:I}=ne.useInkeepApiClient({appId:H,authToken:s,getCaptchaHeader:_,invalidateCaptcha:z,refreshSession:Z}),[v,b]=e.useState(!1),[P,E]=e.useState([]),[k,x]=e.useState(!s&&o),[m,q]=e.useState(0),[w,T]=e.useState(!1),h=e.useRef(!1),j=e.useRef(null),M=e.useRef(a),$=e.useRef(s);e.useEffect(()=>{const r=M.current,n=$.current;M.current=a,$.current=s,(r!==a||n!==null&&s!==null&&n!==s)&&(E([]),q(0),T(!1),h.current=!1)},[a,s]);const L=e.useRef([]);L.current=P;const O=e.useRef(I);O.current=I;const c=e.useCallback(async(r,n=!1)=>{if(!(!S||!s||!o)){n||x(!0);try{const C=`${S}/run/v1/conversations?page=${r+1}&limit=${K}`,g=await O.current(C);if(!g.ok)throw new Error(`Failed to fetch conversations: ${g.status}`);const F=await g.json(),p=(F.data??[]).map(i=>({id:i.id,title:i.title??"",createdAt:new Date(i.createdAt),updatedAt:new Date(i.updatedAt)}));E(i=>{if(r===0&&!n)return p;if(r===0&&n){const d=new Set(p.map(A=>A.id));return[...p,...i.slice(K).filter(A=>!d.has(A.id))]}const N=new Set(i.map(d=>d.id));return[...i,...p.filter(d=>!N.has(d.id))]});const{page:W,pages:G}=F.pagination??{};T(W!=null&&G!=null?W<G:!1),n||q(r)}catch(C){console.error("[useChatHistory] Failed to load conversations:",C)}finally{x(!1)}}},[S,s,o]);e.useEffect(()=>{!v||!s&&!a||!o||(t==="stack"?c(0):!h.current&&s&&(h.current=!0,c(0)))},[v,s,a,o,t,c]);const D=e.useRef("");e.useEffect(()=>{o&&t==="sidepane"&&(!l||!y||h.current&&D.current!==l&&(L.current.some(r=>r.id===l)||(D.current=l,c(0,!0))))},[l,o,t,c,y]);const V=e.useCallback(()=>{!k&&w&&c(m+1)},[k,w,m,c]),X=e.useCallback(()=>{u(),f(),t!=="sidepane"&&b(!1)},[t,u,f]),Y=e.useCallback(async r=>{j.current?.abort();const n=new AbortController;j.current=n,await R(r,n.signal),!n.signal.aborted&&t!=="sidepane"&&b(!1)},[t,R]);return{isEnabled:o,isOpen:v,setIsOpen:b,sessions:P,isLoading:k,hasMore:w,loadMore:V,startNewConversation:X,loadSession:Y}}const oe=({layout:t,children:u})=>{const f=re(t);return ee.jsx(U.Provider,{value:f,children:typeof u=="function"?u(f):u})},ie=()=>{const t=e.useContext(U);if(!t)throw new Error("useChatHistory must be used within a ChatHistoryProvider");return t};exports.ChatHistoryProvider=oe;exports.useChatHistory=ie;
@@ -1,110 +1,110 @@
1
1
  "use client";
2
- import { jsx as re } from "react/jsx-runtime";
3
- import { createContext as oe, useContext as ie, useState as h, useRef as c, useEffect as y, useCallback as S } from "react";
4
- import { useChat as ae } from "../components/embedded-chat/chat-provider.js";
5
- import { useInkeepConfig as ce } from "./config-provider.js";
6
- import { useInkeepApiClient as ue } from "../hooks/use-inkeep-api-client.js";
7
- const B = oe(void 0), z = 25;
8
- function fe(e) {
2
+ import { jsx as se } from "react/jsx-runtime";
3
+ import { createContext as re, useContext as oe, useState as h, useRef as c, useEffect as H, useCallback as S } from "react";
4
+ import { useChat as ie } from "../components/embedded-chat/chat-provider.js";
5
+ import { useInkeepConfig as ae } from "./config-provider.js";
6
+ import { useInkeepApiClient as ce } from "../hooks/use-inkeep-api-client.js";
7
+ const z = re(void 0), q = 25;
8
+ function ue(e) {
9
9
  const {
10
10
  stop: u,
11
11
  clear: f,
12
12
  conversationId: d,
13
- isStreaming: P,
14
- loadAndRestoreSession: x,
15
- sessionToken: s,
16
- refreshSession: J,
17
- getCaptchaHeader: Q,
18
- invalidateCaptcha: V
19
- } = ae(), { aiChatSettings: X, baseSettings: Y } = ce(), { baseUrl: w, appId: E, apiKey: N } = X, o = !!Y.getAuthToken, i = !N && !!E && (!!s || o), m = s, { fetchWithAuth: R } = ue({
20
- appId: E,
21
- authToken: m,
22
- getCaptchaHeader: Q,
23
- invalidateCaptcha: V,
24
- refreshSession: J
25
- }), [A, k] = h(!1), [T, $] = h([]), [b, L] = h(!1), [M, j] = h(0), [I, D] = h(!1), p = c(!1), F = c(null), O = c(o), W = c(s);
26
- y(() => {
27
- const n = O.current, t = W.current;
28
- O.current = o, W.current = s, (n !== o || t !== null && s !== null && t !== s) && ($([]), j(0), D(!1), p.current = !1);
29
- }, [o, s]);
30
- const G = c([]);
31
- G.current = T;
32
- const K = c(R);
33
- K.current = R;
13
+ isStreaming: y,
14
+ loadAndRestoreSession: P,
15
+ authToken: t,
16
+ refreshSession: B,
17
+ getCaptchaHeader: J,
18
+ invalidateCaptcha: Q
19
+ } = ie(), { aiChatSettings: V, baseSettings: X } = ae(), { baseUrl: w, appId: x, apiKey: Y } = V, i = !!X.getAuthToken, r = !Y && !!x && (!!t || i), { fetchWithAuth: E } = ce({
20
+ appId: x,
21
+ authToken: t,
22
+ getCaptchaHeader: J,
23
+ invalidateCaptcha: Q,
24
+ refreshSession: B
25
+ }), [m, A] = h(!1), [R, T] = h([]), [b, $] = h(!t && r), [L, M] = h(0), [k, j] = h(!1), p = c(!1), D = c(null), F = c(i), O = c(t);
26
+ H(() => {
27
+ const s = F.current, n = O.current;
28
+ F.current = i, O.current = t, (s !== i || n !== null && t !== null && n !== t) && (T([]), M(0), j(!1), p.current = !1);
29
+ }, [i, t]);
30
+ const W = c([]);
31
+ W.current = R;
32
+ const G = c(E);
33
+ G.current = E;
34
34
  const a = S(
35
- async (n, t = !1) => {
36
- if (!(!w || !m || !i)) {
37
- t || L(!0);
35
+ async (s, n = !1) => {
36
+ if (!(!w || !t || !r)) {
37
+ n || $(!0);
38
38
  try {
39
- const C = `${w}/run/v1/conversations?page=${n + 1}&limit=${z}`, g = await K.current(C);
39
+ const C = `${w}/run/v1/conversations?page=${s + 1}&limit=${q}`, g = await G.current(C);
40
40
  if (!g.ok) throw new Error(`Failed to fetch conversations: ${g.status}`);
41
- const Z = await g.json(), v = (Z.data ?? []).map((r) => ({
42
- id: r.id,
43
- title: r.title ?? "",
44
- createdAt: new Date(r.createdAt),
45
- updatedAt: new Date(r.updatedAt)
41
+ const U = await g.json(), v = (U.data ?? []).map((o) => ({
42
+ id: o.id,
43
+ title: o.title ?? "",
44
+ createdAt: new Date(o.createdAt),
45
+ updatedAt: new Date(o.updatedAt)
46
46
  }));
47
- $((r) => {
48
- if (n === 0 && !t) return v;
49
- if (n === 0 && t) {
50
- const l = new Set(v.map((H) => H.id));
51
- return [...v, ...r.slice(z).filter((H) => !l.has(H.id))];
47
+ T((o) => {
48
+ if (s === 0 && !n) return v;
49
+ if (s === 0 && n) {
50
+ const l = new Set(v.map((I) => I.id));
51
+ return [...v, ...o.slice(q).filter((I) => !l.has(I.id))];
52
52
  }
53
- const se = new Set(r.map((l) => l.id));
54
- return [...r, ...v.filter((l) => !se.has(l.id))];
53
+ const ne = new Set(o.map((l) => l.id));
54
+ return [...o, ...v.filter((l) => !ne.has(l.id))];
55
55
  });
56
- const { page: _, pages: q } = Z.pagination ?? {};
57
- D(_ != null && q != null ? _ < q : !1), t || j(n);
56
+ const { page: Z, pages: _ } = U.pagination ?? {};
57
+ j(Z != null && _ != null ? Z < _ : !1), n || M(s);
58
58
  } catch (C) {
59
59
  console.error("[useChatHistory] Failed to load conversations:", C);
60
60
  } finally {
61
- L(!1);
61
+ $(!1);
62
62
  }
63
63
  }
64
64
  },
65
- [w, m, i]
65
+ [w, t, r]
66
66
  );
67
- y(() => {
68
- !A || !s && !o || !i || (e === "stack" ? a(0) : p.current || (p.current = !0, a(0)));
69
- }, [A, s, o, i, e, a]);
70
- const U = c("");
71
- y(() => {
72
- i && e === "sidepane" && (!d || !P || p.current && U.current !== d && (G.current.some((n) => n.id === d) || (U.current = d, a(0, !0))));
73
- }, [d, i, e, a, P]);
74
- const ee = S(() => {
75
- !b && I && a(M + 1);
76
- }, [b, I, M, a]), te = S(() => {
77
- u(), f(), e !== "sidepane" && k(!1);
78
- }, [e, u, f]), ne = S(
79
- async (n) => {
80
- F.current?.abort();
81
- const t = new AbortController();
82
- F.current = t, await x(n, t.signal), !t.signal.aborted && e !== "sidepane" && k(!1);
67
+ H(() => {
68
+ !m || !t && !i || !r || (e === "stack" ? a(0) : !p.current && t && (p.current = !0, a(0)));
69
+ }, [m, t, i, r, e, a]);
70
+ const K = c("");
71
+ H(() => {
72
+ r && e === "sidepane" && (!d || !y || p.current && K.current !== d && (W.current.some((s) => s.id === d) || (K.current = d, a(0, !0))));
73
+ }, [d, r, e, a, y]);
74
+ const N = S(() => {
75
+ !b && k && a(L + 1);
76
+ }, [b, k, L, a]), ee = S(() => {
77
+ u(), f(), e !== "sidepane" && A(!1);
78
+ }, [e, u, f]), te = S(
79
+ async (s) => {
80
+ D.current?.abort();
81
+ const n = new AbortController();
82
+ D.current = n, await P(s, n.signal), !n.signal.aborted && e !== "sidepane" && A(!1);
83
83
  },
84
- [e, x]
84
+ [e, P]
85
85
  );
86
86
  return {
87
- isEnabled: i,
88
- isOpen: A,
89
- setIsOpen: k,
90
- sessions: T,
87
+ isEnabled: r,
88
+ isOpen: m,
89
+ setIsOpen: A,
90
+ sessions: R,
91
91
  isLoading: b,
92
- hasMore: I,
93
- loadMore: ee,
94
- startNewConversation: te,
95
- loadSession: ne
92
+ hasMore: k,
93
+ loadMore: N,
94
+ startNewConversation: ee,
95
+ loadSession: te
96
96
  };
97
97
  }
98
- const ve = ({ layout: e, children: u }) => {
99
- const f = fe(e);
100
- return /* @__PURE__ */ re(B.Provider, { value: f, children: typeof u == "function" ? u(f) : u });
101
- }, Se = () => {
102
- const e = ie(B);
98
+ const ge = ({ layout: e, children: u }) => {
99
+ const f = ue(e);
100
+ return /* @__PURE__ */ se(z.Provider, { value: f, children: typeof u == "function" ? u(f) : u });
101
+ }, ve = () => {
102
+ const e = oe(z);
103
103
  if (!e)
104
104
  throw new Error("useChatHistory must be used within a ChatHistoryProvider");
105
105
  return e;
106
106
  };
107
107
  export {
108
- ve as ChatHistoryProvider,
109
- Se as useChatHistory
108
+ ge as ChatHistoryProvider,
109
+ ve as useChatHistory
110
110
  };
@@ -2,6 +2,7 @@ import { AIChatFormSettings } from './settings/form';
2
2
  import { GetHelpOption, CustomMessageAction } from './settings/actions';
3
3
  import { SearchAndChatFilters } from './filters';
4
4
  import { ComponentsConfig } from './components';
5
+ import { FileUIPart } from 'ai';
5
6
  export interface InkeepAIChatSettings {
6
7
  /**
7
8
  * Headers for requests
@@ -30,6 +31,13 @@ export interface InkeepAIChatSettings {
30
31
  * Context to be passed to the chatstream API.
31
32
  */
32
33
  context?: Record<string, unknown>;
34
+ /**
35
+ * Files to be passed to the chatstream API.
36
+ * Attached to the next outgoing message. Re-queued whenever the array content changes (diffed by filename, mediaType, and size), so new or updated files are sent on the next message. Already-sent files are not re-attached unless the content changes.
37
+ *
38
+ * @beta This type is subject to change.
39
+ */
40
+ files?: FileUIPart[];
33
41
  /**
34
42
  * The placeholder text to display in the chat input field when empty.
35
43
  * Use this to provide guidance on what kind of questions users can ask.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-ui",
3
- "version": "0.15.22",
3
+ "version": "0.15.24",
4
4
  "description": "",
5
5
  "homepage": "",
6
6
  "repository": {