reachat 2.1.2 → 3.0.0

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 (65) hide show
  1. package/dist/{CSVFileRenderer-DXI8PDqR.js → CSVFileRenderer-C2tuexJf.js} +2 -2
  2. package/dist/{CSVFileRenderer-DXI8PDqR.js.map → CSVFileRenderer-C2tuexJf.js.map} +1 -1
  3. package/dist/Chat.d.ts +12 -0
  4. package/dist/{Markdown/charts/ChartError.d.ts → ComponentCatalog/ComponentError.d.ts} +2 -2
  5. package/dist/ComponentCatalog/ComponentPre.d.ts +18 -0
  6. package/dist/ComponentCatalog/ComponentRenderer.d.ts +17 -0
  7. package/dist/ComponentCatalog/chartComponentDef.d.ts +36 -0
  8. package/dist/ComponentCatalog/componentCatalog.d.ts +44 -0
  9. package/dist/ComponentCatalog/componentCatalog.spec.d.ts +1 -0
  10. package/dist/ComponentCatalog/generatePrompt.d.ts +9 -0
  11. package/dist/ComponentCatalog/generatePrompt.spec.d.ts +1 -0
  12. package/dist/ComponentCatalog/index.d.ts +9 -0
  13. package/dist/ComponentCatalog/types.d.ts +108 -0
  14. package/dist/ComponentCatalog/validateSpec.d.ts +17 -0
  15. package/dist/ComponentCatalog/validateSpec.spec.d.ts +1 -0
  16. package/dist/{DefaultFileRenderer-Bi8LNDio.js → DefaultFileRenderer-CJ3jwiQa.js} +3 -3
  17. package/dist/{DefaultFileRenderer-Bi8LNDio.js.map → DefaultFileRenderer-CJ3jwiQa.js.map} +1 -1
  18. package/dist/Markdown/charts/ChartRenderer.d.ts +1 -1
  19. package/dist/Markdown/charts/ComponentError.d.ts +1 -0
  20. package/dist/Markdown/charts/index.d.ts +2 -6
  21. package/dist/Markdown/charts/types.d.ts +21 -0
  22. package/dist/Markdown/plugins/index.d.ts +3 -1
  23. package/dist/Markdown/plugins/redactMatchers.d.ts +21 -0
  24. package/dist/Markdown/plugins/remarkComponent.d.ts +27 -0
  25. package/dist/Markdown/plugins/remarkRedact.d.ts +37 -0
  26. package/dist/SessionMessages/SessionMessage/MessageActions.d.ts +2 -2
  27. package/dist/SessionMessages/SessionMessage/MessageFiles.d.ts +2 -2
  28. package/dist/SessionMessages/SessionMessage/MessageQuestion.d.ts +2 -2
  29. package/dist/SessionMessages/SessionMessage/MessageResponse.d.ts +2 -2
  30. package/dist/SessionMessages/SessionMessage/MessageSources.d.ts +2 -2
  31. package/dist/SessionMessages/SessionMessage/SessionMessage.d.ts +2 -2
  32. package/dist/SessionsList/SessionListItem.d.ts +2 -2
  33. package/dist/docs.json +264 -90
  34. package/dist/{index-CBHNcMyR.js → index-8tlsyFe-.js} +1224 -1576
  35. package/dist/index-8tlsyFe-.js.map +1 -0
  36. package/dist/index.css +32 -1
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.js +53 -46
  39. package/dist/index.umd.cjs +1220 -1574
  40. package/dist/index.umd.cjs.map +1 -1
  41. package/dist/stories/AgUi.stories.tsx +118 -0
  42. package/dist/stories/Charts.stories.tsx +118 -130
  43. package/dist/stories/Chat.stories.tsx +6 -1
  44. package/dist/stories/ChatSuggestions.stories.tsx +9 -81
  45. package/dist/stories/Companion.stories.tsx +7 -1
  46. package/dist/stories/ComponentCatalog.stories.tsx +509 -0
  47. package/dist/stories/{ChartError.stories.tsx → ComponentError.stories.tsx} +14 -11
  48. package/dist/stories/Console.stories.tsx +66 -21
  49. package/dist/stories/EnhancedInput.stories.tsx +7 -1
  50. package/dist/stories/Redact.stories.tsx +175 -0
  51. package/dist/stories/examples.ts +31 -0
  52. package/dist/theme.d.ts +3 -0
  53. package/dist/useAgUi/index.d.ts +4 -0
  54. package/dist/useAgUi/types.d.ts +157 -0
  55. package/dist/useAgUi/useAgUi.d.ts +119 -0
  56. package/dist/useAgUi/useAgUi.spec.d.ts +1 -0
  57. package/dist/utils/getChildText.d.ts +10 -0
  58. package/dist/utils/getChildText.spec.d.ts +1 -0
  59. package/package.json +6 -6
  60. package/dist/Markdown/charts/ChartPre.d.ts +0 -6
  61. package/dist/Markdown/charts/chartHelpers.d.ts +0 -40
  62. package/dist/Markdown/plugins/remarkChart.d.ts +0 -59
  63. package/dist/index-CBHNcMyR.js.map +0 -1
  64. package/dist/stories/Integration.stories.tsx +0 -312
  65. /package/dist/{Markdown/charts/chartHelpers.spec.d.ts → ComponentCatalog/chartComponentDef.spec.d.ts} +0 -0
@@ -1,8 +1,9 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
- import { createContext, useContext, useRef, forwardRef, useState, useEffect, useCallback, useImperativeHandle, useMemo, lazy, Suspense, memo, isValidElement, cloneElement } from "react";
4
- import { Button, cn, List, ListItem, Ellipsis, DateFormat, IconButton, Card, useInfinityList, useComponentTheme, ConnectedOverlay } from "reablocks";
3
+ import { createContext, useContext, useRef, forwardRef, useState, useEffect, useCallback, useImperativeHandle, memo, useMemo, lazy, Suspense, isValidElement, cloneElement, Component } from "react";
4
+ import { Button, cn, List, ListItem, Ellipsis, DateFormat, Redact, IconButton, Card, useInfinityList, useComponentTheme, ConnectedOverlay } from "reablocks";
5
5
  import { useEditor, EditorContent, ReactRenderer, posToDOMRect } from "@tiptap/react";
6
+ import { computePosition, shift, flip } from "@floating-ui/dom";
6
7
  import Document from "@tiptap/extension-document";
7
8
  import Paragraph from "@tiptap/extension-paragraph";
8
9
  import Text from "@tiptap/extension-text";
@@ -14,9 +15,9 @@ import { motion, AnimatePresence } from "motion/react";
14
15
  import ReactMarkdown from "react-markdown";
15
16
  import { Prism } from "react-syntax-highlighter";
16
17
  import rehypeKatex from "rehype-katex";
18
+ import rehypeRaw from "rehype-raw";
17
19
  import { SparklineChart, RadialAreaChart, RadialAreaSeries, RadialBarChart, RadialBarSeries, PieChart, PieArcSeries, AreaChart, AreaSeries, LinearYAxis, LinearXAxis, LineChart, LineSeries, BarChart, BarSeries } from "reaviz";
18
20
  import { findAndReplace } from "mdast-util-find-and-replace";
19
- import { visit } from "unist-util-visit";
20
21
  import debounce from "lodash/debounce.js";
21
22
  import { useHotkeys } from "reakeys";
22
23
  import remarkGfm from "remark-gfm";
@@ -24,6 +25,7 @@ import remarkYoutube from "remark-youtube";
24
25
  import remarkMath from "remark-math";
25
26
  import { isToday, isYesterday, isThisWeek, differenceInYears, format } from "date-fns";
26
27
  import { offset } from "@floating-ui/react";
28
+ import { z } from "zod";
27
29
  const SvgSend = (props) => /* @__PURE__ */ React.createElement("svg", { width: 17, height: 17, viewBox: "0 0 17 17", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props }, /* @__PURE__ */ React.createElement("g", { id: "send" }, /* @__PURE__ */ React.createElement("path", { id: "Vector", d: "M14.6111 2.33327C14.5349 2.3339 14.4598 2.35194 14.3917 2.386L2.39168 8.386C2.31456 8.42456 2.24872 8.4824 2.20055 8.55391C2.15238 8.62543 2.12352 8.70818 2.11677 8.79414C2.11002 8.88009 2.12561 8.96634 2.16203 9.04449C2.19845 9.12264 2.25446 9.19005 2.32462 9.24017L4.52514 10.8124L5.47371 13.6581C5.50257 13.7447 5.55457 13.8217 5.62406 13.8808C5.69355 13.9399 5.7779 13.9789 5.86796 13.9935C5.95802 14.0082 6.05036 13.9979 6.13499 13.9638C6.21962 13.9297 6.2933 13.873 6.34806 13.8001L7.05249 12.8606L10.3207 15.2376C10.3843 15.2839 10.4579 15.3146 10.5355 15.3271C10.6132 15.3396 10.6927 15.3336 10.7676 15.3097C10.8425 15.2857 10.9107 15.2444 10.9667 15.1891C11.0226 15.1338 11.0647 15.0661 11.0896 14.9915L15.0896 2.99147C15.1148 2.91597 15.1216 2.83555 15.1094 2.7569C15.0972 2.67825 15.0665 2.60363 15.0197 2.53926C14.9729 2.47488 14.9114 2.42261 14.8403 2.38678C14.7693 2.35096 14.6907 2.33261 14.6111 2.33327ZM13.2478 5.35345L10.3565 14.0266L7.67293 12.0755L13.2478 5.35345ZM10.684 5.35801L4.934 9.87559L3.58113 8.90879L10.684 5.35801ZM11.2784 6.16205L6.56746 11.843C6.56681 11.8437 6.56616 11.8443 6.56551 11.845L6.56355 11.8476C6.55841 11.8538 6.55342 11.8601 6.54858 11.8665C6.54319 11.8733 6.53798 11.8802 6.53295 11.8873L6.12085 12.4361L5.53426 10.6751L11.2784 6.16205Z", fill: "currentColor" })));
28
30
  const SvgStop = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1, strokeLinecap: "round", strokeLinejoin: "round", className: "lucide lucide-octagon-x", ...props }, /* @__PURE__ */ React.createElement("path", { d: "m15 9-6 6" }), /* @__PURE__ */ React.createElement("path", { d: "M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z" }), /* @__PURE__ */ React.createElement("path", { d: "m9 9 6 6" }));
29
31
  const ChatContext = createContext({
@@ -72,1116 +74,6 @@ const FileInput = ({
72
74
  )
73
75
  ] });
74
76
  };
