@inkeep/agents-ui 0.0.0-dev-20260513170019 → 0.0.0-dev-20260513213554
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 -199
- package/dist/primitives/hooks/use-events-api.cjs +1 -1
- package/dist/primitives/hooks/use-events-api.d.ts +1 -3
- package/dist/primitives/hooks/use-events-api.js +29 -30
- package/dist/primitives/hooks/use-feedback-api.cjs +1 -1
- package/dist/primitives/hooks/use-feedback-api.d.ts +1 -3
- package/dist/primitives/hooks/use-feedback-api.js +26 -27
- 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 +33 -33
- package/dist/primitives/providers/feedback-provider.cjs +1 -1
- package/dist/primitives/providers/feedback-provider.js +18 -19
- 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"),T=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:R}=et.useInkeepConfig(),[c="",m]=ct.useControllableState({prop:R.conversationIdOverride,defaultProp:R.conversationIdOverride??""}),{logEvent:h}=at.useBaseEvents(),{setConversationId:ke,emitToParent:k}=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[E,S]=t.useState(""),Fe=e=>S(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:F,invalidateCaptcha:d,effectiveAuthToken:le,applicableRefreshSession:Pe}=tt.useChatAuth(),{onInputMessageChange:xe,filters:de,baseUrl:pe,agentUrl:qe,context:fe,headers:ge,appId:_,apiKey:U,files:C}=R,he=t.useRef(F);he.current=F;const me=qe||`${pe}/run/api/chat`,{loadConversation:ve}=rt.useConversationLoader({baseUrl:pe,appId:_,authToken:le,getCaptchaHeader:F,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),I=t.useRef(void 0),Ne=C?.map(e=>`${e.filename??""}:${e.mediaType}:${e.url.length}:${e.url.slice(0,64)}:${e.url.slice(-32)}`).join(`
|
|
2
|
+
`)??"";t.useEffect(()=>{I.current=C?.length?C: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}},[P,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",..._?{"x-inkeep-app-id":_}:{},...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,_,U]),{messages:A,sendMessage:V,addToolApprovalResponse:J,status:Ee,setMessages:f,stop:x,error:q}=Ze.useChat({transport:Ue,onData(e){k(e.type,e.data)},async onFinish({message:e}){k("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?[{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:T.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:A.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&&S(n),X.current=e;return}f(n=>{const r=[...n],i=r[r.length-1];return i&&(i.role==="user"?r.push({id:T.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(),b(null),f([]),m(""),S(""),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=[...A??[]].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)},[A,Q]),[$e,W]=t.useState(!1),Ie=Q||De&&!$e,Ae=Ce||Ie,Be=A.length===0,Z=!E.trim()&&P.length===0||Ae,Ge=st.useMediaQuery("(max-width: 768px)"),[He,b]=t.useState(null),X=t.useRef(null);t.useEffect(()=>{if(q){if(X.current===q){X.current=null;return}b(q)}},[q]);const Ke=()=>b(null),{inputNotification:ze,showInputNotification:Y,clearInputNotification:je}=lt.useInputNotification(),be=t.useRef(null);t.useEffect(()=>{xe?.(E)},[E]);const Ve=e=>{e.key==="Enter"&&!e.shiftKey&&!Z&&!e.nativeEvent.isComposing&&(e.preventDefault(),ee())},ee=async(e=E)=>{if(Z&&(!e||e.trim().length===0)&&P.length===0)return;const a=P;j([]),S(""),y.current=0,K.current=null,W(!1);let s=c;s||(s=`conv_${T.generateUid(16)}`,m(s));const u=T.generateUid(21);ke(s),await h({eventName:"user_message_submitted",properties:{conversationId:s,messageId:u}});const n=I.current;I.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 M=new FileReader;M.onload=()=>{if(typeof M.result!="string"){Te(new Error(`Failed to read file "${g.name}"`));return}L({type:"file",url:M.result,mediaType:g.type,filename:g.name})},M.onerror=()=>Te(new Error(`Failed to read file "${g.name}"`)),M.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(()=>{k("aborted",{conversationId:c})})},[x,c,k]),we=()=>{Ke(),f([]),m(""),d(),I.current=C?.length?C:void 0,h({eventName:"chat_clear_button_clicked",properties:{conversationId:c}})},w=t.useCallback((e,a)=>{b(null),f(a),m(e),d(),I.current=void 0},[f,m,d]),Me=t.useCallback(async(e,a)=>{te(),w(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:T.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 w(e,n),!0}finally{a?.aborted||ye(!1)}},[w,ve,te]);nt.useInitialConversation({conversationId:R.conversationId,effectiveAuthToken:le,loadAndRestoreSession:Me,onLoadFailed:()=>w("",[])});const{openForm:Qe}=ot.useChatForm(),We=it.useWidget();return t.useImperativeHandle(R.chatFunctionsRef,()=>({submitMessage:ee,updateInputMessage(e){S(e)},clearChat:we,openForm:e=>{We?.setView("chat"),Qe(e,void 0)},focusInput:()=>{be.current?.focus()}})),{messages:A,sendMessage:V,addToolApprovalResponse:Je,isLoading:Ce,isStreaming:Ie,isBusy:Ae,error:He,setError:b,isSubmitDisabled:Z,input:E,handleInputChange:Fe,handleInputKeyDown:Ve,handleSubmit:ee,stop:te,clear:we,inputRef:be,isMobile:Ge,files:P,setFiles:j,isNewChat:Be,conversationId:c,restoreSession:w,loadAndRestoreSession:Me,isSessionLoading:Le,authToken:v?ae:ce,refreshSession:v?ie:ue,getCaptchaHeader:F,invalidateCaptcha:d,inputNotification:ze,showInputNotification:Y,clearInputNotification:je}};exports.useInkeepChat=dt;
|
|
@@ -1,53 +1,53 @@
|
|
|
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 T, useState as M, 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 k } 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: y } = at(), [c = "", g] = mt({
|
|
21
|
+
prop: y.conversationIdOverride,
|
|
22
|
+
defaultProp: y.conversationIdOverride ?? ""
|
|
23
|
+
}), { logEvent: m } = pt(), { setConversationId: Pe, emitToParent: F } = gt(), ae = i(c);
|
|
24
|
+
T(() => {
|
|
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 [I, C] = M(""), Oe = (e) => C(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: x,
|
|
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,
|
|
@@ -56,56 +56,56 @@ const $t = () => {
|
|
|
56
56
|
headers: ve,
|
|
57
57
|
appId: _,
|
|
58
58
|
apiKey: U,
|
|
59
|
-
files:
|
|
60
|
-
} =
|
|
61
|
-
ye.current =
|
|
62
|
-
const
|
|
59
|
+
files: R
|
|
60
|
+
} = y, ye = i(x);
|
|
61
|
+
ye.current = x;
|
|
62
|
+
const Ie = Be || `${ge}/run/api/chat`, { loadConversation: Ce } = lt({
|
|
63
63
|
baseUrl: ge,
|
|
64
64
|
appId: _,
|
|
65
65
|
authToken: fe,
|
|
66
|
-
getCaptchaHeader:
|
|
66
|
+
getCaptchaHeader: x,
|
|
67
67
|
invalidateCaptcha: p,
|
|
68
68
|
refreshSession: Le
|
|
69
|
-
}), [Ue, Re] = M(!1), z =
|
|
69
|
+
}), [Ue, Re] = M(!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), S = i(void 0), ze = R?.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
|
+
T(() => {
|
|
82
|
+
S.current = R?.length ? R : 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
|
+
}, [N, J] = M([]), Ke = _e(
|
|
107
|
+
() => new nt({
|
|
108
|
+
api: Ie,
|
|
109
109
|
headers: () => {
|
|
110
110
|
const e = U ?? H.current ?? z.current;
|
|
111
111
|
return {
|
|
@@ -119,7 +119,7 @@ const $t = () => {
|
|
|
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, _, U]
|
|
146
146
|
), {
|
|
147
|
-
messages:
|
|
147
|
+
messages: w,
|
|
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
|
+
F(e.type, e.data);
|
|
158
158
|
},
|
|
159
159
|
async onFinish({ message: e }) {
|
|
160
|
-
|
|
160
|
+
F("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,147 @@ 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 ? [{ 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: k(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: w.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 && C(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: k(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
|
+
T(() => {
|
|
247
253
|
const e = Ae.current;
|
|
248
|
-
Ae.current =
|
|
249
|
-
}, [
|
|
254
|
+
Ae.current = h, e !== h && (P(), A(null), d([]), g(""), C(""), 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 = [...w ?? []].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
|
+
}, [w, Z]), [je, X] = M(!1), Ee = Z || qe && !je, Te = be || Ee, Ge = w.length === 0, Y = !I.trim() && N.length === 0 || Te, Ve = ct("(max-width: 768px)"), [Je, A] = M(null), ee = i(null);
|
|
266
|
+
T(() => {
|
|
267
|
+
if (O) {
|
|
268
|
+
if (ee.current === O) {
|
|
263
269
|
ee.current = null;
|
|
264
270
|
return;
|
|
265
271
|
}
|
|
266
|
-
|
|
272
|
+
A(O);
|
|
267
273
|
}
|
|
268
|
-
}, [
|
|
269
|
-
const We = () =>
|
|
270
|
-
|
|
271
|
-
$e?.(
|
|
272
|
-
}, [
|
|
274
|
+
}, [O]);
|
|
275
|
+
const We = () => A(null), { inputNotification: Qe, showInputNotification: te, clearInputNotification: Ze } = ht(), Me = i(null);
|
|
276
|
+
T(() => {
|
|
277
|
+
$e?.(I);
|
|
278
|
+
}, [I]);
|
|
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
|
-
const
|
|
278
|
-
J([]), C(""),
|
|
281
|
+
}, se = async (e = I) => {
|
|
282
|
+
if (Y && (!e || e.trim().length === 0) && N.length === 0) return;
|
|
283
|
+
const n = N;
|
|
284
|
+
J([]), C(""), v.current = 0, G.current = null, X(!1);
|
|
279
285
|
let t = c;
|
|
280
|
-
t || (t = `conv_${
|
|
286
|
+
t || (t = `conv_${k(16)}`, g(t));
|
|
287
|
+
const l = k(21);
|
|
288
|
+
Pe(t), await m({
|
|
281
289
|
eventName: "user_message_submitted",
|
|
282
290
|
properties: {
|
|
283
|
-
conversationId: t
|
|
291
|
+
conversationId: t,
|
|
292
|
+
messageId: l
|
|
284
293
|
}
|
|
285
294
|
});
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
let
|
|
289
|
-
if (
|
|
290
|
-
let o;
|
|
295
|
+
const r = S.current;
|
|
296
|
+
S.current = void 0;
|
|
297
|
+
let s = [];
|
|
298
|
+
if (n.length > 0)
|
|
291
299
|
try {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
const
|
|
295
|
-
return new Promise((
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
if (typeof
|
|
299
|
-
|
|
300
|
+
s = await Promise.all(
|
|
301
|
+
n.map((o) => {
|
|
302
|
+
const f = rt(o);
|
|
303
|
+
return new Promise((D, xe) => {
|
|
304
|
+
const E = new FileReader();
|
|
305
|
+
E.onload = () => {
|
|
306
|
+
if (typeof E.result != "string") {
|
|
307
|
+
xe(new Error(`Failed to read file "${f.name}"`));
|
|
300
308
|
return;
|
|
301
309
|
}
|
|
302
|
-
|
|
310
|
+
D({
|
|
303
311
|
type: "file",
|
|
304
|
-
url:
|
|
305
|
-
mediaType:
|
|
306
|
-
filename:
|
|
312
|
+
url: E.result,
|
|
313
|
+
mediaType: f.type,
|
|
314
|
+
filename: f.name
|
|
307
315
|
});
|
|
308
|
-
},
|
|
316
|
+
}, E.onerror = () => xe(new Error(`Failed to read file "${f.name}"`)), E.readAsDataURL(f);
|
|
309
317
|
});
|
|
310
318
|
})
|
|
311
319
|
);
|
|
@@ -316,52 +324,50 @@ const $t = () => {
|
|
|
316
324
|
});
|
|
317
325
|
return;
|
|
318
326
|
}
|
|
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 };
|
|
327
|
+
const a = s.length || r?.length ? [...s, ...r ?? []] : void 0, u = [
|
|
328
|
+
...e.trim() ? [{ type: "text", text: e }] : [],
|
|
329
|
+
...a ?? []
|
|
330
|
+
];
|
|
327
331
|
j.current = {
|
|
328
332
|
content: e,
|
|
333
|
+
messageId: l,
|
|
329
334
|
body: { conversationId: t },
|
|
330
|
-
files:
|
|
331
|
-
}, W(
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
+
files: a
|
|
336
|
+
}, W(
|
|
337
|
+
{ id: l, parts: u },
|
|
338
|
+
{ body: { conversationId: t } }
|
|
339
|
+
);
|
|
340
|
+
}, Ye = L(
|
|
335
341
|
(e) => {
|
|
336
|
-
|
|
342
|
+
v.current = 0, G.current = e, X(!1), Q(e);
|
|
337
343
|
},
|
|
338
344
|
[Q]
|
|
339
|
-
), re =
|
|
340
|
-
X(!0),
|
|
341
|
-
|
|
345
|
+
), re = L(() => {
|
|
346
|
+
X(!0), P().then(() => {
|
|
347
|
+
F("aborted", { conversationId: c });
|
|
342
348
|
});
|
|
343
|
-
}, [
|
|
344
|
-
We(), d([]),
|
|
349
|
+
}, [P, c, F]), ke = () => {
|
|
350
|
+
We(), d([]), g(""), p(), S.current = R?.length ? R : void 0, m({
|
|
345
351
|
eventName: "chat_clear_button_clicked",
|
|
346
352
|
properties: {
|
|
347
353
|
conversationId: c
|
|
348
354
|
}
|
|
349
355
|
});
|
|
350
|
-
},
|
|
351
|
-
(e,
|
|
352
|
-
|
|
356
|
+
}, b = L(
|
|
357
|
+
(e, n) => {
|
|
358
|
+
A(null), d(n), g(e), p(), S.current = void 0;
|
|
353
359
|
},
|
|
354
|
-
[d,
|
|
355
|
-
),
|
|
356
|
-
async (e,
|
|
357
|
-
re(),
|
|
360
|
+
[d, g, p]
|
|
361
|
+
), Fe = L(
|
|
362
|
+
async (e, n) => {
|
|
363
|
+
re(), b(e, []), Re(!0);
|
|
358
364
|
try {
|
|
359
|
-
const t = await
|
|
365
|
+
const t = await Ce(e, n);
|
|
360
366
|
if (t === null) return !1;
|
|
361
|
-
const
|
|
367
|
+
const r = t[t.length - 1]?.role === "user" ? [
|
|
362
368
|
...t,
|
|
363
369
|
{
|
|
364
|
-
id:
|
|
370
|
+
id: k(16),
|
|
365
371
|
role: "assistant",
|
|
366
372
|
parts: [
|
|
367
373
|
{
|
|
@@ -371,60 +377,60 @@ const $t = () => {
|
|
|
371
377
|
]
|
|
372
378
|
}
|
|
373
379
|
] : t;
|
|
374
|
-
return
|
|
380
|
+
return b(e, r), !0;
|
|
375
381
|
} finally {
|
|
376
|
-
|
|
382
|
+
n?.aborted || Re(!1);
|
|
377
383
|
}
|
|
378
384
|
},
|
|
379
|
-
[
|
|
385
|
+
[b, Ce, re]
|
|
380
386
|
);
|
|
381
|
-
|
|
382
|
-
conversationId:
|
|
387
|
+
ut({
|
|
388
|
+
conversationId: y.conversationId,
|
|
383
389
|
effectiveAuthToken: fe,
|
|
384
|
-
loadAndRestoreSession:
|
|
385
|
-
onLoadFailed: () =>
|
|
390
|
+
loadAndRestoreSession: Fe,
|
|
391
|
+
onLoadFailed: () => b("", [])
|
|
386
392
|
});
|
|
387
|
-
const { openForm: et } =
|
|
388
|
-
return
|
|
393
|
+
const { openForm: et } = dt(), tt = ft();
|
|
394
|
+
return ot(y.chatFunctionsRef, () => ({
|
|
389
395
|
submitMessage: se,
|
|
390
396
|
updateInputMessage(e) {
|
|
391
397
|
C(e);
|
|
392
398
|
},
|
|
393
|
-
clearChat:
|
|
399
|
+
clearChat: ke,
|
|
394
400
|
openForm: (e) => {
|
|
395
401
|
tt?.setView("chat"), et(e, void 0);
|
|
396
402
|
},
|
|
397
403
|
focusInput: () => {
|
|
398
|
-
|
|
404
|
+
Me.current?.focus();
|
|
399
405
|
}
|
|
400
406
|
})), {
|
|
401
|
-
messages:
|
|
407
|
+
messages: w,
|
|
402
408
|
sendMessage: W,
|
|
403
409
|
addToolApprovalResponse: Ye,
|
|
404
410
|
isLoading: be,
|
|
405
411
|
isStreaming: Ee,
|
|
406
412
|
isBusy: Te,
|
|
407
413
|
error: Je,
|
|
408
|
-
setError:
|
|
414
|
+
setError: A,
|
|
409
415
|
isSubmitDisabled: Y,
|
|
410
|
-
input:
|
|
411
|
-
handleInputChange:
|
|
416
|
+
input: I,
|
|
417
|
+
handleInputChange: Oe,
|
|
412
418
|
handleInputKeyDown: Xe,
|
|
413
419
|
handleSubmit: se,
|
|
414
420
|
stop: re,
|
|
415
|
-
clear:
|
|
416
|
-
inputRef:
|
|
421
|
+
clear: ke,
|
|
422
|
+
inputRef: Me,
|
|
417
423
|
isMobile: Ve,
|
|
418
|
-
files:
|
|
424
|
+
files: N,
|
|
419
425
|
setFiles: J,
|
|
420
426
|
isNewChat: Ge,
|
|
421
427
|
conversationId: c,
|
|
422
|
-
restoreSession:
|
|
423
|
-
loadAndRestoreSession:
|
|
428
|
+
restoreSession: b,
|
|
429
|
+
loadAndRestoreSession: Fe,
|
|
424
430
|
isSessionLoading: Ue,
|
|
425
|
-
authToken:
|
|
426
|
-
refreshSession:
|
|
427
|
-
getCaptchaHeader:
|
|
431
|
+
authToken: h ? ce : pe,
|
|
432
|
+
refreshSession: h ? ue : de,
|
|
433
|
+
getCaptchaHeader: x,
|
|
428
434
|
invalidateCaptcha: p,
|
|
429
435
|
inputNotification: Qe,
|
|
430
436
|
showInputNotification: te,
|
|
@@ -432,5 +438,5 @@ const $t = () => {
|
|
|
432
438
|
};
|
|
433
439
|
};
|
|
434
440
|
export {
|
|
435
|
-
|
|
441
|
+
Bt as useInkeepChat
|
|
436
442
|
};
|
|
@@ -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;
|
|
@@ -5,8 +5,6 @@ interface UseEventsApiOptions {
|
|
|
5
5
|
getCaptchaHeader: () => Promise<Record<string, string>>;
|
|
6
6
|
invalidateCaptcha?: () => void;
|
|
7
7
|
refreshSession?: () => Promise<string | null>;
|
|
8
|
-
/** Consumer-provided headers from `aiChatSettings.headers`. */
|
|
9
|
-
headers?: Record<string, string>;
|
|
10
8
|
}
|
|
11
9
|
/**
|
|
12
10
|
* Mirrors the backend's `EventApiInsertSchema` for /run/v1/events.
|
|
@@ -25,7 +23,7 @@ interface LogEventBody {
|
|
|
25
23
|
interface LogEventParams {
|
|
26
24
|
body: LogEventBody;
|
|
27
25
|
}
|
|
28
|
-
export declare function useEventsApi({ baseUrl, appId, authToken, getCaptchaHeader, invalidateCaptcha, refreshSession,
|
|
26
|
+
export declare function useEventsApi({ baseUrl, appId, authToken, getCaptchaHeader, invalidateCaptcha, refreshSession, }: UseEventsApiOptions): {
|
|
29
27
|
logEvent: ({ body }: LogEventParams) => Promise<void>;
|
|
30
28
|
};
|
|
31
29
|
export {};
|
|
@@ -1,44 +1,43 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
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:
|
|
11
|
-
invalidateCaptcha:
|
|
12
|
-
refreshSession:
|
|
13
|
-
headers: o
|
|
8
|
+
appId: a,
|
|
9
|
+
authToken: e,
|
|
10
|
+
getCaptchaHeader: s,
|
|
11
|
+
invalidateCaptcha: c,
|
|
12
|
+
refreshSession: r
|
|
14
13
|
}) {
|
|
15
|
-
const { fetchWithAuth:
|
|
16
|
-
appId:
|
|
17
|
-
authToken:
|
|
18
|
-
getCaptchaHeader:
|
|
19
|
-
invalidateCaptcha:
|
|
20
|
-
refreshSession:
|
|
21
|
-
})
|
|
22
|
-
return
|
|
23
|
-
async ({ body:
|
|
24
|
-
if (t)
|
|
14
|
+
const { fetchWithAuth: i } = f({
|
|
15
|
+
appId: a,
|
|
16
|
+
authToken: e,
|
|
17
|
+
getCaptchaHeader: s,
|
|
18
|
+
invalidateCaptcha: c ?? v,
|
|
19
|
+
refreshSession: r
|
|
20
|
+
});
|
|
21
|
+
return { logEvent: u(
|
|
22
|
+
async ({ body: l }) => {
|
|
23
|
+
if (!(!t || !e))
|
|
25
24
|
try {
|
|
26
|
-
const
|
|
25
|
+
const n = `${t}/run/v1/events`, o = await i(n, {
|
|
27
26
|
method: "POST",
|
|
28
|
-
headers: { "Content-Type": "application/json"
|
|
29
|
-
body: JSON.stringify(
|
|
27
|
+
headers: { "Content-Type": "application/json" },
|
|
28
|
+
body: JSON.stringify(l)
|
|
30
29
|
});
|
|
31
|
-
if (!
|
|
32
|
-
const
|
|
33
|
-
console.warn(`[events-api] log failed: ${
|
|
30
|
+
if (!o.ok) {
|
|
31
|
+
const p = await o.text().catch(() => "<unreadable>");
|
|
32
|
+
console.warn(`[events-api] log failed: ${o.status}`, p);
|
|
34
33
|
}
|
|
35
|
-
} catch (
|
|
36
|
-
console.warn("[events-api] log threw",
|
|
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 l=require("react"),f=require("./use-inkeep-api-client.cjs"),k=()=>{};function y({baseUrl:e,appId:s,authToken:t,getCaptchaHeader:c,invalidateCaptcha:o,refreshSession:r}){const{fetchWithAuth:i}=f.useInkeepApiClient({appId:s,authToken:t,getCaptchaHeader:c,invalidateCaptcha:o??k,refreshSession:r});return{submitFeedback:l.useCallback(async({conversationId:u,messageId:a,type:d,details:p})=>{if(!e||!t)return;const b=`${e}/run/v1/feedback`,n=await i(b,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({conversationId:u,messageId:a,type:d,details:p})});if(!n.ok)throw new Error(`Feedback submission failed: ${n.status}`);return n.json()},[e,t,i])}}exports.useFeedbackApi=y;
|
|
@@ -6,8 +6,6 @@ interface UseFeedbackApiOptions {
|
|
|
6
6
|
getCaptchaHeader: () => Promise<Record<string, string>>;
|
|
7
7
|
invalidateCaptcha?: () => void;
|
|
8
8
|
refreshSession?: () => Promise<string | null>;
|
|
9
|
-
/** Consumer-provided headers from `aiChatSettings.headers`. */
|
|
10
|
-
headers?: Record<string, string>;
|
|
11
9
|
}
|
|
12
10
|
interface SubmitFeedbackParams {
|
|
13
11
|
conversationId: string;
|
|
@@ -15,7 +13,7 @@ interface SubmitFeedbackParams {
|
|
|
15
13
|
type: FeedbackType;
|
|
16
14
|
details?: string | null;
|
|
17
15
|
}
|
|
18
|
-
export declare function useFeedbackApi({ baseUrl, appId, authToken, getCaptchaHeader, invalidateCaptcha, refreshSession,
|
|
16
|
+
export declare function useFeedbackApi({ baseUrl, appId, authToken, getCaptchaHeader, invalidateCaptcha, refreshSession, }: UseFeedbackApiOptions): {
|
|
19
17
|
submitFeedback: ({ conversationId, messageId, type, details }: SubmitFeedbackParams) => Promise<any>;
|
|
20
18
|
};
|
|
21
19
|
export {};
|
|
@@ -1,38 +1,37 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import { useInkeepApiClient as
|
|
4
|
-
const
|
|
2
|
+
import { useCallback as b } from "react";
|
|
3
|
+
import { useInkeepApiClient as m } from "./use-inkeep-api-client.js";
|
|
4
|
+
const k = () => {
|
|
5
5
|
};
|
|
6
|
-
function
|
|
6
|
+
function C({
|
|
7
7
|
baseUrl: e,
|
|
8
|
-
appId:
|
|
9
|
-
authToken:
|
|
10
|
-
getCaptchaHeader:
|
|
11
|
-
invalidateCaptcha:
|
|
12
|
-
refreshSession:
|
|
13
|
-
headers: n
|
|
8
|
+
appId: o,
|
|
9
|
+
authToken: t,
|
|
10
|
+
getCaptchaHeader: s,
|
|
11
|
+
invalidateCaptcha: r,
|
|
12
|
+
refreshSession: c
|
|
14
13
|
}) {
|
|
15
|
-
const { fetchWithAuth:
|
|
16
|
-
appId:
|
|
17
|
-
authToken:
|
|
18
|
-
getCaptchaHeader:
|
|
19
|
-
invalidateCaptcha:
|
|
20
|
-
refreshSession:
|
|
21
|
-
})
|
|
22
|
-
return
|
|
23
|
-
async ({ conversationId:
|
|
24
|
-
if (!e) return;
|
|
25
|
-
const
|
|
14
|
+
const { fetchWithAuth: i } = m({
|
|
15
|
+
appId: o,
|
|
16
|
+
authToken: t,
|
|
17
|
+
getCaptchaHeader: s,
|
|
18
|
+
invalidateCaptcha: r ?? k,
|
|
19
|
+
refreshSession: c
|
|
20
|
+
});
|
|
21
|
+
return { submitFeedback: b(
|
|
22
|
+
async ({ conversationId: a, messageId: u, type: p, details: d }) => {
|
|
23
|
+
if (!e || !t) return;
|
|
24
|
+
const f = `${e}/run/v1/feedback`, n = await i(f, {
|
|
26
25
|
method: "POST",
|
|
27
|
-
headers: { "Content-Type": "application/json"
|
|
28
|
-
body: JSON.stringify({ conversationId:
|
|
26
|
+
headers: { "Content-Type": "application/json" },
|
|
27
|
+
body: JSON.stringify({ conversationId: a, messageId: u, type: p, details: d })
|
|
29
28
|
});
|
|
30
|
-
if (!
|
|
31
|
-
return
|
|
29
|
+
if (!n.ok) throw new Error(`Feedback submission failed: ${n.status}`);
|
|
30
|
+
return n.json();
|
|
32
31
|
},
|
|
33
|
-
[e,
|
|
32
|
+
[e, t, i]
|
|
34
33
|
) };
|
|
35
34
|
}
|
|
36
35
|
export {
|
|
37
|
-
|
|
36
|
+
C as useFeedbackApi
|
|
38
37
|
};
|
|
@@ -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.2",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.2", 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
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("react/jsx-runtime"),g=require("react"),j=require("./config-provider.cjs"),B=require("./chat-auth-provider.cjs"),O=require("../hooks/use-events-api.cjs"),U=require("./base-events-provider.cjs"),x=({children:h})=>{const{baseSettings:n,aiChatSettings:y,componentType:c}=j.useInkeepConfig(),{tags:t,analyticsProperties:r,privacyPreferences:b,userProperties:o}=n,p="0.16.2",a=g.useMemo(()=>({widgetLibraryVersion:p,componentType:c}),[c,p]),{effectiveAuthToken:i,applicableRefreshSession:f,getCaptchaHeader:E,invalidateCaptcha:P}=B.useChatAuth(),{baseUrl:m,appId:A,analyticsApiBaseUrl:C}=y,l=b?.optOutAllAnalytics??!1,{logEvent:v}=O.useEventsApi({baseUrl:C??m,appId:A,authToken:i,getCaptchaHeader:E,invalidateCaptcha:P,refreshSession:f}),I={logEvent:g.useCallback(async s=>{const k={eventName:s.eventName,properties:{...a,...t?{tags:t}:{},...s.properties,...r}};if(!l&&i){const e=s.properties??{},u=typeof e.conversationId=="string"?e.conversationId:void 0,d=typeof e.messageId=="string"?e.messageId:void 0,q=!!o&&Object.keys(o).length>0,S={...t?{tags:t}:{},...r??{}},w={...a,...s.properties};v({body:{type:s.eventName,...u?{conversationId:u}:{},...d?{messageId:d}:{},...q?{userProperties:o}:{},properties:S,metadata:w}})}try{return await n.onEvent?.(k)}catch(e){console.warn("[events] onEvent callback threw",e)}},[n,a,t,r,v,l,i,o])};return T.jsx(U.BaseEventsContext.Provider,{value:I,children:h})};exports.ChatBaseEventsProvider=x;
|
|
@@ -1,73 +1,73 @@
|
|
|
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 T } from "react/jsx-runtime";
|
|
3
|
+
import { useMemo as U, useCallback as x } from "react";
|
|
4
|
+
import { useInkeepConfig as B } from "./config-provider.js";
|
|
5
|
+
import { useChatAuth as N } from "./chat-auth-provider.js";
|
|
6
|
+
import { useEventsApi as O } from "../hooks/use-events-api.js";
|
|
7
|
+
import { BaseEventsContext as j } from "./base-events-provider.js";
|
|
8
|
+
const D = ({ children: g }) => {
|
|
9
|
+
const { baseSettings: n, aiChatSettings: f, componentType: c } = B(), { tags: t, analyticsProperties: r, privacyPreferences: u, userProperties: o } = n, p = "0.16.2", a = U(
|
|
10
10
|
() => ({
|
|
11
|
-
widgetLibraryVersion:
|
|
12
|
-
componentType:
|
|
11
|
+
widgetLibraryVersion: p,
|
|
12
|
+
componentType: c
|
|
13
13
|
}),
|
|
14
|
-
[
|
|
15
|
-
), { effectiveAuthToken:
|
|
14
|
+
[c, p]
|
|
15
|
+
), { effectiveAuthToken: i, applicableRefreshSession: h, getCaptchaHeader: y, invalidateCaptcha: b } = N(), { baseUrl: A, appId: E, analyticsApiBaseUrl: C } = f, l = u?.optOutAllAnalytics ?? !1, { logEvent: v } = O({
|
|
16
16
|
baseUrl: C ?? A,
|
|
17
17
|
appId: E,
|
|
18
|
-
authToken:
|
|
18
|
+
authToken: i,
|
|
19
19
|
getCaptchaHeader: y,
|
|
20
20
|
invalidateCaptcha: b,
|
|
21
|
-
refreshSession:
|
|
22
|
-
|
|
23
|
-
}), P = { logEvent: B(
|
|
21
|
+
refreshSession: h
|
|
22
|
+
}), I = { logEvent: x(
|
|
24
23
|
async (s) => {
|
|
25
|
-
const
|
|
24
|
+
const P = {
|
|
26
25
|
eventName: s.eventName,
|
|
27
26
|
properties: {
|
|
28
27
|
...a,
|
|
29
28
|
...t ? { tags: t } : {},
|
|
30
29
|
...s.properties,
|
|
31
|
-
...
|
|
30
|
+
...r
|
|
32
31
|
}
|
|
33
32
|
};
|
|
34
|
-
if (!
|
|
35
|
-
const e = s.properties ?? {},
|
|
33
|
+
if (!l && i) {
|
|
34
|
+
const e = s.properties ?? {}, m = typeof e.conversationId == "string" ? e.conversationId : void 0, d = typeof e.messageId == "string" ? e.messageId : void 0, k = !!o && Object.keys(o).length > 0, w = {
|
|
36
35
|
...t ? { tags: t } : {},
|
|
37
|
-
...
|
|
38
|
-
},
|
|
36
|
+
...r ?? {}
|
|
37
|
+
}, S = {
|
|
39
38
|
...a,
|
|
40
39
|
...s.properties
|
|
41
40
|
};
|
|
42
|
-
|
|
41
|
+
v({
|
|
43
42
|
body: {
|
|
44
43
|
type: s.eventName,
|
|
45
|
-
...
|
|
44
|
+
...m ? { conversationId: m } : {},
|
|
46
45
|
...d ? { messageId: d } : {},
|
|
47
|
-
...
|
|
48
|
-
properties:
|
|
49
|
-
metadata:
|
|
46
|
+
...k ? { userProperties: o } : {},
|
|
47
|
+
properties: w,
|
|
48
|
+
metadata: S
|
|
50
49
|
}
|
|
51
50
|
});
|
|
52
51
|
}
|
|
53
52
|
try {
|
|
54
|
-
return await
|
|
53
|
+
return await n.onEvent?.(P);
|
|
55
54
|
} catch (e) {
|
|
56
55
|
console.warn("[events] onEvent callback threw", e);
|
|
57
56
|
}
|
|
58
57
|
},
|
|
59
58
|
[
|
|
60
|
-
|
|
59
|
+
n,
|
|
61
60
|
a,
|
|
62
61
|
t,
|
|
63
|
-
|
|
62
|
+
r,
|
|
63
|
+
v,
|
|
64
64
|
l,
|
|
65
|
-
|
|
65
|
+
i,
|
|
66
66
|
o
|
|
67
67
|
]
|
|
68
68
|
) };
|
|
69
|
-
return /* @__PURE__ */
|
|
69
|
+
return /* @__PURE__ */ T(j.Provider, { value: I, children: g });
|
|
70
70
|
};
|
|
71
71
|
export {
|
|
72
|
-
|
|
72
|
+
D as ChatBaseEventsProvider
|
|
73
73
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const M=require("react/jsx-runtime"),a=require("react"),T=require("../components/embedded-chat/chat-provider.cjs"),F=require("../utils/misc.cjs"),A=require("./config-provider.cjs"),E=require("./base-events-provider.cjs"),j=require("../hooks/use-feedback-api.cjs"),l=a.createContext(void 0);function y(){const{baseSettings:t,aiChatSettings:c}=A.useInkeepConfig(),[p,g]=a.useState(null),[f,C]=a.useState({}),{conversationId:o,messages:r,authToken:h,getCaptchaHeader:m,invalidateCaptcha:P,refreshSession:q}=T.useChat(),{analyticsProperties:d}=t,{logEvent:b}=E.useBaseEvents(),{submitFeedback:k}=j.useFeedbackApi({baseUrl:c.baseUrl,appId:c.appId,authToken:h,getCaptchaHeader:m,invalidateCaptcha:P,refreshSession:q
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const M=require("react/jsx-runtime"),a=require("react"),T=require("../components/embedded-chat/chat-provider.cjs"),F=require("../utils/misc.cjs"),A=require("./config-provider.cjs"),E=require("./base-events-provider.cjs"),j=require("../hooks/use-feedback-api.cjs"),l=a.createContext(void 0);function y(){const{baseSettings:t,aiChatSettings:c}=A.useInkeepConfig(),[p,g]=a.useState(null),[f,C]=a.useState({}),{conversationId:o,messages:r,authToken:h,getCaptchaHeader:m,invalidateCaptcha:P,refreshSession:q}=T.useChat(),{analyticsProperties:d}=t,{logEvent:b}=E.useBaseEvents(),{submitFeedback:k}=j.useFeedbackApi({baseUrl:c.baseUrl,appId:c.appId,authToken:h,getCaptchaHeader:m,invalidateCaptcha:P,refreshSession:q}),i=a.useCallback(async(e,s,u)=>{C(n=>({...n,[e]:{type:s,messageId:e,details:u}})),t.onFeedback?t.onFeedback({type:s,messageId:e,details:u,properties:d}).catch(n=>console.warn("[feedback] onFeedback error:",n)):k({conversationId:o,messageId:e,type:s,details:u}).catch(n=>console.warn("[feedback] submitFeedbackToApi error:",n));const v=r.findIndex(n=>n.id===e),x=r[v],S={conversationId:o,question:F.getMessageContent(r[v-1]),answer:F.getMessageContent(x),messageId:e,details:u};b({eventName:s==="positive"?"assistant_positive_feedback_submitted":"assistant_negative_feedback_submitted",properties:S}),s==="negative"&&b({eventName:"user_escalation_indicated",properties:{escalationType:"downvote",conversationId:o,messageId:e}})},[r,o,d,t,b,k]),_=a.useCallback(async e=>{i(e,"positive")},[i]),w=a.useCallback(async(e,s)=>{i(e,"negative",s)},[i]);return{feedback:f,currentFeedback:p,setCurrentFeedback:g,submitPositiveFeedback:_,submitNegativeFeedback:w}}const N=({children:t})=>{const c=y();return M.jsx(l.Provider,{value:c,children:t})},R=()=>{const t=a.useContext(l);if(!t)throw new Error("useFeedback must be used within a FeedbackProvider");return t};exports.FeedbackProvider=N;exports.useMessageFeedback=R;
|
|
@@ -8,9 +8,9 @@ import { useBaseEvents as q } from "./base-events-provider.js";
|
|
|
8
8
|
import { useFeedbackApi as y } from "../hooks/use-feedback-api.js";
|
|
9
9
|
const f = M(void 0);
|
|
10
10
|
function B() {
|
|
11
|
-
const { baseSettings: t, aiChatSettings: n } = j(), [F, l] = m(null), [
|
|
11
|
+
const { baseSettings: t, aiChatSettings: n } = j(), [F, l] = m(null), [C, h] = m({}), {
|
|
12
12
|
conversationId: a,
|
|
13
|
-
messages:
|
|
13
|
+
messages: c,
|
|
14
14
|
authToken: g,
|
|
15
15
|
getCaptchaHeader: _,
|
|
16
16
|
invalidateCaptcha: w,
|
|
@@ -21,24 +21,23 @@ function B() {
|
|
|
21
21
|
authToken: g,
|
|
22
22
|
getCaptchaHeader: _,
|
|
23
23
|
invalidateCaptcha: w,
|
|
24
|
-
refreshSession: x
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
(o) => console.warn("[feedback] submitFeedbackToApi error:", o)
|
|
24
|
+
refreshSession: x
|
|
25
|
+
}), r = d(
|
|
26
|
+
async (e, o, i) => {
|
|
27
|
+
h((s) => ({ ...s, [e]: { type: o, messageId: e, details: i } })), t.onFeedback ? t.onFeedback({ type: o, messageId: e, details: i, properties: u }).catch((s) => console.warn("[feedback] onFeedback error:", s)) : k({ conversationId: a, messageId: e, type: o, details: i }).catch(
|
|
28
|
+
(s) => console.warn("[feedback] submitFeedbackToApi error:", s)
|
|
30
29
|
);
|
|
31
|
-
const p =
|
|
30
|
+
const p = c.findIndex((s) => s.id === e), T = c[p], A = {
|
|
32
31
|
conversationId: a,
|
|
33
|
-
question: v(
|
|
32
|
+
question: v(c[p - 1]),
|
|
34
33
|
answer: v(T),
|
|
35
34
|
messageId: e,
|
|
36
35
|
details: i
|
|
37
36
|
};
|
|
38
37
|
b({
|
|
39
|
-
eventName:
|
|
38
|
+
eventName: o === "positive" ? "assistant_positive_feedback_submitted" : "assistant_negative_feedback_submitted",
|
|
40
39
|
properties: A
|
|
41
|
-
}),
|
|
40
|
+
}), o === "negative" && b({
|
|
42
41
|
eventName: "user_escalation_indicated",
|
|
43
42
|
properties: {
|
|
44
43
|
escalationType: "downvote",
|
|
@@ -47,20 +46,20 @@ function B() {
|
|
|
47
46
|
}
|
|
48
47
|
});
|
|
49
48
|
},
|
|
50
|
-
[
|
|
49
|
+
[c, a, u, t, b, k]
|
|
51
50
|
), P = d(
|
|
52
51
|
async (e) => {
|
|
53
|
-
|
|
52
|
+
r(e, "positive");
|
|
54
53
|
},
|
|
55
|
-
[
|
|
54
|
+
[r]
|
|
56
55
|
), S = d(
|
|
57
|
-
async (e,
|
|
58
|
-
|
|
56
|
+
async (e, o) => {
|
|
57
|
+
r(e, "negative", o);
|
|
59
58
|
},
|
|
60
|
-
[
|
|
59
|
+
[r]
|
|
61
60
|
);
|
|
62
61
|
return {
|
|
63
|
-
feedback:
|
|
62
|
+
feedback: C,
|
|
64
63
|
currentFeedback: F,
|
|
65
64
|
setCurrentFeedback: l,
|
|
66
65
|
submitPositiveFeedback: P,
|
package/dist/types/events.d.ts
CHANGED