@inkeep/agents-ui 0.15.26 → 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 +277 -237
  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,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 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);
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 = 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(), [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.`, 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
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 [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
- 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
+ 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 = Ae(
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
- ...W.current ? { "inkeep-filters": W.current } : {},
116
- ...q.current ? { "x-inkeep-user-properties": q.current } : {},
117
- ...me.current
117
+ ...j.current ? { "inkeep-filters": j.current } : {},
118
+ ...K.current ? { "x-inkeep-user-properties": K.current } : {},
119
+ ...he.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 ue.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: le
138
140
  }
139
141
  }),
140
- [le, ae, b, g]
142
+ [pe, le, w, 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: 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: s }), await h({
157
+ x("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,231 @@ 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 = 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 (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" && 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();
184
+ c();
183
185
  if (t) {
184
- z(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
- }), 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
+ }), 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 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 = te;
201
+ return f.role === "user" ? o.push({
202
+ id: L(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 = 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
- 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
+ }), 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
- }, t = [...O ?? []].reverse().find((a) => a.role === "assistant");
237
+ const n = a;
238
+ return typeof n.type == "string" && n.type.startsWith("tool-");
239
+ }, t = [...P ?? []].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 || 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
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_${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
- }, 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(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, K.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: s });
316
+ [Q]
317
+ ), ee = $(() => {
318
+ O().then(() => {
319
+ x("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
+ }, [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
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
+ }, _ = $(
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, r) => {
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 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 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
341
  }] : t;
302
- a !== null && F(e, a);
342
+ a !== null && _(e, a);
303
343
  } finally {
304
- r?.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: 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,
339
- // Additional state for attachments and workflow
340
- messageAttachments: De,
341
- setMessageAttachments: k,
342
- selectedWorkflow: $e,
343
- setSelectedWorkflow: N,
362
+ messages: P,
363
+ sendMessage: G,
364
+ addToolApprovalResponse: Qe,
365
+ isLoading: ve,
366
+ isStreaming: be,
367
+ isBusy: Ce,
368
+ error: Ke,
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
382
  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
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
  };