75
- const min = Math.min;
76
- const max = Math.max;
77
- const round = Math.round;
78
- const createCoords = (v) => ({
79
- x: v,
80
- y: v
81
- });
82
- const oppositeSideMap = {
83
- left: "right",
84
- right: "left",
85
- bottom: "top",
86
- top: "bottom"
87
- };
88
- const oppositeAlignmentMap = {
89
- start: "end",
90
- end: "start"
91
- };
92
- function clamp(start, value, end) {
93
- return max(start, min(value, end));
94
- }
95
- function evaluate(value, param) {
96
- return typeof value === "function" ? value(param) : value;
97
- }
98
- function getSide(placement) {
99
- return placement.split("-")[0];
100
- }
101
- function getAlignment(placement) {
102
- return placement.split("-")[1];
103
- }
104
- function getOppositeAxis(axis) {
105
- return axis === "x" ? "y" : "x";
106
- }
107
- function getAxisLength(axis) {
108
- return axis === "y" ? "height" : "width";
109
- }
110
- const yAxisSides = /* @__PURE__ */ new Set(["top", "bottom"]);
111
- function getSideAxis(placement) {
112
- return yAxisSides.has(getSide(placement)) ? "y" : "x";
113
- }
114
- function getAlignmentAxis(placement) {
115
- return getOppositeAxis(getSideAxis(placement));
116
- }
117
- function getAlignmentSides(placement, rects, rtl) {
118
- if (rtl === void 0) {
119
- rtl = false;
120
- }
121
- const alignment = getAlignment(placement);
122
- const alignmentAxis = getAlignmentAxis(placement);
123
- const length = getAxisLength(alignmentAxis);
124
- let mainAlignmentSide = alignmentAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top";
125
- if (rects.reference[length] > rects.floating[length]) {
126
- mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
127
- }
128
- return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
129
- }
130
- function getExpandedPlacements(placement) {
131
- const oppositePlacement = getOppositePlacement(placement);
132
- return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
133
- }
134
- function getOppositeAlignmentPlacement(placement) {
135
- return placement.replace(/start|end/g, (alignment) => oppositeAlignmentMap[alignment]);
136
- }
137
- const lrPlacement = ["left", "right"];
138
- const rlPlacement = ["right", "left"];
139
- const tbPlacement = ["top", "bottom"];
140
- const btPlacement = ["bottom", "top"];
141
- function getSideList(side, isStart, rtl) {
142
- switch (side) {
143
- case "top":
144
- case "bottom":
145
- if (rtl) return isStart ? rlPlacement : lrPlacement;
146
- return isStart ? lrPlacement : rlPlacement;
147
- case "left":
148
- case "right":
149
- return isStart ? tbPlacement : btPlacement;
150
- default:
151
- return [];
152
- }
153
- }
154
- function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
155
- const alignment = getAlignment(placement);
156
- let list = getSideList(getSide(placement), direction === "start", rtl);
157
- if (alignment) {
158
- list = list.map((side) => side + "-" + alignment);
159
- if (flipAlignment) {
160
- list = list.concat(list.map(getOppositeAlignmentPlacement));
161
- }
162
- }
163
- return list;
164
- }
165
- function getOppositePlacement(placement) {
166
- return placement.replace(/left|right|bottom|top/g, (side) => oppositeSideMap[side]);
167
- }
168
- function expandPaddingObject(padding) {
169
- return {
170
- top: 0,
171
- right: 0,
172
- bottom: 0,
173
- left: 0,
174
- ...padding
175
- };
176
- }
177
- function getPaddingObject(padding) {
178
- return typeof padding !== "number" ? expandPaddingObject(padding) : {
179
- top: padding,
180
- right: padding,
181
- bottom: padding,
182
- left: padding
183
- };
184
- }
185
- function rectToClientRect(rect) {
186
- const {
187
- x,
188
- y,
189
- width,
190
- height
191
- } = rect;
192
- return {
193
- width,
194
- height,
195
- top: y,
196
- left: x,
197
- right: x + width,
198
- bottom: y + height,
199
- x,
200
- y
201
- };
202
- }
203
- function computeCoordsFromPlacement(_ref, placement, rtl) {
204
- let {
205
- reference,
206
- floating
207
- } = _ref;
208
- const sideAxis = getSideAxis(placement);
209
- const alignmentAxis = getAlignmentAxis(placement);
210
- const alignLength = getAxisLength(alignmentAxis);
211
- const side = getSide(placement);
212
- const isVertical = sideAxis === "y";
213
- const commonX = reference.x + reference.width / 2 - floating.width / 2;
214
- const commonY = reference.y + reference.height / 2 - floating.height / 2;
215
- const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;
216
- let coords;
217
- switch (side) {
218
- case "top":
219
- coords = {
220
- x: commonX,
221
- y: reference.y - floating.height
222
- };
223
- break;
224
- case "bottom":
225
- coords = {
226
- x: commonX,
227
- y: reference.y + reference.height
228
- };
229
- break;
230
- case "right":
231
- coords = {
232
- x: reference.x + reference.width,
233
- y: commonY
234
- };
235
- break;
236
- case "left":
237
- coords = {
238
- x: reference.x - floating.width,
239
- y: commonY
240
- };
241
- break;
242
- default:
243
- coords = {
244
- x: reference.x,
245
- y: reference.y
246
- };
247
- }
248
- switch (getAlignment(placement)) {
249
- case "start":
250
- coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
251
- break;
252
- case "end":
253
- coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
254
- break;
255
- }
256
- return coords;
257
- }
258
- const computePosition$1 = async (reference, floating, config) => {
259
- const {
260
- placement = "bottom",
261
- strategy = "absolute",
262
- middleware = [],
263
- platform: platform2
264
- } = config;
265
- const validMiddleware = middleware.filter(Boolean);
266
- const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(floating));
267
- let rects = await platform2.getElementRects({
268
- reference,
269
- floating,
270
- strategy
271
- });
272
- let {
273
- x,
274
- y
275
- } = computeCoordsFromPlacement(rects, placement, rtl);
276
- let statefulPlacement = placement;
277
- let middlewareData = {};
278
- let resetCount = 0;
279
- for (let i = 0; i < validMiddleware.length; i++) {
280
- const {
281
- name,
282
- fn
283
- } = validMiddleware[i];
284
- const {
285
- x: nextX,
286
- y: nextY,
287
- data,
288
- reset
289
- } = await fn({
290
- x,
291
- y,
292
- initialPlacement: placement,
293
- placement: statefulPlacement,
294
- strategy,
295
- middlewareData,
296
- rects,
297
- platform: platform2,
298
- elements: {
299
- reference,
300
- floating
301
- }
302
- });
303
- x = nextX != null ? nextX : x;
304
- y = nextY != null ? nextY : y;
305
- middlewareData = {
306
- ...middlewareData,
307
- [name]: {
308
- ...middlewareData[name],
309
- ...data
310
- }
311
- };
312
- if (reset && resetCount <= 50) {
313
- resetCount++;
314
- if (typeof reset === "object") {
315
- if (reset.placement) {
316
- statefulPlacement = reset.placement;
317
- }
318
- if (reset.rects) {
319
- rects = reset.rects === true ? await platform2.getElementRects({
320
- reference,
321
- floating,
322
- strategy
323
- }) : reset.rects;
324
- }
325
- ({
326
- x,
327
- y
328
- } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
329
- }
330
- i = -1;
331
- }
332
- }
333
- return {
334
- x,
335
- y,
336
- placement: statefulPlacement,
337
- strategy,
338
- middlewareData
339
- };
340
- };
341
- async function detectOverflow(state, options) {
342
- var _await$platform$isEle;
343
- if (options === void 0) {
344
- options = {};
345
- }
346
- const {
347
- x,
348
- y,
349
- platform: platform2,
350
- rects,
351
- elements,
352
- strategy
353
- } = state;
354
- const {
355
- boundary = "clippingAncestors",
356
- rootBoundary = "viewport",
357
- elementContext = "floating",
358
- altBoundary = false,
359
- padding = 0
360
- } = evaluate(options, state);
361
- const paddingObject = getPaddingObject(padding);
362
- const altContext = elementContext === "floating" ? "reference" : "floating";
363
- const element = elements[altBoundary ? altContext : elementContext];
364
- const clippingClientRect = rectToClientRect(await platform2.getClippingRect({
365
- element: ((_await$platform$isEle = await (platform2.isElement == null ? void 0 : platform2.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || await (platform2.getDocumentElement == null ? void 0 : platform2.getDocumentElement(elements.floating)),
366
- boundary,
367
- rootBoundary,
368
- strategy
369
- }));
370
- const rect = elementContext === "floating" ? {
371
- x,
372
- y,
373
- width: rects.floating.width,
374
- height: rects.floating.height
375
- } : rects.reference;
376
- const offsetParent = await (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating));
377
- const offsetScale = await (platform2.isElement == null ? void 0 : platform2.isElement(offsetParent)) ? await (platform2.getScale == null ? void 0 : platform2.getScale(offsetParent)) || {
378
- x: 1,
379
- y: 1
380
- } : {
381
- x: 1,
382
- y: 1
383
- };
384
- const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform2.convertOffsetParentRelativeRectToViewportRelativeRect({
385
- elements,
386
- rect,
387
- offsetParent,
388
- strategy
389
- }) : rect);
390
- return {
391
- top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
392
- bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
393
- left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
394
- right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
395
- };
396
- }
397
- const flip$1 = function(options) {
398
- if (options === void 0) {
399
- options = {};
400
- }
401
- return {
402
- name: "flip",
403
- options,
404
- async fn(state) {
405
- var _middlewareData$arrow, _middlewareData$flip;
406
- const {
407
- placement,
408
- middlewareData,
409
- rects,
410
- initialPlacement,
411
- platform: platform2,
412
- elements
413
- } = state;
414
- const {
415
- mainAxis: checkMainAxis = true,
416
- crossAxis: checkCrossAxis = true,
417
- fallbackPlacements: specifiedFallbackPlacements,
418
- fallbackStrategy = "bestFit",
419
- fallbackAxisSideDirection = "none",
420
- flipAlignment = true,
421
- ...detectOverflowOptions
422
- } = evaluate(options, state);
423
- if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
424
- return {};
425
- }
426
- const side = getSide(placement);
427
- const initialSideAxis = getSideAxis(initialPlacement);
428
- const isBasePlacement = getSide(initialPlacement) === initialPlacement;
429
- const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
430
- const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
431
- const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== "none";
432
- if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) {
433
- fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
434
- }
435
- const placements = [initialPlacement, ...fallbackPlacements];
436
- const overflow = await detectOverflow(state, detectOverflowOptions);
437
- const overflows = [];
438
- let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
439
- if (checkMainAxis) {
440
- overflows.push(overflow[side]);
441
- }
442
- if (checkCrossAxis) {
443
- const sides = getAlignmentSides(placement, rects, rtl);
444
- overflows.push(overflow[sides[0]], overflow[sides[1]]);
445
- }
446
- overflowsData = [...overflowsData, {
447
- placement,
448
- overflows
449
- }];
450
- if (!overflows.every((side2) => side2 <= 0)) {
451
- var _middlewareData$flip2, _overflowsData$filter;
452
- const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
453
- const nextPlacement = placements[nextIndex];
454
- if (nextPlacement) {
455
- const ignoreCrossAxisOverflow = checkCrossAxis === "alignment" ? initialSideAxis !== getSideAxis(nextPlacement) : false;
456
- if (!ignoreCrossAxisOverflow || // We leave the current main axis only if every placement on that axis
457
- // overflows the main axis.
458
- overflowsData.every((d) => getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) {
459
- return {
460
- data: {
461
- index: nextIndex,
462
- overflows: overflowsData
463
- },
464
- reset: {
465
- placement: nextPlacement
466
- }
467
- };
468
- }
469
- }
470
- let resetPlacement = (_overflowsData$filter = overflowsData.filter((d) => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;
471
- if (!resetPlacement) {
472
- switch (fallbackStrategy) {
473
- case "bestFit": {
474
- var _overflowsData$filter2;
475
- const placement2 = (_overflowsData$filter2 = overflowsData.filter((d) => {
476
- if (hasFallbackAxisSideDirection) {
477
- const currentSideAxis = getSideAxis(d.placement);
478
- return currentSideAxis === initialSideAxis || // Create a bias to the `y` side axis due to horizontal
479
- // reading directions favoring greater width.
480
- currentSideAxis === "y";
481
- }
482
- return true;
483
- }).map((d) => [d.placement, d.overflows.filter((overflow2) => overflow2 > 0).reduce((acc, overflow2) => acc + overflow2, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0];
484
- if (placement2) {
485
- resetPlacement = placement2;
486
- }
487
- break;
488
- }
489
- case "initialPlacement":
490
- resetPlacement = initialPlacement;
491
- break;
492
- }
493
- }
494
- if (placement !== resetPlacement) {
495
- return {
496
- reset: {
497
- placement: resetPlacement
498
- }
499
- };
500
- }
501
- }
502
- return {};
503
- }
504
- };
505
- };
506
- const shift$1 = function(options) {
507
- if (options === void 0) {
508
- options = {};
509
- }
510
- return {
511
- name: "shift",
512
- options,
513
- async fn(state) {
514
- const {
515
- x,
516
- y,
517
- placement
518
- } = state;
519
- const {
520
- mainAxis: checkMainAxis = true,
521
- crossAxis: checkCrossAxis = false,
522
- limiter = {
523
- fn: (_ref) => {
524
- let {
525
- x: x2,
526
- y: y2
527
- } = _ref;
528
- return {
529
- x: x2,
530
- y: y2
531
- };
532
- }
533
- },
534
- ...detectOverflowOptions
535
- } = evaluate(options, state);
536
- const coords = {
537
- x,
538
- y
539
- };
540
- const overflow = await detectOverflow(state, detectOverflowOptions);
541
- const crossAxis = getSideAxis(getSide(placement));
542
- const mainAxis = getOppositeAxis(crossAxis);
543
- let mainAxisCoord = coords[mainAxis];
544
- let crossAxisCoord = coords[crossAxis];
545
- if (checkMainAxis) {
546
- const minSide = mainAxis === "y" ? "top" : "left";
547
- const maxSide = mainAxis === "y" ? "bottom" : "right";
548
- const min2 = mainAxisCoord + overflow[minSide];
549
- const max2 = mainAxisCoord - overflow[maxSide];
550
- mainAxisCoord = clamp(min2, mainAxisCoord, max2);
551
- }
552
- if (checkCrossAxis) {
553
- const minSide = crossAxis === "y" ? "top" : "left";
554
- const maxSide = crossAxis === "y" ? "bottom" : "right";
555
- const min2 = crossAxisCoord + overflow[minSide];
556
- const max2 = crossAxisCoord - overflow[maxSide];
557
- crossAxisCoord = clamp(min2, crossAxisCoord, max2);
558
- }
559
- const limitedCoords = limiter.fn({
560
- ...state,
561
- [mainAxis]: mainAxisCoord,
562
- [crossAxis]: crossAxisCoord
563
- });
564
- return {
565
- ...limitedCoords,
566
- data: {
567
- x: limitedCoords.x - x,
568
- y: limitedCoords.y - y,
569
- enabled: {
570
- [mainAxis]: checkMainAxis,
571
- [crossAxis]: checkCrossAxis
572
- }
573
- }
574
- };
575
- }
576
- };
577
- };
578
- function hasWindow() {
579
- return typeof window !== "undefined";
580
- }
581
- function getNodeName(node) {
582
- if (isNode(node)) {
583
- return (node.nodeName || "").toLowerCase();
584
- }
585
- return "#document";
586
- }
587
- function getWindow(node) {
588
- var _node$ownerDocument;
589
- return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
590
- }
591
- function getDocumentElement(node) {
592
- var _ref;
593
- return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
594
- }
595
- function isNode(value) {
596
- if (!hasWindow()) {
597
- return false;
598
- }
599
- return value instanceof Node || value instanceof getWindow(value).Node;
600
- }
601
- function isElement(value) {
602
- if (!hasWindow()) {
603
- return false;
604
- }
605
- return value instanceof Element || value instanceof getWindow(value).Element;
606
- }
607
- function isHTMLElement(value) {
608
- if (!hasWindow()) {
609
- return false;
610
- }
611
- return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
612
- }
613
- function isShadowRoot(value) {
614
- if (!hasWindow() || typeof ShadowRoot === "undefined") {
615
- return false;
616
- }
617
- return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
618
- }
619
- const invalidOverflowDisplayValues = /* @__PURE__ */ new Set(["inline", "contents"]);
620
- function isOverflowElement(element) {
621
- const {
622
- overflow,
623
- overflowX,
624
- overflowY,
625
- display
626
- } = getComputedStyle$1(element);
627
- return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !invalidOverflowDisplayValues.has(display);
628
- }
629
- const tableElements = /* @__PURE__ */ new Set(["table", "td", "th"]);
630
- function isTableElement(element) {
631
- return tableElements.has(getNodeName(element));
632
- }
633
- const topLayerSelectors = [":popover-open", ":modal"];
634
- function isTopLayer(element) {
635
- return topLayerSelectors.some((selector) => {
636
- try {
637
- return element.matches(selector);
638
- } catch (_e) {
639
- return false;
640
- }
641
- });
642
- }
643
- const transformProperties = ["transform", "translate", "scale", "rotate", "perspective"];
644
- const willChangeValues = ["transform", "translate", "scale", "rotate", "perspective", "filter"];
645
- const containValues = ["paint", "layout", "strict", "content"];
646
- function isContainingBlock(elementOrCss) {
647
- const webkit = isWebKit();
648
- const css = isElement(elementOrCss) ? getComputedStyle$1(elementOrCss) : elementOrCss;
649
- return transformProperties.some((value) => css[value] ? css[value] !== "none" : false) || (css.containerType ? css.containerType !== "normal" : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== "none" : false) || !webkit && (css.filter ? css.filter !== "none" : false) || willChangeValues.some((value) => (css.willChange || "").includes(value)) || containValues.some((value) => (css.contain || "").includes(value));
650
- }
651
- function getContainingBlock(element) {
652
- let currentNode = getParentNode(element);
653
- while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
654
- if (isContainingBlock(currentNode)) {
655
- return currentNode;
656
- } else if (isTopLayer(currentNode)) {
657
- return null;
658
- }
659
- currentNode = getParentNode(currentNode);
660
- }
661
- return null;
662
- }
663
- function isWebKit() {
664
- if (typeof CSS === "undefined" || !CSS.supports) return false;
665
- return CSS.supports("-webkit-backdrop-filter", "none");
666
- }
667
- const lastTraversableNodeNames = /* @__PURE__ */ new Set(["html", "body", "#document"]);
668
- function isLastTraversableNode(node) {
669
- return lastTraversableNodeNames.has(getNodeName(node));
670
- }
671
- function getComputedStyle$1(element) {
672
- return getWindow(element).getComputedStyle(element);
673
- }
674
- function getNodeScroll(element) {
675
- if (isElement(element)) {
676
- return {
677
- scrollLeft: element.scrollLeft,
678
- scrollTop: element.scrollTop
679
- };
680
- }
681
- return {
682
- scrollLeft: element.scrollX,
683
- scrollTop: element.scrollY
684
- };
685
- }
686
- function getParentNode(node) {
687
- if (getNodeName(node) === "html") {
688
- return node;
689
- }
690
- const result = (
691
- // Step into the shadow DOM of the parent of a slotted node.
692
- node.assignedSlot || // DOM Element detected.
693
- node.parentNode || // ShadowRoot detected.
694
- isShadowRoot(node) && node.host || // Fallback.
695
- getDocumentElement(node)
696
- );
697
- return isShadowRoot(result) ? result.host : result;
698
- }
699
- function getNearestOverflowAncestor(node) {
700
- const parentNode = getParentNode(node);
701
- if (isLastTraversableNode(parentNode)) {
702
- return node.ownerDocument ? node.ownerDocument.body : node.body;
703
- }
704
- if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
705
- return parentNode;
706
- }
707
- return getNearestOverflowAncestor(parentNode);
708
- }
709
- function getOverflowAncestors(node, list, traverseIframes) {
710
- var _node$ownerDocument2;
711
- if (list === void 0) {
712
- list = [];
713
- }
714
- const scrollableAncestor = getNearestOverflowAncestor(node);
715
- const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
716
- const win = getWindow(scrollableAncestor);
717
- if (isBody) {
718
- getFrameElement(win);
719
- return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], []);
720
- }
721
- return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, []));
722
- }
723
- function getFrameElement(win) {
724
- return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
725
- }
726
- function getCssDimensions(element) {
727
- const css = getComputedStyle$1(element);
728
- let width = parseFloat(css.width) || 0;
729
- let height = parseFloat(css.height) || 0;
730
- const hasOffset = isHTMLElement(element);
731
- const offsetWidth = hasOffset ? element.offsetWidth : width;
732
- const offsetHeight = hasOffset ? element.offsetHeight : height;
733
- const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
734
- if (shouldFallback) {
735
- width = offsetWidth;
736
- height = offsetHeight;
737
- }
738
- return {
739
- width,
740
- height,
741
- $: shouldFallback
742
- };
743
- }
744
- function unwrapElement(element) {
745
- return !isElement(element) ? element.contextElement : element;
746
- }
747
- function getScale(element) {
748
- const domElement = unwrapElement(element);
749
- if (!isHTMLElement(domElement)) {
750
- return createCoords(1);
751
- }
752
- const rect = domElement.getBoundingClientRect();
753
- const {
754
- width,
755
- height,
756
- $
757
- } = getCssDimensions(domElement);
758
- let x = ($ ? round(rect.width) : rect.width) / width;
759
- let y = ($ ? round(rect.height) : rect.height) / height;
760
- if (!x || !Number.isFinite(x)) {
761
- x = 1;
762
- }
763
- if (!y || !Number.isFinite(y)) {
764
- y = 1;
765
- }
766
- return {
767
- x,
768
- y
769
- };
770
- }
771
- const noOffsets = /* @__PURE__ */ createCoords(0);
772
- function getVisualOffsets(element) {
773
- const win = getWindow(element);
774
- if (!isWebKit() || !win.visualViewport) {
775
- return noOffsets;
776
- }
777
- return {
778
- x: win.visualViewport.offsetLeft,
779
- y: win.visualViewport.offsetTop
780
- };
781
- }
782
- function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
783
- if (isFixed === void 0) {
784
- isFixed = false;
785
- }
786
- if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
787
- return false;
788
- }
789
- return isFixed;
790
- }
791
- function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
792
- if (includeScale === void 0) {
793
- includeScale = false;
794
- }
795
- if (isFixedStrategy === void 0) {
796
- isFixedStrategy = false;
797
- }
798
- const clientRect = element.getBoundingClientRect();
799
- const domElement = unwrapElement(element);
800
- let scale = createCoords(1);
801
- if (includeScale) {
802
- if (offsetParent) {
803
- if (isElement(offsetParent)) {
804
- scale = getScale(offsetParent);
805
- }
806
- } else {
807
- scale = getScale(element);
808
- }
809
- }
810
- const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
811
- let x = (clientRect.left + visualOffsets.x) / scale.x;
812
- let y = (clientRect.top + visualOffsets.y) / scale.y;
813
- let width = clientRect.width / scale.x;
814
- let height = clientRect.height / scale.y;
815
- if (domElement) {
816
- const win = getWindow(domElement);
817
- const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
818
- let currentWin = win;
819
- let currentIFrame = getFrameElement(currentWin);
820
- while (currentIFrame && offsetParent && offsetWin !== currentWin) {
821
- const iframeScale = getScale(currentIFrame);
822
- const iframeRect = currentIFrame.getBoundingClientRect();
823
- const css = getComputedStyle$1(currentIFrame);
824
- const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
825
- const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
826
- x *= iframeScale.x;
827
- y *= iframeScale.y;
828
- width *= iframeScale.x;
829
- height *= iframeScale.y;
830
- x += left;
831
- y += top;
832
- currentWin = getWindow(currentIFrame);
833
- currentIFrame = getFrameElement(currentWin);
834
- }
835
- }
836
- return rectToClientRect({
837
- width,
838
- height,
839
- x,
840
- y
841
- });
842
- }
843
- function getWindowScrollBarX(element, rect) {
844
- const leftScroll = getNodeScroll(element).scrollLeft;
845
- if (!rect) {
846
- return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
847
- }
848
- return rect.left + leftScroll;
849
- }
850
- function getHTMLOffset(documentElement, scroll) {
851
- const htmlRect = documentElement.getBoundingClientRect();
852
- const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);
853
- const y = htmlRect.top + scroll.scrollTop;
854
- return {
855
- x,
856
- y
857
- };
858
- }
859
- function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
860
- let {
861
- elements,
862
- rect,
863
- offsetParent,
864
- strategy
865
- } = _ref;
866
- const isFixed = strategy === "fixed";
867
- const documentElement = getDocumentElement(offsetParent);
868
- const topLayer = elements ? isTopLayer(elements.floating) : false;
869
- if (offsetParent === documentElement || topLayer && isFixed) {
870
- return rect;
871
- }
872
- let scroll = {
873
- scrollLeft: 0,
874
- scrollTop: 0
875
- };
876
- let scale = createCoords(1);
877
- const offsets = createCoords(0);
878
- const isOffsetParentAnElement = isHTMLElement(offsetParent);
879
- if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
880
- if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
881
- scroll = getNodeScroll(offsetParent);
882
- }
883
- if (isHTMLElement(offsetParent)) {
884
- const offsetRect = getBoundingClientRect(offsetParent);
885
- scale = getScale(offsetParent);
886
- offsets.x = offsetRect.x + offsetParent.clientLeft;
887
- offsets.y = offsetRect.y + offsetParent.clientTop;
888
- }
889
- }
890
- const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
891
- return {
892
- width: rect.width * scale.x,
893
- height: rect.height * scale.y,
894
- x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
895
- y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
896
- };
897
- }
898
- function getClientRects(element) {
899
- return Array.from(element.getClientRects());
900
- }
901
- function getDocumentRect(element) {
902
- const html = getDocumentElement(element);
903
- const scroll = getNodeScroll(element);
904
- const body = element.ownerDocument.body;
905
- const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
906
- const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
907
- let x = -scroll.scrollLeft + getWindowScrollBarX(element);
908
- const y = -scroll.scrollTop;
909
- if (getComputedStyle$1(body).direction === "rtl") {
910
- x += max(html.clientWidth, body.clientWidth) - width;
911
- }
912
- return {
913
- width,
914
- height,
915
- x,
916
- y
917
- };
918
- }
919
- const SCROLLBAR_MAX = 25;
920
- function getViewportRect(element, strategy) {
921
- const win = getWindow(element);
922
- const html = getDocumentElement(element);
923
- const visualViewport = win.visualViewport;
924
- let width = html.clientWidth;
925
- let height = html.clientHeight;
926
- let x = 0;
927
- let y = 0;
928
- if (visualViewport) {
929
- width = visualViewport.width;
930
- height = visualViewport.height;
931
- const visualViewportBased = isWebKit();
932
- if (!visualViewportBased || visualViewportBased && strategy === "fixed") {
933
- x = visualViewport.offsetLeft;
934
- y = visualViewport.offsetTop;
935
- }
936
- }
937
- const windowScrollbarX = getWindowScrollBarX(html);
938
- if (windowScrollbarX <= 0) {
939
- const doc = html.ownerDocument;
940
- const body = doc.body;
941
- const bodyStyles = getComputedStyle(body);
942
- const bodyMarginInline = doc.compatMode === "CSS1Compat" ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
943
- const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
944
- if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {
945
- width -= clippingStableScrollbarWidth;
946
- }
947
- } else if (windowScrollbarX <= SCROLLBAR_MAX) {
948
- width += windowScrollbarX;
949
- }
950
- return {
951
- width,
952
- height,
953
- x,
954
- y
955
- };
956
- }
957
- const absoluteOrFixed = /* @__PURE__ */ new Set(["absolute", "fixed"]);
958
- function getInnerBoundingClientRect(element, strategy) {
959
- const clientRect = getBoundingClientRect(element, true, strategy === "fixed");
960
- const top = clientRect.top + element.clientTop;
961
- const left = clientRect.left + element.clientLeft;
962
- const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
963
- const width = element.clientWidth * scale.x;
964
- const height = element.clientHeight * scale.y;
965
- const x = left * scale.x;
966
- const y = top * scale.y;
967
- return {
968
- width,
969
- height,
970
- x,
971
- y
972
- };
973
- }
974
- function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
975
- let rect;
976
- if (clippingAncestor === "viewport") {
977
- rect = getViewportRect(element, strategy);
978
- } else if (clippingAncestor === "document") {
979
- rect = getDocumentRect(getDocumentElement(element));
980
- } else if (isElement(clippingAncestor)) {
981
- rect = getInnerBoundingClientRect(clippingAncestor, strategy);
982
- } else {
983
- const visualOffsets = getVisualOffsets(element);
984
- rect = {
985
- x: clippingAncestor.x - visualOffsets.x,
986
- y: clippingAncestor.y - visualOffsets.y,
987
- width: clippingAncestor.width,
988
- height: clippingAncestor.height
989
- };
990
- }
991
- return rectToClientRect(rect);
992
- }
993
- function hasFixedPositionAncestor(element, stopNode) {
994
- const parentNode = getParentNode(element);
995
- if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
996
- return false;
997
- }
998
- return getComputedStyle$1(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode);
999
- }
1000
- function getClippingElementAncestors(element, cache) {
1001
- const cachedResult = cache.get(element);
1002
- if (cachedResult) {
1003
- return cachedResult;
1004
- }
1005
- let result = getOverflowAncestors(element, []).filter((el) => isElement(el) && getNodeName(el) !== "body");
1006
- let currentContainingBlockComputedStyle = null;
1007
- const elementIsFixed = getComputedStyle$1(element).position === "fixed";
1008
- let currentNode = elementIsFixed ? getParentNode(element) : element;
1009
- while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
1010
- const computedStyle = getComputedStyle$1(currentNode);
1011
- const currentNodeIsContaining = isContainingBlock(currentNode);
1012
- if (!currentNodeIsContaining && computedStyle.position === "fixed") {
1013
- currentContainingBlockComputedStyle = null;
1014
- }
1015
- const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && absoluteOrFixed.has(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
1016
- if (shouldDropCurrentNode) {
1017
- result = result.filter((ancestor) => ancestor !== currentNode);
1018
- } else {
1019
- currentContainingBlockComputedStyle = computedStyle;
1020
- }
1021
- currentNode = getParentNode(currentNode);
1022
- }
1023
- cache.set(element, result);
1024
- return result;
1025
- }
1026
- function getClippingRect(_ref) {
1027
- let {
1028
- element,
1029
- boundary,
1030
- rootBoundary,
1031
- strategy
1032
- } = _ref;
1033
- const elementClippingAncestors = boundary === "clippingAncestors" ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
1034
- const clippingAncestors = [...elementClippingAncestors, rootBoundary];
1035
- const firstClippingAncestor = clippingAncestors[0];
1036
- const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
1037
- const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
1038
- accRect.top = max(rect.top, accRect.top);
1039
- accRect.right = min(rect.right, accRect.right);
1040
- accRect.bottom = min(rect.bottom, accRect.bottom);
1041
- accRect.left = max(rect.left, accRect.left);
1042
- return accRect;
1043
- }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
1044
- return {
1045
- width: clippingRect.right - clippingRect.left,
1046
- height: clippingRect.bottom - clippingRect.top,
1047
- x: clippingRect.left,
1048
- y: clippingRect.top
1049
- };
1050
- }
1051
- function getDimensions(element) {
1052
- const {
1053
- width,
1054
- height
1055
- } = getCssDimensions(element);
1056
- return {
1057
- width,
1058
- height
1059
- };
1060
- }
1061
- function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
1062
- const isOffsetParentAnElement = isHTMLElement(offsetParent);
1063
- const documentElement = getDocumentElement(offsetParent);
1064
- const isFixed = strategy === "fixed";
1065
- const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
1066
- let scroll = {
1067
- scrollLeft: 0,
1068
- scrollTop: 0
1069
- };
1070
- const offsets = createCoords(0);
1071
- function setLeftRTLScrollbarOffset() {
1072
- offsets.x = getWindowScrollBarX(documentElement);
1073
- }
1074
- if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
1075
- if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
1076
- scroll = getNodeScroll(offsetParent);
1077
- }
1078
- if (isOffsetParentAnElement) {
1079
- const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
1080
- offsets.x = offsetRect.x + offsetParent.clientLeft;
1081
- offsets.y = offsetRect.y + offsetParent.clientTop;
1082
- } else if (documentElement) {
1083
- setLeftRTLScrollbarOffset();
1084
- }
1085
- }
1086
- if (isFixed && !isOffsetParentAnElement && documentElement) {
1087
- setLeftRTLScrollbarOffset();
1088
- }
1089
- const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
1090
- const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
1091
- const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
1092
- return {
1093
- x,
1094
- y,
1095
- width: rect.width,
1096
- height: rect.height
1097
- };
1098
- }
1099
- function isStaticPositioned(element) {
1100
- return getComputedStyle$1(element).position === "static";
1101
- }
1102
- function getTrueOffsetParent(element, polyfill) {
1103
- if (!isHTMLElement(element) || getComputedStyle$1(element).position === "fixed") {
1104
- return null;
1105
- }
1106
- if (polyfill) {
1107
- return polyfill(element);
1108
- }
1109
- let rawOffsetParent = element.offsetParent;
1110
- if (getDocumentElement(element) === rawOffsetParent) {
1111
- rawOffsetParent = rawOffsetParent.ownerDocument.body;
1112
- }
1113
- return rawOffsetParent;
1114
- }
1115
- function getOffsetParent(element, polyfill) {
1116
- const win = getWindow(element);
1117
- if (isTopLayer(element)) {
1118
- return win;
1119
- }
1120
- if (!isHTMLElement(element)) {
1121
- let svgOffsetParent = getParentNode(element);
1122
- while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
1123
- if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
1124
- return svgOffsetParent;
1125
- }
1126
- svgOffsetParent = getParentNode(svgOffsetParent);
1127
- }
1128
- return win;
1129
- }
1130
- let offsetParent = getTrueOffsetParent(element, polyfill);
1131
- while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
1132
- offsetParent = getTrueOffsetParent(offsetParent, polyfill);
1133
- }
1134
- if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
1135
- return win;
1136
- }
1137
- return offsetParent || getContainingBlock(element) || win;
1138
- }
1139
- const getElementRects = async function(data) {
1140
- const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
1141
- const getDimensionsFn = this.getDimensions;
1142
- const floatingDimensions = await getDimensionsFn(data.floating);
1143
- return {
1144
- reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
1145
- floating: {
1146
- x: 0,
1147
- y: 0,
1148
- width: floatingDimensions.width,
1149
- height: floatingDimensions.height
1150
- }
1151
- };
1152
- };
1153
- function isRTL(element) {
1154
- return getComputedStyle$1(element).direction === "rtl";
1155
- }
1156
- const platform = {
1157
- convertOffsetParentRelativeRectToViewportRelativeRect,
1158
- getDocumentElement,
1159
- getClippingRect,
1160
- getOffsetParent,
1161
- getElementRects,
1162
- getClientRects,
1163
- getDimensions,
1164
- getScale,
1165
- isElement,
1166
- isRTL
1167
- };
1168
- const shift = shift$1;
1169
- const flip = flip$1;
1170
- const computePosition = (reference, floating, options) => {
1171
- const cache = /* @__PURE__ */ new Map();
1172
- const mergedOptions = {
1173
- platform,
1174
- ...options
1175
- };
1176
- const platformWithCache = {
1177
- ...mergedOptions.platform,
1178
- _c: cache
1179
- };
1180
- return computePosition$1(reference, floating, {
1181
- ...mergedOptions,
1182
- platform: platformWithCache
1183
- });
1184
- };
1185
77
  const chatTheme = {
1186
78
  base: "dark:text-white text-gray-500",
1187
79
  console: "flex w-full gap-4 h-full",
@@ -1423,8 +315,12 @@ const chatTheme = {
1423
315
  ].join(" "),
1424
316
  title: "text-yellow-600 dark:text-yellow-400 text-sm font-medium mb-2"
1425
317
  }
