@inkeep/agents-ui 0.17.5 → 0.17.6
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 +54 -52
- package/dist/primitives/hooks/use-initial-conversation.cjs +1 -1
- package/dist/primitives/hooks/use-initial-conversation.d.ts +7 -1
- package/dist/primitives/hooks/use-initial-conversation.js +31 -20
- 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/config/ai.d.ts +8 -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"),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"),
|
|
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"),f=require("./chat-error-helpers.cjs"),dt=()=>{const{baseSettings:se,aiChatSettings:m}=et.useInkeepConfig(),[c="",v]=ct.useControllableState({prop:m.conversationIdOverride,defaultProp:m.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,I]=t.useState(""),Fe=e=>I(e.target.value),{shouldBypassCaptcha:_e,filters:ne,userProperties:N,analyticsProperties:O}=se,{authToken:ae,isAuthenticated:y,isAuthConfigured:oe,refreshAuthToken:ie,sessionToken:ce,refreshSession:ue,getCaptchaHeader:_,invalidateCaptcha:d,effectiveAuthToken:le,applicableRefreshSession:Pe}=tt.useChatAuth(),{onInputMessageChange:xe,filters:de,baseUrl:fe,agentUrl:qe,context:pe,headers:ge,appId:P,apiKey:U,files:A}=m,he=t.useRef(_);he.current=_;const me=qe||`${fe}/run/api/chat`,{loadConversation:ve}=rt.useConversationLoader({baseUrl:fe,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 R=t.useRef(0),H=t.useRef(null),K=t.useRef(null),C=t.useRef(void 0),Ne=A?.map(e=>`${e.filename??""}:${e.mediaType}:${e.url.length}:${e.url.slice(0,64)}:${e.url.slice(-32)}`).join(`
|
|
2
|
+
`)??"";t.useEffect(()=>{C.current=A?.length?A: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(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}},[b,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:pe}}),[me,pe,P,U]),{messages:w,sendMessage:V,addToolApprovalResponse:J,status:Ce,setMessages:p,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:f.resolveStreamingAuthError(e);if(a!==null&&R.current<1){R.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&&(p(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(()=>{R.current=0,d(),p(l=>{const o=[...l],g=o[o.length-1];if(!g)return o;const L=f.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}R.current=0,a!==null&&d();const s=f.isRecoverableError(e),u=Oe(e);if(h({eventName:"chat_error",properties:{conversationId:c,messageId:w.at(-1)?.id,error:e.message}}),s){Y({title:"Request failed",message:u},f.RECOVERABLE_NOTIFICATION_DURATION_MS),p(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&&I(n),X.current=e;return}p(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})}}),Ee=t.useRef(y);t.useEffect(()=>{const e=Ee.current;Ee.current=y,e!==y&&(x(),M(null),p([]),v(""),I(""),j([]),d())},[y,x,p,v,d]);const Se=Ce==="submitted",Q=Ce==="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=[...w??[]].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)},[w,Q]),[$e,W]=t.useState(!1),Ie=Q||De&&!$e,Ae=Se||Ie,Be=w.length===0,Z=!S.trim()&&b.length===0||Ae,Ge=st.useMediaQuery("(max-width: 768px)"),[He,M]=t.useState(null),X=t.useRef(null);t.useEffect(()=>{if(q){if(X.current===q){X.current=null;return}M(q)}},[q]);const Ke=()=>M(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)&&b.length===0||!e.trim()&&!b.length&&!C.current?.length)return;const a=b;j([]),I(""),R.current=0,K.current=null,W(!1);let s=c;s||(s=`conv_${k.generateUid(16)}`,v(s));const u=k.generateUid(21);ke(s),await h({eventName:"user_message_submitted",properties:{conversationId:s,messageId:u}});const n=C.current;C.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=>{R.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(),p([]),v(""),d(),C.current=A?.length?A:void 0,h({eventName:"chat_clear_button_clicked",properties:{conversationId:c}})},E=t.useCallback((e,a)=>{M(null),p(a),v(e),d(),C.current=void 0},[p,v,d]),Me=t.useCallback(async(e,a)=>{te(),E(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 E(e,n),!0}finally{a?.aborted||ye(!1)}},[E,ve,te]);nt.useInitialConversation({conversationId:m.conversationId,fetchedConversation:m.fetchedConversation,effectiveAuthToken:le,restoreSession:E,loadAndRestoreSession:Me,onLoadFailed:()=>E("",[])});const{openForm:Qe}=ot.useChatForm(),We=it.useWidget();return t.useImperativeHandle(m.chatFunctionsRef,()=>({submitMessage:ee,updateInputMessage(e){I(e)},clearChat:we,openForm:e=>{We?.setView("chat"),Qe(e,void 0)},focusInput:()=>{be.current?.focus()}})),{messages:w,sendMessage:V,addToolApprovalResponse:Je,isLoading:Se,isStreaming:Ie,isBusy:Ae,error:He,setError:M,isSubmitDisabled:Z,input:S,handleInputChange:Fe,handleInputKeyDown:Ve,handleSubmit:ee,stop:te,clear:we,inputRef:be,isMobile:Ge,files:b,setFiles:j,isNewChat:Be,conversationId:c,restoreSession:E,loadAndRestoreSession:Me,isSessionLoading:Le,authToken:y?ae:ce,refreshSession:y?ie:ue,getCaptchaHeader:_,invalidateCaptcha:d,inputNotification:ze,showInputNotification:Y,clearInputNotification:je}};exports.useInkeepChat=dt;
|
|
@@ -17,9 +17,9 @@ import { useStreamingEvents as gt } from "../../hooks/use-streaming-events.js";
|
|
|
17
17
|
import { useInputNotification as ht } from "../../hooks/use-input-notification.js";
|
|
18
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
19
|
const Bt = () => {
|
|
20
|
-
const { baseSettings: oe, aiChatSettings:
|
|
21
|
-
prop:
|
|
22
|
-
defaultProp:
|
|
20
|
+
const { baseSettings: oe, aiChatSettings: g } = at(), [c = "", h] = mt({
|
|
21
|
+
prop: g.conversationIdOverride,
|
|
22
|
+
defaultProp: g.conversationIdOverride ?? ""
|
|
23
23
|
}), { logEvent: m } = pt(), { setConversationId: Pe, emitToParent: x } = gt(), ae = i(c);
|
|
24
24
|
M(() => {
|
|
25
25
|
const e = ae.current;
|
|
@@ -31,14 +31,14 @@ const Bt = () => {
|
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
}, [c, m]);
|
|
34
|
-
const [
|
|
34
|
+
const [R, S] = k(""), Oe = (e) => S(e.target.value), {
|
|
35
35
|
shouldBypassCaptcha: De,
|
|
36
36
|
filters: ie,
|
|
37
37
|
userProperties: $,
|
|
38
38
|
analyticsProperties: B
|
|
39
39
|
} = oe, {
|
|
40
40
|
authToken: ce,
|
|
41
|
-
isAuthenticated:
|
|
41
|
+
isAuthenticated: v,
|
|
42
42
|
isAuthConfigured: le,
|
|
43
43
|
refreshAuthToken: ue,
|
|
44
44
|
sessionToken: pe,
|
|
@@ -56,8 +56,8 @@ const Bt = () => {
|
|
|
56
56
|
headers: ve,
|
|
57
57
|
appId: N,
|
|
58
58
|
apiKey: U,
|
|
59
|
-
files:
|
|
60
|
-
} =
|
|
59
|
+
files: w
|
|
60
|
+
} = g, ye = i(_);
|
|
61
61
|
ye.current = _;
|
|
62
62
|
const Ie = Be || `${ge}/run/api/chat`, { loadConversation: Ce } = lt({
|
|
63
63
|
baseUrl: ge,
|
|
@@ -74,12 +74,12 @@ const Bt = () => {
|
|
|
74
74
|
K.current = $ && Object.keys($).length > 0 ? $ : void 0;
|
|
75
75
|
const q = i(void 0);
|
|
76
76
|
q.current = B && Object.keys(B).length > 0 ? B : void 0;
|
|
77
|
-
const
|
|
77
|
+
const y = i(0), j = i(null), G = i(null), I = i(void 0), ze = w?.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
81
|
M(() => {
|
|
82
|
-
|
|
82
|
+
I.current = w?.length ? w : void 0;
|
|
83
83
|
}, [ze]);
|
|
84
84
|
const Se = i(ve);
|
|
85
85
|
Se.current = ve;
|
|
@@ -103,7 +103,7 @@ const Bt = () => {
|
|
|
103
103
|
default:
|
|
104
104
|
return ne;
|
|
105
105
|
}
|
|
106
|
-
}, [
|
|
106
|
+
}, [A, J] = k([]), Ke = _e(
|
|
107
107
|
() => new nt({
|
|
108
108
|
api: Ie,
|
|
109
109
|
headers: () => {
|
|
@@ -144,7 +144,7 @@ const Bt = () => {
|
|
|
144
144
|
}),
|
|
145
145
|
[Ie, he, N, U]
|
|
146
146
|
), {
|
|
147
|
-
messages:
|
|
147
|
+
messages: b,
|
|
148
148
|
sendMessage: W,
|
|
149
149
|
addToolApprovalResponse: Q,
|
|
150
150
|
status: we,
|
|
@@ -174,8 +174,8 @@ const Bt = () => {
|
|
|
174
174
|
onError(e) {
|
|
175
175
|
console.error("onError", { code: e.code, message: e.message });
|
|
176
176
|
const n = De || U ? null : vt(e);
|
|
177
|
-
if (n !== null &&
|
|
178
|
-
|
|
177
|
+
if (n !== null && y.current < 1) {
|
|
178
|
+
y.current++;
|
|
179
179
|
const r = G.current, s = j.current;
|
|
180
180
|
(async () => {
|
|
181
181
|
if (n === "session" && le) {
|
|
@@ -205,7 +205,7 @@ const Bt = () => {
|
|
|
205
205
|
{ body: s.body }
|
|
206
206
|
));
|
|
207
207
|
})().catch(() => {
|
|
208
|
-
|
|
208
|
+
y.current = 0, p(), d((u) => {
|
|
209
209
|
const o = [...u], f = o[o.length - 1];
|
|
210
210
|
if (!f) return o;
|
|
211
211
|
const D = ne;
|
|
@@ -218,13 +218,13 @@ const Bt = () => {
|
|
|
218
218
|
});
|
|
219
219
|
return;
|
|
220
220
|
}
|
|
221
|
-
|
|
221
|
+
y.current = 0, n !== null && p();
|
|
222
222
|
const t = yt(e), l = He(e);
|
|
223
223
|
if (m({
|
|
224
224
|
eventName: "chat_error",
|
|
225
225
|
properties: {
|
|
226
226
|
conversationId: c,
|
|
227
|
-
messageId:
|
|
227
|
+
messageId: b.at(-1)?.id,
|
|
228
228
|
error: e.message
|
|
229
229
|
}
|
|
230
230
|
}), t) {
|
|
@@ -236,7 +236,7 @@ const Bt = () => {
|
|
|
236
236
|
return a.at(-1)?.role === "assistant" && (a = a.slice(0, -1)), a.at(-1)?.role === "user" && (a = a.slice(0, -1)), a;
|
|
237
237
|
});
|
|
238
238
|
const r = j.current?.content;
|
|
239
|
-
r &&
|
|
239
|
+
r && S(r), ee.current = e;
|
|
240
240
|
return;
|
|
241
241
|
}
|
|
242
242
|
d((r) => {
|
|
@@ -248,43 +248,43 @@ const Bt = () => {
|
|
|
248
248
|
}) : a.parts = [{ type: "text", text: l }]), s;
|
|
249
249
|
});
|
|
250
250
|
}
|
|
251
|
-
}), Ae = i(
|
|
251
|
+
}), Ae = i(v);
|
|
252
252
|
M(() => {
|
|
253
253
|
const e = Ae.current;
|
|
254
|
-
Ae.current =
|
|
255
|
-
}, [
|
|
254
|
+
Ae.current = v, e !== v && (P(), E(null), d([]), h(""), S(""), J([]), p());
|
|
255
|
+
}, [v, P, d, h, p]);
|
|
256
256
|
const be = we === "submitted", Z = we === "streaming", qe = _e(() => {
|
|
257
257
|
const e = (r) => {
|
|
258
258
|
if (!r || typeof r != "object") return !1;
|
|
259
259
|
const s = r;
|
|
260
260
|
return typeof s.type == "string" && s.type.startsWith("tool-");
|
|
261
|
-
}, t = [...
|
|
261
|
+
}, t = [...b ?? []].reverse().find((r) => r.role === "assistant");
|
|
262
262
|
if (!t) return !1;
|
|
263
263
|
const l = t.parts?.at(-1);
|
|
264
264
|
return !(!e(l) || l.state !== "output-available" || !l.approval?.id || Z);
|
|
265
|
-
}, [
|
|
265
|
+
}, [b, Z]), [je, X] = k(!1), Ee = Z || qe && !je, Te = be || Ee, Ge = b.length === 0, Y = !R.trim() && A.length === 0 || Te, Ve = ct("(max-width: 768px)"), [Je, E] = k(null), ee = i(null);
|
|
266
266
|
M(() => {
|
|
267
267
|
if (O) {
|
|
268
268
|
if (ee.current === O) {
|
|
269
269
|
ee.current = null;
|
|
270
270
|
return;
|
|
271
271
|
}
|
|
272
|
-
|
|
272
|
+
E(O);
|
|
273
273
|
}
|
|
274
274
|
}, [O]);
|
|
275
|
-
const We = () =>
|
|
275
|
+
const We = () => E(null), { inputNotification: Qe, showInputNotification: te, clearInputNotification: Ze } = ht(), Me = i(null);
|
|
276
276
|
M(() => {
|
|
277
|
-
$e?.(
|
|
278
|
-
}, [
|
|
277
|
+
$e?.(R);
|
|
278
|
+
}, [R]);
|
|
279
279
|
const Xe = (e) => {
|
|
280
280
|
e.key === "Enter" && !e.shiftKey && !Y && !e.nativeEvent.isComposing && (e.preventDefault(), se());
|
|
281
|
-
}, se = async (e =
|
|
282
|
-
if (Y && (!e || e.trim().length === 0) &&
|
|
281
|
+
}, se = async (e = R) => {
|
|
282
|
+
if (Y && (!e || e.trim().length === 0) && A.length === 0 || !e.trim() && !A.length && !I.current?.length)
|
|
283
283
|
return;
|
|
284
|
-
const n =
|
|
285
|
-
J([]),
|
|
284
|
+
const n = A;
|
|
285
|
+
J([]), S(""), y.current = 0, G.current = null, X(!1);
|
|
286
286
|
let t = c;
|
|
287
|
-
t || (t = `conv_${F(16)}`,
|
|
287
|
+
t || (t = `conv_${F(16)}`, h(t));
|
|
288
288
|
const l = F(21);
|
|
289
289
|
Pe(t), await m({
|
|
290
290
|
eventName: "user_message_submitted",
|
|
@@ -293,8 +293,8 @@ const Bt = () => {
|
|
|
293
293
|
messageId: l
|
|
294
294
|
}
|
|
295
295
|
});
|
|
296
|
-
const r =
|
|
297
|
-
|
|
296
|
+
const r = I.current;
|
|
297
|
+
I.current = void 0;
|
|
298
298
|
let s = [];
|
|
299
299
|
if (n.length > 0)
|
|
300
300
|
try {
|
|
@@ -337,7 +337,7 @@ const Bt = () => {
|
|
|
337
337
|
}, W({ id: l, parts: u }, { body: { conversationId: t } });
|
|
338
338
|
}, Ye = L(
|
|
339
339
|
(e) => {
|
|
340
|
-
|
|
340
|
+
y.current = 0, G.current = e, X(!1), Q(e);
|
|
341
341
|
},
|
|
342
342
|
[Q]
|
|
343
343
|
), re = L(() => {
|
|
@@ -345,20 +345,20 @@ const Bt = () => {
|
|
|
345
345
|
x("aborted", { conversationId: c });
|
|
346
346
|
});
|
|
347
347
|
}, [P, c, x]), ke = () => {
|
|
348
|
-
We(), d([]),
|
|
348
|
+
We(), d([]), h(""), p(), I.current = w?.length ? w : void 0, m({
|
|
349
349
|
eventName: "chat_clear_button_clicked",
|
|
350
350
|
properties: {
|
|
351
351
|
conversationId: c
|
|
352
352
|
}
|
|
353
353
|
});
|
|
354
|
-
},
|
|
354
|
+
}, C = L(
|
|
355
355
|
(e, n) => {
|
|
356
|
-
|
|
356
|
+
E(null), d(n), h(e), p(), I.current = void 0;
|
|
357
357
|
},
|
|
358
|
-
[d,
|
|
358
|
+
[d, h, p]
|
|
359
359
|
), Fe = L(
|
|
360
360
|
async (e, n) => {
|
|
361
|
-
re(),
|
|
361
|
+
re(), C(e, []), Re(!0);
|
|
362
362
|
try {
|
|
363
363
|
const t = await Ce(e, n);
|
|
364
364
|
if (t === null) return !1;
|
|
@@ -375,24 +375,26 @@ const Bt = () => {
|
|
|
375
375
|
]
|
|
376
376
|
}
|
|
377
377
|
] : t;
|
|
378
|
-
return
|
|
378
|
+
return C(e, r), !0;
|
|
379
379
|
} finally {
|
|
380
380
|
n?.aborted || Re(!1);
|
|
381
381
|
}
|
|
382
382
|
},
|
|
383
|
-
[
|
|
383
|
+
[C, Ce, re]
|
|
384
384
|
);
|
|
385
385
|
ut({
|
|
386
|
-
conversationId:
|
|
386
|
+
conversationId: g.conversationId,
|
|
387
|
+
fetchedConversation: g.fetchedConversation,
|
|
387
388
|
effectiveAuthToken: fe,
|
|
389
|
+
restoreSession: C,
|
|
388
390
|
loadAndRestoreSession: Fe,
|
|
389
|
-
onLoadFailed: () =>
|
|
391
|
+
onLoadFailed: () => C("", [])
|
|
390
392
|
});
|
|
391
393
|
const { openForm: et } = dt(), tt = ft();
|
|
392
|
-
return ot(
|
|
394
|
+
return ot(g.chatFunctionsRef, () => ({
|
|
393
395
|
submitMessage: se,
|
|
394
396
|
updateInputMessage(e) {
|
|
395
|
-
|
|
397
|
+
S(e);
|
|
396
398
|
},
|
|
397
399
|
clearChat: ke,
|
|
398
400
|
openForm: (e) => {
|
|
@@ -402,16 +404,16 @@ const Bt = () => {
|
|
|
402
404
|
Me.current?.focus();
|
|
403
405
|
}
|
|
404
406
|
})), {
|
|
405
|
-
messages:
|
|
407
|
+
messages: b,
|
|
406
408
|
sendMessage: W,
|
|
407
409
|
addToolApprovalResponse: Ye,
|
|
408
410
|
isLoading: be,
|
|
409
411
|
isStreaming: Ee,
|
|
410
412
|
isBusy: Te,
|
|
411
413
|
error: Je,
|
|
412
|
-
setError:
|
|
414
|
+
setError: E,
|
|
413
415
|
isSubmitDisabled: Y,
|
|
414
|
-
input:
|
|
416
|
+
input: R,
|
|
415
417
|
handleInputChange: Oe,
|
|
416
418
|
handleInputKeyDown: Xe,
|
|
417
419
|
handleSubmit: se,
|
|
@@ -419,15 +421,15 @@ const Bt = () => {
|
|
|
419
421
|
clear: ke,
|
|
420
422
|
inputRef: Me,
|
|
421
423
|
isMobile: Ve,
|
|
422
|
-
files:
|
|
424
|
+
files: A,
|
|
423
425
|
setFiles: J,
|
|
424
426
|
isNewChat: Ge,
|
|
425
427
|
conversationId: c,
|
|
426
|
-
restoreSession:
|
|
428
|
+
restoreSession: C,
|
|
427
429
|
loadAndRestoreSession: Fe,
|
|
428
430
|
isSessionLoading: Ue,
|
|
429
|
-
authToken:
|
|
430
|
-
refreshSession:
|
|
431
|
+
authToken: v ? ce : pe,
|
|
432
|
+
refreshSession: v ? ue : de,
|
|
431
433
|
getCaptchaHeader: _,
|
|
432
434
|
invalidateCaptcha: p,
|
|
433
435
|
inputNotification: Qe,
|
|
@@ -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"),d=({conversationId:r,fetchedConversation:n,effectiveAuthToken:s,restoreSession:o,loadAndRestoreSession:c,onLoadFailed:i})=>{const e=t.useRef(null),a=t.useRef(o);a.current=o;const f=t.useRef(c);f.current=c;const R=t.useRef(i);R.current=i,t.useEffect(()=>{if(n&&!r&&console.warn("[useInitialConversation] fetchedConversation was provided without conversationId and will be ignored"),!r||e.current===r)return;if(n){e.current=r,a.current(r,n);return}if(!s)return;e.current=r;const u=new AbortController,b=l=>{e.current=null,console.error("[useInitialConversation] failed to load conversation:",r,l),R.current?.()};return(async()=>{try{!await f.current(r,u.signal)&&!u.signal.aborted&&b()}catch(l){u.signal.aborted||b(l)}})(),()=>{e.current=null,u.abort()}},[r,n,s])};exports.useInitialConversation=d;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import { Message } from '../../types/message';
|
|
1
2
|
interface UseInitialConversationOptions {
|
|
2
3
|
/** The conversationId provided via props to load and restore. */
|
|
3
4
|
conversationId: string | undefined;
|
|
5
|
+
/** Pre-fetched messages — when provided, skips the network fetch entirely. */
|
|
6
|
+
fetchedConversation: Message[] | undefined;
|
|
4
7
|
/** Resolved auth token — fetch is skipped until one is available. */
|
|
5
8
|
effectiveAuthToken: string | null;
|
|
9
|
+
/** Restores a session with the given id and messages (no fetch). */
|
|
10
|
+
restoreSession: (sessionId: string, messages: Message[]) => void;
|
|
6
11
|
/** Returns true if the conversation was loaded successfully, false otherwise. */
|
|
7
12
|
loadAndRestoreSession: (sessionId: string, signal?: AbortSignal) => Promise<boolean>;
|
|
8
13
|
/** Called when the load fails (404 or other error) — use to reset conversation state. */
|
|
@@ -10,7 +15,8 @@ interface UseInitialConversationOptions {
|
|
|
10
15
|
}
|
|
11
16
|
/**
|
|
12
17
|
* Loads and restores a conversation by ID once an auth token is available.
|
|
18
|
+
* When `fetchedConversation` is provided, seeds the session directly without fetching.
|
|
13
19
|
* Calls `onLoadFailed` if the conversation is not found or the fetch fails.
|
|
14
20
|
*/
|
|
15
|
-
export declare const useInitialConversation: ({ conversationId, effectiveAuthToken, loadAndRestoreSession, onLoadFailed, }: UseInitialConversationOptions) => void;
|
|
21
|
+
export declare const useInitialConversation: ({ conversationId, fetchedConversation, effectiveAuthToken, restoreSession, loadAndRestoreSession, onLoadFailed, }: UseInitialConversationOptions) => void;
|
|
16
22
|
export {};
|
|
@@ -1,34 +1,45 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useRef as
|
|
3
|
-
const
|
|
2
|
+
import { useRef as l, useEffect as d } from "react";
|
|
3
|
+
const p = ({
|
|
4
4
|
conversationId: r,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
fetchedConversation: e,
|
|
6
|
+
effectiveAuthToken: o,
|
|
7
|
+
restoreSession: s,
|
|
8
|
+
loadAndRestoreSession: c,
|
|
9
|
+
onLoadFailed: i
|
|
8
10
|
}) => {
|
|
9
|
-
const t =
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const t = l(null), a = l(s);
|
|
12
|
+
a.current = s;
|
|
13
|
+
const f = l(c);
|
|
14
|
+
f.current = c;
|
|
15
|
+
const b = l(i);
|
|
16
|
+
b.current = i, d(() => {
|
|
17
|
+
if (e && !r && console.warn(
|
|
18
|
+
"[useInitialConversation] fetchedConversation was provided without conversationId and will be ignored"
|
|
19
|
+
), !r || t.current === r) return;
|
|
20
|
+
if (e) {
|
|
21
|
+
t.current = r, a.current(r, e);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (!o) return;
|
|
14
25
|
t.current = r;
|
|
15
|
-
const
|
|
16
|
-
t.current = null, console.error("[useInitialConversation] failed to load conversation:", r,
|
|
26
|
+
const n = new AbortController(), w = (u) => {
|
|
27
|
+
t.current = null, console.error("[useInitialConversation] failed to load conversation:", r, u), b.current?.();
|
|
17
28
|
};
|
|
18
29
|
return (async () => {
|
|
19
30
|
try {
|
|
20
|
-
!await
|
|
31
|
+
!await f.current(
|
|
21
32
|
r,
|
|
22
|
-
|
|
23
|
-
) && !
|
|
24
|
-
} catch (
|
|
25
|
-
|
|
33
|
+
n.signal
|
|
34
|
+
) && !n.signal.aborted && w();
|
|
35
|
+
} catch (u) {
|
|
36
|
+
n.signal.aborted || w(u);
|
|
26
37
|
}
|
|
27
38
|
})(), () => {
|
|
28
|
-
t.current = null,
|
|
39
|
+
t.current = null, n.abort();
|
|
29
40
|
};
|
|
30
|
-
}, [r,
|
|
41
|
+
}, [r, e, o]);
|
|
31
42
|
};
|
|
32
43
|
export {
|
|
33
|
-
|
|
44
|
+
p as useInitialConversation
|
|
34
45
|
};
|
|
@@ -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.17.
|
|
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.17.6",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.17.
|
|
6
|
+
const { baseSettings: t, componentType: o } = x(), { tags: s, analyticsProperties: n } = t, r = "0.17.6", 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.17.
|
|
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.17.6",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.17.
|
|
9
|
+
const { baseSettings: r, aiChatSettings: g, componentType: i } = N(), { tags: t, analyticsProperties: n, privacyPreferences: f, userProperties: o } = r, c = "0.17.6", a = x(
|
|
10
10
|
() => ({
|
|
11
11
|
widgetLibraryVersion: c,
|
|
12
12
|
componentType: i
|
|
@@ -3,6 +3,7 @@ import { GetHelpOption, CustomMessageAction } from './settings/actions';
|
|
|
3
3
|
import { SearchAndChatFilters } from './filters';
|
|
4
4
|
import { ComponentsConfig } from './components';
|
|
5
5
|
import { FileUIPart } from 'ai';
|
|
6
|
+
import { Message } from '../message';
|
|
6
7
|
export type { FileUIPart } from 'ai';
|
|
7
8
|
export interface InkeepAIChatSettings {
|
|
8
9
|
/**
|
|
@@ -166,6 +167,13 @@ export interface InkeepAIChatSettings {
|
|
|
166
167
|
* restore a previous conversation state.
|
|
167
168
|
*/
|
|
168
169
|
conversationIdOverride?: string;
|
|
170
|
+
/**
|
|
171
|
+
* Pre-fetched conversation messages to render without fetching.
|
|
172
|
+
* Requires `conversationId` to be set.
|
|
173
|
+
*
|
|
174
|
+
* @beta This prop is subject to change.
|
|
175
|
+
*/
|
|
176
|
+
fetchedConversation?: Message[];
|
|
169
177
|
/**
|
|
170
178
|
* When enabled, prevents users from sending new messages.
|
|
171
179
|
* Useful for displaying archived or shared chat sessions.
|