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