@inkeep/agents-ui 0.15.25 → 0.15.27

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