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