@inkeep/agents-ui 0.0.0-dev-20260401193828 → 0.0.0-dev-20260402200940

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