318
+ },
319
+ component: {
320
+ base: "my-4"
1426
321
  }
1427
322
  };
323
+ const POPUP_STYLE = { zIndex: 9999 };
1428
324
  const MentionList = forwardRef(
1429
325
  ({ items, command, triggerChar, config, query }, ref) => {
1430
326
  var _a;
@@ -1483,7 +379,7 @@ const MentionList = forwardRef(
1483
379
  List,
1484
380
  {
1485
381
  className: cn(popupTheme.base, popupTheme.content),
1486
- style: { zIndex: 9999 },
382
+ style: POPUP_STYLE,
1487
383
  role: "listbox",
1488
384
  id: popupId,
1489
385
  "aria-label": `${triggerChar === "@" ? "Mentions" : "Commands"} suggestions`,
@@ -1514,29 +410,28 @@ const MentionList = forwardRef(
1514
410
  );
1515
411
  }
1516
412
  );
1517
- function DefaultItemRenderer({
1518
- item,
1519
- isHighlighted,
1520
- popupTheme
1521
- }) {
1522
- const shortcut = "shortcut" in item ? item.shortcut : void 0;
1523
- return /* @__PURE__ */ jsx(
1524
- ListItem,
1525
- {
1526
- className: cn(
1527
- popupTheme.item,
1528
- isHighlighted && popupTheme.itemHighlighted
1529
- ),
1530
- dense: true,
1531
- start: item.icon ? /* @__PURE__ */ jsx("span", { className: cn(popupTheme.itemIcon), children: item.icon }) : void 0,
1532
- end: shortcut ? /* @__PURE__ */ jsx("span", { className: cn(popupTheme.itemShortcut), children: shortcut }) : void 0,
1533
- children: /* @__PURE__ */ jsxs("div", { className: cn(popupTheme.itemContent), children: [
1534
- /* @__PURE__ */ jsx("span", { className: cn(popupTheme.itemLabel), children: item.label }),
1535
- item.description && /* @__PURE__ */ jsx("span", { className: cn(popupTheme.itemDescription), children: item.description })
1536
- ] })
1537
- }
1538
- );
1539
- }
413
+ const DefaultItemRenderer = memo(
414
+ ({ item, isHighlighted, popupTheme }) => {
415
+ const shortcut = "shortcut" in item ? item.shortcut : void 0;
416
+ return /* @__PURE__ */ jsx(
417
+ ListItem,
418
+ {
419
+ className: cn(
420
+ popupTheme.item,
421
+ isHighlighted && popupTheme.itemHighlighted
422
+ ),
423
+ dense: true,
424
+ start: item.icon ? /* @__PURE__ */ jsx("span", { className: cn(popupTheme.itemIcon), children: item.icon }) : void 0,
425
+ end: shortcut ? /* @__PURE__ */ jsx("span", { className: cn(popupTheme.itemShortcut), children: shortcut }) : void 0,
426
+ children: /* @__PURE__ */ jsxs("div", { className: cn(popupTheme.itemContent), children: [
427
+ /* @__PURE__ */ jsx("span", { className: cn(popupTheme.itemLabel), children: item.label }),
428
+ item.description && /* @__PURE__ */ jsx("span", { className: cn(popupTheme.itemDescription), children: item.description })
429
+ ] })
430
+ }
431
+ );
432
+ }
433
+ );
434
+ DefaultItemRenderer.displayName = "DefaultItemRenderer";
1540
435
  MentionList.displayName = "MentionList";
1541
436
  function updatePopupPosition(editor, element) {
1542
437
  const virtualElement = {
@@ -1846,8 +741,14 @@ const ChatInput = forwardRef(
1846
741
  },
1847
742
  [fileUpload]
1848
743
  );
1849
- const mentionsConfig = mentions ? { ...mentions, trigger: mentions.trigger || "@" } : void 0;
1850
- const commandsConfig = commands ? { ...commands, trigger: commands.trigger || "/" } : void 0;
744
+ const mentionsConfig = useMemo(
745
+ () => mentions ? { ...mentions, trigger: mentions.trigger || "@" } : void 0,
746
+ [mentions]
747
+ );
748
+ const commandsConfig = useMemo(
749
+ () => commands ? { ...commands, trigger: commands.trigger || "/" } : void 0,
750
+ [commands]
751
+ );
1851
752
  return /* @__PURE__ */ jsx("div", { ref: containerRef, className: cn(theme.input.base), children: /* @__PURE__ */ jsxs("div", { className: cn("relative flex-1", theme.input.input), children: [
1852
753
  /* @__PURE__ */ jsx(
1853
754
  RichTextInput,
@@ -3017,7 +1918,7 @@ const TableDataCell = ({ children, ...props }) => /* @__PURE__ */ jsx("td", { ..
3017
1918
  const Markdown = ({
3018
1919
  children,
3019
1920
  remarkPlugins,
3020
- rehypePlugins = [rehypeKatex],
1921
+ rehypePlugins = [rehypeRaw, rehypeKatex],
3021
1922
  customComponents
3022
1923
  }) => {
3023
1924
  const { theme, markdownComponents } = useContext(ChatContext);
@@ -3059,7 +1960,17 @@ const Markdown = ({
3059
1960
  p: (props) => /* @__PURE__ */ jsx("p", { ...props, className: cn(theme.messages.message.markdown.p) }),
3060
1961
  li: (props) => /* @__PURE__ */ jsx("li", { ...props, className: cn(theme.messages.message.markdown.li) }),
3061
1962
  ul: (props) => /* @__PURE__ */ jsx("ul", { ...props, className: cn(theme.messages.message.markdown.ul) }),
3062
- ol: (props) => /* @__PURE__ */ jsx("ol", { ...props, className: cn(theme.messages.message.markdown.ol) })
1963
+ ol: (props) => /* @__PURE__ */ jsx("ol", { ...props, className: cn(theme.messages.message.markdown.ol) }),
1964
+ // 'redact' is a custom element created by remarkRedact, not a standard
1965
+ // HTML tag, so it falls outside react-markdown's Components type.
1966
+ redact: (props) => /* @__PURE__ */ jsx(
1967
+ Redact,
1968
+ {
1969
+ value: props["data-redact-value"] || props.children,
1970
+ allowToggle: true,
1971
+ tooltipText: `${props["data-redact-name"] || "Sensitive"} information - Click to toggle`
1972
+ }
1973
+ )
3063
1974
  };
3064
1975
  return {
3065
1976
  ...defaultComponents,
@@ -3077,7 +1988,7 @@ const Markdown = ({
3077
1988
  }
3078
1989
  );
3079
1990
  };
3080
- const ChartError = ({
1991
+ const ComponentError = ({
3081
1992
  variant = "error",
3082
1993
  title,
3083
1994
  message,
@@ -3105,12 +2016,12 @@ const ChartRenderer = ({
3105
2016
  data: d.data
3106
2017
  }));
3107
2018
  if (!chartData || chartData.length === 0) {
3108
- return /* @__PURE__ */ jsx(ChartError, { variant: "warning", message: "No chart data available" });
2019
+ return /* @__PURE__ */ jsx(ComponentError, { variant: "warning", message: "No chart data available" });
3109
2020
  }
3110
2021
  for (const point of chartData) {
3111
2022
  if (typeof point.data !== "number" || isNaN(point.data)) {
3112
2023
  return /* @__PURE__ */ jsx(
3113
- ChartError,
2024
+ ComponentError,
3114
2025
  {
3115
2026
  message: `Invalid data point: ${JSON.stringify(point)}`
3116
2027
  }
@@ -3179,10 +2090,10 @@ const ChartRenderer = ({
3179
2090
  case "sparkline":
3180
2091
  return /* @__PURE__ */ jsx(SparklineChart, { width, height, data: chartData });
3181
2092
  default:
3182
- return /* @__PURE__ */ jsx(ChartError, { message: `Unknown chart type: ${type}` });
2093
+ return /* @__PURE__ */ jsx(ComponentError, { message: `Unknown chart type: ${type}` });
3183
2094
  }
3184
2095
  } catch (error) {
3185
- return /* @__PURE__ */ jsx(ChartError, { message: `Chart render error: ${String(error)}` });
2096
+ return /* @__PURE__ */ jsx(ComponentError, { message: `Chart render error: ${String(error)}` });
3186
2097
  }
3187
2098
  }, [type, data, width, height]);
3188
2099
  return /* @__PURE__ */ jsxs("div", { className: cn(theme.chart.base, className), children: [
@@ -3190,93 +2101,6 @@ const ChartRenderer = ({
3190
2101
  /* @__PURE__ */ jsx("div", { className: theme.chart.content, children: chartElement })
3191
2102
  ] });
3192
2103
  };
3193
- function validateChartData(data) {
3194
- if (!Array.isArray(data)) {
3195
- return null;
3196
- }
3197
- const validData = [];
3198
- for (const item of data) {
3199
- if (item && typeof item === "object" && "key" in item && "data" in item && typeof item.data === "number") {
3200
- validData.push({
3201
- key: String(item.key),
3202
- data: item.data
3203
- });
3204
- } else {
3205
- return null;
3206
- }
3207
- }
3208
- return validData.length > 0 ? validData : null;
3209
- }
3210
- function parseChartConfig(value) {
3211
- try {
3212
- const config = JSON.parse(value);
3213
- if (!config || !config.type || !config.data) {
3214
- return null;
3215
- }
3216
- const validData = validateChartData(config.data);
3217
- if (!validData) {
3218
- console.warn("parseChartConfig: Invalid chart data format");
3219
- return null;
3220
- }
3221
- return {
3222
- ...config,
3223
- data: validData
3224
- };
3225
- } catch (error) {
3226
- console.warn("parseChartConfig: Failed to parse JSON", error);
3227
- return null;
3228
- }
3229
- }
3230
- function isChartClassName(className) {
3231
- return className === "language-chart";
3232
- }
3233
- function getChildText(children) {
3234
- if (children === null || children === void 0) {
3235
- return "";
3236
- }
3237
- if (typeof children === "string") {
3238
- return children;
3239
- }
3240
- if (typeof children === "number") {
3241
- return String(children);
3242
- }
3243
- if (Array.isArray(children)) {
3244
- return children.map(getChildText).join("");
3245
- }
3246
- if (typeof children === "object") {
3247
- if ("props" in children && children.props) {
3248
- const element = children;
3249
- return getChildText(element.props.children);
3250
- }
3251
- }
3252
- return "";
3253
- }
3254
- const ChartPre = ({ children, ...props }) => {
3255
- var _a, _b;
3256
- if (children && typeof children === "object" && "props" in children) {
3257
- const codeElement = children;
3258
- if (isChartClassName((_a = codeElement.props) == null ? void 0 : _a.className)) {
3259
- const codeContent = getChildText((_b = codeElement.props) == null ? void 0 : _b.children);
3260
- if (codeContent) {
3261
- const chartConfig = parseChartConfig(codeContent);
3262
- if (chartConfig) {
3263
- return /* @__PURE__ */ jsx(ChartRenderer, { config: chartConfig });
3264
- }
3265
- }
3266
- return /* @__PURE__ */ jsx(
3267
- ChartError,
3268
- {
3269
- title: "Failed to parse chart configuration",
3270
- code: codeContent || "No content"
3271
- }
3272
- );
3273
- }
3274
- }
3275
- return /* @__PURE__ */ jsx("pre", { ...props, children });
3276
- };
3277
- const chartComponents = {
3278
- pre: ChartPre
3279
- };
3280
2104
  const CVE_REGEX = /(CVE-(19|20)\d{2}-\d{4,7})/gi;
3281
2105
  function remarkCve() {
3282
2106
  return (tree, _file) => {
@@ -3297,36 +2121,66 @@ function remarkCve() {
3297
2121
  ];
3298
2122
  }
3299
2123
  }
3300
- const remarkChart = (options = {}) => {
3301
- const { defaultWidth = 400, defaultHeight = 300 } = options;
3302
- return (tree) => {
3303
- visit(tree, "code", (node) => {
3304
- if (node.lang !== "chart") {
3305
- return;
3306
- }
3307
- try {
3308
- const config = JSON.parse(node.value);
3309
- if (!config.type || !config.data) {
3310
- console.warn(
3311
- "remarkChart: Invalid chart config - missing type or data"
3312
- );
3313
- return;
2124
+ const remarkComponent = (_options = {}) => {
2125
+ return () => {
2126
+ };
2127
+ };
2128
+ function remarkRedact(matchers) {
2129
+ return () => (tree) => {
2130
+ if (!tree || !matchers || matchers.length === 0) {
2131
+ return;
2132
+ }
2133
+ const patterns = [];
2134
+ for (const { name, pattern, validate } of matchers) {
2135
+ patterns.push([
2136
+ pattern,
2137
+ (value) => {
2138
+ if (validate && !validate(value)) {
2139
+ return false;
2140
+ }
2141
+ return {
2142
+ type: "html",
2143
+ value: `<redact data-redact-name="${name}" data-redact-value="${value.replace(/"/g, "&quot;")}">${value}</redact>`
2144
+ };
3314
2145
  }
3315
- const chartConfig = {
3316
- ...config,
3317
- width: config.width ?? defaultWidth,
3318
- height: config.height ?? defaultHeight
3319
- };
3320
- node.value = JSON.stringify(chartConfig);
3321
- } catch (error) {
3322
- console.warn("remarkChart: Failed to parse chart config:", error);
2146
+ ]);
2147
+ }
2148
+ if (patterns.length > 0) {
2149
+ try {
2150
+ findAndReplace(tree, patterns);
2151
+ } catch (err) {
2152
+ console.warn("Redact plugin error:", err);
3323
2153
  }
3324
- });
2154
+ }
3325
2155
  };
2156
+ }
2157
+ const ssnMatcher = {
2158
+ name: "SSN",
2159
+ pattern: /\b\d{3}-\d{2}-\d{4}\b/g
2160
+ };
2161
+ const creditCardMatcher = {
2162
+ name: "Credit Card",
2163
+ pattern: /\b(?:\d[ -]*?){13,19}\b/g,
2164
+ validate: (match) => {
2165
+ if (/(?:years?|year|yr|yrs|old|age|phone|tel|call)/.test(match)) {
2166
+ return false;
2167
+ }
2168
+ const cardNumber = match.replace(/[ -]/g, "");
2169
+ return cardNumber.length >= 13 && cardNumber.length <= 19;
2170
+ }
3326
2171
  };
2172
+ const bitcoinMatcher = {
2173
+ name: "Bitcoin",
2174
+ pattern: /\b[13][a-km-zA-HJ-NP-Z1-9]{25,34}\b/g
2175
+ };
2176
+ const commonRedactMatchers = [
2177
+ ssnMatcher,
2178
+ creditCardMatcher,
2179
+ bitcoinMatcher
2180
+ ];
3327
2181
  const SvgFile = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 16, height: 16, viewBox: "0 0 16 16", fill: "currentColor", ...props }, /* @__PURE__ */ React.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M2.7036 1.37034C3.04741 1.02653 3.51373 0.833374 3.99996 0.833374H9.33329H9.33331C9.47275 0.833374 9.59885 0.890449 9.68954 0.98251L13.6843 4.97722C13.7763 5.0679 13.8333 5.19398 13.8333 5.33337L13.8333 5.3379V13.3334C13.8333 13.8196 13.6401 14.2859 13.2963 14.6297C12.9525 14.9736 12.4862 15.1667 12 15.1667H3.99996C3.51373 15.1667 3.04741 14.9736 2.7036 14.6297C2.35978 14.2859 2.16663 13.8196 2.16663 13.3334V2.66671C2.16663 2.18048 2.35978 1.71416 2.7036 1.37034ZM3.99996 1.83337H8.83331V5.33337C8.83331 5.60952 9.05717 5.83337 9.33331 5.83337H12.8333V13.3334C12.8333 13.5544 12.7455 13.7663 12.5892 13.9226C12.4329 14.0789 12.221 14.1667 12 14.1667H3.99996C3.77895 14.1667 3.56698 14.0789 3.4107 13.9226C3.25442 13.7663 3.16663 13.5544 3.16663 13.3334V2.66671C3.16663 2.44569 3.25442 2.23373 3.4107 2.07745C3.56698 1.92117 3.77895 1.83337 3.99996 1.83337ZM9.83331 2.5405L12.1262 4.83337H9.83331V2.5405ZM5.33331 8.16663C5.05717 8.16663 4.83331 8.39048 4.83331 8.66663C4.83331 8.94277 5.05717 9.16663 5.33331 9.16663H10.6666C10.9428 9.16663 11.1666 8.94277 11.1666 8.66663C11.1666 8.39048 10.9428 8.16663 10.6666 8.16663H5.33331ZM4.83331 11.3334C4.83331 11.0572 5.05717 10.8334 5.33331 10.8334H10.6666C10.9428 10.8334 11.1666 11.0572 11.1666 11.3334C11.1666 11.6095 10.9428 11.8334 10.6666 11.8334H5.33331C5.05717 11.8334 4.83331 11.6095 4.83331 11.3334ZM5.33331 5.5C5.05717 5.5 4.83331 5.72386 4.83331 6C4.83331 6.27614 5.05717 6.5 5.33331 6.5H6.66665C6.94279 6.5 7.16665 6.27614 7.16665 6C7.16665 5.72386 6.94279 5.5 6.66665 5.5H5.33331Z" }));
3328
- const DefaultFileRenderer = lazy(() => import("./DefaultFileRenderer-Bi8LNDio.js"));
3329
- const CSVFileRenderer = lazy(() => import("./CSVFileRenderer-DXI8PDqR.js"));
2182
+ const DefaultFileRenderer = lazy(() => import("./DefaultFileRenderer-CJ3jwiQa.js"));
2183
+ const CSVFileRenderer = lazy(() => import("./CSVFileRenderer-C2tuexJf.js"));
3330
2184
  const ImageFileRenderer = lazy(() => import("./ImageFileRenderer-C8tVW3I8.js"));
3331
2185
  const PDFFileRenderer = lazy(() => import("./PDFFileRenderer-DQdFS2l6.js"));
3332
2186
  const FILE_TYPE_RENDERER_MAP = {
@@ -3354,27 +2208,36 @@ const MessageFile = ({
3354
2208
  }
3355
2209
  );
3356
2210
  };
3357
- const MessageFiles = ({ files, children }) => {
2211
+ const MessageFiles = memo(({ files, children }) => {
3358
2212
  const { theme } = useContext(ChatContext);
3359
2213
  const Comp = children ? Slot : MessageFile;
3360
2214
  const [expanded, setExpanded] = useState(false);
2215
+ const { imageFiles, otherFiles } = useMemo(() => {
2216
+ if (!files || files.length === 0) {
2217
+ return {
2218
+ imageFiles: [],
2219
+ otherFiles: []
2220
+ };
2221
+ }
2222
+ return files.reduce(
2223
+ (acc, file) => {
2224
+ var _a;
2225
+ if ((_a = file.type) == null ? void 0 : _a.startsWith("image/")) {
2226
+ acc.imageFiles.push(file);
2227
+ } else {
2228
+ acc.otherFiles.push(file);
2229
+ }
2230
+ return acc;
2231
+ },
2232
+ {
2233
+ imageFiles: [],
2234
+ otherFiles: []
2235
+ }
2236
+ );
2237
+ }, [files]);
3361
2238
  if (!files || files.length === 0) {
3362
2239
  return null;
3363
2240
  }
3364
- const { imageFiles, otherFiles } = files.reduce(
3365
- (acc, file) => {
3366
- if (file.type.startsWith("image/")) {
3367
- acc.imageFiles.push(file);
3368
- } else {
3369
- acc.otherFiles.push(file);
3370
- }
3371
- return acc;
3372
- },
3373
- {
3374
- imageFiles: [],
3375
- otherFiles: []
3376
- }
3377
- );
3378
2241
  const maxImageLength = 3;
3379
2242
  const truncateImages = !expanded && imageFiles.length > maxImageLength;
3380
2243
  const renderImageFiles = (images) => {
@@ -3420,70 +2283,70 @@ const MessageFiles = ({ files, children }) => {
3420
2283
  ]
3421
2284
  }
3422
2285
  );
3423
- };
3424
- const MessageQuestion = ({
3425
- children,
3426
- ...props
3427
- }) => {
3428
- const { theme, remarkPlugins } = useContext(ChatContext);
3429
- const { question, files } = props;
3430
- const Comp = children ? Slot : "div";
3431
- const [expanded, setExpanded] = useState(false);
3432
- const isLong = question.length > 500;
3433
- return /* @__PURE__ */ jsx(
3434
- Comp,
3435
- {
3436
- className: cn(theme.messages.message.question, {
3437
- [theme.messages.message.overlay]: isLong && !expanded
3438
- }),
3439
- ...props,
3440
- children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
3441
- /* @__PURE__ */ jsx(MessageFiles, { files }),
3442
- /* @__PURE__ */ jsx(Markdown, { remarkPlugins, children: question }),
3443
- isLong && !expanded && /* @__PURE__ */ jsx(
3444
- Button,
3445
- {
3446
- variant: "link",
3447
- size: "small",
3448
- className: theme.messages.message.expand,
3449
- onClick: () => setExpanded(true),
3450
- children: "Show more"
3451
- }
3452
- )
3453
- ] })
3454
- }
3455
- );
3456
- };
3457
- const MessageResponse = ({
3458
- response,
3459
- isLoading,
3460
- children
3461
- }) => {
3462
- const { theme, isCompact, remarkPlugins } = useContext(ChatContext);
3463
- const Comp = children ? Slot : "div";
3464
- return /* @__PURE__ */ jsx(
3465
- Comp,
3466
- {
3467
- "data-compact": isCompact,
3468
- className: cn(theme.messages.message.response),
3469
- children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
3470
- /* @__PURE__ */ jsx(Markdown, { remarkPlugins, children: response }),
3471
- isLoading && /* @__PURE__ */ jsx(
3472
- motion.div,
3473
- {
3474
- className: cn(theme.messages.message.cursor),
3475
- animate: { opacity: [1, 0] },
3476
- transition: {
3477
- duration: 0.7,
3478
- repeat: Infinity,
3479
- repeatType: "reverse"
2286
+ });
2287
+ MessageFiles.displayName = "MessageFiles";
2288
+ const MessageQuestion = memo(
2289
+ ({ children, ...props }) => {
2290
+ const { theme, remarkPlugins } = useContext(ChatContext);
2291
+ const { question, files } = props;
2292
+ const Comp = children ? Slot : "div";
2293
+ const [expanded, setExpanded] = useState(false);
2294
+ const isLong = question.length > 500;
2295
+ return /* @__PURE__ */ jsx(
2296
+ Comp,
2297
+ {
2298
+ className: cn(theme.messages.message.question, {
2299
+ [theme.messages.message.overlay]: isLong && !expanded
2300
+ }),
2301
+ ...props,
2302
+ children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
2303
+ /* @__PURE__ */ jsx(MessageFiles, { files }),
2304
+ /* @__PURE__ */ jsx(Markdown, { remarkPlugins, children: question }),
2305
+ isLong && !expanded && /* @__PURE__ */ jsx(
2306
+ Button,
2307
+ {
2308
+ variant: "link",
2309
+ size: "small",
2310
+ className: theme.messages.message.expand,
2311
+ onClick: () => setExpanded(true),
2312
+ children: "Show more"
3480
2313
  }
3481
- }
3482
- )
3483
- ] })
3484
- }
3485
- );
3486
- };
2314
+ )
2315
+ ] })
2316
+ }
2317
+ );
2318
+ }
2319
+ );
2320
+ MessageQuestion.displayName = "MessageQuestion";
2321
+ const MessageResponse = memo(
2322
+ ({ response, isLoading, children }) => {
2323
+ const { theme, isCompact, remarkPlugins } = useContext(ChatContext);
2324
+ const Comp = children ? Slot : "div";
2325
+ return /* @__PURE__ */ jsx(
2326
+ Comp,
2327
+ {
2328
+ "data-compact": isCompact,
2329
+ className: cn(theme.messages.message.response),
2330
+ children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
2331
+ /* @__PURE__ */ jsx(Markdown, { remarkPlugins, children: response }),
2332
+ isLoading && /* @__PURE__ */ jsx(
2333
+ motion.div,
2334
+ {
2335
+ className: cn(theme.messages.message.cursor),
2336
+ animate: { opacity: [1, 0] },
2337
+ transition: {
2338
+ duration: 0.7,
2339
+ repeat: Infinity,
2340
+ repeatType: "reverse"
2341
+ }
2342
+ }
2343
+ )
2344
+ ] })
2345
+ }
2346
+ );
2347
+ }
2348
+ );
2349
+ MessageResponse.displayName = "MessageResponse";
3487
2350
  const MessageSource = ({ title, url, image, limit = 50 }) => {
3488
2351
  const { theme, isCompact } = useContext(ChatContext);
3489
2352
  return /* @__PURE__ */ jsxs(
@@ -3507,93 +2370,100 @@ const MessageSource = ({ title, url, image, limit = 50 }) => {
3507
2370
  }
3508
2371
  );
3509
2372
  };
3510
- const MessageSources = ({
3511
- sources,
3512
- children
3513
- }) => {
3514
- const { theme } = useContext(ChatContext);
3515
- const Comp = children ? Slot : MessageSource;
3516
- if (!sources || sources.length === 0) {
3517
- return null;
2373
+ const MessageSources = memo(
2374
+ ({ sources, children }) => {
2375
+ const { theme } = useContext(ChatContext);
2376
+ const Comp = children ? Slot : MessageSource;
2377
+ if (!sources || sources.length === 0) {
2378
+ return null;
2379
+ }
2380
+ return /* @__PURE__ */ jsx("div", { className: cn(theme.messages.message.sources.base), children: sources.map((source, index) => /* @__PURE__ */ jsx(Comp, { ...source, children }, index)) });
3518
2381
  }
3519
- return sources && sources.length > 0 && /* @__PURE__ */ jsx("div", { className: cn(theme.messages.message.sources.base), children: sources.map((source, index) => /* @__PURE__ */ jsx(Comp, { ...source, children }, index)) });
3520
- };
2382
+ );
2383
+ MessageSources.displayName = "MessageSources";
3521
2384
  const SvgThumbsDown = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1, strokeLinecap: "round", strokeLinejoin: "round", className: "lucide lucide-thumbs-down", ...props }, /* @__PURE__ */ React.createElement("path", { d: "M17 14V2" }), /* @__PURE__ */ React.createElement("path", { d: "M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z" }));
3522
2385
  const SvgThumbsUp = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1, strokeLinecap: "round", strokeLinejoin: "round", className: "lucide lucide-thumbs-up", ...props }, /* @__PURE__ */ React.createElement("path", { d: "M7 10v12" }), /* @__PURE__ */ React.createElement("path", { d: "M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z" }));
3523
2386
  const SvgRefresh = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1, strokeLinecap: "round", strokeLinejoin: "round", className: "lucide lucide-refresh-ccw", ...props }, /* @__PURE__ */ React.createElement("path", { d: "M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }), /* @__PURE__ */ React.createElement("path", { d: "M3 3v5h5" }), /* @__PURE__ */ React.createElement("path", { d: "M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16" }), /* @__PURE__ */ React.createElement("path", { d: "M16 16h5v5" }));
3524
- const MessageActions = ({
3525
- children,
3526
- ...props
3527
- }) => {
3528
- const { theme } = useContext(ChatContext);
3529
- const {
3530
- question,
3531
- response,
3532
- copyIcon = /* @__PURE__ */ jsx(SvgCopy, {}),
3533
- thumbsUpIcon = /* @__PURE__ */ jsx(SvgThumbsUp, {}),
3534
- thumbsDownIcon = /* @__PURE__ */ jsx(SvgThumbsDown, {}),
3535
- refreshIcon = /* @__PURE__ */ jsx(SvgRefresh, {}),
3536
- onCopy,
3537
- onUpvote,
3538
- onDownvote,
3539
- onRefresh
3540
- } = props;
3541
- const Comp = children ? Slot : "div";
3542
- const handleCopy = (text) => {
3543
- navigator.clipboard.writeText(text).then(() => {
3544
- console.log("Text copied to clipboard");
3545
- }).catch((err) => {
3546
- console.error("Could not copy text: ", err);
3547
- });
3548
- };
3549
- return (copyIcon || thumbsDownIcon || thumbsUpIcon || refreshIcon) && /* @__PURE__ */ jsx(Comp, { className: cn(theme.messages.message.footer.base), children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
3550
- copyIcon && /* @__PURE__ */ jsx(
3551
- IconButton,
3552
- {
3553
- variant: "text",
3554
- disablePadding: true,
3555
- title: "Copy question and response",
3556
- className: cn(theme.messages.message.footer.copy),
3557
- onClick: onCopy ? onCopy : () => handleCopy(`${question}
3558
- ${response}`),
3559
- children: copyIcon
3560
- }
3561
- ),
3562
- thumbsUpIcon && /* @__PURE__ */ jsx(
3563
- IconButton,
3564
- {
3565
- variant: "text",
3566
- disablePadding: true,
3567
- title: "Upvote",
3568
- className: cn(theme.messages.message.footer.upvote),
3569
- onClick: onUpvote,
3570
- children: thumbsUpIcon
3571
- }
3572
- ),
3573
- thumbsDownIcon && /* @__PURE__ */ jsx(
3574
- IconButton,
3575
- {
3576
- variant: "text",
3577
- disablePadding: true,
3578
- title: "Downvote",
3579
- className: cn(theme.messages.message.footer.downvote),
3580
- onClick: onDownvote,
3581
- children: thumbsDownIcon
3582
- }
3583
- ),
3584
- refreshIcon && /* @__PURE__ */ jsx(
3585
- IconButton,
3586
- {
3587
- variant: "text",
3588
- disablePadding: true,
3589
- title: "Refresh",
3590
- className: cn(theme.messages.message.footer.refresh),
3591
- onClick: onRefresh,
3592
- children: refreshIcon
2387
+ const MessageActions = memo(
2388
+ ({ children, ...props }) => {
2389
+ const { theme } = useContext(ChatContext);
2390
+ const {
2391
+ question,
2392
+ response,
2393
+ copyIcon = /* @__PURE__ */ jsx(SvgCopy, {}),
2394
+ thumbsUpIcon = /* @__PURE__ */ jsx(SvgThumbsUp, {}),
2395
+ thumbsDownIcon = /* @__PURE__ */ jsx(SvgThumbsDown, {}),
2396
+ refreshIcon = /* @__PURE__ */ jsx(SvgRefresh, {}),
2397
+ onCopy,
2398
+ onUpvote,
2399
+ onDownvote,
2400
+ onRefresh
2401
+ } = props;
2402
+ const Comp = children ? Slot : "div";
2403
+ const handleCopy = useCallback((text) => {
2404
+ navigator.clipboard.writeText(text).then(() => {
2405
+ console.log("Text copied to clipboard");
2406
+ }).catch((err) => {
2407
+ console.error("Could not copy text: ", err);
2408
+ });
2409
+ }, []);
2410
+ const handleCopyClick = useCallback(() => {
2411
+ if (onCopy) {
2412
+ onCopy();
2413
+ } else {
2414
+ handleCopy(`${question}${response ? `
2415
+ ${response}` : ""}`);
3593
2416
  }
3594
- )
3595
- ] }) });
3596
- };
2417
+ }, [onCopy, handleCopy, question, response]);
2418
+ return (copyIcon || thumbsDownIcon || thumbsUpIcon || refreshIcon) && /* @__PURE__ */ jsx(Comp, { className: cn(theme.messages.message.footer.base), children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
2419
+ copyIcon && /* @__PURE__ */ jsx(
2420
+ IconButton,
2421
+ {
2422
+ variant: "text",
2423
+ disablePadding: true,
2424
+ title: "Copy question and response",
2425
+ className: cn(theme.messages.message.footer.copy),
2426
+ onClick: handleCopyClick,
2427
+ children: copyIcon
2428
+ }
2429
+ ),
2430
+ thumbsUpIcon && /* @__PURE__ */ jsx(
2431
+ IconButton,
2432
+ {
2433
+ variant: "text",
2434
+ disablePadding: true,
2435
+ title: "Upvote",
2436
+ className: cn(theme.messages.message.footer.upvote),
2437
+ onClick: onUpvote,
2438
+ children: thumbsUpIcon
2439
+ }
2440
+ ),
2441
+ thumbsDownIcon && /* @__PURE__ */ jsx(
2442
+ IconButton,
2443
+ {
2444
+ variant: "text",
2445
+ disablePadding: true,
2446
+ title: "Downvote",
2447
+ className: cn(theme.messages.message.footer.downvote),
2448
+ onClick: onDownvote,
2449
+ children: thumbsDownIcon
2450
+ }
2451
+ ),
2452
+ refreshIcon && /* @__PURE__ */ jsx(
2453
+ IconButton,
2454
+ {
2455
+ variant: "text",
2456
+ disablePadding: true,
2457
+ title: "Refresh",
2458
+ className: cn(theme.messages.message.footer.refresh),
2459
+ onClick: onRefresh,
2460
+ children: refreshIcon
2461
+ }
2462
+ )
2463
+ ] }) });
2464
+ }
2465
+ );
2466
+ MessageActions.displayName = "MessageActions";
3597
2467
  const messageVariants = {
3598
2468
  hidden: {
3599
2469
  opacity: 0,
@@ -3607,37 +2477,36 @@ const messageVariants = {
3607
2477
  }
3608
2478
  }
3609
2479
  };
3610
- const SessionMessage = ({
3611
- conversation,
3612
- isLast,
3613
- children
3614
- }) => {
3615
- const { theme, isLoading } = useContext(ChatContext);
3616
- return /* @__PURE__ */ jsx(motion.div, { variants: messageVariants, children: /* @__PURE__ */ jsx(Card, { className: cn(theme.messages.message.base), children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
3617
- /* @__PURE__ */ jsx(
3618
- MessageQuestion,
3619
- {
3620
- question: conversation.question,
3621
- files: conversation.files
3622
- }
3623
- ),
3624
- /* @__PURE__ */ jsx(
3625
- MessageResponse,
3626
- {
3627
- response: conversation.response,
3628
- isLoading: isLast && isLoading
3629
- }
3630
- ),
3631
- /* @__PURE__ */ jsx(MessageSources, { sources: conversation.sources }),
3632
- /* @__PURE__ */ jsx(
3633
- MessageActions,
3634
- {
3635
- question: conversation.question,
3636
- response: conversation.response
3637
- }
3638
- )
3639
- ] }) }) }, conversation.id);
3640
- };
2480
+ const SessionMessage = memo(
2481
+ ({ conversation, isLast, children }) => {
2482
+ const { theme, isLoading } = useContext(ChatContext);
2483
+ return /* @__PURE__ */ jsx(motion.div, { variants: messageVariants, children: /* @__PURE__ */ jsx(Card, { className: cn(theme.messages.message.base), children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
2484
+ /* @__PURE__ */ jsx(
2485
+ MessageQuestion,
2486
+ {
2487
+ question: conversation.question,
2488
+ files: conversation.files
2489
+ }
2490
+ ),
2491
+ /* @__PURE__ */ jsx(
2492
+ MessageResponse,
2493
+ {
2494
+ response: conversation.response,
2495
+ isLoading: isLast && isLoading
2496
+ }
2497
+ ),
2498
+ /* @__PURE__ */ jsx(MessageSources, { sources: conversation.sources }),
2499
+ /* @__PURE__ */ jsx(
2500
+ MessageActions,
2501
+ {
2502
+ question: conversation.question,
2503
+ response: conversation.response
2504
+ }
2505
+ )
2506
+ ] }) }) }, conversation.id);
2507
+ }
2508
+ );
2509
+ SessionMessage.displayName = "SessionMessage";
3641
2510
  const SvgArrowDown = (props) => /* @__PURE__ */ React.createElement("svg", { width: 20, height: 20, viewBox: "0 0 20 20", fill: "currentColor", xmlns: "http://www.w3.org/2000/svg", className: "shrink-0 mix-blend-luminosity", "aria-hidden": "true", ...props }, /* @__PURE__ */ React.createElement("path", { d: "M10 3C10.2761 3.00006 10.5 3.2239 10.5 3.5V15.293L14.6465 11.1465C14.8418 10.9514 15.1583 10.9513 15.3536 11.1465C15.5487 11.3417 15.5486 11.6583 15.3536 11.8535L10.3535 16.8535C10.2598 16.9473 10.1326 17 10 17C9.90062 17 9.8042 16.9703 9.72268 16.916L9.64651 16.8535L4.6465 11.8535C4.45138 11.6582 4.45128 11.3417 4.6465 11.1465C4.84172 10.9513 5.15827 10.9514 5.35353 11.1465L9.50003 15.293V3.5C9.50003 3.22386 9.72389 3 10 3Z" }));
