@inkeep/agents-ui 0.15.22 → 0.15.24
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 +3 -2
- package/dist/primitives/components/embedded-chat/use-inkeep-chat.d.ts +2 -2
- package/dist/primitives/components/embedded-chat/use-inkeep-chat.js +205 -193
- 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-history-provider.cjs +1 -1
- package/dist/primitives/providers/chat-history-provider.js +80 -80
- package/dist/types/config/ai.d.ts +8 -0
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
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 We=require("@ai-sdk/react"),ze=require("ai"),t=require("react"),Je=require("../modal/modal-provider.cjs"),Ge=require("../../providers/chat-bubble-provider.cjs"),Qe=require("../../providers/sidebar-chat-provider.cjs"),Ve=require("../../providers/config-provider.cjs"),Ze=require("./use-captcha.cjs"),Xe=require("../../hooks/use-media-query.cjs"),Ye=require("../../hooks/use-anonymous-session.cjs"),et=require("../../hooks/use-auth-token.cjs"),tt=require("../../hooks/use-conversation-loader.cjs"),N=require("../../utils/generate-uid.cjs"),st=require("../../providers/base-events-provider.cjs"),nt=require("../../providers/chat-form-provider.cjs"),rt=require("../../providers/widget-provider.cjs"),at=require("@radix-ui/react-use-controllable-state"),ot=require("../../hooks/use-streaming-events.cjs"),it=require("../../hooks/use-inkeep-api-client.cjs");function ut(f){const h=f.message??"";let s=Number(f.code)||Number(f.statusCode);if(Number.isNaN(s))try{s=Number(JSON.parse(h).status)}catch{}const l=it.parseAuthError(s,{detail:h});return l!==null?l:s===401?"session":null}const O=`Hmm..
|
|
2
2
|
|
|
3
|
-
It seems I might be having some issues right now. Please clear the chat and try again.`,
|
|
3
|
+
It seems I might be having some issues right now. Please clear the chat and try again.`,ct=()=>{const{baseSettings:f,aiChatSettings:h}=Ve.useInkeepConfig(),[s="",l]=at.useControllableState({prop:h.conversationId,defaultProp:h.conversationId??""}),be=Je.useModal(),Ce=Ge.useOptionalChatBubble(),Se=Qe.useOptionalSidebarChat(),{logEvent:g}=st.useBaseEvents(),{setConversationId:Re,emitToParent:I}=ot.useStreamingEvents(),Z=t.useRef(s);t.useEffect(()=>{const e=Z.current;Z.current=s,e!==s&&g({eventName:"chat_conversation_changed",properties:{conversationId:s,previousConversationId:e}})},[s,g]);const[y,E]=t.useState(""),Ae=e=>E(e.target.value),{shouldBypassCaptcha:X,filters:Y,privacyPreferences:ke,userProperties:_}=f,{authToken:T,isLoading:Ie,refreshToken:ee}=et.useAuthToken(),te=!!f.getAuthToken,d=!!T,{onInputMessageChange:Ee,filters:se,baseUrl:w,agentUrl:Te,context:ne,headers:re,appId:b,apiKey:m,files:C}=h,we=be?.isOpen??Ce?.isOpen??Se?.isOpen??!0,{getCaptchaHeader:S,invalidate:c}=Ze.useCaptcha({baseUrl:w,shouldBypassCaptcha:X||!!m,shouldMakeInitialRequest:we}),ae=t.useRef(S);ae.current=S;const oe=Te||`${w}/run/api/chat`,{sessionToken:F,refreshSession:U}=Ye.useAnonymousSession({baseUrl:w,appId:b,getCaptchaHeader:S,invalidateCaptcha:c,optOutAllAnalytics:ke?.optOutAllAnalytics,enabled:!d&&!Ie}),{loadConversation:ie}=tt.useConversationLoader({baseUrl:w,appId:b,authToken:m??(d?T:F),getCaptchaHeader:S,invalidateCaptcha:c,refreshSession:m||d?void 0:U}),[Me,ue]=t.useState(!1),D=t.useRef(null);D.current=F;const B=t.useRef(null);B.current=T;const L=t.useRef(void 0);L.current=_&&Object.keys(_).length>0?JSON.stringify(_):void 0;const v=t.useRef(0),ce=t.useRef(null),$=t.useRef(null),R=t.useRef(void 0),xe=C?.map(e=>`${e.filename??""}:${e.mediaType}:${e.url.length}:${e.url.slice(0,64)}:${e.url.slice(-32)}`).join(`
|
|
4
|
+
`)??"";t.useEffect(()=>{R.current=C?.length?C:void 0},[xe]);const le=t.useRef(re);le.current=re;const H=t.useRef(void 0);H.current=Y||se?JSON.stringify({...Y,...se}):void 0;const qe=e=>{switch(e.code){case 400:return e.message;case 401:return te?"Authentication failed. Please try again.":O;case 403:return`There seems to be a configuration error. Please contact ${f.organizationDisplayName??"Administrator"}`;default:return O}},[Pe,A]=t.useState([]),[Ne,M]=t.useState(null),Oe=t.useMemo(()=>new ze.DefaultChatTransport({api:oe,headers:()=>{const e=m??B.current??D.current;return{"x-inkeep-client-timezone":Intl.DateTimeFormat().resolvedOptions().timeZone,"x-inkeep-client-timestamp":new Date().toISOString(),...b?{"x-inkeep-app-id":b}:{},...e?{Authorization:`Bearer ${e}`}:{},...H.current?{"inkeep-filters":H.current}:{},...L.current?{"x-inkeep-user-properties":L.current}:{},...le.current}},prepareSendMessagesRequest:async e=>{const n=await ae.current();return{body:{...e.body,id:e.id,messages:e.messages,trigger:e.trigger,messageId:e.messageId},headers:{...e.headers,...n}}},body:{requestContext:ne}}),[oe,ne,b,m]),{messages:x,sendMessage:j,addToolApprovalResponse:K,status:de,setMessages:p,stop:q,error:W}=We.useChat({transport:Oe,onData(e){I(e.type,e.data)},async onFinish(){I("completion",{conversationId:s}),await g({eventName:"assistant_message_received",properties:{conversationId:s}}),g({eventName:"assistant_answer_displayed",properties:{conversationId:s}})},onError(e){console.error("onError",{code:e.code,message:e.message});const n=X||m?null:ut(e);if(n!==null&&v.current<1){v.current++;const r=$.current,a=ce.current;(async()=>{if(n==="session"&&te){const o=await ee();if(!o)throw new Error("Auth token refresh failed");B.current=o}else if(n==="session"){const o=await U();o&&(D.current=o)}else c();if(r){K(r);return}a&&(p(o=>{let u=[...o];return u.at(-1)?.role==="assistant"&&(u=u.slice(0,-1)),u.at(-1)?.role==="user"&&(u=u.slice(0,-1)),u}),j(a.files?.length?{parts:[{type:"text",text:a.content},...a.files]}:{text:a.content},{body:a.body}))})().catch(()=>{v.current=0,c(),p(o=>{const u=[...o],V=u[u.length-1];if(!V)return u;const ye=O;return V.role==="user"?u.push({id:N.generateUid(16),role:"assistant",parts:[{type:"text",text:ye}]}):V.parts=[{type:"text",text:ye}],u})});return}v.current=0,n!==null&&c(),g({eventName:"chat_error",properties:{conversationId:s,error:e.message}}),p(r=>{const a=[...r],i=a[a.length-1];if(i){const o=qe(e);i.role==="user"?a.push({id:N.generateUid(16),role:"assistant",parts:[{type:"text",text:o}]}):i.parts=[{type:"text",text:o}]}return a})}}),pe=t.useRef(d);t.useEffect(()=>{const e=pe.current;pe.current=d,e!==d&&(q(),k(null),p([]),l(""),E(""),A([]),M(null),c())},[d,q,p,l,c]);const fe=de==="submitted",z=de==="streaming",_e=t.useMemo(()=>{const e=i=>{if(!i||typeof i!="object")return!1;const o=i;return typeof o.type=="string"&&o.type.startsWith("tool-")},r=[...x??[]].reverse().find(i=>i.role==="assistant");if(!r)return!1;const a=r.parts?.at(-1);return!(!e(a)||a.state!=="output-available"||!a.approval?.id||z)},[x,z]),he=z||_e,ge=fe||he,Fe=x.length===0,J=!y.trim()||ge,Ue=Xe.useMediaQuery("(max-width: 768px)"),[De,k]=t.useState(null);t.useEffect(()=>{W&&k(W)},[W]);const Be=()=>k(null),me=t.useRef(null);t.useEffect(()=>{Ee?.(y)},[y]);const Le=e=>{e.key==="Enter"&&!e.shiftKey&&!J&&!e.nativeEvent.isComposing&&(e.preventDefault(),G())},G=async(e=y)=>{if(J&&(!e||e.trim().length===0))return;A([]),E(""),v.current=0,$.current=null,await g({eventName:"user_message_submitted",properties:{conversationId:s}});let n=s;n||(n=`conv_${N.generateUid(16)}`,l(n)),Re(n);const r=R.current;R.current=void 0,ce.current={content:e,body:{conversationId:n},files:r},j(r?{parts:[{type:"text",text:e},...r]}:{text:e},{body:{conversationId:n}})},$e=t.useCallback(e=>{v.current=0,$.current=e,K(e)},[K]),Q=t.useCallback(()=>{q().then(()=>{I("aborted",{conversationId:s})})},[q,s,I]),ve=()=>{Be(),p([]),l(""),A([]),M(null),c(),R.current=C?.length?C:void 0,g({eventName:"chat_clear_button_clicked",properties:{conversationId:s}})},P=t.useCallback((e,n)=>{k(null),p(n),l(e),A([]),M(null),c(),R.current=void 0},[p,l,c]),He=t.useCallback(async(e,n)=>{Q(),P(e,[]),ue(!0);try{const r=await ie(e,n),a=r?.[r.length-1],i=r!==null&&a?.role==="user"?[...r,{id:N.generateUid(16),role:"assistant",parts:[{type:"text",text:"This session was interrupted. Please check back in a few minutes or start a new conversation."}]}]:r;i!==null&&P(e,i)}finally{n?.aborted||ue(!1)}},[P,ie,Q]),{openForm:je}=nt.useChatForm(),Ke=rt.useWidget();return t.useImperativeHandle(h.chatFunctionsRef,()=>({submitMessage:G,updateInputMessage(e){E(e)},clearChat:ve,openForm:e=>{Ke?.setView("chat"),je(e,void 0)},focusInput:()=>{me.current?.focus()}})),{messages:x,sendMessage:j,addToolApprovalResponse:$e,isLoading:fe,isStreaming:he,isBusy:ge,error:De,setError:k,isSubmitDisabled:J,input:y,handleInputChange:Ae,handleInputKeyDown:Le,handleSubmit:G,stop:Q,clear:ve,inputRef:me,isMobile:Ue,messageAttachments:Pe,setMessageAttachments:A,selectedWorkflow:Ne,setSelectedWorkflow:M,isNewChat:Fe,conversationId:s,restoreSession:P,loadAndRestoreSession:He,isSessionLoading:Me,authToken:d?T:F,refreshSession:d?ee:U,getCaptchaHeader:S,invalidateCaptcha:c}};exports.DEFAULT_ERROR_MESSAGE=O;exports.useInkeepChat=ct;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { KeyboardEvent, Dispatch, SetStateAction, RefObject } from 'react';
|
|
2
|
-
import { Message, MessageAttachment, Workflow } from '../../../types/index.ts';
|
|
3
2
|
import { FileUIPart, ChatRequestOptions } from 'ai';
|
|
3
|
+
import { Message, MessageAttachment, Workflow } from '../../../types/index.ts';
|
|
4
4
|
export declare const DEFAULT_ERROR_MESSAGE = "Hmm.. \n\nIt seems I might be having some issues right now. Please clear the chat and try again.";
|
|
5
5
|
export declare const useInkeepChat: () => {
|
|
6
6
|
messages: Message[];
|
|
@@ -50,7 +50,7 @@ export declare const useInkeepChat: () => {
|
|
|
50
50
|
restoreSession: (sessionId: string, loadedMessages: Message[]) => void;
|
|
51
51
|
loadAndRestoreSession: (sessionId: string, signal?: AbortSignal) => Promise<void>;
|
|
52
52
|
isSessionLoading: boolean;
|
|
53
|
-
|
|
53
|
+
authToken: string | null;
|
|
54
54
|
refreshSession: () => Promise<string | null>;
|
|
55
55
|
getCaptchaHeader: () => Promise<Record<string, string>>;
|
|
56
56
|
invalidateCaptcha: () => void;
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useChat as
|
|
3
|
-
import { DefaultChatTransport as
|
|
4
|
-
import { useRef as c, useEffect as
|
|
5
|
-
import { useModal as
|
|
6
|
-
import { useOptionalChatBubble as
|
|
7
|
-
import { useOptionalSidebarChat as
|
|
8
|
-
import { useInkeepConfig as
|
|
9
|
-
import { useCaptcha as
|
|
10
|
-
import { useMediaQuery as
|
|
11
|
-
import { useAnonymousSession as
|
|
12
|
-
import { useAuthToken as
|
|
13
|
-
import { useConversationLoader as
|
|
14
|
-
import { generateUid as
|
|
15
|
-
import { useBaseEvents as
|
|
16
|
-
import { useChatForm as
|
|
17
|
-
import { useWidget as
|
|
18
|
-
import { useControllableState as
|
|
19
|
-
import { useStreamingEvents as
|
|
20
|
-
import { parseAuthError as
|
|
21
|
-
function
|
|
2
|
+
import { useChat as Qe } from "@ai-sdk/react";
|
|
3
|
+
import { DefaultChatTransport as Ve } from "ai";
|
|
4
|
+
import { useRef as c, useEffect as w, useState as R, useMemo as Se, useCallback as P, useImperativeHandle as Ze } from "react";
|
|
5
|
+
import { useModal as Xe } from "../modal/modal-provider.js";
|
|
6
|
+
import { useOptionalChatBubble as Ye } from "../../providers/chat-bubble-provider.js";
|
|
7
|
+
import { useOptionalSidebarChat as et } from "../../providers/sidebar-chat-provider.js";
|
|
8
|
+
import { useInkeepConfig as tt } from "../../providers/config-provider.js";
|
|
9
|
+
import { useCaptcha as st } from "./use-captcha.js";
|
|
10
|
+
import { useMediaQuery as rt } from "../../hooks/use-media-query.js";
|
|
11
|
+
import { useAnonymousSession as nt } from "../../hooks/use-anonymous-session.js";
|
|
12
|
+
import { useAuthToken as ot } from "../../hooks/use-auth-token.js";
|
|
13
|
+
import { useConversationLoader as at } from "../../hooks/use-conversation-loader.js";
|
|
14
|
+
import { generateUid as D } from "../../utils/generate-uid.js";
|
|
15
|
+
import { useBaseEvents as it } from "../../providers/base-events-provider.js";
|
|
16
|
+
import { useChatForm as ct } from "../../providers/chat-form-provider.js";
|
|
17
|
+
import { useWidget as lt } from "../../providers/widget-provider.js";
|
|
18
|
+
import { useControllableState as ut } from "@radix-ui/react-use-controllable-state";
|
|
19
|
+
import { useStreamingEvents as pt } from "../../hooks/use-streaming-events.js";
|
|
20
|
+
import { parseAuthError as dt } from "../../hooks/use-inkeep-api-client.js";
|
|
21
|
+
function mt(m) {
|
|
22
22
|
const f = m.message ?? "";
|
|
23
23
|
let t = Number(m.code) || Number(m.statusCode);
|
|
24
24
|
if (Number.isNaN(t))
|
|
@@ -26,19 +26,19 @@ function ut(m) {
|
|
|
26
26
|
t = Number(JSON.parse(f).status);
|
|
27
27
|
} catch {
|
|
28
28
|
}
|
|
29
|
-
const
|
|
30
|
-
return
|
|
29
|
+
const u = dt(t, { detail: f });
|
|
30
|
+
return u !== null ? u : t === 401 ? "session" : null;
|
|
31
31
|
}
|
|
32
|
-
const
|
|
32
|
+
const Y = `Hmm..
|
|
33
33
|
|
|
34
|
-
It seems I might be having some issues right now. Please clear the chat and try again.`,
|
|
35
|
-
const { baseSettings: m, aiChatSettings: f } =
|
|
34
|
+
It seems I might be having some issues right now. Please clear the chat and try again.`, _t = () => {
|
|
35
|
+
const { baseSettings: m, aiChatSettings: f } = tt(), [t = "", u] = ut({
|
|
36
36
|
prop: f.conversationId,
|
|
37
37
|
defaultProp: f.conversationId ?? ""
|
|
38
|
-
}),
|
|
39
|
-
|
|
40
|
-
const e =
|
|
41
|
-
|
|
38
|
+
}), ke = Xe(), Ie = Ye(), we = et(), { logEvent: h } = it(), { setConversationId: Re, emitToParent: T } = pt(), ee = c(t);
|
|
39
|
+
w(() => {
|
|
40
|
+
const e = ee.current;
|
|
41
|
+
ee.current = t, e !== t && h({
|
|
42
42
|
eventName: "chat_conversation_changed",
|
|
43
43
|
properties: {
|
|
44
44
|
conversationId: t,
|
|
@@ -46,73 +46,79 @@ It seems I might be having some issues right now. Please clear the chat and try
|
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
48
|
}, [t, h]);
|
|
49
|
-
const [y,
|
|
50
|
-
onInputMessageChange:
|
|
51
|
-
filters:
|
|
52
|
-
baseUrl:
|
|
53
|
-
agentUrl:
|
|
54
|
-
context:
|
|
55
|
-
headers:
|
|
49
|
+
const [y, x] = R(""), Te = (e) => x(e.target.value), { shouldBypassCaptcha: te, filters: se, privacyPreferences: xe, userProperties: $ } = m, { authToken: M, isLoading: Me, refreshToken: re } = ot(), ne = !!m.getAuthToken, p = !!M, {
|
|
50
|
+
onInputMessageChange: Ee,
|
|
51
|
+
filters: oe,
|
|
52
|
+
baseUrl: E,
|
|
53
|
+
agentUrl: Ne,
|
|
54
|
+
context: ae,
|
|
55
|
+
headers: ie,
|
|
56
56
|
appId: b,
|
|
57
|
-
apiKey: g
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
57
|
+
apiKey: g,
|
|
58
|
+
files: C
|
|
59
|
+
} = f, Oe = ke?.isOpen ?? Ie?.isOpen ?? we?.isOpen ?? !0, { getCaptchaHeader: A, invalidate: l } = st({
|
|
60
|
+
baseUrl: E,
|
|
61
|
+
shouldBypassCaptcha: te || !!g,
|
|
62
|
+
shouldMakeInitialRequest: Oe
|
|
63
|
+
}), ce = c(A);
|
|
64
|
+
ce.current = A;
|
|
65
|
+
const le = Ne || `${E}/run/api/chat`, { sessionToken: B, refreshSession: L } = nt({
|
|
66
|
+
baseUrl: E,
|
|
66
67
|
appId: b,
|
|
67
|
-
getCaptchaHeader:
|
|
68
|
-
invalidateCaptcha:
|
|
69
|
-
optOutAllAnalytics:
|
|
70
|
-
enabled: !p
|
|
71
|
-
}), { loadConversation:
|
|
72
|
-
baseUrl:
|
|
68
|
+
getCaptchaHeader: A,
|
|
69
|
+
invalidateCaptcha: l,
|
|
70
|
+
optOutAllAnalytics: xe?.optOutAllAnalytics,
|
|
71
|
+
enabled: !p && !Me
|
|
72
|
+
}), { loadConversation: ue } = at({
|
|
73
|
+
baseUrl: E,
|
|
73
74
|
appId: b,
|
|
74
|
-
authToken: g ?? (p ?
|
|
75
|
-
getCaptchaHeader:
|
|
76
|
-
invalidateCaptcha:
|
|
77
|
-
refreshSession: g || p ? void 0 :
|
|
78
|
-
}), [
|
|
79
|
-
H.current =
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
const v = c(0),
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
75
|
+
authToken: g ?? (p ? M : B),
|
|
76
|
+
getCaptchaHeader: A,
|
|
77
|
+
invalidateCaptcha: l,
|
|
78
|
+
refreshSession: g || p ? void 0 : L
|
|
79
|
+
}), [_e, pe] = R(!1), H = c(null);
|
|
80
|
+
H.current = B;
|
|
81
|
+
const U = c(null);
|
|
82
|
+
U.current = M;
|
|
83
|
+
const K = c(void 0);
|
|
84
|
+
K.current = $ && Object.keys($).length > 0 ? JSON.stringify($) : void 0;
|
|
85
|
+
const v = c(0), de = c(null), W = c(null), S = c(void 0), Fe = C?.map((e) => `${e.filename ?? ""}:${e.mediaType}:${e.url.length}:${e.url.slice(0, 64)}:${e.url.slice(-32)}`).join(`
|
|
86
|
+
`) ?? "";
|
|
87
|
+
w(() => {
|
|
88
|
+
S.current = C?.length ? C : void 0;
|
|
89
|
+
}, [Fe]);
|
|
90
|
+
const me = c(ie);
|
|
91
|
+
me.current = ie;
|
|
92
|
+
const j = c(void 0);
|
|
93
|
+
j.current = se || oe ? JSON.stringify({ ...se, ...oe }) : void 0;
|
|
94
|
+
const Pe = (e) => {
|
|
89
95
|
switch (e.code) {
|
|
90
96
|
case 400:
|
|
91
97
|
return e.message;
|
|
92
98
|
case 401:
|
|
93
|
-
return
|
|
99
|
+
return ne ? "Authentication failed. Please try again." : Y;
|
|
94
100
|
case 403:
|
|
95
101
|
return `There seems to be a configuration error. Please contact ${m.organizationDisplayName ?? "Administrator"}`;
|
|
96
102
|
default:
|
|
97
|
-
return
|
|
103
|
+
return Y;
|
|
98
104
|
}
|
|
99
|
-
}, [
|
|
100
|
-
() => new
|
|
101
|
-
api:
|
|
105
|
+
}, [De, k] = R([]), [$e, N] = R(null), Be = Se(
|
|
106
|
+
() => new Ve({
|
|
107
|
+
api: le,
|
|
102
108
|
headers: () => {
|
|
103
|
-
const e = g ??
|
|
109
|
+
const e = g ?? U.current ?? H.current;
|
|
104
110
|
return {
|
|
105
111
|
"x-inkeep-client-timezone": Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
106
112
|
"x-inkeep-client-timestamp": (/* @__PURE__ */ new Date()).toISOString(),
|
|
107
113
|
...b ? { "x-inkeep-app-id": b } : {},
|
|
108
114
|
...e ? { Authorization: `Bearer ${e}` } : {},
|
|
109
|
-
|
|
110
|
-
...
|
|
111
|
-
...
|
|
115
|
+
...j.current ? { "inkeep-filters": j.current } : {},
|
|
116
|
+
...K.current ? { "x-inkeep-user-properties": K.current } : {},
|
|
117
|
+
...me.current
|
|
112
118
|
};
|
|
113
119
|
},
|
|
114
120
|
prepareSendMessagesRequest: async (e) => {
|
|
115
|
-
const s = await
|
|
121
|
+
const s = await ce.current();
|
|
116
122
|
return {
|
|
117
123
|
body: {
|
|
118
124
|
...e.body,
|
|
@@ -128,25 +134,25 @@ It seems I might be having some issues right now. Please clear the chat and try
|
|
|
128
134
|
};
|
|
129
135
|
},
|
|
130
136
|
body: {
|
|
131
|
-
requestContext:
|
|
137
|
+
requestContext: ae
|
|
132
138
|
}
|
|
133
139
|
}),
|
|
134
|
-
[
|
|
140
|
+
[le, ae, b, g]
|
|
135
141
|
), {
|
|
136
|
-
messages:
|
|
142
|
+
messages: O,
|
|
137
143
|
sendMessage: q,
|
|
138
144
|
addToolApprovalResponse: z,
|
|
139
|
-
status:
|
|
145
|
+
status: fe,
|
|
140
146
|
setMessages: d,
|
|
141
|
-
stop:
|
|
147
|
+
stop: _,
|
|
142
148
|
error: J
|
|
143
|
-
} =
|
|
144
|
-
transport:
|
|
149
|
+
} = Qe({
|
|
150
|
+
transport: Be,
|
|
145
151
|
onData(e) {
|
|
146
|
-
|
|
152
|
+
T(e.type, e.data);
|
|
147
153
|
},
|
|
148
154
|
async onFinish() {
|
|
149
|
-
|
|
155
|
+
T("completion", { conversationId: t }), await h({
|
|
150
156
|
eventName: "assistant_message_received",
|
|
151
157
|
properties: {
|
|
152
158
|
conversationId: t
|
|
@@ -160,187 +166,193 @@ It seems I might be having some issues right now. Please clear the chat and try
|
|
|
160
166
|
},
|
|
161
167
|
onError(e) {
|
|
162
168
|
console.error("onError", { code: e.code, message: e.message });
|
|
163
|
-
const s =
|
|
169
|
+
const s = te || g ? null : mt(e);
|
|
164
170
|
if (s !== null && v.current < 1) {
|
|
165
171
|
v.current++;
|
|
166
|
-
const
|
|
172
|
+
const r = W.current, n = de.current;
|
|
167
173
|
(async () => {
|
|
168
|
-
if (s === "session" &&
|
|
169
|
-
const
|
|
170
|
-
if (!
|
|
171
|
-
|
|
174
|
+
if (s === "session" && ne) {
|
|
175
|
+
const o = await re();
|
|
176
|
+
if (!o) throw new Error("Auth token refresh failed");
|
|
177
|
+
U.current = o;
|
|
172
178
|
} else if (s === "session") {
|
|
173
|
-
const
|
|
174
|
-
|
|
179
|
+
const o = await L();
|
|
180
|
+
o && (H.current = o);
|
|
175
181
|
} else
|
|
176
|
-
|
|
177
|
-
if (
|
|
178
|
-
z(
|
|
182
|
+
l();
|
|
183
|
+
if (r) {
|
|
184
|
+
z(r);
|
|
179
185
|
return;
|
|
180
186
|
}
|
|
181
|
-
n && (d((
|
|
182
|
-
let i = [...
|
|
187
|
+
n && (d((o) => {
|
|
188
|
+
let i = [...o];
|
|
183
189
|
return i.at(-1)?.role === "assistant" && (i = i.slice(0, -1)), i.at(-1)?.role === "user" && (i = i.slice(0, -1)), i;
|
|
184
|
-
}), q(
|
|
190
|
+
}), q(
|
|
191
|
+
n.files?.length ? { parts: [{ type: "text", text: n.content }, ...n.files] } : { text: n.content },
|
|
192
|
+
{ body: n.body }
|
|
193
|
+
));
|
|
185
194
|
})().catch(() => {
|
|
186
|
-
v.current = 0,
|
|
187
|
-
const i = [...
|
|
188
|
-
if (!
|
|
189
|
-
const
|
|
190
|
-
return
|
|
191
|
-
id:
|
|
195
|
+
v.current = 0, l(), d((o) => {
|
|
196
|
+
const i = [...o], X = i[i.length - 1];
|
|
197
|
+
if (!X) return i;
|
|
198
|
+
const Ae = Y;
|
|
199
|
+
return X.role === "user" ? i.push({
|
|
200
|
+
id: D(16),
|
|
192
201
|
role: "assistant",
|
|
193
|
-
parts: [{ type: "text", text:
|
|
194
|
-
}) :
|
|
202
|
+
parts: [{ type: "text", text: Ae }]
|
|
203
|
+
}) : X.parts = [{ type: "text", text: Ae }], i;
|
|
195
204
|
});
|
|
196
205
|
});
|
|
197
206
|
return;
|
|
198
207
|
}
|
|
199
|
-
v.current = 0, s !== null &&
|
|
208
|
+
v.current = 0, s !== null && l(), h({
|
|
200
209
|
eventName: "chat_error",
|
|
201
210
|
properties: {
|
|
202
211
|
conversationId: t,
|
|
203
212
|
error: e.message
|
|
204
213
|
}
|
|
205
|
-
}), d((
|
|
206
|
-
const n = [...
|
|
214
|
+
}), d((r) => {
|
|
215
|
+
const n = [...r], a = n[n.length - 1];
|
|
207
216
|
if (a) {
|
|
208
|
-
const
|
|
217
|
+
const o = Pe(e);
|
|
209
218
|
a.role === "user" ? n.push({
|
|
210
|
-
id:
|
|
219
|
+
id: D(16),
|
|
211
220
|
role: "assistant",
|
|
212
|
-
parts: [{ type: "text", text:
|
|
213
|
-
}) : a.parts = [{ type: "text", text:
|
|
221
|
+
parts: [{ type: "text", text: o }]
|
|
222
|
+
}) : a.parts = [{ type: "text", text: o }];
|
|
214
223
|
}
|
|
215
224
|
return n;
|
|
216
225
|
});
|
|
217
226
|
}
|
|
218
|
-
}),
|
|
219
|
-
|
|
220
|
-
const e =
|
|
221
|
-
|
|
222
|
-
}, [p,
|
|
223
|
-
const
|
|
227
|
+
}), he = c(p);
|
|
228
|
+
w(() => {
|
|
229
|
+
const e = he.current;
|
|
230
|
+
he.current = p, e !== p && (_(), I(null), d([]), u(""), x(""), k([]), N(null), l());
|
|
231
|
+
}, [p, _, d, u, l]);
|
|
232
|
+
const ge = fe === "submitted", G = fe === "streaming", Le = Se(() => {
|
|
224
233
|
const e = (a) => {
|
|
225
234
|
if (!a || typeof a != "object") return !1;
|
|
226
|
-
const
|
|
227
|
-
return typeof
|
|
228
|
-
},
|
|
229
|
-
if (!
|
|
230
|
-
const n =
|
|
231
|
-
return !(!e(n) || n.state !== "output-available" || !n.approval?.id ||
|
|
232
|
-
}, [
|
|
233
|
-
|
|
234
|
-
J &&
|
|
235
|
+
const o = a;
|
|
236
|
+
return typeof o.type == "string" && o.type.startsWith("tool-");
|
|
237
|
+
}, r = [...O ?? []].reverse().find((a) => a.role === "assistant");
|
|
238
|
+
if (!r) return !1;
|
|
239
|
+
const n = r.parts?.at(-1);
|
|
240
|
+
return !(!e(n) || n.state !== "output-available" || !n.approval?.id || G);
|
|
241
|
+
}, [O, G]), ve = G || Le, ye = ge || ve, He = O.length === 0, Q = !y.trim() || ye, Ue = rt("(max-width: 768px)"), [Ke, I] = R(null);
|
|
242
|
+
w(() => {
|
|
243
|
+
J && I(J);
|
|
235
244
|
}, [J]);
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
245
|
+
const We = () => I(null), be = c(null);
|
|
246
|
+
w(() => {
|
|
247
|
+
Ee?.(y);
|
|
239
248
|
}, [y]);
|
|
240
|
-
const
|
|
241
|
-
e.key === "Enter" && !e.shiftKey && !
|
|
242
|
-
},
|
|
243
|
-
if (
|
|
244
|
-
|
|
249
|
+
const je = (e) => {
|
|
250
|
+
e.key === "Enter" && !e.shiftKey && !Q && !e.nativeEvent.isComposing && (e.preventDefault(), V());
|
|
251
|
+
}, V = async (e = y) => {
|
|
252
|
+
if (Q && (!e || e.trim().length === 0)) return;
|
|
253
|
+
k([]), x(""), v.current = 0, W.current = null, await h({
|
|
245
254
|
eventName: "user_message_submitted",
|
|
246
255
|
properties: {
|
|
247
256
|
conversationId: t
|
|
248
257
|
}
|
|
249
258
|
});
|
|
250
259
|
let s = t;
|
|
251
|
-
s || (s = `conv_${
|
|
260
|
+
s || (s = `conv_${D(16)}`, u(s)), Re(s);
|
|
261
|
+
const r = S.current;
|
|
262
|
+
S.current = void 0, de.current = {
|
|
252
263
|
content: e,
|
|
253
|
-
body: { conversationId: s }
|
|
264
|
+
body: { conversationId: s },
|
|
265
|
+
files: r
|
|
254
266
|
}, q(
|
|
255
|
-
{ text: e },
|
|
267
|
+
r ? { parts: [{ type: "text", text: e }, ...r] } : { text: e },
|
|
256
268
|
{
|
|
257
269
|
body: { conversationId: s }
|
|
258
270
|
}
|
|
259
271
|
);
|
|
260
|
-
},
|
|
272
|
+
}, qe = P(
|
|
261
273
|
(e) => {
|
|
262
274
|
v.current = 0, W.current = e, z(e);
|
|
263
275
|
},
|
|
264
276
|
[z]
|
|
265
|
-
),
|
|
266
|
-
|
|
267
|
-
|
|
277
|
+
), Z = P(() => {
|
|
278
|
+
_().then(() => {
|
|
279
|
+
T("aborted", { conversationId: t });
|
|
268
280
|
});
|
|
269
|
-
}, [
|
|
270
|
-
|
|
281
|
+
}, [_, t, T]), Ce = () => {
|
|
282
|
+
We(), d([]), u(""), k([]), N(null), l(), S.current = C?.length ? C : void 0, h({
|
|
271
283
|
eventName: "chat_clear_button_clicked",
|
|
272
284
|
properties: {
|
|
273
285
|
conversationId: t
|
|
274
286
|
}
|
|
275
287
|
});
|
|
276
|
-
},
|
|
288
|
+
}, F = P(
|
|
277
289
|
(e, s) => {
|
|
278
|
-
|
|
290
|
+
I(null), d(s), u(e), k([]), N(null), l(), S.current = void 0;
|
|
279
291
|
},
|
|
280
|
-
[d,
|
|
281
|
-
),
|
|
292
|
+
[d, u, l]
|
|
293
|
+
), ze = P(
|
|
282
294
|
async (e, s) => {
|
|
283
|
-
|
|
295
|
+
Z(), F(e, []), pe(!0);
|
|
284
296
|
try {
|
|
285
|
-
const
|
|
286
|
-
id:
|
|
297
|
+
const r = await ue(e, s), n = r?.[r.length - 1], a = r !== null && n?.role === "user" ? [...r, {
|
|
298
|
+
id: D(16),
|
|
287
299
|
role: "assistant",
|
|
288
300
|
parts: [{ type: "text", text: "This session was interrupted. Please check back in a few minutes or start a new conversation." }]
|
|
289
|
-
}] :
|
|
290
|
-
a !== null &&
|
|
301
|
+
}] : r;
|
|
302
|
+
a !== null && F(e, a);
|
|
291
303
|
} finally {
|
|
292
|
-
s?.aborted ||
|
|
304
|
+
s?.aborted || pe(!1);
|
|
293
305
|
}
|
|
294
306
|
},
|
|
295
|
-
[
|
|
296
|
-
), { openForm:
|
|
297
|
-
return
|
|
298
|
-
submitMessage:
|
|
307
|
+
[F, ue, Z]
|
|
308
|
+
), { openForm: Je } = ct(), Ge = lt();
|
|
309
|
+
return Ze(f.chatFunctionsRef, () => ({
|
|
310
|
+
submitMessage: V,
|
|
299
311
|
updateInputMessage(e) {
|
|
300
|
-
|
|
312
|
+
x(e);
|
|
301
313
|
},
|
|
302
|
-
clearChat:
|
|
314
|
+
clearChat: Ce,
|
|
303
315
|
openForm: (e) => {
|
|
304
|
-
|
|
316
|
+
Ge?.setView("chat"), Je(e, void 0);
|
|
305
317
|
},
|
|
306
318
|
focusInput: () => {
|
|
307
|
-
|
|
319
|
+
be.current?.focus();
|
|
308
320
|
}
|
|
309
321
|
})), {
|
|
310
|
-
messages:
|
|
322
|
+
messages: O,
|
|
311
323
|
sendMessage: q,
|
|
312
|
-
addToolApprovalResponse:
|
|
313
|
-
isLoading:
|
|
314
|
-
isStreaming:
|
|
315
|
-
isBusy:
|
|
316
|
-
error:
|
|
317
|
-
setError:
|
|
318
|
-
isSubmitDisabled:
|
|
324
|
+
addToolApprovalResponse: qe,
|
|
325
|
+
isLoading: ge,
|
|
326
|
+
isStreaming: ve,
|
|
327
|
+
isBusy: ye,
|
|
328
|
+
error: Ke,
|
|
329
|
+
setError: I,
|
|
330
|
+
isSubmitDisabled: Q,
|
|
319
331
|
input: y,
|
|
320
|
-
handleInputChange:
|
|
321
|
-
handleInputKeyDown:
|
|
322
|
-
handleSubmit:
|
|
323
|
-
stop:
|
|
324
|
-
clear:
|
|
325
|
-
inputRef:
|
|
326
|
-
isMobile:
|
|
332
|
+
handleInputChange: Te,
|
|
333
|
+
handleInputKeyDown: je,
|
|
334
|
+
handleSubmit: V,
|
|
335
|
+
stop: Z,
|
|
336
|
+
clear: Ce,
|
|
337
|
+
inputRef: be,
|
|
338
|
+
isMobile: Ue,
|
|
327
339
|
// Additional state for attachments and workflow
|
|
328
|
-
messageAttachments:
|
|
329
|
-
setMessageAttachments:
|
|
330
|
-
selectedWorkflow:
|
|
331
|
-
setSelectedWorkflow:
|
|
332
|
-
isNewChat:
|
|
340
|
+
messageAttachments: De,
|
|
341
|
+
setMessageAttachments: k,
|
|
342
|
+
selectedWorkflow: $e,
|
|
343
|
+
setSelectedWorkflow: N,
|
|
344
|
+
isNewChat: He,
|
|
333
345
|
conversationId: t,
|
|
334
|
-
restoreSession:
|
|
335
|
-
loadAndRestoreSession:
|
|
336
|
-
isSessionLoading:
|
|
337
|
-
|
|
338
|
-
refreshSession: p ?
|
|
339
|
-
getCaptchaHeader:
|
|
340
|
-
invalidateCaptcha:
|
|
346
|
+
restoreSession: F,
|
|
347
|
+
loadAndRestoreSession: ze,
|
|
348
|
+
isSessionLoading: _e,
|
|
349
|
+
authToken: p ? M : B,
|
|
350
|
+
refreshSession: p ? re : L,
|
|
351
|
+
getCaptchaHeader: A,
|
|
352
|
+
invalidateCaptcha: l
|
|
341
353
|
};
|
|
342
354
|
};
|
|
343
355
|
export {
|
|
344
|
-
|
|
345
|
-
|
|
356
|
+
Y as DEFAULT_ERROR_MESSAGE,
|
|
357
|
+
_t as useInkeepChat
|
|
346
358
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("react/jsx-runtime"),t=require("react"),l=require("./config-provider.cjs"),a=t.createContext(void 0),p=({children:e})=>{const{baseSettings:s,componentType:n}=l.useInkeepConfig(),{tags:o,analyticsProperties:r}=s,i=t.useMemo(()=>({widgetLibraryVersion:"0.15.
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("react/jsx-runtime"),t=require("react"),l=require("./config-provider.cjs"),a=t.createContext(void 0),p=({children:e})=>{const{baseSettings:s,componentType:n}=l.useInkeepConfig(),{tags:o,analyticsProperties:r}=s,i=t.useMemo(()=>({widgetLibraryVersion:"0.15.24",componentType:n,tags:o}),[n,o]),u={logEvent:t.useCallback(async c=>{const v={...i,...c.properties,...r},d={eventName:c.eventName,properties:v};return s.onEvent?.(d)},[s,i,r])};return E.jsx(a.Provider,{value:u,children:e})},g=()=>{const e=t.useContext(a);if(!e)throw new Error("useBaseEvents must be used within a BaseEventsProvider");return e};exports.BaseEventsProvider=p;exports.useBaseEvents=g;
|
|
@@ -5,7 +5,7 @@ import { useInkeepConfig as g } from "./config-provider.js";
|
|
|
5
5
|
const a = d(void 0), P = ({ children: e }) => {
|
|
6
6
|
const { baseSettings: t, componentType: o } = g(), { tags: s, analyticsProperties: n } = t, r = u(
|
|
7
7
|
() => ({
|
|
8
|
-
widgetLibraryVersion: "0.15.
|
|
8
|
+
widgetLibraryVersion: "0.15.24",
|
|
9
9
|
componentType: o,
|
|
10
10
|
tags: s
|
|
11
11
|
}),
|
|
@@ -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 ee=require("react/jsx-runtime"),e=require("react"),te=require("../components/embedded-chat/chat-provider.cjs"),se=require("./config-provider.cjs"),ne=require("../hooks/use-inkeep-api-client.cjs"),U=e.createContext(void 0),K=25;function re(t){const{stop:u,clear:f,conversationId:l,isStreaming:y,loadAndRestoreSession:R,authToken:s,refreshSession:Z,getCaptchaHeader:_,invalidateCaptcha:z}=te.useChat(),{aiChatSettings:B,baseSettings:J}=se.useInkeepConfig(),{baseUrl:S,appId:H,apiKey:Q}=B,a=!!J.getAuthToken,o=!Q&&!!H&&(!!s||a),{fetchWithAuth:I}=ne.useInkeepApiClient({appId:H,authToken:s,getCaptchaHeader:_,invalidateCaptcha:z,refreshSession:Z}),[v,b]=e.useState(!1),[P,E]=e.useState([]),[k,x]=e.useState(!s&&o),[m,q]=e.useState(0),[w,T]=e.useState(!1),h=e.useRef(!1),j=e.useRef(null),M=e.useRef(a),$=e.useRef(s);e.useEffect(()=>{const r=M.current,n=$.current;M.current=a,$.current=s,(r!==a||n!==null&&s!==null&&n!==s)&&(E([]),q(0),T(!1),h.current=!1)},[a,s]);const L=e.useRef([]);L.current=P;const O=e.useRef(I);O.current=I;const c=e.useCallback(async(r,n=!1)=>{if(!(!S||!s||!o)){n||x(!0);try{const C=`${S}/run/v1/conversations?page=${r+1}&limit=${K}`,g=await O.current(C);if(!g.ok)throw new Error(`Failed to fetch conversations: ${g.status}`);const F=await g.json(),p=(F.data??[]).map(i=>({id:i.id,title:i.title??"",createdAt:new Date(i.createdAt),updatedAt:new Date(i.updatedAt)}));E(i=>{if(r===0&&!n)return p;if(r===0&&n){const d=new Set(p.map(A=>A.id));return[...p,...i.slice(K).filter(A=>!d.has(A.id))]}const N=new Set(i.map(d=>d.id));return[...i,...p.filter(d=>!N.has(d.id))]});const{page:W,pages:G}=F.pagination??{};T(W!=null&&G!=null?W<G:!1),n||q(r)}catch(C){console.error("[useChatHistory] Failed to load conversations:",C)}finally{x(!1)}}},[S,s,o]);e.useEffect(()=>{!v||!s&&!a||!o||(t==="stack"?c(0):!h.current&&s&&(h.current=!0,c(0)))},[v,s,a,o,t,c]);const D=e.useRef("");e.useEffect(()=>{o&&t==="sidepane"&&(!l||!y||h.current&&D.current!==l&&(L.current.some(r=>r.id===l)||(D.current=l,c(0,!0))))},[l,o,t,c,y]);const V=e.useCallback(()=>{!k&&w&&c(m+1)},[k,w,m,c]),X=e.useCallback(()=>{u(),f(),t!=="sidepane"&&b(!1)},[t,u,f]),Y=e.useCallback(async r=>{j.current?.abort();const n=new AbortController;j.current=n,await R(r,n.signal),!n.signal.aborted&&t!=="sidepane"&&b(!1)},[t,R]);return{isEnabled:o,isOpen:v,setIsOpen:b,sessions:P,isLoading:k,hasMore:w,loadMore:V,startNewConversation:X,loadSession:Y}}const oe=({layout:t,children:u})=>{const f=re(t);return ee.jsx(U.Provider,{value:f,children:typeof u=="function"?u(f):u})},ie=()=>{const t=e.useContext(U);if(!t)throw new Error("useChatHistory must be used within a ChatHistoryProvider");return t};exports.ChatHistoryProvider=oe;exports.useChatHistory=ie;
|
|
@@ -1,110 +1,110 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as
|
|
3
|
-
import { createContext as
|
|
4
|
-
import { useChat as
|
|
5
|
-
import { useInkeepConfig as
|
|
6
|
-
import { useInkeepApiClient as
|
|
7
|
-
const
|
|
8
|
-
function
|
|
2
|
+
import { jsx as se } from "react/jsx-runtime";
|
|
3
|
+
import { createContext as re, useContext as oe, useState as h, useRef as c, useEffect as H, useCallback as S } from "react";
|
|
4
|
+
import { useChat as ie } from "../components/embedded-chat/chat-provider.js";
|
|
5
|
+
import { useInkeepConfig as ae } from "./config-provider.js";
|
|
6
|
+
import { useInkeepApiClient as ce } from "../hooks/use-inkeep-api-client.js";
|
|
7
|
+
const z = re(void 0), q = 25;
|
|
8
|
+
function ue(e) {
|
|
9
9
|
const {
|
|
10
10
|
stop: u,
|
|
11
11
|
clear: f,
|
|
12
12
|
conversationId: d,
|
|
13
|
-
isStreaming:
|
|
14
|
-
loadAndRestoreSession:
|
|
15
|
-
|
|
16
|
-
refreshSession:
|
|
17
|
-
getCaptchaHeader:
|
|
18
|
-
invalidateCaptcha:
|
|
19
|
-
} =
|
|
20
|
-
appId:
|
|
21
|
-
authToken:
|
|
22
|
-
getCaptchaHeader:
|
|
23
|
-
invalidateCaptcha:
|
|
24
|
-
refreshSession:
|
|
25
|
-
}), [
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
}, [
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
13
|
+
isStreaming: y,
|
|
14
|
+
loadAndRestoreSession: P,
|
|
15
|
+
authToken: t,
|
|
16
|
+
refreshSession: B,
|
|
17
|
+
getCaptchaHeader: J,
|
|
18
|
+
invalidateCaptcha: Q
|
|
19
|
+
} = ie(), { aiChatSettings: V, baseSettings: X } = ae(), { baseUrl: w, appId: x, apiKey: Y } = V, i = !!X.getAuthToken, r = !Y && !!x && (!!t || i), { fetchWithAuth: E } = ce({
|
|
20
|
+
appId: x,
|
|
21
|
+
authToken: t,
|
|
22
|
+
getCaptchaHeader: J,
|
|
23
|
+
invalidateCaptcha: Q,
|
|
24
|
+
refreshSession: B
|
|
25
|
+
}), [m, A] = h(!1), [R, T] = h([]), [b, $] = h(!t && r), [L, M] = h(0), [k, j] = h(!1), p = c(!1), D = c(null), F = c(i), O = c(t);
|
|
26
|
+
H(() => {
|
|
27
|
+
const s = F.current, n = O.current;
|
|
28
|
+
F.current = i, O.current = t, (s !== i || n !== null && t !== null && n !== t) && (T([]), M(0), j(!1), p.current = !1);
|
|
29
|
+
}, [i, t]);
|
|
30
|
+
const W = c([]);
|
|
31
|
+
W.current = R;
|
|
32
|
+
const G = c(E);
|
|
33
|
+
G.current = E;
|
|
34
34
|
const a = S(
|
|
35
|
-
async (
|
|
36
|
-
if (!(!w || !
|
|
37
|
-
|
|
35
|
+
async (s, n = !1) => {
|
|
36
|
+
if (!(!w || !t || !r)) {
|
|
37
|
+
n || $(!0);
|
|
38
38
|
try {
|
|
39
|
-
const C = `${w}/run/v1/conversations?page=${
|
|
39
|
+
const C = `${w}/run/v1/conversations?page=${s + 1}&limit=${q}`, g = await G.current(C);
|
|
40
40
|
if (!g.ok) throw new Error(`Failed to fetch conversations: ${g.status}`);
|
|
41
|
-
const
|
|
42
|
-
id:
|
|
43
|
-
title:
|
|
44
|
-
createdAt: new Date(
|
|
45
|
-
updatedAt: new Date(
|
|
41
|
+
const U = await g.json(), v = (U.data ?? []).map((o) => ({
|
|
42
|
+
id: o.id,
|
|
43
|
+
title: o.title ?? "",
|
|
44
|
+
createdAt: new Date(o.createdAt),
|
|
45
|
+
updatedAt: new Date(o.updatedAt)
|
|
46
46
|
}));
|
|
47
|
-
|
|
48
|
-
if (
|
|
49
|
-
if (
|
|
50
|
-
const l = new Set(v.map((
|
|
51
|
-
return [...v, ...
|
|
47
|
+
T((o) => {
|
|
48
|
+
if (s === 0 && !n) return v;
|
|
49
|
+
if (s === 0 && n) {
|
|
50
|
+
const l = new Set(v.map((I) => I.id));
|
|
51
|
+
return [...v, ...o.slice(q).filter((I) => !l.has(I.id))];
|
|
52
52
|
}
|
|
53
|
-
const
|
|
54
|
-
return [...
|
|
53
|
+
const ne = new Set(o.map((l) => l.id));
|
|
54
|
+
return [...o, ...v.filter((l) => !ne.has(l.id))];
|
|
55
55
|
});
|
|
56
|
-
const { page:
|
|
57
|
-
|
|
56
|
+
const { page: Z, pages: _ } = U.pagination ?? {};
|
|
57
|
+
j(Z != null && _ != null ? Z < _ : !1), n || M(s);
|
|
58
58
|
} catch (C) {
|
|
59
59
|
console.error("[useChatHistory] Failed to load conversations:", C);
|
|
60
60
|
} finally {
|
|
61
|
-
|
|
61
|
+
$(!1);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
|
-
[w,
|
|
65
|
+
[w, t, r]
|
|
66
66
|
);
|
|
67
|
-
|
|
68
|
-
!
|
|
69
|
-
}, [
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}, [d,
|
|
74
|
-
const
|
|
75
|
-
!b &&
|
|
76
|
-
}, [b,
|
|
77
|
-
u(), f(), e !== "sidepane" &&
|
|
78
|
-
}, [e, u, f]),
|
|
79
|
-
async (
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
67
|
+
H(() => {
|
|
68
|
+
!m || !t && !i || !r || (e === "stack" ? a(0) : !p.current && t && (p.current = !0, a(0)));
|
|
69
|
+
}, [m, t, i, r, e, a]);
|
|
70
|
+
const K = c("");
|
|
71
|
+
H(() => {
|
|
72
|
+
r && e === "sidepane" && (!d || !y || p.current && K.current !== d && (W.current.some((s) => s.id === d) || (K.current = d, a(0, !0))));
|
|
73
|
+
}, [d, r, e, a, y]);
|
|
74
|
+
const N = S(() => {
|
|
75
|
+
!b && k && a(L + 1);
|
|
76
|
+
}, [b, k, L, a]), ee = S(() => {
|
|
77
|
+
u(), f(), e !== "sidepane" && A(!1);
|
|
78
|
+
}, [e, u, f]), te = S(
|
|
79
|
+
async (s) => {
|
|
80
|
+
D.current?.abort();
|
|
81
|
+
const n = new AbortController();
|
|
82
|
+
D.current = n, await P(s, n.signal), !n.signal.aborted && e !== "sidepane" && A(!1);
|
|
83
83
|
},
|
|
84
|
-
[e,
|
|
84
|
+
[e, P]
|
|
85
85
|
);
|
|
86
86
|
return {
|
|
87
|
-
isEnabled:
|
|
88
|
-
isOpen:
|
|
89
|
-
setIsOpen:
|
|
90
|
-
sessions:
|
|
87
|
+
isEnabled: r,
|
|
88
|
+
isOpen: m,
|
|
89
|
+
setIsOpen: A,
|
|
90
|
+
sessions: R,
|
|
91
91
|
isLoading: b,
|
|
92
|
-
hasMore:
|
|
93
|
-
loadMore:
|
|
94
|
-
startNewConversation:
|
|
95
|
-
loadSession:
|
|
92
|
+
hasMore: k,
|
|
93
|
+
loadMore: N,
|
|
94
|
+
startNewConversation: ee,
|
|
95
|
+
loadSession: te
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
|
-
const
|
|
99
|
-
const f =
|
|
100
|
-
return /* @__PURE__ */
|
|
101
|
-
},
|
|
102
|
-
const e =
|
|
98
|
+
const ge = ({ layout: e, children: u }) => {
|
|
99
|
+
const f = ue(e);
|
|
100
|
+
return /* @__PURE__ */ se(z.Provider, { value: f, children: typeof u == "function" ? u(f) : u });
|
|
101
|
+
}, ve = () => {
|
|
102
|
+
const e = oe(z);
|
|
103
103
|
if (!e)
|
|
104
104
|
throw new Error("useChatHistory must be used within a ChatHistoryProvider");
|
|
105
105
|
return e;
|
|
106
106
|
};
|
|
107
107
|
export {
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
ge as ChatHistoryProvider,
|
|
109
|
+
ve as useChatHistory
|
|
110
110
|
};
|
|
@@ -2,6 +2,7 @@ import { AIChatFormSettings } from './settings/form';
|
|
|
2
2
|
import { GetHelpOption, CustomMessageAction } from './settings/actions';
|
|
3
3
|
import { SearchAndChatFilters } from './filters';
|
|
4
4
|
import { ComponentsConfig } from './components';
|
|
5
|
+
import { FileUIPart } from 'ai';
|
|
5
6
|
export interface InkeepAIChatSettings {
|
|
6
7
|
/**
|
|
7
8
|
* Headers for requests
|
|
@@ -30,6 +31,13 @@ export interface InkeepAIChatSettings {
|
|
|
30
31
|
* Context to be passed to the chatstream API.
|
|
31
32
|
*/
|
|
32
33
|
context?: Record<string, unknown>;
|
|
34
|
+
/**
|
|
35
|
+
* Files to be passed to the chatstream API.
|
|
36
|
+
* Attached to the next outgoing message. Re-queued whenever the array content changes (diffed by filename, mediaType, and size), so new or updated files are sent on the next message. Already-sent files are not re-attached unless the content changes.
|
|
37
|
+
*
|
|
38
|
+
* @beta This type is subject to change.
|
|
39
|
+
*/
|
|
40
|
+
files?: FileUIPart[];
|
|
33
41
|
/**
|
|
34
42
|
* The placeholder text to display in the chat input field when empty.
|
|
35
43
|
* Use this to provide guidance on what kind of questions users can ask.
|