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