3642
2511
  const containerVariants = {
3643
2512
  hidden: {},
@@ -3743,7 +2612,7 @@ const SessionMessages = ({
3743
2612
  SessionMessage,
3744
2613
  {
3745
2614
  conversation,
3746
- isLast: index === conversation.length - 1
2615
+ isLast: index === convosToRender.length - 1
3747
2616
  },
3748
2617
  conversation.id
3749
2618
  ))
@@ -3777,23 +2646,35 @@ const SessionMessages = ({
3777
2646
  const useDimensions = () => {
3778
2647
  const [ref, setRef] = useState(null);
3779
2648
  const [width, setWidth] = useState(void 0);
2649
+ const rafId = useRef(null);
3780
2650
  const observe = useCallback((element) => {
3781
2651
  if (element) setRef(element);
3782
2652
  }, []);
3783
2653
  useEffect(() => {
3784
2654
  if (!ref) return;
3785
2655
  const resizeObserver = new ResizeObserver((entries) => {
3786
- for (let entry of entries) {
3787
- setWidth(entry.contentRect.width);
2656
+ if (rafId.current !== null) {
2657
+ cancelAnimationFrame(rafId.current);
3788
2658
  }
2659
+ rafId.current = requestAnimationFrame(() => {
2660
+ for (const entry of entries) {
2661
+ setWidth(entry.contentRect.width);
2662
+ }
2663
+ rafId.current = null;
2664
+ });
3789
2665
  });
3790
2666
  resizeObserver.observe(ref);
3791
2667
  return () => {
2668
+ if (rafId.current !== null) {
2669
+ cancelAnimationFrame(rafId.current);
2670
+ rafId.current = null;
2671
+ }
3792
2672
  resizeObserver.disconnect();
3793
2673
  };
3794
2674
  }, [ref]);
3795
2675
  return { width, observe };
3796
2676
  };
2677
+ const defaultRemarkPlugins = [remarkGfm, remarkYoutube, remarkMath];
3797
2678
  const Chat = ({
3798
2679
  children,
3799
2680
  viewType = "console",
@@ -3807,8 +2688,9 @@ const Chat = ({
3807
2688
  activeSessionId,
3808
2689
  theme: customTheme = chatTheme,
3809
2690
  onNewSession,
3810
- remarkPlugins = [remarkGfm, remarkYoutube, remarkMath],
2691
+ remarkPlugins = defaultRemarkPlugins,
3811
2692
  markdownComponents,
2693
+ components: componentCatalog2,
3812
2694
  disabled,
3813
2695
  style,
3814
2696
  className
@@ -3853,12 +2735,23 @@ const Chat = ({
3853
2735
  () => sessions.find((session) => session.id === internalActiveSessionID),
3854
2736
  [sessions, internalActiveSessionID]
3855
2737
  );
2738
+ const mergedRemarkPlugins = useMemo(() => {
2739
+ if (!componentCatalog2) return remarkPlugins;
2740
+ return [...remarkPlugins, componentCatalog2.remarkPlugin];
2741
+ }, [remarkPlugins, componentCatalog2]);
2742
+ const mergedMarkdownComponents = useMemo(() => {
2743
+ if (!componentCatalog2) return markdownComponents;
2744
+ return {
2745
+ ...componentCatalog2.components,
2746
+ ...markdownComponents
2747
+ };
2748
+ }, [markdownComponents, componentCatalog2]);
3856
2749
  const contextValue = useMemo(
3857
2750
  () => ({
3858
2751
  sessions,
3859
2752
  activeSession,
3860
- remarkPlugins,
3861
- markdownComponents,
2753
+ remarkPlugins: mergedRemarkPlugins,
2754
+ markdownComponents: mergedMarkdownComponents,
3862
2755
  theme,
3863
2756
  disabled,
3864
2757
  isLoading,
@@ -3878,8 +2771,8 @@ const Chat = ({
3878
2771
  viewType,
3879
2772
  disabled,
3880
2773
  theme,
3881
- remarkPlugins,
3882
- markdownComponents,
2774
+ mergedRemarkPlugins,
2775
+ mergedMarkdownComponents,
3883
2776
  sessions,
3884
2777
  activeSession,
3885
2778
  internalActiveSessionID,
@@ -3906,44 +2799,54 @@ const Chat = ({
3906
2799
  };
3907
2800
  const SvgTrash = (props) => /* @__PURE__ */ React.createElement("svg", { width: 14, height: 14, viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props }, /* @__PURE__ */ React.createElement("g", { id: "Delete" }, /* @__PURE__ */ React.createElement("path", { id: "Vector", d: "M5.97905 1.16666C5.90859 1.16576 5.83895 1.18189 5.77605 1.21368C5.71316 1.24547 5.65888 1.29199 5.61783 1.34926C5.57677 1.40654 5.55016 1.47288 5.54025 1.54265C5.53034 1.61242 5.53743 1.68355 5.56092 1.75H4.27007C3.7342 1.75 3.2324 2.01817 2.93535 2.46435L2.24492 3.5H2.18738C2.12941 3.49918 2.07185 3.50989 2.01805 3.5315C1.96425 3.55312 1.91529 3.58522 1.874 3.62593C1.83271 3.66663 1.79993 3.71514 1.77755 3.76863C1.75518 3.82211 1.74365 3.87952 1.74365 3.9375C1.74365 3.99548 1.75518 4.05288 1.77755 4.10636C1.79993 4.15985 1.83271 4.20836 1.874 4.24907C1.91529 4.28977 1.96425 4.32187 2.01805 4.34349C2.07185 4.3651 2.12941 4.37582 2.18738 4.375H2.41012C2.44765 4.38067 2.48576 4.38143 2.52348 4.37727L3.24468 11.1084C3.33169 11.9199 4.02367 12.5417 4.83973 12.5417H9.15947C9.97553 12.5417 10.6675 11.9199 10.7545 11.1084L11.4763 4.37727C11.5133 4.38124 11.5506 4.38047 11.5874 4.375H11.8124C11.8704 4.37582 11.9279 4.3651 11.9817 4.34349C12.0355 4.32187 12.0845 4.28977 12.1258 4.24907C12.1671 4.20836 12.1998 4.15985 12.2222 4.10636C12.2446 4.05288 12.2561 3.99548 12.2561 3.9375C12.2561 3.87952 12.2446 3.82211 12.2222 3.76863C12.1998 3.71514 12.1671 3.66663 12.1258 3.62593C12.0845 3.58522 12.0355 3.55312 11.9817 3.5315C11.9279 3.50989 11.8704 3.49918 11.8124 3.5H11.7548L11.0644 2.46435C10.7671 2.01841 10.2654 1.75 9.7297 1.75H8.43885C8.46234 1.68355 8.46943 1.61242 8.45952 1.54265C8.44961 1.47288 8.423 1.40654 8.38194 1.34926C8.34089 1.29199 8.2866 1.24547 8.22371 1.21368C8.16082 1.18189 8.09118 1.16576 8.02072 1.16666H5.97905ZM4.27007 2.625H9.7297C9.97394 2.625 10.2009 2.74639 10.3364 2.9497L10.7033 3.5H3.29651L3.66338 2.9497L3.66395 2.94913C3.79913 2.74608 4.02543 2.625 4.27007 2.625ZM3.40361 4.375H10.5962L9.88465 11.015C9.8445 11.3894 9.53575 11.6667 9.15947 11.6667H4.83973C4.46345 11.6667 4.15527 11.3894 4.11512 11.015L3.40361 4.375Z", fill: "currentColor" })));
3908
2801
  const SvgChat = (props) => /* @__PURE__ */ React.createElement("svg", { width: 16, height: 17, viewBox: "0 0 16 17", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props }, /* @__PURE__ */ React.createElement("path", { d: "M8 3C4.55375 3 1.75 5.23753 1.75 7.98828C1.75 9.70653 2.83659 11.2762 4.62109 12.188C4.11184 13.0465 3.62587 13.7378 3.62012 13.7461C3.50687 13.9071 3.49862 14.1196 3.59912 14.2891C3.69012 14.4418 3.8543 14.5342 4.0293 14.5342C4.0483 14.5342 4.06743 14.533 4.08643 14.5308C4.15168 14.5233 5.66214 14.3364 7.50439 12.9604C7.67239 12.9712 7.8385 12.9766 8 12.9766C11.4462 12.9766 14.25 10.739 14.25 7.98828C14.25 5.23753 11.4462 3 8 3ZM8 4C10.8948 4 13.25 5.78903 13.25 7.98828C13.25 10.1875 10.8948 11.9766 8 11.9766C7.8055 11.9766 7.60225 11.968 7.396 11.9497C7.271 11.9382 7.1454 11.9752 7.0459 12.0527C6.3589 12.5855 5.72033 12.9308 5.20508 13.1528C5.38383 12.8648 5.57691 12.5418 5.76416 12.2061C5.83416 12.0813 5.84705 11.9324 5.7998 11.7974C5.75255 11.6624 5.64983 11.5542 5.51758 11.5C3.81033 10.7993 2.75 9.45328 2.75 7.98828C2.75 5.78903 5.10525 4 8 4ZM5.5 7.25C5.08575 7.25 4.75 7.58575 4.75 8C4.75 8.41425 5.08575 8.75 5.5 8.75C5.91425 8.75 6.25 8.41425 6.25 8C6.25 7.58575 5.91425 7.25 5.5 7.25ZM8 7.25C7.58575 7.25 7.25 7.58575 7.25 8C7.25 8.41425 7.58575 8.75 8 8.75C8.41425 8.75 8.75 8.41425 8.75 8C8.75 7.58575 8.41425 7.25 8 7.25ZM10.5 7.25C10.0857 7.25 9.75 7.58575 9.75 8C9.75 8.41425 10.0857 8.75 10.5 8.75C10.9143 8.75 11.25 8.41425 11.25 8C11.25 7.58575 10.9143 7.25 10.5 7.25Z", fill: "currentColor" }));
3909
- const SessionListItem = ({
3910
- children,
3911
- session,
3912
- deletable = true,
3913
- limit = 100,
3914
- deleteIcon = /* @__PURE__ */ jsx(SvgTrash, {}),
3915
- chatIcon = /* @__PURE__ */ jsx(SvgChat, { className: "mr-2" })
3916
- }) => {
3917
- const { activeSessionId, selectSession, deleteSession, theme } = useContext(ChatContext);
3918
- const Comp = children ? Slot : ListItem;
3919
- return /* @__PURE__ */ jsx(
3920
- Comp,
3921
- {
3922
- dense: true,
3923
- disableGutters: true,
3924
- active: session.id === activeSessionId,
3925
- className: cn(theme.sessions.session.base, {
3926
- [theme.sessions.session.active]: session.id === activeSessionId
3927
- }),
3928
- onClick: () => selectSession == null ? void 0 : selectSession(session.id),
3929
- start: chatIcon,
3930
- end: /* @__PURE__ */ jsx(Fragment, { children: deletable && /* @__PURE__ */ jsx(
3931
- IconButton,
3932
- {
3933
- size: "small",
3934
- variant: "text",
3935
- onClick: (e) => {
3936
- e.stopPropagation();
3937
- deleteSession(session.id);
3938
- },
3939
- className: cn(theme.sessions.session.delete),
3940
- children: deleteIcon
3941
- }
3942
- ) }),
3943
- children: children || /* @__PURE__ */ jsx(Ellipsis, { value: session.title, limit })
3944
- }
3945
- );
3946
- };
2802
+ const SessionListItem = memo(
2803
+ ({
2804
+ children,
2805
+ session,
2806
+ deletable = true,
2807
+ limit = 100,
2808
+ deleteIcon = /* @__PURE__ */ jsx(SvgTrash, {}),
2809
+ chatIcon = /* @__PURE__ */ jsx(SvgChat, { className: "mr-2" })
2810
+ }) => {
2811
+ const { activeSessionId, selectSession, deleteSession, theme } = useContext(ChatContext);
2812
+ const Comp = children ? Slot : ListItem;
2813
+ const handleSelect = useCallback(() => {
2814
+ selectSession == null ? void 0 : selectSession(session.id);
2815
+ }, [selectSession, session.id]);
2816
+ const handleDelete = useCallback(
2817
+ (e) => {
2818
+ e.stopPropagation();
2819
+ deleteSession(session.id);
2820
+ },
2821
+ [deleteSession, session.id]
2822
+ );
2823
+ return /* @__PURE__ */ jsx(
2824
+ Comp,
2825
+ {
2826
+ dense: true,
2827
+ disableGutters: true,
2828
+ active: session.id === activeSessionId,
2829
+ className: cn(theme.sessions.session.base, {
2830
+ [theme.sessions.session.active]: session.id === activeSessionId
2831
+ }),
2832
+ onClick: handleSelect,
2833
+ start: chatIcon,
2834
+ end: /* @__PURE__ */ jsx(Fragment, { children: deletable && /* @__PURE__ */ jsx(
2835
+ IconButton,
2836
+ {
2837
+ size: "small",
2838
+ variant: "text",
2839
+ onClick: handleDelete,
2840
+ className: cn(theme.sessions.session.delete),
2841
+ children: deleteIcon
2842
+ }
2843
+ ) }),
2844
+ children: children || /* @__PURE__ */ jsx(Ellipsis, { value: session.title, limit })
2845
+ }
2846
+ );
2847
+ }
2848
+ );
2849
+ SessionListItem.displayName = "SessionListItem";
3947
2850
  const SessionsList = ({
3948
2851
  children,
3949
2852
  templates
@@ -4026,49 +2929,43 @@ const sortOrder = [
4026
2929
  "December",
4027
2930
  "Last Year"
4028
2931
  ];
2932
+ const sortOrderMap = new Map(sortOrder.map((v, i) => [v, i]));
4029
2933
  function groupSessionsByDate(sessions) {
4030
2934
  const grouped = {};
2935
+ const now = /* @__PURE__ */ new Date();
4031
2936
  sessions.forEach((session) => {
4032
- const createdAt = new Date(session.createdAt);
4033
- const now = /* @__PURE__ */ new Date();
4034
- if (isToday(createdAt)) {
4035
- if (!grouped["Today"]) grouped["Today"] = [];
4036
- grouped["Today"].push(session);
2937
+ const createdAt = session.createdAt ? new Date(session.createdAt) : null;
2938
+ let group;
2939
+ if (!createdAt || isNaN(createdAt.getTime())) {
2940
+ group = "Last Year";
2941
+ } else if (isToday(createdAt)) {
2942
+ group = "Today";
4037
2943
  } else if (isYesterday(createdAt)) {
4038
- if (!grouped["Yesterday"]) grouped["Yesterday"] = [];
4039
- grouped["Yesterday"].push(session);
2944
+ group = "Yesterday";
4040
2945
  } else if (isThisWeek(createdAt)) {
4041
- if (!grouped["Last Week"]) grouped["Last Week"] = [];
4042
- grouped["Last Week"].push(session);
2946
+ group = "Last Week";
4043
2947
  } else if (differenceInYears(now, createdAt) === 0) {
4044
2948
  const monthDiff = now.getMonth() - createdAt.getMonth();
4045
2949
  const yearDiff = now.getFullYear() - createdAt.getFullYear();
4046
2950
  const adjustedMonthDiff = yearDiff > 0 ? monthDiff + 12 : monthDiff;
4047
2951
  if (adjustedMonthDiff === 1 || adjustedMonthDiff === 0 && now.getDate() > createdAt.getDate()) {
4048
- if (!grouped["Last Month"]) grouped["Last Month"] = [];
4049
- grouped["Last Month"].push(session);
2952
+ group = "Last Month";
4050
2953
  } else {
4051
- const monthName = format(createdAt, "MMMM");
4052
- if (!grouped[monthName]) grouped[monthName] = [];
4053
- grouped[monthName].push(session);
2954
+ group = format(createdAt, "MMMM");
4054
2955
  }
4055
2956
  } else {
4056
- if (!grouped["Last Year"]) grouped["Last Year"] = [];
4057
- grouped["Last Year"].push(session);
4058
- }
4059
- });
4060
- Object.keys(grouped).forEach((key) => {
4061
- if (grouped[key].length === 0) {
4062
- delete grouped[key];
2957
+ group = "Last Year";
4063
2958
  }
2959
+ if (!grouped[group]) grouped[group] = [];
2960
+ grouped[group].push(session);
4064
2961
  });
4065
2962
  const sortedGroups = Object.keys(grouped).sort(
4066
- (a, b) => sortOrder.indexOf(a) - sortOrder.indexOf(b)
2963
+ (a, b) => (sortOrderMap.get(a) ?? 999) - (sortOrderMap.get(b) ?? 999)
4067
2964
  );
4068
2965
  return sortedGroups.map((heading) => ({
4069
2966
  heading,
4070
2967
  sessions: grouped[heading].sort(
4071
- (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
2968
+ (a, b) => (b.createdAt ? new Date(b.createdAt).getTime() : 0) - (a.createdAt ? new Date(a.createdAt).getTime() : 0)
4072
2969
  )
4073
2970
  }));
4074
2971
  }
@@ -4102,16 +2999,21 @@ const AppBar = ({
4102
2999
  const theme = useComponentTheme("chat", customTheme);
4103
3000
  return /* @__PURE__ */ jsx("div", { className: cn(theme.appbar), children: content });
4104
3001
  };
3002
+ const DEFAULT_MODIFIERS = [offset({ mainAxis: 0, crossAxis: -40 })];
4105
3003
  const ChatBubble = memo(
4106
3004
  ({
4107
3005
  children,
4108
3006
  bubbleContent,
4109
3007
  position = "right-end",
4110
- modifiers = [offset({ mainAxis: 0, crossAxis: -40 })],
3008
+ modifiers = DEFAULT_MODIFIERS,
4111
3009
  className
4112
3010
  }) => {
4113
3011
  const [isOpen, setIsOpen] = useState(false);
4114
3012
  const ref = useRef(null);
3013
+ const handleOpen = useCallback(() => setIsOpen(true), []);
3014
+ const handleClose = useCallback(() => setIsOpen(false), []);
3015
+ const handleToggle = useCallback(() => setIsOpen((prev) => !prev), []);
3016
+ const renderContent = useCallback(() => /* @__PURE__ */ jsx(Fragment, { children }), [children]);
4115
3017
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4116
3018
  /* @__PURE__ */ jsx(
4117
3019
  ConnectedOverlay,
@@ -4120,20 +3022,12 @@ const ChatBubble = memo(
4120
3022
  modifiers,
4121
3023
  reference: ref.current,
4122
3024
  open: isOpen,
4123
- onOpen: () => setIsOpen(true),
4124
- onClose: () => setIsOpen(false),
4125
- content: () => /* @__PURE__ */ jsx(Fragment, { children })
3025
+ onOpen: handleOpen,
3026
+ onClose: handleClose,
3027
+ content: renderContent
4126
3028
  }
4127
3029
  ),
4128
- /* @__PURE__ */ jsx(
4129
- "div",
4130
- {
4131
- ref,
4132
- className,
4133
- onClick: () => setIsOpen((prev) => !prev),
4134
- children: bubbleContent
4135
- }
4136
- )
3030
+ /* @__PURE__ */ jsx("div", { ref, className, onClick: handleToggle, children: bubbleContent })
4137
3031
  ] });
4138
3032
  }
4139
3033
  );
@@ -4314,56 +3208,810 @@ const MessageStatus = ({
4314
3208
  }
4315
3209
  ) });
4316
3210
  };
3211
+ var AgUiEventType = /* @__PURE__ */ ((AgUiEventType2) => {
3212
+ AgUiEventType2["RUN_STARTED"] = "RUN_STARTED";
3213
+ AgUiEventType2["RUN_FINISHED"] = "RUN_FINISHED";
3214
+ AgUiEventType2["RUN_ERROR"] = "RUN_ERROR";
3215
+ AgUiEventType2["STEP_STARTED"] = "STEP_STARTED";
3216
+ AgUiEventType2["STEP_FINISHED"] = "STEP_FINISHED";
3217
+ AgUiEventType2["TEXT_MESSAGE_START"] = "TEXT_MESSAGE_START";
3218
+ AgUiEventType2["TEXT_MESSAGE_CONTENT"] = "TEXT_MESSAGE_CONTENT";
3219
+ AgUiEventType2["TEXT_MESSAGE_END"] = "TEXT_MESSAGE_END";
3220
+ AgUiEventType2["TEXT_MESSAGE_CHUNK"] = "TEXT_MESSAGE_CHUNK";
3221
+ AgUiEventType2["TOOL_CALL_START"] = "TOOL_CALL_START";
3222
+ AgUiEventType2["TOOL_CALL_ARGS"] = "TOOL_CALL_ARGS";
3223
+ AgUiEventType2["TOOL_CALL_END"] = "TOOL_CALL_END";
3224
+ AgUiEventType2["TOOL_CALL_RESULT"] = "TOOL_CALL_RESULT";
3225
+ AgUiEventType2["TOOL_CALL_CHUNK"] = "TOOL_CALL_CHUNK";
3226
+ AgUiEventType2["STATE_SNAPSHOT"] = "STATE_SNAPSHOT";
3227
+ AgUiEventType2["STATE_DELTA"] = "STATE_DELTA";
3228
+ AgUiEventType2["MESSAGES_SNAPSHOT"] = "MESSAGES_SNAPSHOT";
3229
+ AgUiEventType2["RAW"] = "RAW";
3230
+ AgUiEventType2["CUSTOM"] = "CUSTOM";
3231
+ return AgUiEventType2;
3232
+ })(AgUiEventType || {});
3233
+ function generateId() {
3234
+ return Math.random().toString(36).substring(2, 11);
3235
+ }
3236
+ function addConversationToSession(sessions, sessionId, conversation) {
3237
+ return sessions.map((s) => {
3238
+ if (s.id !== sessionId) return s;
3239
+ return {
3240
+ ...s,
3241
+ updatedAt: conversation.createdAt,
3242
+ conversations: [...s.conversations, conversation]
3243
+ };
3244
+ });
3245
+ }
3246
+ function updateConversationInSession(sessions, sessionId, conversationId, response) {
3247
+ return sessions.map((s) => {
3248
+ if (s.id !== sessionId) return s;
3249
+ return {
3250
+ ...s,
3251
+ updatedAt: /* @__PURE__ */ new Date(),
3252
+ conversations: s.conversations.map((c) => {
3253
+ if (c.id !== conversationId) return c;
3254
+ return { ...c, response, updatedAt: /* @__PURE__ */ new Date() };
3255
+ })
3256
+ };
3257
+ });
3258
+ }
3259
+ function sessionsToAgUiMessages(session) {
3260
+ const messages = [];
3261
+ for (const conv of session.conversations) {
3262
+ messages.push({
3263
+ id: `${conv.id}-q`,
3264
+ role: "user",
3265
+ content: conv.question
3266
+ });
3267
+ if (conv.response) {
3268
+ messages.push({
3269
+ id: `${conv.id}-r`,
3270
+ role: "assistant",
3271
+ content: conv.response
3272
+ });
3273
+ }
3274
+ }
3275
+ return messages;
3276
+ }
3277
+ function parseSSELine(line) {
3278
+ const trimmed = line.trim();
3279
+ if (!trimmed || trimmed.startsWith(":")) return null;
3280
+ if (trimmed.startsWith("data:")) {
3281
+ const data = trimmed.slice(5).trim();
3282
+ if (data === "[DONE]") return null;
3283
+ try {
3284
+ return JSON.parse(data);
3285
+ } catch (err) {
3286
+ return new Error(
3287
+ `Failed to parse AG-UI event: ${err instanceof Error ? err.message : err}`
3288
+ );
3289
+ }
3290
+ }
3291
+ return null;
3292
+ }
3293
+ async function* parseSSE(response, signal) {
3294
+ var _a;
3295
+ const reader = (_a = response.body) == null ? void 0 : _a.getReader();
3296
+ if (!reader) {
3297
+ throw new Error("Response body is not readable");
3298
+ }
3299
+ const decoder = new TextDecoder();
3300
+ let buffer = "";
3301
+ try {
3302
+ while (!signal.aborted) {
3303
+ const { done, value } = await reader.read();
3304
+ if (done) break;
3305
+ buffer += decoder.decode(value, { stream: true });
3306
+ const lines = buffer.split("\n");
3307
+ buffer = lines.pop() || "";
3308
+ for (const line of lines) {
3309
+ const result = parseSSELine(line);
3310
+ if (result !== null) yield result;
3311
+ }
3312
+ }
3313
+ if (buffer.trim()) {
3314
+ const result = parseSSELine(buffer);
3315
+ if (result !== null) yield result;
3316
+ }
3317
+ } finally {
3318
+ reader.releaseLock();
3319
+ }
3320
+ }
3321
+ function useAgUi({
3322
+ agent,
3323
+ initialSessions = [],
3324
+ initialActiveSessionId,
3325
+ tools = [],
3326
+ context = [],
3327
+ forwardedProps = {},
3328
+ headers = {},
3329
+ onToolCall,
3330
+ onError,
3331
+ onEvent
3332
+ }) {
3333
+ const [sessions, setSessions] = useState(initialSessions);
3334
+ const [activeSessionId, setActiveSessionId] = useState(
3335
+ initialActiveSessionId
3336
+ );
3337
+ const [isLoading, setIsLoading] = useState(false);
3338
+ const abortRef = useRef(null);
3339
+ const onToolCallRef = useRef(onToolCall);
3340
+ onToolCallRef.current = onToolCall;
3341
+ const onErrorRef = useRef(onError);
3342
+ onErrorRef.current = onError;
3343
+ const onEventRef = useRef(onEvent);
3344
+ onEventRef.current = onEvent;
3345
+ useEffect(() => {
3346
+ return () => {
3347
+ var _a;
3348
+ (_a = abortRef.current) == null ? void 0 : _a.abort();
3349
+ };
3350
+ }, []);
3351
+ const selectSession = useCallback((sessionId) => {
3352
+ setActiveSessionId(sessionId);
3353
+ }, []);
3354
+ const deleteSession = useCallback(
3355
+ (sessionId) => {
3356
+ setSessions((prev) => prev.filter((s) => s.id !== sessionId));
3357
+ if (activeSessionId === sessionId) {
3358
+ setActiveSessionId(void 0);
3359
+ }
3360
+ },
3361
+ [activeSessionId]
3362
+ );
3363
+ const createSession = useCallback(() => {
3364
+ const id = generateId();
3365
+ const newSession = {
3366
+ id,
3367
+ title: "New Session",
3368
+ createdAt: /* @__PURE__ */ new Date(),
3369
+ updatedAt: /* @__PURE__ */ new Date(),
3370
+ conversations: []
3371
+ };
3372
+ setSessions((prev) => [newSession, ...prev]);
3373
+ setActiveSessionId(id);
3374
+ }, []);
3375
+ const stopMessage = useCallback(() => {
3376
+ var _a;
3377
+ (_a = abortRef.current) == null ? void 0 : _a.abort();
3378
+ abortRef.current = null;
3379
+ setIsLoading(false);
3380
+ }, []);
3381
+ const sendMessage = useCallback(
3382
+ async (message) => {
3383
+ var _a, _b, _c, _d, _e, _f;
3384
+ (_a = abortRef.current) == null ? void 0 : _a.abort();
3385
+ const abortController = new AbortController();
3386
+ abortRef.current = abortController;
3387
+ let sessionId = activeSessionId;
3388
+ if (!sessionId) {
3389
+ sessionId = generateId();
3390
+ const newSession = {
3391
+ id: sessionId,
3392
+ title: message.slice(0, 50),
3393
+ createdAt: /* @__PURE__ */ new Date(),
3394
+ updatedAt: /* @__PURE__ */ new Date(),
3395
+ conversations: []
3396
+ };
3397
+ setSessions((prev) => [newSession, ...prev]);
3398
+ setActiveSessionId(sessionId);
3399
+ }
3400
+ const conversationId = generateId();
3401
+ const now = /* @__PURE__ */ new Date();
3402
+ setSessions(
3403
+ (prev) => addConversationToSession(prev, sessionId, {
3404
+ id: conversationId,
3405
+ question: message,
3406
+ createdAt: now
3407
+ })
3408
+ );
3409
+ setIsLoading(true);
3410
+ const currentSession = [
3411
+ ...((_b = sessions.find((s) => s.id === sessionId)) == null ? void 0 : _b.conversations) ?? []
3412
+ ];
3413
+ const historyMessages = sessionsToAgUiMessages({
3414
+ conversations: currentSession
3415
+ });
3416
+ historyMessages.push({
3417
+ id: `${conversationId}-q`,
3418
+ role: "user",
3419
+ content: message
3420
+ });
3421
+ const runId = generateId();
3422
+ const input = {
3423
+ threadId: sessionId,
3424
+ runId,
3425
+ messages: historyMessages,
3426
+ tools,
3427
+ context,
3428
+ state: null,
3429
+ forwardedProps
3430
+ };
3431
+ try {
3432
+ const response = await fetch(agent, {
3433
+ method: "POST",
3434
+ headers: {
3435
+ "Content-Type": "application/json",
3436
+ Accept: "text/event-stream",
3437
+ ...headers
3438
+ },
3439
+ body: JSON.stringify(input),
3440
+ signal: abortController.signal
3441
+ });
3442
+ if (!response.ok) {
3443
+ throw new Error(
3444
+ `Agent returned ${response.status}: ${response.statusText}`
3445
+ );
3446
+ }
3447
+ let responseText = "";
3448
+ const toolCalls = /* @__PURE__ */ new Map();
3449
+ const updateResponse = (text) => {
3450
+ setSessions(
3451
+ (prev) => updateConversationInSession(prev, sessionId, conversationId, text)
3452
+ );
3453
+ };
3454
+ for await (const eventOrError of parseSSE(
3455
+ response,
3456
+ abortController.signal
3457
+ )) {
3458
+ if (eventOrError instanceof Error) {
3459
+ (_c = onErrorRef.current) == null ? void 0 : _c.call(onErrorRef, eventOrError);
3460
+ continue;
3461
+ }
3462
+ const event = eventOrError;
3463
+ (_d = onEventRef.current) == null ? void 0 : _d.call(onEventRef, event);
3464
+ switch (event.type) {
3465
+ case AgUiEventType.TEXT_MESSAGE_CONTENT: {
3466
+ responseText += event.delta;
3467
+ updateResponse(responseText);
3468
+ break;
3469
+ }
3470
+ case AgUiEventType.TEXT_MESSAGE_CHUNK: {
3471
+ if (event.delta) {
3472
+ responseText += event.delta;
3473
+ updateResponse(responseText);
3474
+ }
3475
+ break;
3476
+ }
3477
+ case AgUiEventType.TOOL_CALL_START: {
3478
+ toolCalls.set(event.toolCallId, {
3479
+ name: event.toolCallName,
3480
+ args: ""
3481
+ });
3482
+ break;
3483
+ }
3484
+ case AgUiEventType.TOOL_CALL_ARGS: {
3485
+ const tc = toolCalls.get(event.toolCallId);
3486
+ if (tc) {
3487
+ tc.args += event.delta;
3488
+ }
3489
+ break;
3490
+ }
3491
+ case AgUiEventType.TOOL_CALL_END: {
3492
+ const tc = toolCalls.get(event.toolCallId);
3493
+ if (tc && onToolCallRef.current) {
3494
+ try {
3495
+ await onToolCallRef.current({
3496
+ toolCallId: event.toolCallId,
3497
+ toolCallName: tc.name,
3498
+ args: tc.args
3499
+ });
3500
+ } catch {
3501
+ }
3502
+ }
3503
+ toolCalls.delete(event.toolCallId);
3504
+ break;
3505
+ }
3506
+ case AgUiEventType.RUN_ERROR: {
3507
+ const err = new Error(event.message);
3508
+ (_e = onErrorRef.current) == null ? void 0 : _e.call(onErrorRef, err);
3509
+ break;
3510
+ }
3511
+ case AgUiEventType.RUN_FINISHED: {
3512
+ break;
3513
+ }
3514
+ }
3515
+ }
3516
+ } catch (err) {
3517
+ if (err instanceof DOMException && err.name === "AbortError") {
3518
+ return;
3519
+ }
3520
+ const error = err instanceof Error ? err : new Error(String(err));
3521
+ (_f = onErrorRef.current) == null ? void 0 : _f.call(onErrorRef, error);
3522
+ } finally {
3523
+ if (abortRef.current === abortController) {
3524
+ abortRef.current = null;
3525
+ }
3526
+ setIsLoading(false);
3527
+ }
3528
+ },
3529
+ [activeSessionId, agent, context, forwardedProps, headers, sessions, tools]
3530
+ );
3531
+ return {
3532
+ sessions,
3533
+ activeSessionId,
3534
+ isLoading,
3535
+ selectSession,
3536
+ deleteSession,
3537
+ createSession,
3538
+ sendMessage,
3539
+ stopMessage
3540
+ };
3541
+ }
3542
+ function validateSpec(raw, definitions) {
3543
+ let parsed;
3544
+ try {
3545
+ parsed = JSON.parse(raw);
3546
+ } catch {
3547
+ return {
3548
+ ok: false,
3549
+ error: {
3550
+ type: "invalid_json",
3551
+ message: "Failed to parse component JSON",
3552
+ raw
3553
+ }
3554
+ };
3555
+ }
3556
+ const specArray = Array.isArray(parsed) ? parsed : [parsed];
3557
+ const validated = [];
3558
+ for (const item of specArray) {
3559
+ const result = validateSingleSpec(item, raw, definitions);
3560
+ if (!result.ok) {
3561
+ return { ok: false, error: result.error };
3562
+ }
3563
+ validated.push(result.spec);
3564
+ }
3565
+ return { ok: true, specs: validated };
3566
+ }
3567
+ function validateSingleSpec(item, raw, definitions) {
3568
+ if (!item || typeof item !== "object" || !("type" in item)) {
3569
+ return {
3570
+ ok: false,
3571
+ error: {
3572
+ type: "invalid_json",
3573
+ message: 'Component spec must be an object with a "type" field',
3574
+ raw
3575
+ }
3576
+ };
3577
+ }
3578
+ const spec = item;
3579
+ if (typeof spec.type !== "string") {
3580
+ return {
3581
+ ok: false,
3582
+ error: {
3583
+ type: "invalid_json",
3584
+ message: '"type" must be a string',
3585
+ raw
3586
+ }
3587
+ };
3588
+ }
3589
+ const componentType = spec.type;
3590
+ const definition = definitions[componentType];
3591
+ if (!definition) {
3592
+ return {
3593
+ ok: false,
3594
+ error: {
3595
+ type: "unknown_component",
3596
+ message: `Unknown component "${componentType}". Available: ${Object.keys(definitions).join(", ")}`,
3597
+ raw,
3598
+ componentType
3599
+ }
3600
+ };
3601
+ }
3602
+ const props = spec.props && typeof spec.props === "object" && !Array.isArray(spec.props) ? spec.props : {};
3603
+ const parseResult = definition.props.safeParse(props);
3604
+ if (!parseResult.success) {
3605
+ return {
3606
+ ok: false,
3607
+ error: {
3608
+ type: "invalid_props",
3609
+ message: `Invalid props for "${componentType}": ${parseResult.error.issues.map((i) => i.message).join(", ")}`,
3610
+ raw,
3611
+ componentType,
3612
+ issues: parseResult.error.issues.map((i) => ({
3613
+ message: i.message,
3614
+ path: i.path
3615
+ }))
3616
+ }
3617
+ };
3618
+ }
3619
+ let validatedChildren;
3620
+ if (spec.children) {
3621
+ if (!Array.isArray(spec.children)) {
3622
+ return {
3623
+ ok: false,
3624
+ error: {
3625
+ type: "invalid_json",
3626
+ message: '"children" must be an array',
3627
+ raw,
3628
+ componentType
3629
+ }
3630
+ };
3631
+ }
3632
+ validatedChildren = [];
3633
+ for (const child of spec.children) {
3634
+ const childResult = validateSingleSpec(child, raw, definitions);
3635
+ if (!childResult.ok) {
3636
+ return childResult;
3637
+ }
3638
+ validatedChildren.push(childResult.spec);
3639
+ }
3640
+ }
3641
+ return {
3642
+ ok: true,
3643
+ spec: {
3644
+ type: componentType,
3645
+ props: parseResult.data,
3646
+ ...validatedChildren ? { children: validatedChildren } : {}
3647
+ }
3648
+ };
3649
+ }
3650
+ const ComponentRenderer = ({
3651
+ raw,
3652
+ definitions,
3653
+ options
3654
+ }) => {
3655
+ var _a, _b;
3656
+ const { theme, sendMessage } = useContext(ChatContext);
3657
+ const result = useMemo(
3658
+ () => validateSpec(raw, definitions),
3659
+ [raw, definitions]
3660
+ );
3661
+ if (!result.ok) {
3662
+ const error = result.error;
3663
+ const custom = (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, error);
3664
+ if (custom !== void 0) {
3665
+ return /* @__PURE__ */ jsx(Fragment, { children: custom });
3666
+ }
3667
+ return /* @__PURE__ */ jsx(
3668
+ ComponentError,
3669
+ {
3670
+ title: errorTitle(error.type),
3671
+ message: error.message,
3672
+ code: error.raw
3673
+ }
3674
+ );
3675
+ }
3676
+ const specs = result.specs;
3677
+ return /* @__PURE__ */ jsx("div", { className: (_b = theme.component) == null ? void 0 : _b.base, children: specs.map((spec, index) => /* @__PURE__ */ jsx(
3678
+ SpecRenderer,
3679
+ {
3680
+ spec,
3681
+ definitions,
3682
+ options,
3683
+ sendMessage
3684
+ },
3685
+ `${spec.type}-${index}-${stableKey(spec)}`
3686
+ )) });
3687
+ };
3688
+ const SpecRenderer = ({
3689
+ spec,
3690
+ definitions,
3691
+ options,
3692
+ sendMessage
3693
+ }) => {
3694
+ var _a, _b;
3695
+ const definition = definitions[spec.type];
3696
+ if (!definition) {
3697
+ const error = {
3698
+ type: "unknown_component",
3699
+ message: `Unknown component "${spec.type}"`,
3700
+ raw: JSON.stringify(spec),
3701
+ componentType: spec.type
3702
+ };
3703
+ const custom = (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, error);
3704
+ if (custom !== void 0) {
3705
+ return /* @__PURE__ */ jsx(Fragment, { children: custom });
3706
+ }
3707
+ return /* @__PURE__ */ jsx(ComponentError, { title: errorTitle(error.type), message: error.message });
3708
+ }
3709
+ const RenderedComponent = definition.component;
3710
+ const children = (_b = spec.children) == null ? void 0 : _b.map((child, index) => /* @__PURE__ */ jsx(
3711
+ SpecRenderer,
3712
+ {
3713
+ spec: child,
3714
+ definitions,
3715
+ options,
3716
+ sendMessage
3717
+ },
3718
+ `${child.type}-${index}-${stableKey(child)}`
3719
+ ));
3720
+ return /* @__PURE__ */ jsx(SpecErrorBoundary, { spec, options, children: /* @__PURE__ */ jsx(RenderedComponent, { ...spec.props, sendMessage, children }) });
3721
+ };
3722
+ class SpecErrorBoundary extends Component {
3723
+ constructor() {
3724
+ super(...arguments);
3725
+ this.state = { error: null };
3726
+ }
3727
+ static getDerivedStateFromError(error) {
3728
+ return { error };
3729
+ }
3730
+ render() {
3731
+ var _a;
3732
+ if (this.state.error) {
3733
+ const { spec, options } = this.props;
3734
+ const catalogError = {
3735
+ type: "render_error",
3736
+ message: `Error rendering "${spec.type}": ${this.state.error.message}`,
3737
+ raw: JSON.stringify(spec),
3738
+ componentType: spec.type
3739
+ };
3740
+ const custom = (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, catalogError);
3741
+ if (custom !== void 0) {
3742
+ return /* @__PURE__ */ jsx(Fragment, { children: custom });
3743
+ }
3744
+ return /* @__PURE__ */ jsx(
3745
+ ComponentError,
3746
+ {
3747
+ title: errorTitle(catalogError.type),
3748
+ message: catalogError.message
3749
+ }
3750
+ );
3751
+ }
3752
+ return this.props.children;
3753
+ }
3754
+ }
3755
+ function stableKey(spec) {
3756
+ const str = JSON.stringify({
3757
+ t: spec.type,
3758
+ p: spec.props,
3759
+ c: spec.children
3760
+ });
3761
+ let h = 0;
3762
+ for (let i = 0; i < str.length; i++) {
3763
+ h = h * 31 + str.charCodeAt(i) | 0;
3764
+ }
3765
+ return (h >>> 0).toString(36);
3766
+ }
3767
+ function errorTitle(type) {
3768
+ switch (type) {
3769
+ case "unknown_component":
3770
+ return "Unknown Component";
3771
+ case "invalid_props":
3772
+ return "Invalid Props";
3773
+ case "render_error":
3774
+ return "Render Error";
3775
+ default:
3776
+ return "Invalid Component";
3777
+ }
3778
+ }
3779
+ function getChildText(children) {
3780
+ if (children === null || children === void 0) {
3781
+ return "";
3782
+ }
3783
+ if (typeof children === "string") {
3784
+ return children;
3785
+ }
3786
+ if (typeof children === "number") {
3787
+ return String(children);
3788
+ }
3789
+ if (Array.isArray(children)) {
3790
+ return children.map(getChildText).join("");
3791
+ }
3792
+ if (typeof children === "object") {
3793
+ if ("props" in children && children.props) {
3794
+ const element = children;
3795
+ return getChildText(element.props.children);
3796
+ }
3797
+ }
3798
+ return "";
3799
+ }
3800
+ function createComponentPre(definitions, options) {
3801
+ const language = (options == null ? void 0 : options.language) ?? "component";
3802
+ const className = `language-${language}`;
3803
+ const ComponentPre = ({ children, ...props }) => {
3804
+ var _a, _b;
3805
+ if (children && typeof children === "object" && "props" in children) {
3806
+ const codeElement = children;
3807
+ if (((_a = codeElement.props) == null ? void 0 : _a.className) === className) {
3808
+ const codeContent = getChildText((_b = codeElement.props) == null ? void 0 : _b.children);
3809
+ if (codeContent) {
3810
+ return /* @__PURE__ */ jsx(
3811
+ ComponentRenderer,
3812
+ {
3813
+ raw: codeContent,
3814
+ definitions,
3815
+ options
3816
+ }
3817
+ );
3818
+ }
3819
+ }
3820
+ }
3821
+ return /* @__PURE__ */ jsx("pre", { ...props, children });
3822
+ };
3823
+ ComponentPre.displayName = "ComponentPre";
3824
+ return ComponentPre;
3825
+ }
3826
+ function describeJsonSchemaProperty(prop, indent = "") {
3827
+ const description = prop.description ? ` // ${prop.description}` : "";
3828
+ if (prop.anyOf) {
3829
+ const nonNull = prop.anyOf.filter((s) => !(s.type === "null"));
3830
+ const hasNull = prop.anyOf.some((s) => s.type === "null");
3831
+ if (nonNull.length === 1 && hasNull) {
3832
+ return `${describeJsonSchemaProperty(nonNull[0], indent)} | null${description}`;
3833
+ }
3834
+ const parts = prop.anyOf.map(
3835
+ (s) => describeJsonSchemaProperty(s, indent)
3836
+ );
3837
+ return `${parts.join(" | ")}${description}`;
3838
+ }
3839
+ if (prop.enum) {
3840
+ return `${prop.enum.map((v) => `"${v}"`).join(" | ")}${description}`;
3841
+ }
3842
+ if (prop.type === "array") {
3843
+ const items = prop.items ? describeJsonSchemaProperty(prop.items, indent) : "any";
3844
+ return `${items}[]${description}`;
3845
+ }
3846
+ if (prop.type === "object" && prop.properties) {
3847
+ const required = new Set(prop.required ?? []);
3848
+ const fields = [];
3849
+ for (const [key, value] of Object.entries(prop.properties)) {
3850
+ const opt = required.has(key) ? "" : "?";
3851
+ fields.push(
3852
+ `${indent} ${key}: ${describeJsonSchemaProperty(value, indent + " ")}${opt}`
3853
+ );
3854
+ }
3855
+ return `{
3856
+ ${fields.join(",\n")}
3857
+ ${indent}}${description}`;
3858
+ }
3859
+ if (prop.type === "string") return `string${description}`;
3860
+ if (prop.type === "number" || prop.type === "integer")
3861
+ return `number${description}`;
3862
+ if (prop.type === "boolean") return `boolean${description}`;
3863
+ if (prop.type === "null") return `null${description}`;
3864
+ return `any${description}`;
3865
+ }
3866
+ function describeProps(schema) {
3867
+ try {
3868
+ const jsonSchema = z.toJSONSchema(schema);
3869
+ if (jsonSchema.type === "object" && jsonSchema.properties) {
3870
+ return describeJsonSchemaProperty(jsonSchema);
3871
+ }
3872
+ return "Record<string, any>";
3873
+ } catch {
3874
+ return "Record<string, any>";
3875
+ }
3876
+ }
3877
+ function generatePrompt(definitions, language = "component") {
3878
+ const names = Object.keys(definitions);
3879
+ if (names.length === 0) {
3880
+ return "";
3881
+ }
3882
+ const componentDocs = names.map((name) => {
3883
+ const def = definitions[name];
3884
+ const propsDesc = describeProps(def.props);
3885
+ return `- **${name}**: ${def.description}
3886
+ Props: ${propsDesc}`;
3887
+ }).join("\n\n");
3888
+ return `When you need to render a dynamic UI component in your response, use a fenced code block with language \`${language}\` containing a JSON object:
3889
+
3890
+ \`\`\`${language}
3891
+ { "type": "ComponentName", "props": { ... } }
3892
+ \`\`\`
3893
+
3894
+ For multiple components, use a JSON array:
3895
+
3896
+ \`\`\`${language}
3897
+ [
3898
+ { "type": "ComponentA", "props": { ... } },
3899
+ { "type": "ComponentB", "props": { ... } }
3900
+ ]
3901
+ \`\`\`
3902
+
3903
+ For nested/composed layouts, use the "children" field:
3904
+
3905
+ \`\`\`${language}
3906
+ {
3907
+ "type": "Parent",
3908
+ "props": { ... },
3909
+ "children": [
3910
+ { "type": "Child", "props": { ... } }
3911
+ ]
3912
+ }
3913
+ \`\`\`
3914
+
3915
+ Available components:
3916
+
3917
+ ${componentDocs}`;
3918
+ }
3919
+ function componentCatalog(definitions, options) {
3920
+ const language = (options == null ? void 0 : options.language) ?? "component";
3921
+ const plugin = remarkComponent.bind(void 0, {
3922
+ language
3923
+ });
3924
+ const Pre = createComponentPre(definitions, options);
3925
+ return {
3926
+ remarkPlugin: plugin,
3927
+ components: { pre: Pre },
3928
+ systemPrompt: () => generatePrompt(definitions, language),
3929
+ definitions
3930
+ };
3931
+ }
3932
+ function createChartComponentDef() {
3933
+ const chartPropsSchema = z.object({
3934
+ type: z.enum([
3935
+ "bar",
3936
+ "line",
3937
+ "area",
3938
+ "pie",
3939
+ "radialBar",
3940
+ "radialArea",
3941
+ "sparkline"
3942
+ ]).describe("Chart type"),
3943
+ data: z.array(z.object({ key: z.string(), data: z.number() })).describe("Array of { key, data } data points"),
3944
+ width: z.number().describe("Chart width in px").optional(),
3945
+ height: z.number().describe("Chart height in px").optional(),
3946
+ title: z.string().describe("Chart title").optional()
3947
+ });
3948
+ return {
3949
+ description: "Renders a chart. Supported types: bar, line, area, pie, radialBar, radialArea, sparkline",
3950
+ props: chartPropsSchema,
3951
+ component: ({
3952
+ children: _children,
3953
+ sendMessage: _sendMessage,
3954
+ ...config
3955
+ }) => /* @__PURE__ */ jsx(ChartRenderer, { config })
3956
+ };
3957
+ }
4317
3958
  export {
4318
- ChartError as A,
4319
- validateChartData as B,
4320
- ChatInput as C,
4321
- parseChartConfig as D,
4322
- isChartClassName as E,
3959
+ remarkRedact as $,
3960
+ AgUiEventType as A,
3961
+ SessionMessages as B,
3962
+ ChartRenderer as C,
3963
+ SessionMessagesHeader as D,
3964
+ SessionsGroup as E,
4323
3965
  FileInput as F,
4324
- getChildText as G,
4325
- remarkCve as H,
4326
- remarkChart as I,
4327
- dark as J,
4328
- light as K,
4329
- ChatContext as L,
4330
- MentionList as M,
3966
+ SessionsList as G,
3967
+ StatusIcon as H,
3968
+ TableDataCell as I,
3969
+ TableHeaderCell as J,
3970
+ bitcoinMatcher as K,
3971
+ chatTheme as L,
3972
+ Markdown as M,
4331
3973
  NewSessionButton as N,
4332
- AppBar as O,
4333
- ChatBubble as P,
4334
- ChatSuggestions as Q,
3974
+ commonRedactMatchers as O,
3975
+ componentCatalog as P,
3976
+ createChartComponentDef as Q,
4335
3977
  RichTextInput as R,
4336
3978
  SvgFile as S,
4337
3979
  TableComponent as T,
4338
- ChatSuggestion as U,
4339
- MessageStatus as V,
4340
- MessageStatusItem as W,
4341
- StatusIcon as X,
3980
+ createComponentPre as U,
3981
+ creditCardMatcher as V,
3982
+ dark as W,
3983
+ generatePrompt as X,
3984
+ light as Y,
3985
+ remarkComponent as Z,
3986
+ remarkCve as _,
4342
3987
  SvgCopy as a,
4343
- SessionEmpty as b,
4344
- SessionMessagesHeader as c,
4345
- SessionMessagePanel as d,
4346
- SessionMessage as e,
4347
- MessageSource as f,
4348
- MessageActions as g,
4349
- MessageFile as h,
4350
- MessageFiles as i,
4351
- MessageQuestion as j,
4352
- MessageResponse as k,
4353
- MessageSources as l,
4354
- SessionMessages as m,
4355
- Chat as n,
4356
- SessionsList as o,
4357
- SessionListItem as p,
4358
- SessionGroups as q,
4359
- SessionsGroup as r,
4360
- chatTheme as s,
4361
- Markdown as t,
4362
- TableHeaderCell as u,
4363
- TableDataCell as v,
4364
- CodeHighlighter as w,
4365
- chartComponents as x,
4366
- ChartRenderer as y,
4367
- ChartPre as z
3988
+ ssnMatcher as a0,
3989
+ useAgUi as a1,
3990
+ validateSpec as a2,
3991
+ AppBar as b,
3992
+ Chat as c,
3993
+ ChatBubble as d,
3994
+ ChatContext as e,
3995
+ ChatInput as f,
3996
+ ChatSuggestion as g,
3997
+ ChatSuggestions as h,
3998
+ CodeHighlighter as i,
3999
+ ComponentError as j,
4000
+ ComponentRenderer as k,
4001
+ MentionList as l,
4002
+ MessageActions as m,
4003
+ MessageFile as n,
4004
+ MessageFiles as o,
4005
+ MessageQuestion as p,
4006
+ MessageResponse as q,
4007
+ MessageSource as r,
4008
+ MessageSources as s,
4009
+ MessageStatus as t,
4010
+ MessageStatusItem as u,
4011
+ SessionEmpty as v,
4012
+ SessionGroups as w,
4013
+ SessionListItem as x,
4014
+ SessionMessage as y,
4015
+ SessionMessagePanel as z
4368
4016
  };
4369
- //# sourceMappingURL=index-CBHNcMyR.js.map
4017
+ //# sourceMappingURL=index-8tlsyFe-.js.map