@inkeep/agents-ui 0.17.6 → 0.17.8

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