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