reachat 3.2.1 → 3.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4014 +0,0 @@
1
- import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
- import * as React from "react";
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
- import { useEditor, EditorContent, ReactRenderer, posToDOMRect } from "@tiptap/react";
6
- import { computePosition, shift, flip } from "@floating-ui/dom";
7
- import Document from "@tiptap/extension-document";
8
- import Paragraph from "@tiptap/extension-paragraph";
9
- import Text from "@tiptap/extension-text";
10
- import HardBreak from "@tiptap/extension-hard-break";
11
- import Placeholder from "@tiptap/extension-placeholder";
12
- import Mention from "@tiptap/extension-mention";
13
- import { Slot } from "@radix-ui/react-slot";
14
- import { motion, AnimatePresence } from "motion/react";
15
- import ReactMarkdown from "react-markdown";
16
- import rehypeKatex from "rehype-katex";
17
- import rehypeRaw from "rehype-raw";
18
- import { Prism } from "react-syntax-highlighter";
19
- import { SparklineChart, RadialAreaChart, RadialAreaSeries, RadialBarChart, RadialBarSeries, PieChart, PieArcSeries, AreaChart, AreaSeries, LinearYAxis, LinearXAxis, LineChart, LineSeries, BarChart, BarSeries } from "reaviz";
20
- import { findAndReplace } from "mdast-util-find-and-replace";
21
- import debounce from "lodash/debounce.js";
22
- import { useHotkeys } from "reakeys";
23
- import remarkGfm from "remark-gfm";
24
- import remarkYoutube from "remark-youtube";
25
- import remarkMath from "remark-math";
26
- import { isToday, isYesterday, isThisWeek, differenceInYears, format } from "date-fns";
27
- import { offset } from "@floating-ui/react";
28
- import { z } from "zod";
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" })));
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" }));
31
- const ChatContext = createContext({
32
- sessions: [],
33
- activeSessionId: null
34
- });
35
- const SvgPaperclip = (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-paperclip", ...props }, /* @__PURE__ */ React.createElement("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48" }));
36
- const FileInput = ({
37
- allowedFiles,
38
- multiple,
39
- onFileUpload,
40
- isLoading,
41
- disabled,
42
- attachIcon = /* @__PURE__ */ jsx(SvgPaperclip, {})
43
- }) => {
44
- const { theme } = useContext(ChatContext);
45
- const fileInputRef = useRef(null);
46
- return /* @__PURE__ */ jsxs(Fragment, { children: [
47
- /* @__PURE__ */ jsx(
48
- "input",
49
- {
50
- type: "file",
51
- ref: fileInputRef,
52
- className: "hidden",
53
- accept: allowedFiles.join(","),
54
- multiple,
55
- onChange: (e) => {
56
- onFileUpload(e);
57
- if (fileInputRef.current) {
58
- fileInputRef.current.value = "";
59
- }
60
- }
61
- }
62
- ),
63
- /* @__PURE__ */ jsx(
64
- Button,
65
- {
66
- title: "Upload",
67
- variant: "text",
68
- disabled: isLoading || disabled,
69
- className: cn(theme.input.upload),
70
- onClick: () => fileInputRef.current?.click(),
71
- children: attachIcon
72
- }
73
- )
74
- ] });
75
- };
76
- const chatTheme = {
77
- base: "dark:text-white text-gray-500",
78
- console: "flex w-full gap-4 h-full",
79
- companion: "w-full h-full overflow-hidden",
80
- empty: "text-center flex-1",
81
- appbar: "flex p-5",
82
- status: {
83
- base: "py-2 px-3 rounded-lg bg-gray-100/50 dark:bg-gray-800/30",
84
- header: "flex items-center gap-2",
85
- icon: {
86
- base: "flex-shrink-0 w-4 h-4",
87
- loading: "text-blue-500 dark:text-blue-400",
88
- complete: "text-green-500 dark:text-green-400",
89
- error: "text-red-500 dark:text-red-400"
90
- },
91
- text: {
92
- base: "text-sm",
93
- loading: "text-gray-600 dark:text-gray-400",
94
- complete: "text-gray-600 dark:text-gray-400",
95
- error: "text-red-600 dark:text-red-400"
96
- },
97
- steps: {
98
- base: "mt-1 ml-6 space-y-0.5",
99
- step: {
100
- base: "flex items-center gap-2",
101
- icon: "flex-shrink-0 w-3.5 h-3.5",
102
- text: "text-sm",
103
- loading: "text-gray-500 dark:text-gray-500",
104
- complete: "text-gray-500 dark:text-gray-500",
105
- error: "text-red-500 dark:text-red-400"
106
- }
107
- }
108
- },
109
- sessions: {
110
- base: "overflow-auto",
111
- console: "min-w-[150px] w-[30%] max-w-[300px] dark:bg-[#11111F] bg-[#F2F3F7] p-5 rounded-3xl",
112
- companion: "w-full h-full",
113
- group: "text-xs dart:text-gray-400 text-gray-700 mt-4 hover:bg-transparent mb-1",
114
- create: "relative mb-4 rounded-[10px] text-white",
115
- session: {
116
- base: [
117
- "group my-1 rounded-[10px] p-2 text-gray-500 border border-transparent hover:bg-gray-300 hover:border-gray-400 [&_svg]:text-gray-500",
118
- "dark:text-typography dark:text-gray-400 dark:hover:bg-gray-800/50 dark:hover:border-gray-700/50 dark:[&_svg]:text-gray-200"
119
- ].join(" "),
120
- active: [
121
- "border border-gray-300 hover:border-gray-400 text-gray-700 bg-gray-200 hover:bg-gray-300 ",
122
- "dark:text-gray-500 dark:bg-gray-800/70 dark:border-gray-700/50 dark:text-white dark:border-gray-700/70 dark:hover:bg-gray-800/50",
123
- "[&_button]:opacity-100!"
124
- ].join(" "),
125
- delete: "[&>svg]:w-4 [&>svg]:h-4 opacity-0 group-hover:opacity-50!"
126
- }
127
- },
128
- messages: {
129
- base: "",
130
- console: "flex flex-col mx-5 flex-1 min-h-0",
131
- companion: "flex w-full h-full",
132
- back: "self-start p-0 my-2",
133
- inner: "flex-1 h-full flex flex-col",
134
- title: ["text-base font-bold text-gray-500", "dark:text-gray-200"].join(
135
- " "
136
- ),
137
- date: "text-xs whitespace-nowrap text-gray-400",
138
- content: [
139
- "mt-2 flex-1 overflow-auto [&_hr]:bg-gray-200",
140
- "dark:[&_hr]:bg-gray-800/60"
141
- ].join(" "),
142
- header: "flex justify-between items-center gap-2",
143
- showMore: "mb-4",
144
- message: {
145
- base: "mt-4 mb-4 flex flex-col p-0 rounded-sm border-none bg-transparent",
146
- question: [
147
- "relative font-semibold mb-4 px-4 py-4 pb-2 rounded-3xl rounded-br-none text-typography border bg-gray-200 border-gray-300 text-gray-900",
148
- "dark:bg-gray-900/60 dark:border-gray-700/50 dark:text-gray-100"
149
- ].join(" "),
150
- response: [
151
- "relative data-[compact=false]:px-4 text-gray-900",
152
- "dark:text-gray-100"
153
- ].join(" "),
154
- overlay: "overflow-y-hidden max-h-[350px] after:content-[''] after:absolute after:inset-x-0 after:bottom-0 after:h-16 after:bg-linear-to-b after:from-transparent dark:after:to-gray-900 after:to-gray-200",
155
- cursor: "inline-block w-1 h-4 bg-current",
156
- expand: "absolute bottom-1 right-1 z-10",
157
- scrollToBottom: {
158
- container: "absolute bottom-2 left-1/2 transform -translate-x-1/2 z-10",
159
- button: "rounded-full p-2 shadow-lg"
160
- },
161
- files: {
162
- base: "mb-2 flex flex-wrap gap-3 ",
163
- file: {
164
- base: [
165
- "flex items-center gap-2 border border-gray-300 px-3 py-2 rounded-lg cursor-pointer",
166
- "dark:border-gray-700"
167
- ].join(" "),
168
- name: ["text-sm text-gray-500", "dark:text-gray-200"].join(" ")
169
- }
170
- },
171
- sources: {
172
- base: "my-4 flex flex-wrap gap-3",
173
- source: {
174
- base: [
175
- "flex gap-2 border border-gray-200 px-4 py-2 rounded-lg cursor-pointer",
176
- "dark:border-gray-700"
177
- ].join(" "),
178
- companion: "flex-1 px-3 py-1.5",
179
- image: "max-w-10 max-h-10 rounded-md w-full h-fit self-center",
180
- title: "text-md block",
181
- url: "text-sm text-blue-400 underline"
182
- }
183
- },
184
- markdown: {
185
- hr: "my-4 border-t border-stroke-neutral-4",
186
- copy: "sticky py-1 [&>svg]:w-4 [&>svg]:h-4 opacity-50",
187
- p: "mb-2",
188
- a: "text-buttons-colors-link-primary-text-resting underline",
189
- table: "table-auto w-full m-2",
190
- th: "px-4 py-2 text-left font-bold border-b border-stroke-neutral-4",
191
- td: "px-4 py-2",
192
- code: "m-2 rounded-b relative",
193
- inlineCode: "bg-gradient-neutral-200 p-1 rounded",
194
- toolbar: "text-xs flex items-center justify-between px-2 py-1 rounded-t sticky top-0 backdrop-blur-md bg-gradient-neutral-500/50",
195
- li: "mb-2 ml-6",
196
- ul: "mb-4 list-disc",
197
- ol: "mb-4 list-decimal",
198
- h1: "text-4xl font-bold mb-4 mt-6",
199
- h2: "text-3xl font-bold mb-3 mt-5",
200
- h3: "text-2xl font-bold mb-3 mt-4",
201
- h4: "text-xl font-bold mb-2 mt-3",
202
- h5: "text-lg font-bold mb-2 mt-2",
203
- h6: "text-base font-bold mb-2 mt-2"
204
- },
205
- footer: {
206
- base: "mt-3 flex gap-1.5",
207
- copy: [
208
- "p-3 rounded-[10px] [&>svg]:w-4 [&>svg]:h-4 opacity-50 hover:opacity-100! hover:bg-gray-200 hover:text-gray-500",
209
- "dark:hover:bg-gray-800 dark:hover:text-white text-gray-400"
210
- ].join(" "),
211
- upvote: "p-3 rounded-[10px] [&>svg]:w-4 [&>svg]:h-4 opacity-50 hover:opacity-100! hover:bg-gray-700/40 hover:text-white text-gray-400",
212
- downvote: "p-3 rounded-[10px] [&>svg]:w-4 [&>svg]:h-4 opacity-50 hover:opacity-100! hover:bg-gray-700/40 hover:text-white text-gray-400",
213
- refresh: "p-3 rounded-[10px] [&>svg]:w-4 [&>svg]:h-4 opacity-50 hover:opacity-100! hover:bg-gray-700/40 hover:text-white text-gray-400"
214
- }
215
- }
216
- },
217
- input: {
218
- base: "flex mt-4 relative",
219
- upload: ["px-5 py-2 text-gray-400 size-10", "dark:gray-500"].join(" "),
220
- input: [
221
- "w-full border rounded-3xl px-3 py-2 pr-16 text-gray-500 border-gray-200 hover:bg-blue-100 hover:border-blue-500 after:hidden after:mx-10! bg-white [&>textarea]:w-full [&>textarea]:flex-none",
222
- "dark:border-gray-700/50 dark:text-gray-200 dark:bg-gray-950 dark:hover:bg-blue-950/40"
223
- ].join(" "),
224
- actions: {
225
- base: "absolute flex gap-2 items-center right-5 inset-y-1/2 -translate-y-1/2 z-10",
226
- send: [
227
- "px-3 py-3 hover:bg-primary-hover rounded-full bg-gray-200 hover:bg-gray-300 text-gray-500",
228
- "dark:text-white light:text-gray-500 dark:bg-gray-800 dark:hover:bg-gray-700"
229
- ].join(" "),
230
- stop: "px-2 py-2 bg-red-500 text-white rounded-full hover:bg-red-700 "
231
- },
232
- popup: {
233
- base: [
234
- "bg-white border border-gray-200 rounded-lg shadow-lg overflow-hidden min-w-[200px] max-w-[300px]",
235
- "dark:bg-gray-900 dark:border-gray-700"
236
- ].join(" "),
237
- content: "overflow-y-auto max-h-[250px]",
238
- item: [
239
- "flex items-center gap-2 px-3 py-2 cursor-pointer transition-colors",
240
- "hover:bg-gray-100 dark:hover:bg-gray-800"
241
- ].join(" "),
242
- itemHighlighted: "bg-gray-100 dark:bg-gray-800",
243
- itemIcon: [
244
- "flex-shrink-0 w-5 h-5 text-gray-500 [&>svg]:w-full [&>svg]:h-full",
245
- "dark:text-gray-400"
246
- ].join(" "),
247
- itemContent: "flex flex-col min-w-0 flex-1",
248
- itemLabel: [
249
- "text-sm font-medium text-gray-900 truncate",
250
- "dark:text-gray-100"
251
- ].join(" "),
252
- itemDescription: "text-xs text-gray-500 dark:text-gray-400 truncate",
253
- itemShortcut: "text-xs text-gray-400 dark:text-gray-500 ml-auto",
254
- empty: "px-3 py-4 text-sm text-center text-gray-500 dark:text-gray-400",
255
- loading: [
256
- "flex items-center justify-center gap-2 px-3 py-4 text-gray-500",
257
- "dark:text-gray-400"
258
- ].join(" ")
259
- },
260
- tag: {
261
- base: [
262
- "inline-flex items-center px-1.5 py-0.5 mx-0.5 rounded",
263
- "font-medium text-sm leading-[1.2] relative top-[1px]"
264
- ].join(" "),
265
- mention: [
266
- "bg-blue-100 dark:bg-blue-900/30",
267
- "text-blue-700 dark:text-blue-300"
268
- ].join(" "),
269
- command: [
270
- "bg-purple-100 dark:bg-purple-900/30",
271
- "text-purple-700 dark:text-purple-300"
272
- ].join(" ")
273
- },
274
- editor: {
275
- base: [
276
- "outline-none w-full overflow-y-auto",
277
- "text-inherit font-inherit",
278
- "[&_.tiptap-paragraph]:m-0"
279
- ].join(" "),
280
- container: "px-3 py-2 pr-16",
281
- placeholder: [
282
- "[&_.is-editor-empty]:before:content-[attr(data-placeholder)]",
283
- "[&_.is-editor-empty]:before:text-gray-400",
284
- "[&_.is-editor-empty]:before:dark:text-gray-500",
285
- "[&_.is-editor-empty]:before:float-left",
286
- "[&_.is-editor-empty]:before:h-0",
287
- "[&_.is-editor-empty]:before:pointer-events-none"
288
- ].join(" ")
289
- }
290
- },
291
- suggestions: {
292
- base: "flex flex-wrap gap-2 mt-4",
293
- item: {
294
- base: [
295
- "rounded-full! max-w-full py-2 px-4",
296
- "bg-gray-100 border-gray-200 hover:bg-gray-200 hover:border-gray-300 text-gray-700",
297
- "dark:bg-gray-800/50 dark:border-gray-700 dark:hover:bg-gray-700/70 dark:hover:border-gray-600 dark:text-gray-200",
298
- "[&>svg]:w-4 [&>svg]:h-4 [&>svg]:text-blue-500 [&>svg]:dark:text-blue-400 [&>svg]:flex-shrink-0"
299
- ].join(" "),
300
- icon: "w-4 h-4 text-blue-500 dark:text-blue-400 flex-shrink-0",
301
- text: "text-sm truncate"
302
- }
303
- },
304
- chart: {
305
- base: "my-6",
306
- title: "text-sm font-medium mb-2 text-gray-600 dark:text-gray-400",
307
- content: "flex items-center justify-center",
308
- error: {
309
- base: [
310
- "my-4 p-4 border rounded",
311
- "border-red-300 bg-red-50 text-red-500",
312
- "dark:border-red-700 dark:bg-red-900/20"
313
- ].join(" "),
314
- title: "text-red-600 dark:text-red-400 text-sm font-medium mb-2",
315
- code: "text-xs overflow-auto"
316
- },
317
- warning: {
318
- base: [
319
- "my-4 p-4 border rounded",
320
- "border-yellow-300 bg-yellow-50 text-yellow-600",
321
- "dark:border-yellow-700 dark:bg-yellow-900/20 dark:text-yellow-400"
322
- ].join(" "),
323
- title: "text-yellow-600 dark:text-yellow-400 text-sm font-medium mb-2"
324
- }
325
- },
326
- component: {
327
- base: "my-4"
328
- }
329
- };
330
- const POPUP_STYLE = { zIndex: 9999 };
331
- const MentionList = forwardRef(
332
- ({ items, command, triggerChar, config, query }, ref) => {
333
- const [selectedIndex, setSelectedIndex] = useState(0);
334
- const itemRefs = useRef([]);
335
- const { theme } = useContext(ChatContext);
336
- const popupTheme = theme?.input?.popup || chatTheme.input.popup;
337
- useEffect(() => {
338
- setSelectedIndex(0);
339
- }, [items]);
340
- useEffect(() => {
341
- if (itemRefs.current[selectedIndex]) {
342
- itemRefs.current[selectedIndex]?.scrollIntoView({
343
- block: "nearest",
344
- behavior: "smooth"
345
- });
346
- }
347
- }, [selectedIndex]);
348
- const selectItem = useCallback(
349
- (index) => {
350
- const item = items[index];
351
- if (!item) return;
352
- if (config.onSelect) {
353
- config.onSelect(item, (text) => {
354
- command({ id: item.id, label: text || item.label });
355
- });
356
- } else {
357
- command({ id: item.id, label: item.label });
358
- }
359
- },
360
- [items, command, config]
361
- );
362
- useImperativeHandle(ref, () => ({
363
- onKeyDown: ({ event }) => {
364
- if (event.key === "ArrowUp") {
365
- event.preventDefault();
366
- setSelectedIndex((prev) => prev <= 0 ? items.length - 1 : prev - 1);
367
- return true;
368
- }
369
- if (event.key === "ArrowDown") {
370
- event.preventDefault();
371
- setSelectedIndex((prev) => prev >= items.length - 1 ? 0 : prev + 1);
372
- return true;
373
- }
374
- if (event.key === "Enter" || event.key === "Tab") {
375
- event.preventDefault();
376
- selectItem(selectedIndex);
377
- return true;
378
- }
379
- return false;
380
- }
381
- }));
382
- const popupId = `mention-list-${triggerChar}`;
383
- return /* @__PURE__ */ jsx(
384
- List,
385
- {
386
- className: cn(popupTheme.base, popupTheme.content),
387
- style: POPUP_STYLE,
388
- role: "listbox",
389
- id: popupId,
390
- "aria-label": `${triggerChar === "@" ? "Mentions" : "Commands"} suggestions`,
391
- children: items.length === 0 ? /* @__PURE__ */ jsx(ListItem, { className: cn(popupTheme.empty), disabled: true, dense: true, children: config.renderEmpty ? config.renderEmpty(query || "") : query ? `No results for "${query}"` : "No items available" }) : items.map((item, index) => /* @__PURE__ */ jsx(
392
- "div",
393
- {
394
- id: `${popupId}-option-${item.id}`,
395
- role: "option",
396
- "aria-selected": index === selectedIndex,
397
- ref: (el) => {
398
- itemRefs.current[index] = el;
399
- },
400
- onClick: () => selectItem(index),
401
- onMouseEnter: () => setSelectedIndex(index),
402
- className: "cursor-pointer",
403
- children: config.renderItem ? config.renderItem(item, index === selectedIndex) : /* @__PURE__ */ jsx(
404
- DefaultItemRenderer,
405
- {
406
- item,
407
- isHighlighted: index === selectedIndex,
408
- popupTheme
409
- }
410
- )
411
- },
412
- item.id
413
- ))
414
- }
415
- );
416
- }
417
- );
418
- const DefaultItemRenderer = memo(
419
- ({ item, isHighlighted, popupTheme }) => {
420
- const shortcut = "shortcut" in item ? item.shortcut : void 0;
421
- return /* @__PURE__ */ jsx(
422
- ListItem,
423
- {
424
- className: cn(
425
- popupTheme.item,
426
- isHighlighted && popupTheme.itemHighlighted
427
- ),
428
- dense: true,
429
- start: item.icon ? /* @__PURE__ */ jsx("span", { className: cn(popupTheme.itemIcon), children: item.icon }) : void 0,
430
- end: shortcut ? /* @__PURE__ */ jsx("span", { className: cn(popupTheme.itemShortcut), children: shortcut }) : void 0,
431
- children: /* @__PURE__ */ jsxs("div", { className: cn(popupTheme.itemContent), children: [
432
- /* @__PURE__ */ jsx("span", { className: cn(popupTheme.itemLabel), children: item.label }),
433
- item.description && /* @__PURE__ */ jsx("span", { className: cn(popupTheme.itemDescription), children: item.description })
434
- ] })
435
- }
436
- );
437
- }
438
- );
439
- DefaultItemRenderer.displayName = "DefaultItemRenderer";
440
- MentionList.displayName = "MentionList";
441
- function updatePopupPosition(editor, element) {
442
- const virtualElement = {
443
- getBoundingClientRect: () => posToDOMRect(
444
- editor.view,
445
- editor.state.selection.from,
446
- editor.state.selection.to
447
- )
448
- };
449
- computePosition(virtualElement, element, {
450
- placement: "bottom-start",
451
- strategy: "absolute",
452
- middleware: [shift(), flip()]
453
- }).then(({ x, y, strategy }) => {
454
- element.style.width = "max-content";
455
- element.style.position = strategy;
456
- element.style.left = `${x}px`;
457
- element.style.top = `${y}px`;
458
- });
459
- }
460
- function createSuggestionConfig(config, triggerChar, suggestionActiveRef) {
461
- return {
462
- char: triggerChar,
463
- allowSpaces: false,
464
- // Fetch and filter suggestion items based on query
465
- items: async ({ query }) => {
466
- if (config.onSearch) {
467
- return await config.onSearch(query);
468
- }
469
- if (!config.items) return [];
470
- if (!query) return config.items.slice(0, config.maxResults || 10);
471
- const lowerQuery = query.toLowerCase();
472
- return config.items.filter(
473
- (item) => item.label.toLowerCase().includes(lowerQuery) || item.description?.toLowerCase().includes(lowerQuery)
474
- ).slice(0, config.maxResults || 10);
475
- },
476
- // Render callbacks for managing the popup lifecycle
477
- render: () => {
478
- let component = null;
479
- return {
480
- // Called when suggestion is triggered
481
- onStart: (props) => {
482
- suggestionActiveRef.current = true;
483
- component = new ReactRenderer(MentionList, {
484
- props: {
485
- ...props,
486
- triggerChar,
487
- config
488
- },
489
- editor: props.editor
490
- });
491
- if (!props.clientRect) {
492
- return;
493
- }
494
- component.element.style.position = "absolute";
495
- document.body.appendChild(component.element);
496
- updatePopupPosition(props.editor, component.element);
497
- },
498
- // Called when query or items change
499
- onUpdate: (props) => {
500
- component?.updateProps({
501
- ...props,
502
- triggerChar,
503
- config
504
- });
505
- if (!props.clientRect) {
506
- return;
507
- }
508
- if (component?.element) {
509
- updatePopupPosition(props.editor, component.element);
510
- }
511
- },
512
- // Handle keyboard navigation (Escape closes popup)
513
- onKeyDown: (props) => {
514
- if (props.event.key === "Escape") {
515
- component?.destroy();
516
- return true;
517
- }
518
- return component?.ref?.onKeyDown(props) ?? false;
519
- },
520
- // Cleanup when suggestion is dismissed
521
- onExit: () => {
522
- suggestionActiveRef.current = false;
523
- component?.element?.remove();
524
- component?.destroy();
525
- }
526
- };
527
- }
528
- };
529
- }
530
- const RichTextInput = forwardRef(
531
- ({
532
- value = "",
533
- placeholder = "Type a message...",
534
- disabled = false,
535
- autoFocus = true,
536
- className,
537
- minHeight = 24,
538
- maxHeight = 200,
539
- mentions,
540
- commands,
541
- onSubmit,
542
- onChange
543
- }, ref) => {
544
- const { theme } = useContext(ChatContext);
545
- const containerRef = useRef(null);
546
- const suggestionActiveRef = useRef(false);
547
- const extensions = useMemo(() => {
548
- const exts = [
549
- Document,
550
- Paragraph.configure({
551
- HTMLAttributes: {
552
- class: "tiptap-paragraph"
553
- }
554
- }),
555
- Text,
556
- HardBreak,
557
- Placeholder.configure({
558
- placeholder,
559
- emptyEditorClass: "is-editor-empty"
560
- })
561
- ];
562
- if (mentions) {
563
- exts.push(
564
- Mention.configure({
565
- HTMLAttributes: {
566
- class: cn(theme?.input?.tag?.base, theme?.input?.tag?.mention)
567
- },
568
- suggestion: createSuggestionConfig(
569
- mentions,
570
- mentions.trigger || "@",
571
- suggestionActiveRef
572
- )
573
- }).extend({
574
- name: "mention"
575
- })
576
- );
577
- }
578
- if (commands) {
579
- exts.push(
580
- Mention.configure({
581
- HTMLAttributes: {
582
- class: cn(theme?.input?.tag?.base, theme?.input?.tag?.command)
583
- },
584
- suggestion: createSuggestionConfig(
585
- commands,
586
- commands.trigger || "/",
587
- suggestionActiveRef
588
- )
589
- }).extend({
590
- name: "command"
591
- })
592
- );
593
- }
594
- return exts;
595
- }, [placeholder, mentions, commands, theme]);
596
- const editor = useEditor({
597
- extensions,
598
- content: value ? `<p>${value}</p>` : "",
599
- editable: !disabled,
600
- immediatelyRender: false,
601
- onUpdate: ({ editor: editor2 }) => {
602
- const text = editor2.getText();
603
- onChange?.(text);
604
- },
605
- editorProps: {
606
- attributes: {
607
- class: cn(
608
- theme?.input?.editor?.base,
609
- theme?.input?.editor?.placeholder
610
- ),
611
- style: `min-height: ${minHeight}px; max-height: ${maxHeight}px;`,
612
- role: "textbox",
613
- "aria-multiline": "true",
614
- "aria-placeholder": placeholder,
615
- "aria-disabled": disabled ? "true" : "false",
616
- tabindex: disabled ? "-1" : "0"
617
- },
618
- handleKeyDown: (view, event) => {
619
- if (suggestionActiveRef.current) {
620
- return false;
621
- }
622
- if (event.key === "Enter" && !event.shiftKey) {
623
- const text = view.state.doc.textContent;
624
- if (text.trim() && onSubmit) {
625
- event.preventDefault();
626
- onSubmit(text);
627
- editor?.commands.clearContent();
628
- return true;
629
- }
630
- }
631
- return false;
632
- }
633
- }
634
- });
635
- useEffect(() => {
636
- if (autoFocus && editor) {
637
- setTimeout(() => {
638
- editor.commands.focus("end");
639
- }, 0);
640
- }
641
- }, [editor, autoFocus]);
642
- useImperativeHandle(ref, () => ({
643
- focus: () => {
644
- editor?.commands.focus();
645
- },
646
- getValue: () => {
647
- return editor?.getText() || "";
648
- },
649
- setValue: (newValue) => {
650
- editor?.commands.setContent(newValue ? `<p>${newValue}</p>` : "");
651
- },
652
- insertText: (text) => {
653
- editor?.commands.insertContent(text);
654
- }
655
- }));
656
- return /* @__PURE__ */ jsx("div", { ref: containerRef, className: cn("relative w-full", className), children: /* @__PURE__ */ jsx(EditorContent, { editor }) });
657
- }
658
- );
659
- RichTextInput.displayName = "RichTextInput";
660
- const ChatInput = forwardRef(
661
- ({
662
- allowedFiles,
663
- placeholder = "Type a message...",
664
- allowMultipleFiles = false,
665
- defaultValue,
666
- className,
667
- sendIcon = /* @__PURE__ */ jsx(SvgSend, {}),
668
- stopIcon = /* @__PURE__ */ jsx(SvgStop, {}),
669
- attachIcon,
670
- mentions,
671
- commands,
672
- minHeight = 24,
673
- maxHeight = 200,
674
- autoFocus = true,
675
- onMessageChange
676
- }, ref) => {
677
- const {
678
- theme,
679
- isLoading,
680
- disabled,
681
- sendMessage,
682
- stopMessage,
683
- fileUpload,
684
- activeSessionId
685
- } = useContext(ChatContext);
686
- const [message, setMessage] = useState(defaultValue || "");
687
- const inputRef = useRef(null);
688
- const containerRef = useRef(null);
689
- useEffect(() => {
690
- if (autoFocus) {
691
- inputRef.current?.focus();
692
- }
693
- }, [activeSessionId, autoFocus]);
694
- useImperativeHandle(ref, () => ({
695
- focus: () => {
696
- inputRef.current?.focus();
697
- },
698
- getValue: () => {
699
- return inputRef.current?.getValue() || "";
700
- },
701
- setValue: (value) => {
702
- setMessage(value);
703
- inputRef.current?.setValue(value);
704
- onMessageChange?.(value);
705
- },
706
- insertText: (text) => {
707
- inputRef.current?.insertText(text);
708
- }
709
- }));
710
- const handleSendMessage = useCallback(() => {
711
- const currentMessage = inputRef.current?.getValue();
712
- if (currentMessage.trim()) {
713
- sendMessage?.(currentMessage);
714
- setMessage("");
715
- inputRef.current?.setValue("");
716
- }
717
- }, [sendMessage]);
718
- const handleSubmit = useCallback(
719
- (value) => {
720
- if (value.trim()) {
721
- sendMessage?.(value);
722
- setMessage("");
723
- }
724
- },
725
- [sendMessage]
726
- );
727
- const handleChange = useCallback(
728
- (value) => {
729
- setMessage(value);
730
- onMessageChange?.(value);
731
- },
732
- [onMessageChange]
733
- );
734
- const handleFileUpload = (event) => {
735
- const files = event.target.files;
736
- if (files?.length && fileUpload) {
737
- fileUpload(allowMultipleFiles ? Array.from(files) : files[0]);
738
- }
739
- };
740
- const mentionsConfig = useMemo(
741
- () => mentions ? { ...mentions, trigger: mentions.trigger || "@" } : void 0,
742
- [mentions]
743
- );
744
- const commandsConfig = useMemo(
745
- () => commands ? { ...commands, trigger: commands.trigger || "/" } : void 0,
746
- [commands]
747
- );
748
- return /* @__PURE__ */ jsx("div", { ref: containerRef, className: cn(theme.input.base, className), children: /* @__PURE__ */ jsxs("div", { className: cn("relative flex-1", theme.input.input), children: [
749
- /* @__PURE__ */ jsx(
750
- RichTextInput,
751
- {
752
- ref: inputRef,
753
- value: message,
754
- onChange: handleChange,
755
- onSubmit: handleSubmit,
756
- placeholder,
757
- disabled: isLoading || disabled,
758
- autoFocus,
759
- minHeight,
760
- maxHeight,
761
- className: theme.input.editor.container,
762
- mentions: mentionsConfig,
763
- commands: commandsConfig
764
- }
765
- ),
766
- /* @__PURE__ */ jsxs("div", { className: cn(theme.input.actions.base), children: [
767
- allowedFiles?.length > 0 && /* @__PURE__ */ jsx(
768
- FileInput,
769
- {
770
- allowedFiles,
771
- multiple: allowMultipleFiles,
772
- onFileUpload: handleFileUpload,
773
- isLoading,
774
- disabled,
775
- attachIcon
776
- }
777
- ),
778
- isLoading && /* @__PURE__ */ jsx(
779
- Button,
780
- {
781
- title: "Stop",
782
- className: cn(theme.input.actions.stop),
783
- onClick: stopMessage,
784
- disabled,
785
- children: stopIcon
786
- }
787
- ),
788
- /* @__PURE__ */ jsx(
789
- Button,
790
- {
791
- title: "Send",
792
- className: cn(theme.input.actions.send),
793
- onClick: handleSendMessage,
794
- disabled: isLoading || disabled,
795
- children: sendIcon
796
- }
797
- )
798
- ] })
799
- ] }) });
800
- }
801
- );
802
- const SessionEmpty = ({
803
- children
804
- }) => {
805
- const { theme } = useContext(ChatContext);
806
- return /* @__PURE__ */ jsx("div", { className: cn(theme.empty), children });
807
- };
808
- const SessionMessagesHeader = ({ children }) => {
809
- const { activeSession, theme } = useContext(ChatContext);
810
- const Comp = children ? Slot : "header";
811
- if (!activeSession) {
812
- return null;
813
- }
814
- return /* @__PURE__ */ jsx(Comp, { className: cn(theme.messages.header), children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
815
- /* @__PURE__ */ jsx("h2", { className: cn(theme.messages.title), children: /* @__PURE__ */ jsx(Ellipsis, { limit: 125, value: activeSession.title }) }),
816
- /* @__PURE__ */ jsx(
817
- DateFormat,
818
- {
819
- className: cn(theme.messages.date),
820
- date: activeSession.createdAt
821
- }
822
- )
823
- ] }) });
824
- };
825
- const SvgBack = (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-chevron-left", ...props }, /* @__PURE__ */ React.createElement("path", { d: "m15 18-6-6 6-6" }));
826
- const SessionMessagePanel = ({
827
- children,
828
- allowBack = true
829
- }) => {
830
- const { activeSessionId, theme, isCompact, selectSession, viewType } = useContext(ChatContext);
831
- const isVisible = isCompact && activeSessionId || viewType === "chat" || !isCompact;
832
- return isVisible && /* @__PURE__ */ jsx(
833
- motion.div,
834
- {
835
- initial: { translateX: "200%" },
836
- animate: {
837
- translateX: "0%",
838
- transition: {
839
- type: "tween",
840
- ease: "linear",
841
- duration: 0.2,
842
- when: "beforeChildren"
843
- }
844
- },
845
- exit: { translateX: "200%" },
846
- className: cn(theme.messages.base, {
847
- [theme.messages.companion]: isCompact,
848
- [theme.messages.console]: !isCompact
849
- }),
850
- children: /* @__PURE__ */ jsxs("div", { className: cn(theme.messages.inner), children: [
851
- allowBack && isCompact && viewType !== "chat" && /* @__PURE__ */ jsxs(
852
- Button,
853
- {
854
- variant: "text",
855
- size: "small",
856
- onClick: () => selectSession(null),
857
- className: cn(theme.messages.back),
858
- children: [
859
- /* @__PURE__ */ jsx(SvgBack, {}),
860
- "Back"
861
- ]
862
- }
863
- ),
864
- children
865
- ] })
866
- }
867
- );
868
- };
869
- const SvgCopy = (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-copy", ...props }, /* @__PURE__ */ React.createElement("rect", { width: 14, height: 14, x: 8, y: 8, rx: 2, ry: 2 }), /* @__PURE__ */ React.createElement("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" }));
870
- const dark = {
871
- 'code[class*="language-"]': {
872
- "background": "#11111f",
873
- "color": "#e2e8f0",
874
- "textShadow": "0 1px rgba(0, 0, 0, 0.3)",
875
- "fontFamily": '"Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace',
876
- "direction": "ltr",
877
- "textAlign": "left",
878
- "whiteSpace": "pre",
879
- "wordSpacing": "normal",
880
- "wordBreak": "normal",
881
- "lineHeight": "1.5",
882
- "MozTabSize": "2",
883
- "OTabSize": "2",
884
- "tabSize": "2",
885
- "WebkitHyphens": "none",
886
- "MozHyphens": "none",
887
- "msHyphens": "none",
888
- "hyphens": "none"
889
- },
890
- 'pre[class*="language-"]': {
891
- "background": "#11111f",
892
- "color": "#e2e8f0",
893
- "textShadow": "0 1px rgba(0, 0, 0, 0.3)",
894
- "fontFamily": '"Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace',
895
- "direction": "ltr",
896
- "textAlign": "left",
897
- "whiteSpace": "pre",
898
- "wordSpacing": "normal",
899
- "wordBreak": "normal",
900
- "lineHeight": "1.5",
901
- "MozTabSize": "2",
902
- "OTabSize": "2",
903
- "tabSize": "2",
904
- "WebkitHyphens": "none",
905
- "MozHyphens": "none",
906
- "msHyphens": "none",
907
- "hyphens": "none",
908
- "padding": "1em",
909
- "margin": "0",
910
- "overflow": "auto"
911
- },
912
- 'code[class*="language-"]::-moz-selection': {
913
- "background": "#1e293b",
914
- "color": "inherit",
915
- "textShadow": "none"
916
- },
917
- 'code[class*="language-"] *::-moz-selection': {
918
- "background": "#1e293b",
919
- "color": "inherit",
920
- "textShadow": "none"
921
- },
922
- 'pre[class*="language-"] *::-moz-selection': {
923
- "background": "#1e293b",
924
- "color": "inherit",
925
- "textShadow": "none"
926
- },
927
- 'code[class*="language-"]::selection': {
928
- "background": "#1e293b",
929
- "color": "inherit",
930
- "textShadow": "none"
931
- },
932
- 'code[class*="language-"] *::selection': {
933
- "background": "#1e293b",
934
- "color": "inherit",
935
- "textShadow": "none"
936
- },
937
- 'pre[class*="language-"] *::selection': {
938
- "background": "#1e293b",
939
- "color": "inherit",
940
- "textShadow": "none"
941
- },
942
- ':not(pre) > code[class*="language-"]': {
943
- "padding": "0.2em 0.3em",
944
- "borderRadius": "0.3em",
945
- "whiteSpace": "normal"
946
- },
947
- "comment": {
948
- "color": "#64748b",
949
- "fontStyle": "italic"
950
- },
951
- "prolog": {
952
- "color": "#64748b"
953
- },
954
- "cdata": {
955
- "color": "#64748b"
956
- },
957
- "doctype": {
958
- "color": "#e2e8f0"
959
- },
960
- "punctuation": {
961
- "color": "#e2e8f0"
962
- },
963
- "entity": {
964
- "color": "#3b82f6",
965
- "cursor": "help"
966
- },
967
- "attr-name": {
968
- "color": "#f59e0b"
969
- },
970
- "class-name": {
971
- "color": "#f59e0b"
972
- },
973
- "boolean": {
974
- "color": "#3b82f6"
975
- },
976
- "constant": {
977
- "color": "#3b82f6"
978
- },
979
- "number": {
980
- "color": "#3b82f6"
981
- },
982
- "atrule": {
983
- "color": "#f59e0b"
984
- },
985
- "keyword": {
986
- "color": "#f472b6"
987
- },
988
- "property": {
989
- "color": "#3b82f6"
990
- },
991
- "tag": {
992
- "color": "#3b82f6"
993
- },
994
- "symbol": {
995
- "color": "#3b82f6"
996
- },
997
- "deleted": {
998
- "color": "#ef4444"
999
- },
1000
- "important": {
1001
- "color": "#f472b6"
1002
- },
1003
- "selector": {
1004
- "color": "#10b981"
1005
- },
1006
- "string": {
1007
- "color": "#10b981"
1008
- },
1009
- "char": {
1010
- "color": "#10b981"
1011
- },
1012
- "builtin": {
1013
- "color": "#10b981"
1014
- },
1015
- "inserted": {
1016
- "color": "#10b981"
1017
- },
1018
- "regex": {
1019
- "color": "#10b981"
1020
- },
1021
- "attr-value": {
1022
- "color": "#10b981"
1023
- },
1024
- "attr-value > .token.punctuation": {
1025
- "color": "#10b981"
1026
- },
1027
- "variable": {
1028
- "color": "#60a5fa"
1029
- },
1030
- "operator": {
1031
- "color": "#60a5fa"
1032
- },
1033
- "function": {
1034
- "color": "#60a5fa"
1035
- },
1036
- "url": {
1037
- "color": "#60a5fa"
1038
- },
1039
- "attr-value > .token.punctuation.attr-equals": {
1040
- "color": "#e2e8f0"
1041
- },
1042
- "special-attr > .token.attr-value > .token.value.css": {
1043
- "color": "#e2e8f0"
1044
- },
1045
- ".language-css .token.selector": {
1046
- "color": "#3b82f6"
1047
- },
1048
- ".language-css .token.property": {
1049
- "color": "#e2e8f0"
1050
- },
1051
- ".language-css .token.function": {
1052
- "color": "#60a5fa"
1053
- },
1054
- ".language-css .token.url > .token.function": {
1055
- "color": "#60a5fa"
1056
- },
1057
- ".language-css .token.url > .token.string.url": {
1058
- "color": "#10b981"
1059
- },
1060
- ".language-css .token.important": {
1061
- "color": "#f472b6"
1062
- },
1063
- ".language-css .token.atrule .token.rule": {
1064
- "color": "#f472b6"
1065
- },
1066
- ".language-javascript .token.operator": {
1067
- "color": "#f472b6"
1068
- },
1069
- ".language-javascript .token.template-string > .token.interpolation > .token.interpolation-punctuation.punctuation": {
1070
- "color": "#ef4444"
1071
- },
1072
- ".language-json .token.operator": {
1073
- "color": "#e2e8f0"
1074
- },
1075
- ".language-json .token.null.keyword": {
1076
- "color": "#3b82f6"
1077
- },
1078
- ".language-markdown .token.url": {
1079
- "color": "#e2e8f0"
1080
- },
1081
- ".language-markdown .token.url > .token.operator": {
1082
- "color": "#e2e8f0"
1083
- },
1084
- ".language-markdown .token.url-reference.url > .token.string": {
1085
- "color": "#e2e8f0"
1086
- },
1087
- ".language-markdown .token.url > .token.content": {
1088
- "color": "#60a5fa"
1089
- },
1090
- ".language-markdown .token.url > .token.url": {
1091
- "color": "#60a5fa"
1092
- },
1093
- ".language-markdown .token.url-reference.url": {
1094
- "color": "#60a5fa"
1095
- },
1096
- ".language-markdown .token.blockquote.punctuation": {
1097
- "color": "#64748b",
1098
- "fontStyle": "italic"
1099
- },
1100
- ".language-markdown .token.hr.punctuation": {
1101
- "color": "#64748b",
1102
- "fontStyle": "italic"
1103
- },
1104
- ".language-markdown .token.code-snippet": {
1105
- "color": "#10b981"
1106
- },
1107
- ".language-markdown .token.bold .token.content": {
1108
- "color": "#f59e0b"
1109
- },
1110
- ".language-markdown .token.italic .token.content": {
1111
- "color": "#f472b6"
1112
- },
1113
- ".language-markdown .token.strike .token.content": {
1114
- "color": "#3b82f6"
1115
- },
1116
- ".language-markdown .token.strike .token.punctuation": {
1117
- "color": "#3b82f6"
1118
- },
1119
- ".language-markdown .token.list.punctuation": {
1120
- "color": "#3b82f6"
1121
- },
1122
- ".language-markdown .token.title.important > .token.punctuation": {
1123
- "color": "#3b82f6"
1124
- },
1125
- "bold": {
1126
- "fontWeight": "bold"
1127
- },
1128
- "italic": {
1129
- "fontStyle": "italic"
1130
- },
1131
- "namespace": {
1132
- "Opacity": "0.8"
1133
- },
1134
- "token.tab:not(:empty):before": {
1135
- "color": "#64748b",
1136
- "textShadow": "none"
1137
- },
1138
- "token.cr:before": {
1139
- "color": "#64748b",
1140
- "textShadow": "none"
1141
- },
1142
- "token.lf:before": {
1143
- "color": "#64748b",
1144
- "textShadow": "none"
1145
- },
1146
- "token.space:before": {
1147
- "color": "#64748b",
1148
- "textShadow": "none"
1149
- },
1150
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item": {
1151
- "marginRight": "0.4em"
1152
- },
1153
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > button": {
1154
- "background": "#1e293b",
1155
- "color": "#94a3b8",
1156
- "padding": "0.1em 0.4em",
1157
- "borderRadius": "0.3em"
1158
- },
1159
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > a": {
1160
- "background": "#1e293b",
1161
- "color": "#94a3b8",
1162
- "padding": "0.1em 0.4em",
1163
- "borderRadius": "0.3em"
1164
- },
1165
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > span": {
1166
- "background": "#1e293b",
1167
- "color": "#94a3b8",
1168
- "padding": "0.1em 0.4em",
1169
- "borderRadius": "0.3em"
1170
- },
1171
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover": {
1172
- "background": "#3b82f6",
1173
- "color": "#ffffff"
1174
- },
1175
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus": {
1176
- "background": "#3b82f6",
1177
- "color": "#ffffff"
1178
- },
1179
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover": {
1180
- "background": "#3b82f6",
1181
- "color": "#ffffff"
1182
- },
1183
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus": {
1184
- "background": "#3b82f6",
1185
- "color": "#ffffff"
1186
- },
1187
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover": {
1188
- "background": "#3b82f6",
1189
- "color": "#ffffff"
1190
- },
1191
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus": {
1192
- "background": "#3b82f6",
1193
- "color": "#ffffff"
1194
- },
1195
- ".line-highlight.line-highlight": {
1196
- "background": "rgba(59, 130, 246, 0.08)"
1197
- },
1198
- ".line-highlight.line-highlight:before": {
1199
- "background": "#1e293b",
1200
- "color": "#e2e8f0",
1201
- "padding": "0.1em 0.6em",
1202
- "borderRadius": "0.3em",
1203
- "boxShadow": "0 2px 0 0 rgba(0, 0, 0, 0.2)"
1204
- },
1205
- ".line-highlight.line-highlight[data-end]:after": {
1206
- "background": "#1e293b",
1207
- "color": "#e2e8f0",
1208
- "padding": "0.1em 0.6em",
1209
- "borderRadius": "0.3em",
1210
- "boxShadow": "0 2px 0 0 rgba(0, 0, 0, 0.2)"
1211
- },
1212
- "pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before": {
1213
- "backgroundColor": "rgba(59, 130, 246, 0.08)"
1214
- },
1215
- ".line-numbers.line-numbers .line-numbers-rows": {
1216
- "borderRightColor": "#1e293b"
1217
- },
1218
- ".command-line .command-line-prompt": {
1219
- "borderRightColor": "#1e293b"
1220
- },
1221
- ".line-numbers .line-numbers-rows > span:before": {
1222
- "color": "#64748b"
1223
- },
1224
- ".command-line .command-line-prompt > span:before": {
1225
- "color": "#64748b"
1226
- },
1227
- ".rainbow-braces .token.token.punctuation.brace-level-1": {
1228
- "color": "#3b82f6"
1229
- },
1230
- ".rainbow-braces .token.token.punctuation.brace-level-5": {
1231
- "color": "#3b82f6"
1232
- },
1233
- ".rainbow-braces .token.token.punctuation.brace-level-9": {
1234
- "color": "#3b82f6"
1235
- },
1236
- ".rainbow-braces .token.token.punctuation.brace-level-2": {
1237
- "color": "#10b981"
1238
- },
1239
- ".rainbow-braces .token.token.punctuation.brace-level-6": {
1240
- "color": "#10b981"
1241
- },
1242
- ".rainbow-braces .token.token.punctuation.brace-level-10": {
1243
- "color": "#10b981"
1244
- },
1245
- ".rainbow-braces .token.token.punctuation.brace-level-3": {
1246
- "color": "#60a5fa"
1247
- },
1248
- ".rainbow-braces .token.token.punctuation.brace-level-7": {
1249
- "color": "#60a5fa"
1250
- },
1251
- ".rainbow-braces .token.token.punctuation.brace-level-11": {
1252
- "color": "#60a5fa"
1253
- },
1254
- ".rainbow-braces .token.token.punctuation.brace-level-4": {
1255
- "color": "#f472b6"
1256
- },
1257
- ".rainbow-braces .token.token.punctuation.brace-level-8": {
1258
- "color": "#f472b6"
1259
- },
1260
- ".rainbow-braces .token.token.punctuation.brace-level-12": {
1261
- "color": "#f472b6"
1262
- },
1263
- "pre.diff-highlight > code .token.token.deleted:not(.prefix)": {
1264
- "backgroundColor": "rgba(239, 68, 68, 0.15)"
1265
- },
1266
- "pre > code.diff-highlight .token.token.deleted:not(.prefix)": {
1267
- "backgroundColor": "rgba(239, 68, 68, 0.15)"
1268
- },
1269
- "pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection": {
1270
- "backgroundColor": "rgba(239, 68, 68, 0.25)"
1271
- },
1272
- "pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection": {
1273
- "backgroundColor": "rgba(239, 68, 68, 0.25)"
1274
- },
1275
- "pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection": {
1276
- "backgroundColor": "rgba(239, 68, 68, 0.25)"
1277
- },
1278
- "pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection": {
1279
- "backgroundColor": "rgba(239, 68, 68, 0.25)"
1280
- },
1281
- "pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection": {
1282
- "backgroundColor": "rgba(239, 68, 68, 0.25)"
1283
- },
1284
- "pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection": {
1285
- "backgroundColor": "rgba(239, 68, 68, 0.25)"
1286
- },
1287
- "pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection": {
1288
- "backgroundColor": "rgba(239, 68, 68, 0.25)"
1289
- },
1290
- "pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection": {
1291
- "backgroundColor": "rgba(239, 68, 68, 0.25)"
1292
- },
1293
- "pre.diff-highlight > code .token.token.inserted:not(.prefix)": {
1294
- "backgroundColor": "rgba(16, 185, 129, 0.15)"
1295
- },
1296
- "pre > code.diff-highlight .token.token.inserted:not(.prefix)": {
1297
- "backgroundColor": "rgba(16, 185, 129, 0.15)"
1298
- },
1299
- "pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection": {
1300
- "backgroundColor": "rgba(16, 185, 129, 0.25)"
1301
- },
1302
- "pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection": {
1303
- "backgroundColor": "rgba(16, 185, 129, 0.25)"
1304
- },
1305
- "pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection": {
1306
- "backgroundColor": "rgba(16, 185, 129, 0.25)"
1307
- },
1308
- "pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection": {
1309
- "backgroundColor": "rgba(16, 185, 129, 0.25)"
1310
- },
1311
- "pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection": {
1312
- "backgroundColor": "rgba(16, 185, 129, 0.25)"
1313
- },
1314
- "pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection": {
1315
- "backgroundColor": "rgba(16, 185, 129, 0.25)"
1316
- },
1317
- "pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection": {
1318
- "backgroundColor": "rgba(16, 185, 129, 0.25)"
1319
- },
1320
- "pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection": {
1321
- "backgroundColor": "rgba(16, 185, 129, 0.25)"
1322
- },
1323
- ".prism-previewer.prism-previewer:before": {
1324
- "borderColor": "#11111f"
1325
- },
1326
- ".prism-previewer-gradient.prism-previewer-gradient div": {
1327
- "borderColor": "#11111f",
1328
- "borderRadius": "0.3em"
1329
- },
1330
- ".prism-previewer-color.prism-previewer-color:before": {
1331
- "borderRadius": "0.3em"
1332
- },
1333
- ".prism-previewer-easing.prism-previewer-easing:before": {
1334
- "borderRadius": "0.3em"
1335
- },
1336
- ".prism-previewer.prism-previewer:after": {
1337
- "borderTopColor": "#11111f"
1338
- },
1339
- ".prism-previewer-flipped.prism-previewer-flipped.after": {
1340
- "borderBottomColor": "#11111f"
1341
- },
1342
- ".prism-previewer-angle.prism-previewer-angle:before": {
1343
- "background": "#1e293b"
1344
- },
1345
- ".prism-previewer-time.prism-previewer-time:before": {
1346
- "background": "#1e293b"
1347
- },
1348
- ".prism-previewer-easing.prism-previewer-easing": {
1349
- "background": "#1e293b"
1350
- },
1351
- ".prism-previewer-angle.prism-previewer-angle circle": {
1352
- "stroke": "#e2e8f0",
1353
- "strokeOpacity": "1"
1354
- },
1355
- ".prism-previewer-time.prism-previewer-time circle": {
1356
- "stroke": "#e2e8f0",
1357
- "strokeOpacity": "1"
1358
- },
1359
- ".prism-previewer-easing.prism-previewer-easing circle": {
1360
- "stroke": "#e2e8f0",
1361
- "fill": "transparent"
1362
- },
1363
- ".prism-previewer-easing.prism-previewer-easing path": {
1364
- "stroke": "#e2e8f0"
1365
- },
1366
- ".prism-previewer-easing.prism-previewer-easing line": {
1367
- "stroke": "#e2e8f0"
1368
- }
1369
- };
1370
- const light = {
1371
- 'code[class*="language-"]': {
1372
- "background": "#fff",
1373
- "color": "#1e293b",
1374
- "textShadow": "none",
1375
- "fontFamily": '"Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace',
1376
- "direction": "ltr",
1377
- "textAlign": "left",
1378
- "whiteSpace": "pre",
1379
- "wordSpacing": "normal",
1380
- "wordBreak": "normal",
1381
- "lineHeight": "1.5",
1382
- "MozTabSize": "2",
1383
- "OTabSize": "2",
1384
- "tabSize": "2",
1385
- "WebkitHyphens": "none",
1386
- "MozHyphens": "none",
1387
- "msHyphens": "none",
1388
- "hyphens": "none"
1389
- },
1390
- 'pre[class*="language-"]': {
1391
- "background": "#fff",
1392
- "color": "#1e293b",
1393
- "textShadow": "none",
1394
- "fontFamily": '"Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace',
1395
- "direction": "ltr",
1396
- "textAlign": "left",
1397
- "whiteSpace": "pre",
1398
- "wordSpacing": "normal",
1399
- "wordBreak": "normal",
1400
- "lineHeight": "1.5",
1401
- "MozTabSize": "2",
1402
- "OTabSize": "2",
1403
- "tabSize": "2",
1404
- "WebkitHyphens": "none",
1405
- "MozHyphens": "none",
1406
- "msHyphens": "none",
1407
- "hyphens": "none",
1408
- "padding": "1em",
1409
- "margin": "0.5em 0",
1410
- "overflow": "auto",
1411
- "borderRadius": "0.3em",
1412
- "border": "1px solid #e2e8f0"
1413
- },
1414
- 'code[class*="language-"]::-moz-selection': {
1415
- "background": "#e2e8f0",
1416
- "color": "inherit",
1417
- "textShadow": "none"
1418
- },
1419
- 'code[class*="language-"] *::-moz-selection': {
1420
- "background": "#e2e8f0",
1421
- "color": "inherit",
1422
- "textShadow": "none"
1423
- },
1424
- 'pre[class*="language-"] *::-moz-selection': {
1425
- "background": "#e2e8f0",
1426
- "color": "inherit",
1427
- "textShadow": "none"
1428
- },
1429
- 'code[class*="language-"]::selection': {
1430
- "background": "#e2e8f0",
1431
- "color": "inherit",
1432
- "textShadow": "none"
1433
- },
1434
- 'code[class*="language-"] *::selection': {
1435
- "background": "#e2e8f0",
1436
- "color": "inherit",
1437
- "textShadow": "none"
1438
- },
1439
- 'pre[class*="language-"] *::selection': {
1440
- "background": "#e2e8f0",
1441
- "color": "inherit",
1442
- "textShadow": "none"
1443
- },
1444
- ':not(pre) > code[class*="language-"]': {
1445
- "padding": "0.2em 0.3em",
1446
- "borderRadius": "0.3em",
1447
- "whiteSpace": "normal",
1448
- "background": "#f1f5f9"
1449
- },
1450
- "comment": {
1451
- "color": "#64748b",
1452
- "fontStyle": "italic"
1453
- },
1454
- "prolog": {
1455
- "color": "#64748b"
1456
- },
1457
- "cdata": {
1458
- "color": "#64748b"
1459
- },
1460
- "doctype": {
1461
- "color": "#1e293b"
1462
- },
1463
- "punctuation": {
1464
- "color": "#64748b"
1465
- },
1466
- "entity": {
1467
- "color": "#3b82f6",
1468
- "cursor": "help"
1469
- },
1470
- "attr-name": {
1471
- "color": "#ea580c"
1472
- },
1473
- "class-name": {
1474
- "color": "#ea580c"
1475
- },
1476
- "boolean": {
1477
- "color": "#3b82f6"
1478
- },
1479
- "constant": {
1480
- "color": "#3b82f6"
1481
- },
1482
- "number": {
1483
- "color": "#3b82f6"
1484
- },
1485
- "atrule": {
1486
- "color": "#ea580c"
1487
- },
1488
- "keyword": {
1489
- "color": "#9333ea"
1490
- },
1491
- "property": {
1492
- "color": "#3b82f6"
1493
- },
1494
- "tag": {
1495
- "color": "#3b82f6"
1496
- },
1497
- "symbol": {
1498
- "color": "#3b82f6"
1499
- },
1500
- "deleted": {
1501
- "color": "#dc2626"
1502
- },
1503
- "important": {
1504
- "color": "#9333ea"
1505
- },
1506
- "selector": {
1507
- "color": "#16a34a"
1508
- },
1509
- "string": {
1510
- "color": "#16a34a"
1511
- },
1512
- "char": {
1513
- "color": "#16a34a"
1514
- },
1515
- "builtin": {
1516
- "color": "#16a34a"
1517
- },
1518
- "inserted": {
1519
- "color": "#16a34a"
1520
- },
1521
- "regex": {
1522
- "color": "#16a34a"
1523
- },
1524
- "attr-value": {
1525
- "color": "#16a34a"
1526
- },
1527
- "attr-value > .token.punctuation": {
1528
- "color": "#16a34a"
1529
- },
1530
- "variable": {
1531
- "color": "#3b82f6"
1532
- },
1533
- "operator": {
1534
- "color": "#3b82f6"
1535
- },
1536
- "function": {
1537
- "color": "#3b82f6"
1538
- },
1539
- "url": {
1540
- "color": "#3b82f6"
1541
- },
1542
- "attr-value > .token.punctuation.attr-equals": {
1543
- "color": "#64748b"
1544
- },
1545
- "special-attr > .token.attr-value > .token.value.css": {
1546
- "color": "#1e293b"
1547
- },
1548
- ".language-css .token.selector": {
1549
- "color": "#3b82f6"
1550
- },
1551
- ".language-css .token.property": {
1552
- "color": "#1e293b"
1553
- },
1554
- ".language-css .token.function": {
1555
- "color": "#3b82f6"
1556
- },
1557
- ".language-css .token.url > .token.function": {
1558
- "color": "#3b82f6"
1559
- },
1560
- ".language-css .token.url > .token.string.url": {
1561
- "color": "#16a34a"
1562
- },
1563
- ".language-css .token.important": {
1564
- "color": "#9333ea"
1565
- },
1566
- ".language-css .token.atrule .token.rule": {
1567
- "color": "#9333ea"
1568
- },
1569
- ".language-javascript .token.operator": {
1570
- "color": "#9333ea"
1571
- },
1572
- ".language-javascript .token.template-string > .token.interpolation > .token.interpolation-punctuation.punctuation": {
1573
- "color": "#dc2626"
1574
- },
1575
- ".language-json .token.operator": {
1576
- "color": "#1e293b"
1577
- },
1578
- ".language-json .token.null.keyword": {
1579
- "color": "#3b82f6"
1580
- },
1581
- ".language-markdown .token.url": {
1582
- "color": "#1e293b"
1583
- },
1584
- ".language-markdown .token.url > .token.operator": {
1585
- "color": "#1e293b"
1586
- },
1587
- ".language-markdown .token.url-reference.url > .token.string": {
1588
- "color": "#1e293b"
1589
- },
1590
- ".language-markdown .token.url > .token.content": {
1591
- "color": "#3b82f6"
1592
- },
1593
- ".language-markdown .token.url > .token.url": {
1594
- "color": "#3b82f6"
1595
- },
1596
- ".language-markdown .token.url-reference.url": {
1597
- "color": "#3b82f6"
1598
- },
1599
- ".language-markdown .token.blockquote.punctuation": {
1600
- "color": "#64748b",
1601
- "fontStyle": "italic"
1602
- },
1603
- ".language-markdown .token.hr.punctuation": {
1604
- "color": "#64748b",
1605
- "fontStyle": "italic"
1606
- },
1607
- ".language-markdown .token.code-snippet": {
1608
- "color": "#16a34a"
1609
- },
1610
- ".language-markdown .token.bold .token.content": {
1611
- "color": "#ea580c"
1612
- },
1613
- ".language-markdown .token.italic .token.content": {
1614
- "color": "#9333ea"
1615
- },
1616
- ".language-markdown .token.strike .token.content": {
1617
- "color": "#3b82f6"
1618
- },
1619
- ".language-markdown .token.strike .token.punctuation": {
1620
- "color": "#3b82f6"
1621
- },
1622
- ".language-markdown .token.list.punctuation": {
1623
- "color": "#3b82f6"
1624
- },
1625
- ".language-markdown .token.title.important > .token.punctuation": {
1626
- "color": "#3b82f6"
1627
- },
1628
- "bold": {
1629
- "fontWeight": "bold"
1630
- },
1631
- "italic": {
1632
- "fontStyle": "italic"
1633
- },
1634
- "namespace": {
1635
- "Opacity": "0.8"
1636
- },
1637
- "token.tab:not(:empty):before": {
1638
- "color": "#94a3b8"
1639
- },
1640
- "token.cr:before": {
1641
- "color": "#94a3b8"
1642
- },
1643
- "token.lf:before": {
1644
- "color": "#94a3b8"
1645
- },
1646
- "token.space:before": {
1647
- "color": "#94a3b8"
1648
- },
1649
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item": {
1650
- "marginRight": "0.4em"
1651
- },
1652
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > button": {
1653
- "background": "#f1f5f9",
1654
- "color": "#475569",
1655
- "padding": "0.1em 0.4em",
1656
- "borderRadius": "0.3em"
1657
- },
1658
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > a": {
1659
- "background": "#f1f5f9",
1660
- "color": "#475569",
1661
- "padding": "0.1em 0.4em",
1662
- "borderRadius": "0.3em"
1663
- },
1664
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > span": {
1665
- "background": "#f1f5f9",
1666
- "color": "#475569",
1667
- "padding": "0.1em 0.4em",
1668
- "borderRadius": "0.3em"
1669
- },
1670
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover": {
1671
- "background": "#3b82f6",
1672
- "color": "#ffffff"
1673
- },
1674
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus": {
1675
- "background": "#3b82f6",
1676
- "color": "#ffffff"
1677
- },
1678
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover": {
1679
- "background": "#3b82f6",
1680
- "color": "#ffffff"
1681
- },
1682
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus": {
1683
- "background": "#3b82f6",
1684
- "color": "#ffffff"
1685
- },
1686
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover": {
1687
- "background": "#3b82f6",
1688
- "color": "#ffffff"
1689
- },
1690
- "div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus": {
1691
- "background": "#3b82f6",
1692
- "color": "#ffffff"
1693
- },
1694
- ".line-highlight.line-highlight": {
1695
- "background": "rgba(59, 130, 246, 0.08)"
1696
- },
1697
- ".line-highlight.line-highlight:before": {
1698
- "background": "#f1f5f9",
1699
- "color": "#1e293b",
1700
- "padding": "0.1em 0.6em",
1701
- "borderRadius": "0.3em",
1702
- "boxShadow": "0 2px 0 0 rgba(0, 0, 0, 0.1)"
1703
- },
1704
- ".line-highlight.line-highlight[data-end]:after": {
1705
- "background": "#f1f5f9",
1706
- "color": "#1e293b",
1707
- "padding": "0.1em 0.6em",
1708
- "borderRadius": "0.3em",
1709
- "boxShadow": "0 2px 0 0 rgba(0, 0, 0, 0.1)"
1710
- },
1711
- "pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before": {
1712
- "backgroundColor": "rgba(59, 130, 246, 0.08)"
1713
- },
1714
- ".line-numbers.line-numbers .line-numbers-rows": {
1715
- "borderRightColor": "#e2e8f0"
1716
- },
1717
- ".command-line .command-line-prompt": {
1718
- "borderRightColor": "#e2e8f0"
1719
- },
1720
- ".line-numbers .line-numbers-rows > span:before": {
1721
- "color": "#94a3b8"
1722
- },
1723
- ".command-line .command-line-prompt > span:before": {
1724
- "color": "#94a3b8"
1725
- },
1726
- ".rainbow-braces .token.token.punctuation.brace-level-1": {
1727
- "color": "#3b82f6"
1728
- },
1729
- ".rainbow-braces .token.token.punctuation.brace-level-5": {
1730
- "color": "#3b82f6"
1731
- },
1732
- ".rainbow-braces .token.token.punctuation.brace-level-9": {
1733
- "color": "#3b82f6"
1734
- },
1735
- ".rainbow-braces .token.token.punctuation.brace-level-2": {
1736
- "color": "#16a34a"
1737
- },
1738
- ".rainbow-braces .token.token.punctuation.brace-level-6": {
1739
- "color": "#16a34a"
1740
- },
1741
- ".rainbow-braces .token.token.punctuation.brace-level-10": {
1742
- "color": "#16a34a"
1743
- },
1744
- ".rainbow-braces .token.token.punctuation.brace-level-3": {
1745
- "color": "#ea580c"
1746
- },
1747
- ".rainbow-braces .token.token.punctuation.brace-level-7": {
1748
- "color": "#ea580c"
1749
- },
1750
- ".rainbow-braces .token.token.punctuation.brace-level-11": {
1751
- "color": "#ea580c"
1752
- },
1753
- ".rainbow-braces .token.token.punctuation.brace-level-4": {
1754
- "color": "#9333ea"
1755
- },
1756
- ".rainbow-braces .token.token.punctuation.brace-level-8": {
1757
- "color": "#9333ea"
1758
- },
1759
- ".rainbow-braces .token.token.punctuation.brace-level-12": {
1760
- "color": "#9333ea"
1761
- },
1762
- "pre.diff-highlight > code .token.token.deleted:not(.prefix)": {
1763
- "backgroundColor": "rgba(220, 38, 38, 0.15)"
1764
- },
1765
- "pre > code.diff-highlight .token.token.deleted:not(.prefix)": {
1766
- "backgroundColor": "rgba(220, 38, 38, 0.15)"
1767
- },
1768
- "pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection": {
1769
- "backgroundColor": "rgba(220, 38, 38, 0.25)"
1770
- },
1771
- "pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection": {
1772
- "backgroundColor": "rgba(220, 38, 38, 0.25)"
1773
- },
1774
- "pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection": {
1775
- "backgroundColor": "rgba(220, 38, 38, 0.25)"
1776
- },
1777
- "pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection": {
1778
- "backgroundColor": "rgba(220, 38, 38, 0.25)"
1779
- },
1780
- "pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection": {
1781
- "backgroundColor": "rgba(220, 38, 38, 0.25)"
1782
- },
1783
- "pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection": {
1784
- "backgroundColor": "rgba(220, 38, 38, 0.25)"
1785
- },
1786
- "pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection": {
1787
- "backgroundColor": "rgba(220, 38, 38, 0.25)"
1788
- },
1789
- "pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection": {
1790
- "backgroundColor": "rgba(220, 38, 38, 0.25)"
1791
- },
1792
- "pre.diff-highlight > code .token.token.inserted:not(.prefix)": {
1793
- "backgroundColor": "rgba(22, 163, 74, 0.15)"
1794
- },
1795
- "pre > code.diff-highlight .token.token.inserted:not(.prefix)": {
1796
- "backgroundColor": "rgba(22, 163, 74, 0.15)"
1797
- },
1798
- "pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection": {
1799
- "backgroundColor": "rgba(22, 163, 74, 0.25)"
1800
- },
1801
- "pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection": {
1802
- "backgroundColor": "rgba(22, 163, 74, 0.25)"
1803
- },
1804
- "pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection": {
1805
- "backgroundColor": "rgba(22, 163, 74, 0.25)"
1806
- },
1807
- "pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection": {
1808
- "backgroundColor": "rgba(22, 163, 74, 0.25)"
1809
- },
1810
- "pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection": {
1811
- "backgroundColor": "rgba(22, 163, 74, 0.25)"
1812
- },
1813
- "pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection": {
1814
- "backgroundColor": "rgba(22, 163, 74, 0.25)"
1815
- },
1816
- "pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection": {
1817
- "backgroundColor": "rgba(22, 163, 74, 0.25)"
1818
- },
1819
- "pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection": {
1820
- "backgroundColor": "rgba(22, 163, 74, 0.25)"
1821
- },
1822
- ".prism-previewer.prism-previewer:before": {
1823
- "borderColor": "#fff"
1824
- },
1825
- ".prism-previewer-gradient.prism-previewer-gradient div": {
1826
- "borderColor": "#fff",
1827
- "borderRadius": "0.3em"
1828
- },
1829
- ".prism-previewer-color.prism-previewer-color:before": {
1830
- "borderRadius": "0.3em"
1831
- },
1832
- ".prism-previewer-easing.prism-previewer-easing:before": {
1833
- "borderRadius": "0.3em"
1834
- },
1835
- ".prism-previewer.prism-previewer:after": {
1836
- "borderTopColor": "#fff"
1837
- },
1838
- ".prism-previewer-flipped.prism-previewer-flipped.after": {
1839
- "borderBottomColor": "#fff"
1840
- },
1841
- ".prism-previewer-angle.prism-previewer-angle:before": {
1842
- "background": "#f1f5f9"
1843
- },
1844
- ".prism-previewer-time.prism-previewer-time:before": {
1845
- "background": "#f1f5f9"
1846
- },
1847
- ".prism-previewer-easing.prism-previewer-easing": {
1848
- "background": "#f1f5f9"
1849
- },
1850
- ".prism-previewer-angle.prism-previewer-angle circle": {
1851
- "stroke": "#1e293b",
1852
- "strokeOpacity": "1"
1853
- },
1854
- ".prism-previewer-time.prism-previewer-time circle": {
1855
- "stroke": "#1e293b",
1856
- "strokeOpacity": "1"
1857
- },
1858
- ".prism-previewer-easing.prism-previewer-easing circle": {
1859
- "stroke": "#1e293b",
1860
- "fill": "transparent"
1861
- },
1862
- ".prism-previewer-easing.prism-previewer-easing path": {
1863
- "stroke": "#1e293b"
1864
- },
1865
- ".prism-previewer-easing.prism-previewer-easing line": {
1866
- "stroke": "#1e293b"
1867
- }
1868
- };
1869
- const CodeHighlighter = ({
1870
- className,
1871
- children,
1872
- inlineClassName,
1873
- copyClassName,
1874
- copyIcon = /* @__PURE__ */ jsx(SvgCopy, {}),
1875
- language,
1876
- toolbarClassName,
1877
- theme = dark,
1878
- ...props
1879
- }) => {
1880
- const match = language?.match(/language-(\w+)/);
1881
- const lang = match ? match[1] : "text";
1882
- const isInline = !match;
1883
- const handleCopy = (text) => {
1884
- navigator.clipboard.writeText(text).then(() => {
1885
- console.log("Text copied to clipboard");
1886
- }).catch((err) => {
1887
- console.error("Could not copy text: ", err);
1888
- });
1889
- };
1890
- if (isInline) {
1891
- return /* @__PURE__ */ jsx("code", { className: cn(inlineClassName), ...props, children });
1892
- }
1893
- return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
1894
- /* @__PURE__ */ jsxs("div", { className: cn(toolbarClassName), children: [
1895
- /* @__PURE__ */ jsx("div", { children: lang }),
1896
- copyIcon && /* @__PURE__ */ jsx(
1897
- Button,
1898
- {
1899
- className: cn(copyClassName),
1900
- size: "small",
1901
- variant: "text",
1902
- title: "Copy code",
1903
- onClick: () => handleCopy(children),
1904
- children: copyIcon
1905
- }
1906
- )
1907
- ] }),
1908
- /* @__PURE__ */ jsx(Prism, { language: lang, style: theme, children })
1909
- ] });
1910
- };
1911
- const TableComponent = ({ children, ...props }) => /* @__PURE__ */ jsx("table", { ...props, children });
1912
- const TableHeaderCell = ({ children, ...props }) => /* @__PURE__ */ jsx("th", { ...props, children });
1913
- const TableDataCell = ({ children, ...props }) => /* @__PURE__ */ jsx("td", { ...props, children });
1914
- const Markdown = ({
1915
- children,
1916
- remarkPlugins,
1917
- rehypePlugins = [rehypeRaw, rehypeKatex],
1918
- theme: themeProp,
1919
- customComponents
1920
- }) => {
1921
- const { theme: contextTheme, markdownComponents } = useContext(ChatContext);
1922
- const theme = themeProp || contextTheme;
1923
- const components = useMemo(() => {
1924
- const defaultComponents = {
1925
- code: ({ className, children: children2, ...props }) => /* @__PURE__ */ jsx(
1926
- CodeHighlighter,
1927
- {
1928
- ...props,
1929
- language: cn(className),
1930
- inlineClassName: cn(theme.messages.message.markdown.inlineCode),
1931
- className: cn(theme.messages.message.markdown.code, className),
1932
- copyClassName: cn(theme.messages.message.markdown.copy),
1933
- toolbarClassName: cn(theme.messages.message.markdown.toolbar),
1934
- children: children2
1935
- }
1936
- ),
1937
- table: (props) => /* @__PURE__ */ jsx(
1938
- TableComponent,
1939
- {
1940
- ...props,
1941
- className: cn(theme.messages.message.markdown.table)
1942
- }
1943
- ),
1944
- th: (props) => /* @__PURE__ */ jsx(
1945
- TableHeaderCell,
1946
- {
1947
- ...props,
1948
- className: cn(theme.messages.message.markdown.th)
1949
- }
1950
- ),
1951
- td: (props) => /* @__PURE__ */ jsx(
1952
- TableDataCell,
1953
- {
1954
- ...props,
1955
- className: cn(theme.messages.message.markdown.td)
1956
- }
1957
- ),
1958
- a: (props) => /* @__PURE__ */ jsx("a", { ...props, className: cn(theme.messages.message.markdown.a) }),
1959
- hr: (props) => /* @__PURE__ */ jsx("hr", { ...props, className: cn(theme.messages.message.markdown.hr) }),
1960
- p: (props) => /* @__PURE__ */ jsx("p", { ...props, className: cn(theme.messages.message.markdown.p) }),
1961
- li: (props) => /* @__PURE__ */ jsx("li", { ...props, className: cn(theme.messages.message.markdown.li) }),
1962
- ul: (props) => /* @__PURE__ */ jsx("ul", { ...props, className: cn(theme.messages.message.markdown.ul) }),
1963
- ol: (props) => /* @__PURE__ */ jsx("ol", { ...props, className: cn(theme.messages.message.markdown.ol) }),
1964
- h1: (props) => /* @__PURE__ */ jsx("h1", { ...props, className: cn(theme.messages.message.markdown.h1) }),
1965
- h2: (props) => /* @__PURE__ */ jsx("h2", { ...props, className: cn(theme.messages.message.markdown.h2) }),
1966
- h3: (props) => /* @__PURE__ */ jsx("h3", { ...props, className: cn(theme.messages.message.markdown.h3) }),
1967
- h4: (props) => /* @__PURE__ */ jsx("h4", { ...props, className: cn(theme.messages.message.markdown.h4) }),
1968
- h5: (props) => /* @__PURE__ */ jsx("h5", { ...props, className: cn(theme.messages.message.markdown.h5) }),
1969
- h6: (props) => /* @__PURE__ */ jsx("h6", { ...props, className: cn(theme.messages.message.markdown.h6) }),
1970
- // 'redact' is a custom element created by remarkRedact, not a standard
1971
- // HTML tag, so it falls outside react-markdown's Components type.
1972
- redact: ((props) => /* @__PURE__ */ jsx(
1973
- Redact,
1974
- {
1975
- value: props["data-redact-value"] || props.children,
1976
- allowToggle: true,
1977
- tooltipText: `${props["data-redact-name"] || "Sensitive"} information - Click to toggle`
1978
- }
1979
- ))
1980
- };
1981
- return {
1982
- ...defaultComponents,
1983
- ...markdownComponents,
1984
- ...customComponents
1985
- };
1986
- }, [theme, markdownComponents, customComponents]);
1987
- return /* @__PURE__ */ jsx(
1988
- ReactMarkdown,
1989
- {
1990
- remarkPlugins,
1991
- rehypePlugins,
1992
- components,
1993
- children
1994
- }
1995
- );
1996
- };
1997
- const ComponentError = ({
1998
- variant = "error",
1999
- title,
2000
- message,
2001
- code
2002
- }) => {
2003
- const { theme } = useContext(ChatContext);
2004
- const styles = variant === "warning" ? theme.chart.warning : theme.chart.error;
2005
- return /* @__PURE__ */ jsxs("div", { className: styles.base, children: [
2006
- title && /* @__PURE__ */ jsx("div", { className: styles.title, children: title }),
2007
- message && /* @__PURE__ */ jsx("div", { children: message }),
2008
- code && "code" in styles && /* @__PURE__ */ jsx("pre", { className: styles.code, children: /* @__PURE__ */ jsx("code", { children: code }) })
2009
- ] });
2010
- };
2011
- const ChartRenderer = ({
2012
- config,
2013
- className
2014
- }) => {
2015
- const { theme } = useContext(ChatContext);
2016
- const { type, data, width = 400, height = 300, title } = config;
2017
- const chartElement = useMemo(() => {
2018
- const chartData = data.filter(
2019
- (d) => typeof d.data === "number"
2020
- ).map((d) => ({
2021
- key: d.key,
2022
- data: d.data
2023
- }));
2024
- if (!chartData || chartData.length === 0) {
2025
- return /* @__PURE__ */ jsx(ComponentError, { variant: "warning", message: "No chart data available" });
2026
- }
2027
- for (const point of chartData) {
2028
- if (typeof point.data !== "number" || isNaN(point.data)) {
2029
- return /* @__PURE__ */ jsx(
2030
- ComponentError,
2031
- {
2032
- message: `Invalid data point: ${JSON.stringify(point)}`
2033
- }
2034
- );
2035
- }
2036
- }
2037
- const chartProps = {
2038
- width,
2039
- height,
2040
- data: chartData
2041
- };
2042
- try {
2043
- switch (type) {
2044
- case "bar":
2045
- return /* @__PURE__ */ jsx(BarChart, { ...chartProps, series: /* @__PURE__ */ jsx(BarSeries, {}) });
2046
- case "line":
2047
- return /* @__PURE__ */ jsx(
2048
- LineChart,
2049
- {
2050
- ...chartProps,
2051
- xAxis: /* @__PURE__ */ jsx(LinearXAxis, { type: "category" }),
2052
- yAxis: /* @__PURE__ */ jsx(LinearYAxis, { type: "value" }),
2053
- series: /* @__PURE__ */ jsx(LineSeries, {})
2054
- }
2055
- );
2056
- case "area":
2057
- return /* @__PURE__ */ jsx(
2058
- AreaChart,
2059
- {
2060
- ...chartProps,
2061
- xAxis: /* @__PURE__ */ jsx(LinearXAxis, { type: "category" }),
2062
- yAxis: /* @__PURE__ */ jsx(LinearYAxis, { type: "value" }),
2063
- series: /* @__PURE__ */ jsx(AreaSeries, {})
2064
- }
2065
- );
2066
- case "pie":
2067
- return /* @__PURE__ */ jsx(
2068
- PieChart,
2069
- {
2070
- width,
2071
- height,
2072
- data: chartData,
2073
- series: /* @__PURE__ */ jsx(PieArcSeries, {})
2074
- }
2075
- );
2076
- case "radialBar":
2077
- return /* @__PURE__ */ jsx(
2078
- RadialBarChart,
2079
- {
2080
- width,
2081
- height,
2082
- data: chartData,
2083
- series: /* @__PURE__ */ jsx(RadialBarSeries, {})
2084
- }
2085
- );
2086
- case "radialArea":
2087
- return /* @__PURE__ */ jsx(
2088
- RadialAreaChart,
2089
- {
2090
- width,
2091
- height,
2092
- data: chartData,
2093
- series: /* @__PURE__ */ jsx(RadialAreaSeries, {})
2094
- }
2095
- );
2096
- case "sparkline":
2097
- return /* @__PURE__ */ jsx(SparklineChart, { width, height, data: chartData });
2098
- default:
2099
- return /* @__PURE__ */ jsx(ComponentError, { message: `Unknown chart type: ${type}` });
2100
- }
2101
- } catch (error) {
2102
- return /* @__PURE__ */ jsx(ComponentError, { message: `Chart render error: ${String(error)}` });
2103
- }
2104
- }, [type, data, width, height]);
2105
- return /* @__PURE__ */ jsxs("div", { className: cn(theme.chart.base, className), children: [
2106
- title && /* @__PURE__ */ jsx("div", { className: theme.chart.title, children: title }),
2107
- /* @__PURE__ */ jsx("div", { className: theme.chart.content, children: chartElement })
2108
- ] });
2109
- };
2110
- const CVE_REGEX = /(CVE-(19|20)\d{2}-\d{4,7})/gi;
2111
- const remarkCve = () => (tree) => {
2112
- findAndReplace(tree, [
2113
- [
2114
- CVE_REGEX,
2115
- (value) => ({
2116
- type: "link",
2117
- url: `https://cve.mitre.org/cgi-bin/cvename.cgi?name=${value.trim()}`,
2118
- children: [{ type: "text", value: value.trim() }]
2119
- })
2120
- ]
2121
- ]);
2122
- };
2123
- const remarkComponent = (_options = {}) => {
2124
- return () => {
2125
- };
2126
- };
2127
- function remarkRedact(matchers) {
2128
- return () => (tree) => {
2129
- if (!tree || !matchers || matchers.length === 0) {
2130
- return;
2131
- }
2132
- const patterns = [];
2133
- for (const { name, pattern, validate } of matchers) {
2134
- patterns.push([
2135
- pattern,
2136
- (value) => {
2137
- if (validate && !validate(value)) {
2138
- return false;
2139
- }
2140
- return {
2141
- type: "html",
2142
- value: `<redact data-redact-name="${name}" data-redact-value="${value.replace(/"/g, "&quot;")}">${value}</redact>`
2143
- };
2144
- }
2145
- ]);
2146
- }
2147
- if (patterns.length > 0) {
2148
- try {
2149
- findAndReplace(tree, patterns);
2150
- } catch (err) {
2151
- console.warn("Redact plugin error:", err);
2152
- }
2153
- }
2154
- };
2155
- }
2156
- const ssnMatcher = {
2157
- name: "SSN",
2158
- pattern: /\b\d{3}-\d{2}-\d{4}\b/g
2159
- };
2160
- const creditCardMatcher = {
2161
- name: "Credit Card",
2162
- pattern: /\b(?:\d[ -]*?){13,19}\b/g,
2163
- validate: (match) => {
2164
- if (/(?:years?|year|yr|yrs|old|age|phone|tel|call)/.test(match)) {
2165
- return false;
2166
- }
2167
- const cardNumber = match.replace(/[ -]/g, "");
2168
- return cardNumber.length >= 13 && cardNumber.length <= 19;
2169
- }
2170
- };
2171
- const bitcoinMatcher = {
2172
- name: "Bitcoin",
2173
- pattern: /\b[13][a-km-zA-HJ-NP-Z1-9]{25,34}\b/g
2174
- };
2175
- const commonRedactMatchers = [
2176
- ssnMatcher,
2177
- creditCardMatcher,
2178
- bitcoinMatcher
2179
- ];
2180
- 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" }));
2181
- const DefaultFileRenderer = lazy(() => import("./DefaultFileRenderer-B0ZTdkz2.js"));
2182
- const CSVFileRenderer = lazy(() => import("./CSVFileRenderer-CQkyw8il.js"));
2183
- const ImageFileRenderer = lazy(() => import("./ImageFileRenderer-C8tVW3I8.js"));
2184
- const PDFFileRenderer = lazy(() => import("./PDFFileRenderer-DQdFS2l6.js"));
2185
- const FILE_TYPE_RENDERER_MAP = {
2186
- "image/": ImageFileRenderer,
2187
- "text/csv": CSVFileRenderer,
2188
- "application/pdf": PDFFileRenderer
2189
- };
2190
- const MessageFile = ({
2191
- name,
2192
- type,
2193
- url,
2194
- limit = 100,
2195
- fileIcon = /* @__PURE__ */ jsx(SvgFile, {})
2196
- }) => {
2197
- const { theme } = useContext(ChatContext);
2198
- const FileRenderer = useMemo(() => {
2199
- const Renderer = Object.keys(FILE_TYPE_RENDERER_MAP).find((key) => type?.startsWith(key)) ?? "default";
2200
- return FILE_TYPE_RENDERER_MAP[Renderer] || DefaultFileRenderer;
2201
- }, [type]);
2202
- return /* @__PURE__ */ jsx(
2203
- "div",
2204
- {
2205
- className: cn(theme.messages.message.files.file.base),
2206
- children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsx(FileRenderer, { name, url, fileIcon, limit }) })
2207
- }
2208
- );
2209
- };
2210
- const MessageFiles = memo(({ files, children }) => {
2211
- const { theme } = useContext(ChatContext);
2212
- const Comp = children ? Slot : MessageFile;
2213
- const [expanded, setExpanded] = useState(false);
2214
- const { imageFiles, otherFiles } = useMemo(() => {
2215
- if (!files || files.length === 0) {
2216
- return {
2217
- imageFiles: [],
2218
- otherFiles: []
2219
- };
2220
- }
2221
- return files.reduce(
2222
- (acc, file) => {
2223
- if (file.type?.startsWith("image/")) {
2224
- acc.imageFiles.push(file);
2225
- } else {
2226
- acc.otherFiles.push(file);
2227
- }
2228
- return acc;
2229
- },
2230
- {
2231
- imageFiles: [],
2232
- otherFiles: []
2233
- }
2234
- );
2235
- }, [files]);
2236
- if (!files || files.length === 0) {
2237
- return null;
2238
- }
2239
- const maxImageLength = 3;
2240
- const truncateImages = !expanded && imageFiles.length > maxImageLength;
2241
- const renderImageFiles = (images) => {
2242
- return truncateImages ? images.slice(0, maxImageLength).map((image, index) => /* @__PURE__ */ jsxs(
2243
- "figure",
2244
- {
2245
- className: index === 0 ? "col-span-2 row-span-2" : "relative",
2246
- children: [
2247
- /* @__PURE__ */ jsx(
2248
- "img",
2249
- {
2250
- src: image.url,
2251
- alt: image.name,
2252
- className: "relative w-full h-full object-cover rounded-lg"
2253
- }
2254
- ),
2255
- index === maxImageLength - 1 && /* @__PURE__ */ jsxs(
2256
- "div",
2257
- {
2258
- className: "absolute top-0 left-0 w-full h-full flex justify-center items-center bg-black bg-opacity-50 rounded-lg cursor-pointer",
2259
- onClick: () => setExpanded(true),
2260
- children: [
2261
- "+",
2262
- (imageFiles.length - maxImageLength).toLocaleString()
2263
- ]
2264
- }
2265
- )
2266
- ]
2267
- },
2268
- index
2269
- )) : images.map((image, index) => /* @__PURE__ */ jsx(Comp, { ...image, children }, index));
2270
- };
2271
- return /* @__PURE__ */ jsxs(
2272
- "div",
2273
- {
2274
- className: cn(
2275
- theme.messages.message.files.base,
2276
- truncateImages ? "grid grid-rows-2 grid-flow-col gap-2 w-1/3" : ""
2277
- ),
2278
- children: [
2279
- imageFiles.length > 0 && renderImageFiles(imageFiles),
2280
- otherFiles.length > 0 && otherFiles.map((file, index) => /* @__PURE__ */ jsx(Comp, { ...file, children }, index))
2281
- ]
2282
- }
2283
- );
2284
- });
2285
- MessageFiles.displayName = "MessageFiles";
2286
- const MessageQuestion = memo(
2287
- ({ children, ...props }) => {
2288
- const { theme, remarkPlugins } = useContext(ChatContext);
2289
- const { question, files } = props;
2290
- const Comp = children ? Slot : "div";
2291
- const [expanded, setExpanded] = useState(false);
2292
- const isLong = question.length > 500;
2293
- return /* @__PURE__ */ jsx(
2294
- Comp,
2295
- {
2296
- className: cn(theme.messages.message.question, {
2297
- [theme.messages.message.overlay]: isLong && !expanded
2298
- }),
2299
- ...props,
2300
- children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
2301
- /* @__PURE__ */ jsx(MessageFiles, { files }),
2302
- /* @__PURE__ */ jsx(Markdown, { remarkPlugins, theme, children: question }),
2303
- isLong && !expanded && /* @__PURE__ */ jsx(
2304
- Button,
2305
- {
2306
- variant: "link",
2307
- size: "small",
2308
- className: theme.messages.message.expand,
2309
- onClick: () => setExpanded(true),
2310
- children: "Show more"
2311
- }
2312
- )
2313
- ] })
2314
- }
2315
- );
2316
- }
2317
- );
2318
- MessageQuestion.displayName = "MessageQuestion";
2319
- const MessageResponse = memo(
2320
- ({ response, isLoading, children }) => {
2321
- const { theme, isCompact, remarkPlugins } = useContext(ChatContext);
2322
- const Comp = children ? Slot : "div";
2323
- return /* @__PURE__ */ jsx(
2324
- Comp,
2325
- {
2326
- "data-compact": isCompact,
2327
- className: cn(theme.messages.message.response),
2328
- children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
2329
- /* @__PURE__ */ jsx(Markdown, { remarkPlugins, theme, children: response }),
2330
- isLoading && /* @__PURE__ */ jsx(
2331
- motion.div,
2332
- {
2333
- className: cn(theme.messages.message.cursor),
2334
- animate: { opacity: [1, 0] },
2335
- transition: {
2336
- duration: 0.7,
2337
- repeat: Infinity,
2338
- repeatType: "reverse"
2339
- }
2340
- }
2341
- )
2342
- ] })
2343
- }
2344
- );
2345
- }
2346
- );
2347
- const MessageSource = ({ title, url, image, limit = 50 }) => {
2348
- const { theme, isCompact } = useContext(ChatContext);
2349
- return /* @__PURE__ */ jsxs(
2350
- "figure",
2351
- {
2352
- className: cn(theme.messages.message.sources.source.base, {
2353
- [theme.messages.message.sources.source.companion]: isCompact
2354
- }),
2355
- onClick: () => {
2356
- if (url) {
2357
- window.open(url, "_blank");
2358
- }
2359
- },
2360
- children: [
2361
- image && /* @__PURE__ */ jsx("img", { src: image, alt: title, className: cn(theme.messages.message.sources.source.image) }),
2362
- (title || url) && /* @__PURE__ */ jsxs("figcaption", { children: [
2363
- title && /* @__PURE__ */ jsx("span", { className: cn(theme.messages.message.sources.source.title), children: /* @__PURE__ */ jsx(Ellipsis, { value: title, limit }) }),
2364
- url && /* @__PURE__ */ jsx("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: cn(theme.messages.message.sources.source.url), children: url })
2365
- ] })
2366
- ]
2367
- }
2368
- );
2369
- };
2370
- const MessageSources = memo(
2371
- ({ sources, children }) => {
2372
- const { theme } = useContext(ChatContext);
2373
- const Comp = children ? Slot : MessageSource;
2374
- if (!sources || sources.length === 0) {
2375
- return null;
2376
- }
2377
- return /* @__PURE__ */ jsx("div", { className: cn(theme.messages.message.sources.base), children: sources.map((source, index) => /* @__PURE__ */ jsx(Comp, { ...source, children }, index)) });
2378
- }
2379
- );
2380
- MessageSources.displayName = "MessageSources";
2381
- 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" }));
2382
- 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" }));
2383
- 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" }));
2384
- const MessageActions = memo(
2385
- ({ children, ...props }) => {
2386
- const { theme } = useContext(ChatContext);
2387
- const {
2388
- question,
2389
- response,
2390
- copyIcon = /* @__PURE__ */ jsx(SvgCopy, {}),
2391
- thumbsUpIcon = /* @__PURE__ */ jsx(SvgThumbsUp, {}),
2392
- thumbsDownIcon = /* @__PURE__ */ jsx(SvgThumbsDown, {}),
2393
- refreshIcon = /* @__PURE__ */ jsx(SvgRefresh, {}),
2394
- onCopy,
2395
- onUpvote,
2396
- onDownvote,
2397
- onRefresh
2398
- } = props;
2399
- const Comp = children ? Slot : "div";
2400
- const handleCopy = useCallback((text) => {
2401
- navigator.clipboard.writeText(text).then(() => {
2402
- console.log("Text copied to clipboard");
2403
- }).catch((err) => {
2404
- console.error("Could not copy text: ", err);
2405
- });
2406
- }, []);
2407
- const handleCopyClick = useCallback(() => {
2408
- if (onCopy) {
2409
- onCopy();
2410
- } else {
2411
- handleCopy(`${question}${response ? `
2412
- ${response}` : ""}`);
2413
- }
2414
- }, [onCopy, handleCopy, question, response]);
2415
- return (copyIcon || thumbsDownIcon || thumbsUpIcon || refreshIcon) && /* @__PURE__ */ jsx(Comp, { className: cn(theme.messages.message.footer.base), children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
2416
- copyIcon && /* @__PURE__ */ jsx(
2417
- IconButton,
2418
- {
2419
- variant: "text",
2420
- disablePadding: true,
2421
- title: "Copy question and response",
2422
- className: cn(theme.messages.message.footer.copy),
2423
- onClick: handleCopyClick,
2424
- children: copyIcon
2425
- }
2426
- ),
2427
- thumbsUpIcon && /* @__PURE__ */ jsx(
2428
- IconButton,
2429
- {
2430
- variant: "text",
2431
- disablePadding: true,
2432
- title: "Upvote",
2433
- className: cn(theme.messages.message.footer.upvote),
2434
- onClick: onUpvote,
2435
- children: thumbsUpIcon
2436
- }
2437
- ),
2438
- thumbsDownIcon && /* @__PURE__ */ jsx(
2439
- IconButton,
2440
- {
2441
- variant: "text",
2442
- disablePadding: true,
2443
- title: "Downvote",
2444
- className: cn(theme.messages.message.footer.downvote),
2445
- onClick: onDownvote,
2446
- children: thumbsDownIcon
2447
- }
2448
- ),
2449
- refreshIcon && /* @__PURE__ */ jsx(
2450
- IconButton,
2451
- {
2452
- variant: "text",
2453
- disablePadding: true,
2454
- title: "Refresh",
2455
- className: cn(theme.messages.message.footer.refresh),
2456
- onClick: onRefresh,
2457
- children: refreshIcon
2458
- }
2459
- )
2460
- ] }) });
2461
- }
2462
- );
2463
- MessageActions.displayName = "MessageActions";
2464
- const messageVariants = {
2465
- hidden: {
2466
- opacity: 0,
2467
- y: 20
2468
- },
2469
- visible: {
2470
- opacity: 1,
2471
- y: 0,
2472
- transition: {
2473
- duration: 0.3
2474
- }
2475
- }
2476
- };
2477
- const SessionMessage = memo(
2478
- ({ conversation, isLast, children, className }) => {
2479
- const { theme, isLoading } = useContext(ChatContext);
2480
- return /* @__PURE__ */ jsx(motion.div, { variants: messageVariants, children: /* @__PURE__ */ jsx(Card, { className: cn(theme.messages.message.base, className), children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
2481
- /* @__PURE__ */ jsx(
2482
- MessageQuestion,
2483
- {
2484
- question: conversation.question,
2485
- files: conversation.files
2486
- }
2487
- ),
2488
- /* @__PURE__ */ jsx(
2489
- MessageResponse,
2490
- {
2491
- response: conversation.response,
2492
- isLoading: isLast && isLoading
2493
- }
2494
- ),
2495
- /* @__PURE__ */ jsx(MessageSources, { sources: conversation.sources }),
2496
- /* @__PURE__ */ jsx(
2497
- MessageActions,
2498
- {
2499
- question: conversation.question,
2500
- response: conversation.response
2501
- }
2502
- )
2503
- ] }) }) }, conversation.id);
2504
- }
2505
- );
2506
- SessionMessage.displayName = "SessionMessage";
2507
- 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" }));
2508
- const containerVariants = {
2509
- hidden: {},
2510
- visible: {
2511
- transition: {
2512
- staggerChildren: 0.07,
2513
- when: "beforeChildren"
2514
- }
2515
- }
2516
- };
2517
- const SessionMessages = ({
2518
- children,
2519
- newSessionContent,
2520
- limit = 10,
2521
- className,
2522
- showMoreText = "Show more",
2523
- autoScroll = true,
2524
- showLoadMoreButton = false,
2525
- showScrollBottomButton,
2526
- loadMoreButtonDisabled,
2527
- onScroll,
2528
- onLoadMore
2529
- }) => {
2530
- const { activeSession, theme } = useContext(ChatContext);
2531
- const contentRef = useRef(null);
2532
- const messagesRef = useRef(null);
2533
- const [isAnimating, setIsAnimating] = useState(true);
2534
- const [iAtBottom, setIsAtBottom] = useState(true);
2535
- useEffect(() => {
2536
- if (!contentRef.current || !showScrollBottomButton) {
2537
- return;
2538
- }
2539
- const handleScroll = debounce(() => {
2540
- if (contentRef.current) {
2541
- setIsAtBottom(
2542
- contentRef.current.scrollHeight - contentRef.current.clientHeight === contentRef.current.scrollTop
2543
- );
2544
- }
2545
- }, 50);
2546
- const currentRef = contentRef.current;
2547
- currentRef.addEventListener("scroll", handleScroll);
2548
- return () => currentRef.removeEventListener("scroll", handleScroll);
2549
- }, [showScrollBottomButton]);
2550
- useEffect(() => {
2551
- if (contentRef.current && autoScroll) {
2552
- requestAnimationFrame(
2553
- () => contentRef.current.scrollTop = contentRef.current.scrollHeight
2554
- );
2555
- }
2556
- }, [activeSession, autoScroll, isAnimating]);
2557
- const handleShowMore = () => {
2558
- showNext(limit);
2559
- requestAnimationFrame(() => contentRef.current.scrollTop = 0);
2560
- };
2561
- const handleScrollToBottom = () => {
2562
- if (contentRef.current) {
2563
- contentRef.current.scrollTo({
2564
- top: contentRef.current.scrollHeight,
2565
- behavior: "smooth"
2566
- });
2567
- }
2568
- };
2569
- const reversedConvos = useMemo(
2570
- () => [...activeSession?.conversations ?? []].reverse(),
2571
- [activeSession]
2572
- );
2573
- const { data, hasMore, showNext } = useInfinityList({
2574
- items: reversedConvos,
2575
- size: limit
2576
- });
2577
- const reReversedConvo = useMemo(() => [...data].reverse(), [data]);
2578
- const convosToRender = limit ? reReversedConvo : activeSession?.conversations;
2579
- if (!activeSession) {
2580
- return /* @__PURE__ */ jsx(SessionEmpty, { children: newSessionContent });
2581
- }
2582
- return /* @__PURE__ */ jsxs("div", { className: cn("relative flex-1 overflow-y-hidden", className), children: [
2583
- /* @__PURE__ */ jsxs(
2584
- "div",
2585
- {
2586
- className: cn(theme.messages.content, className, "h-full"),
2587
- ref: contentRef,
2588
- id: activeSession?.id,
2589
- onScrollCapture: onScroll,
2590
- children: [
2591
- (showLoadMoreButton || hasMore) && /* @__PURE__ */ jsx(
2592
- Button,
2593
- {
2594
- disabled: loadMoreButtonDisabled,
2595
- variant: "outline",
2596
- className: cn(theme.messages.showMore),
2597
- fullWidth: true,
2598
- onClick: onLoadMore ?? handleShowMore,
2599
- children: showMoreText
2600
- }
2601
- ),
2602
- /* @__PURE__ */ jsx(AnimatePresence, { children: /* @__PURE__ */ jsx(
2603
- motion.div,
2604
- {
2605
- ref: messagesRef,
2606
- variants: containerVariants,
2607
- initial: "hidden",
2608
- animate: "visible",
2609
- onAnimationComplete: () => requestAnimationFrame(() => {
2610
- setIsAnimating(false);
2611
- if (contentRef.current && autoScroll) {
2612
- contentRef.current.scrollTop = contentRef.current.scrollHeight;
2613
- }
2614
- }),
2615
- children: children ? children(convosToRender) : convosToRender.map((conversation, index) => /* @__PURE__ */ jsx(
2616
- SessionMessage,
2617
- {
2618
- conversation,
2619
- isLast: index === convosToRender.length - 1
2620
- },
2621
- conversation.id
2622
- ))
2623
- },
2624
- activeSession?.id
2625
- ) })
2626
- ]
2627
- }
2628
- ),
2629
- /* @__PURE__ */ jsx(AnimatePresence, { children: !iAtBottom && showScrollBottomButton && /* @__PURE__ */ jsx(
2630
- motion.div,
2631
- {
2632
- initial: { y: 100, opacity: 0 },
2633
- animate: { y: 0, opacity: 1 },
2634
- exit: { y: 100, opacity: 0 },
2635
- transition: { duration: 0.3, ease: "easeOut" },
2636
- className: theme.messages?.message?.scrollToBottom?.container,
2637
- children: /* @__PURE__ */ jsx(
2638
- IconButton,
2639
- {
2640
- onClick: handleScrollToBottom,
2641
- className: theme.messages?.message?.scrollToBottom?.button,
2642
- size: "small",
2643
- children: /* @__PURE__ */ jsx(SvgArrowDown, {})
2644
- }
2645
- )
2646
- }
2647
- ) })
2648
- ] });
2649
- };
2650
- const useDimensions = () => {
2651
- const [ref, setRef] = useState(null);
2652
- const [width, setWidth] = useState(void 0);
2653
- const rafId = useRef(null);
2654
- const observe = useCallback((element) => {
2655
- if (element) setRef(element);
2656
- }, []);
2657
- useEffect(() => {
2658
- if (!ref) return;
2659
- const resizeObserver = new ResizeObserver((entries) => {
2660
- if (rafId.current !== null) {
2661
- cancelAnimationFrame(rafId.current);
2662
- }
2663
- rafId.current = requestAnimationFrame(() => {
2664
- for (const entry of entries) {
2665
- setWidth(entry.contentRect.width);
2666
- }
2667
- rafId.current = null;
2668
- });
2669
- });
2670
- resizeObserver.observe(ref);
2671
- return () => {
2672
- if (rafId.current !== null) {
2673
- cancelAnimationFrame(rafId.current);
2674
- rafId.current = null;
2675
- }
2676
- resizeObserver.disconnect();
2677
- };
2678
- }, [ref]);
2679
- return { width, observe };
2680
- };
2681
- const defaultRemarkPlugins = [remarkGfm, remarkYoutube, remarkMath];
2682
- const Chat = ({
2683
- children,
2684
- viewType = "console",
2685
- sessions,
2686
- onSelectSession,
2687
- onDeleteSession,
2688
- onSendMessage,
2689
- onStopMessage,
2690
- onFileUpload,
2691
- isLoading,
2692
- activeSessionId,
2693
- theme: customTheme = chatTheme,
2694
- onNewSession,
2695
- remarkPlugins = defaultRemarkPlugins,
2696
- markdownComponents,
2697
- components: componentCatalog2,
2698
- disabled,
2699
- style,
2700
- className
2701
- }) => {
2702
- const theme = useComponentTheme("chat", customTheme);
2703
- const [internalActiveSessionID, setInternalActiveSessionID] = useState(activeSessionId);
2704
- const { width, observe } = useDimensions();
2705
- const isCompact = viewType === "companion" || width && width < 767;
2706
- useEffect(() => {
2707
- setInternalActiveSessionID(activeSessionId);
2708
- }, [activeSessionId]);
2709
- const handleSelectSession = useCallback(
2710
- (sessionId) => {
2711
- setInternalActiveSessionID(sessionId);
2712
- onSelectSession?.(sessionId);
2713
- },
2714
- [onSelectSession]
2715
- );
2716
- const handleDeleteSession = useCallback(
2717
- (sessionId) => {
2718
- setInternalActiveSessionID(void 0);
2719
- onDeleteSession?.(sessionId);
2720
- },
2721
- [onDeleteSession]
2722
- );
2723
- const handleCreateNewSession = useCallback(() => {
2724
- setInternalActiveSessionID(void 0);
2725
- onNewSession?.();
2726
- }, [onNewSession]);
2727
- useHotkeys([
2728
- {
2729
- name: "Create new session",
2730
- category: "Chat",
2731
- keys: "meta+shift+s",
2732
- callback: (event) => {
2733
- event.preventDefault();
2734
- handleCreateNewSession();
2735
- }
2736
- }
2737
- ]);
2738
- const activeSession = useMemo(
2739
- () => sessions.find((session) => session.id === internalActiveSessionID),
2740
- [sessions, internalActiveSessionID]
2741
- );
2742
- const mergedRemarkPlugins = useMemo(() => {
2743
- if (!componentCatalog2) return remarkPlugins;
2744
- return [...remarkPlugins, componentCatalog2.remarkPlugin];
2745
- }, [remarkPlugins, componentCatalog2]);
2746
- const mergedMarkdownComponents = useMemo(() => {
2747
- if (!componentCatalog2) return markdownComponents;
2748
- return {
2749
- ...componentCatalog2.components,
2750
- ...markdownComponents
2751
- };
2752
- }, [markdownComponents, componentCatalog2]);
2753
- const contextValue = useMemo(
2754
- () => ({
2755
- sessions,
2756
- activeSession,
2757
- remarkPlugins: mergedRemarkPlugins,
2758
- markdownComponents: mergedMarkdownComponents,
2759
- theme,
2760
- disabled,
2761
- isLoading,
2762
- isCompact,
2763
- viewType,
2764
- activeSessionId: internalActiveSessionID,
2765
- selectSession: handleSelectSession,
2766
- deleteSession: handleDeleteSession,
2767
- createSession: handleCreateNewSession,
2768
- sendMessage: onSendMessage,
2769
- stopMessage: onStopMessage,
2770
- fileUpload: onFileUpload
2771
- }),
2772
- [
2773
- isLoading,
2774
- isCompact,
2775
- viewType,
2776
- disabled,
2777
- theme,
2778
- mergedRemarkPlugins,
2779
- mergedMarkdownComponents,
2780
- sessions,
2781
- activeSession,
2782
- internalActiveSessionID,
2783
- handleSelectSession,
2784
- handleDeleteSession,
2785
- handleCreateNewSession,
2786
- onSendMessage,
2787
- onStopMessage,
2788
- onFileUpload
2789
- ]
2790
- );
2791
- return /* @__PURE__ */ jsx(ChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: /* @__PURE__ */ jsx(
2792
- "div",
2793
- {
2794
- ref: observe,
2795
- className: cn(className, theme.base, {
2796
- [theme.companion]: isCompact,
2797
- [theme.console]: !isCompact
2798
- }),
2799
- style,
2800
- children
2801
- }
2802
- ) }) });
2803
- };
2804
- 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" })));
2805
- 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" }));
2806
- const SessionListItem = memo(
2807
- ({
2808
- children,
2809
- session,
2810
- deletable = true,
2811
- limit = 100,
2812
- deleteIcon = /* @__PURE__ */ jsx(SvgTrash, {}),
2813
- chatIcon = /* @__PURE__ */ jsx(SvgChat, { className: "mr-2" })
2814
- }) => {
2815
- const { activeSessionId, selectSession, deleteSession, theme } = useContext(ChatContext);
2816
- const Comp = children ? Slot : ListItem;
2817
- const handleSelect = useCallback(() => {
2818
- selectSession?.(session.id);
2819
- }, [selectSession, session.id]);
2820
- const handleDelete = useCallback(
2821
- (e) => {
2822
- e.stopPropagation();
2823
- deleteSession(session.id);
2824
- },
2825
- [deleteSession, session.id]
2826
- );
2827
- return /* @__PURE__ */ jsx(
2828
- Comp,
2829
- {
2830
- dense: true,
2831
- disableGutters: true,
2832
- active: session.id === activeSessionId,
2833
- className: cn(theme.sessions.session.base, {
2834
- [theme.sessions.session.active]: session.id === activeSessionId
2835
- }),
2836
- onClick: handleSelect,
2837
- start: chatIcon,
2838
- end: /* @__PURE__ */ jsx(Fragment, { children: deletable && /* @__PURE__ */ jsx(
2839
- IconButton,
2840
- {
2841
- size: "small",
2842
- variant: "text",
2843
- onClick: handleDelete,
2844
- className: cn(theme.sessions.session.delete),
2845
- children: deleteIcon
2846
- }
2847
- ) }),
2848
- children: children || /* @__PURE__ */ jsx(Ellipsis, { value: session.title, limit })
2849
- }
2850
- );
2851
- }
2852
- );
2853
- SessionListItem.displayName = "SessionListItem";
2854
- const SessionsList = ({
2855
- children,
2856
- templates
2857
- }) => {
2858
- const { theme, isCompact, activeSessionId, createSession } = useContext(ChatContext);
2859
- const isVisible = isCompact && !activeSessionId;
2860
- return (!isCompact || isVisible) && /* @__PURE__ */ jsxs(
2861
- motion.div,
2862
- {
2863
- initial: { translateX: "-100%" },
2864
- animate: {
2865
- translateX: "0%",
2866
- transition: {
2867
- type: "tween",
2868
- ease: "linear",
2869
- duration: 0.2,
2870
- when: "beforeChildren"
2871
- }
2872
- },
2873
- exit: { translateX: "-100%" },
2874
- className: cn(theme.sessions.base, {
2875
- [theme.sessions.companion]: isCompact,
2876
- [theme.sessions.console]: !isCompact
2877
- }),
2878
- children: [
2879
- /* @__PURE__ */ jsx(List, { children }),
2880
- templates && !activeSessionId && /* @__PURE__ */ jsx("div", { className: "mt-4", children: templates.map((template) => /* @__PURE__ */ jsx("div", { onClick: () => createSession?.(), children: /* @__PURE__ */ jsx(
2881
- SessionListItem,
2882
- {
2883
- session: {
2884
- id: template.id,
2885
- title: template.title,
2886
- conversations: []
2887
- },
2888
- chatIcon: template.icon,
2889
- deletable: false
2890
- }
2891
- ) }, template.id)) })
2892
- ]
2893
- }
2894
- );
2895
- };
2896
- const SvgPlus = (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: "add" }, /* @__PURE__ */ React.createElement("path", { id: "Vector", d: "M13.1667 9.16658H9.16671V13.1666H7.83337V9.16658H3.83337V7.83325H7.83337V3.83325H9.16671V7.83325H13.1667V9.16658Z", fill: "currentColor" })));
2897
- const NewSessionButton = ({
2898
- children,
2899
- newSessionText = "New Session"
2900
- }) => {
2901
- const { theme, createSession, disabled } = useContext(ChatContext);
2902
- const Comp = children ? Slot : Button;
2903
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
2904
- Comp,
2905
- {
2906
- fullWidth: true,
2907
- disableMargins: true,
2908
- color: "primary",
2909
- start: /* @__PURE__ */ jsx(SvgPlus, {}),
2910
- className: cn(theme.sessions.create),
2911
- disabled,
2912
- onClick: createSession,
2913
- children: children || newSessionText
2914
- }
2915
- ) });
2916
- };
2917
- const sortOrder = [
2918
- "Today",
2919
- "Yesterday",
2920
- "Last Week",
2921
- "Last Month",
2922
- "January",
2923
- "February",
2924
- "March",
2925
- "April",
2926
- "May",
2927
- "June",
2928
- "July",
2929
- "August",
2930
- "September",
2931
- "October",
2932
- "November",
2933
- "December",
2934
- "Last Year"
2935
- ];
2936
- const sortOrderMap = new Map(sortOrder.map((v, i) => [v, i]));
2937
- function groupSessionsByDate(sessions) {
2938
- const grouped = {};
2939
- const now = /* @__PURE__ */ new Date();
2940
- sessions.forEach((session) => {
2941
- const createdAt = session.createdAt ? new Date(session.createdAt) : null;
2942
- let group;
2943
- if (!createdAt || isNaN(createdAt.getTime())) {
2944
- group = "Last Year";
2945
- } else if (isToday(createdAt)) {
2946
- group = "Today";
2947
- } else if (isYesterday(createdAt)) {
2948
- group = "Yesterday";
2949
- } else if (isThisWeek(createdAt)) {
2950
- group = "Last Week";
2951
- } else if (differenceInYears(now, createdAt) === 0) {
2952
- const monthDiff = now.getMonth() - createdAt.getMonth();
2953
- const yearDiff = now.getFullYear() - createdAt.getFullYear();
2954
- const adjustedMonthDiff = yearDiff > 0 ? monthDiff + 12 : monthDiff;
2955
- if (adjustedMonthDiff === 1 || adjustedMonthDiff === 0 && now.getDate() > createdAt.getDate()) {
2956
- group = "Last Month";
2957
- } else {
2958
- group = format(createdAt, "MMMM");
2959
- }
2960
- } else {
2961
- group = "Last Year";
2962
- }
2963
- if (!grouped[group]) grouped[group] = [];
2964
- grouped[group].push(session);
2965
- });
2966
- const sortedGroups = Object.keys(grouped).sort(
2967
- (a, b) => (sortOrderMap.get(a) ?? 999) - (sortOrderMap.get(b) ?? 999)
2968
- );
2969
- return sortedGroups.map((heading) => ({
2970
- heading,
2971
- sessions: grouped[heading].sort(
2972
- (a, b) => (b.createdAt ? new Date(b.createdAt).getTime() : 0) - (a.createdAt ? new Date(a.createdAt).getTime() : 0)
2973
- )
2974
- }));
2975
- }
2976
- const SessionsGroup = ({
2977
- heading,
2978
- children
2979
- }) => {
2980
- const { theme } = useContext(ChatContext);
2981
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2982
- heading && /* @__PURE__ */ jsx(
2983
- ListItem,
2984
- {
2985
- disableGutters: true,
2986
- disablePadding: true,
2987
- className: cn(theme.sessions.group),
2988
- children: heading
2989
- }
2990
- ),
2991
- children
2992
- ] });
2993
- };
2994
- const SessionGroups = ({ children }) => {
2995
- const { sessions } = useContext(ChatContext);
2996
- const groups = useMemo(() => groupSessionsByDate(sessions), [sessions]);
2997
- return /* @__PURE__ */ jsx(Fragment, { children: children ? children(groups) : groups.map(({ heading, sessions: sessions2 }) => /* @__PURE__ */ jsx(SessionsGroup, { heading, children: sessions2.map((session) => /* @__PURE__ */ jsx(SessionListItem, { session }, session.id)) }, heading)) });
2998
- };
2999
- const AppBar = ({
3000
- content,
3001
- theme: customTheme = chatTheme
3002
- }) => {
3003
- const theme = useComponentTheme("chat", customTheme);
3004
- return /* @__PURE__ */ jsx("div", { className: cn(theme.appbar), children: content });
3005
- };
3006
- const DEFAULT_MODIFIERS = [offset({ mainAxis: 0, crossAxis: -40 })];
3007
- const ChatBubble = memo(
3008
- ({
3009
- children,
3010
- bubbleContent,
3011
- position = "right-end",
3012
- modifiers = DEFAULT_MODIFIERS,
3013
- className
3014
- }) => {
3015
- const [isOpen, setIsOpen] = useState(false);
3016
- const ref = useRef(null);
3017
- const handleOpen = useCallback(() => setIsOpen(true), []);
3018
- const handleClose = useCallback(() => setIsOpen(false), []);
3019
- const handleToggle = useCallback(() => setIsOpen((prev) => !prev), []);
3020
- const renderContent = useCallback(() => /* @__PURE__ */ jsx(Fragment, { children }), [children]);
3021
- return /* @__PURE__ */ jsxs(Fragment, { children: [
3022
- /* @__PURE__ */ jsx(
3023
- ConnectedOverlay,
3024
- {
3025
- placement: position,
3026
- modifiers,
3027
- reference: ref.current,
3028
- open: isOpen,
3029
- onOpen: handleOpen,
3030
- onClose: handleClose,
3031
- content: renderContent
3032
- }
3033
- ),
3034
- /* @__PURE__ */ jsx("div", { ref, className, onClick: handleToggle, children: bubbleContent })
3035
- ] });
3036
- }
3037
- );
3038
- const ChatSuggestion = ({
3039
- content,
3040
- onClick
3041
- }) => {
3042
- const { theme, disabled, isLoading } = useContext(ChatContext);
3043
- const handleClick = () => {
3044
- if (disabled || isLoading) return;
3045
- onClick?.(content);
3046
- };
3047
- return /* @__PURE__ */ jsx(
3048
- Button,
3049
- {
3050
- type: "button",
3051
- variant: "outline",
3052
- disableMargins: true,
3053
- className: cn(theme.suggestions.item.base, {
3054
- "opacity-50 cursor-not-allowed": disabled || isLoading
3055
- }),
3056
- onClick: handleClick,
3057
- disabled: disabled || isLoading,
3058
- children: /* @__PURE__ */ jsx("span", { className: cn(theme.suggestions.item.text), children: content })
3059
- }
3060
- );
3061
- };
3062
- const ChatSuggestions = ({
3063
- suggestions,
3064
- className,
3065
- onSuggestionClick,
3066
- children
3067
- }) => {
3068
- const { theme } = useContext(ChatContext);
3069
- if (!suggestions || suggestions.length === 0) {
3070
- return null;
3071
- }
3072
- return /* @__PURE__ */ jsx("div", { className: cn(theme.suggestions.base, className), children: suggestions.map((suggestion) => {
3073
- if (children && isValidElement(children)) {
3074
- return cloneElement(children, {
3075
- key: suggestion.id,
3076
- ...suggestion,
3077
- onClick: onSuggestionClick
3078
- });
3079
- }
3080
- return /* @__PURE__ */ jsx(
3081
- ChatSuggestion,
3082
- {
3083
- ...suggestion,
3084
- onClick: onSuggestionClick
3085
- },
3086
- suggestion.id
3087
- );
3088
- }) });
3089
- };
3090
- const SvgSpinner = (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: 2, strokeLinecap: "round", strokeLinejoin: "round", ...props }, /* @__PURE__ */ React.createElement("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }));
3091
- const SvgCheck = (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: 2, strokeLinecap: "round", strokeLinejoin: "round", ...props }, /* @__PURE__ */ React.createElement("polyline", { points: "20 6 9 17 4 12" }));
3092
- const SvgError = (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: 2, strokeLinecap: "round", strokeLinejoin: "round", ...props }, /* @__PURE__ */ React.createElement("circle", { cx: 12, cy: 12, r: 10 }), /* @__PURE__ */ React.createElement("line", { x1: 15, y1: 9, x2: 9, y2: 15 }), /* @__PURE__ */ React.createElement("line", { x1: 9, y1: 9, x2: 15, y2: 15 }));
3093
- const StatusIcon = ({
3094
- state,
3095
- className,
3096
- colorClassName
3097
- }) => {
3098
- switch (state) {
3099
- case "loading":
3100
- return /* @__PURE__ */ jsx(
3101
- motion.div,
3102
- {
3103
- animate: { rotate: 360 },
3104
- transition: { duration: 1, repeat: Infinity, ease: "linear" },
3105
- className: cn(className, colorClassName),
3106
- children: /* @__PURE__ */ jsx(SvgSpinner, { className: "w-full h-full" })
3107
- }
3108
- );
3109
- case "complete":
3110
- return /* @__PURE__ */ jsx(
3111
- motion.div,
3112
- {
3113
- initial: { scale: 0, opacity: 0 },
3114
- animate: { scale: 1, opacity: 1 },
3115
- transition: { type: "spring", stiffness: 500, damping: 25 },
3116
- className: cn(className, colorClassName),
3117
- children: /* @__PURE__ */ jsx(SvgCheck, { className: "w-full h-full" })
3118
- }
3119
- );
3120
- case "error":
3121
- return /* @__PURE__ */ jsx(
3122
- motion.div,
3123
- {
3124
- initial: { scale: 0, opacity: 0 },
3125
- animate: { scale: 1, opacity: 1 },
3126
- transition: { type: "spring", stiffness: 500, damping: 25 },
3127
- className: cn(className, colorClassName),
3128
- children: /* @__PURE__ */ jsx(SvgError, { className: "w-full h-full" })
3129
- }
3130
- );
3131
- }
3132
- };
3133
- const MessageStatusItem = ({ step }) => {
3134
- const { theme: chatTheme$1 } = useContext(ChatContext);
3135
- const theme = (chatTheme$1 ?? chatTheme).status.steps.step;
3136
- const stepStatus = step.status || "loading";
3137
- return /* @__PURE__ */ jsxs(
3138
- motion.div,
3139
- {
3140
- initial: { opacity: 0, x: -10 },
3141
- animate: { opacity: 1, x: 0 },
3142
- transition: { duration: 0.2 },
3143
- className: theme.base,
3144
- children: [
3145
- /* @__PURE__ */ jsx(
3146
- StatusIcon,
3147
- {
3148
- state: stepStatus,
3149
- className: theme.icon,
3150
- colorClassName: theme[stepStatus]
3151
- }
3152
- ),
3153
- /* @__PURE__ */ jsx(
3154
- "span",
3155
- {
3156
- className: cn(
3157
- theme.text,
3158
- stepStatus === "loading" && theme.loading,
3159
- stepStatus === "complete" && theme.complete,
3160
- stepStatus === "error" && theme.error
3161
- ),
3162
- children: step.text
3163
- }
3164
- )
3165
- ]
3166
- }
3167
- );
3168
- };
3169
- const MessageStatus = ({
3170
- status = "loading",
3171
- text,
3172
- steps,
3173
- icon,
3174
- className,
3175
- children
3176
- }) => {
3177
- const { theme: chatTheme$1 } = useContext(ChatContext);
3178
- const theme = (chatTheme$1 ?? chatTheme).status;
3179
- const Comp = children ? Slot : "div";
3180
- return /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsx(
3181
- motion.div,
3182
- {
3183
- initial: { opacity: 0, y: -10 },
3184
- animate: { opacity: 1, y: 0 },
3185
- exit: { opacity: 0, y: -10 },
3186
- transition: { duration: 0.2 },
3187
- children: /* @__PURE__ */ jsx(Comp, { className: cn(theme.base, className), children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
3188
- /* @__PURE__ */ jsxs("div", { className: theme.header, children: [
3189
- icon || /* @__PURE__ */ jsx(
3190
- StatusIcon,
3191
- {
3192
- state: status,
3193
- className: theme.icon.base,
3194
- colorClassName: theme.icon[status]
3195
- }
3196
- ),
3197
- /* @__PURE__ */ jsx(
3198
- "span",
3199
- {
3200
- className: cn(
3201
- theme.text.base,
3202
- status === "loading" && theme.text.loading,
3203
- status === "complete" && theme.text.complete,
3204
- status === "error" && theme.text.error
3205
- ),
3206
- children: text
3207
- }
3208
- )
3209
- ] }),
3210
- steps && steps.length > 0 && /* @__PURE__ */ jsx("div", { className: theme.steps.base, children: steps.map((step) => /* @__PURE__ */ jsx(MessageStatusItem, { step }, step.id)) })
3211
- ] }) })
3212
- }
3213
- ) });
3214
- };
3215
- var AgUiEventType = /* @__PURE__ */ ((AgUiEventType2) => {
3216
- AgUiEventType2["RUN_STARTED"] = "RUN_STARTED";
3217
- AgUiEventType2["RUN_FINISHED"] = "RUN_FINISHED";
3218
- AgUiEventType2["RUN_ERROR"] = "RUN_ERROR";
3219
- AgUiEventType2["STEP_STARTED"] = "STEP_STARTED";
3220
- AgUiEventType2["STEP_FINISHED"] = "STEP_FINISHED";
3221
- AgUiEventType2["TEXT_MESSAGE_START"] = "TEXT_MESSAGE_START";
3222
- AgUiEventType2["TEXT_MESSAGE_CONTENT"] = "TEXT_MESSAGE_CONTENT";
3223
- AgUiEventType2["TEXT_MESSAGE_END"] = "TEXT_MESSAGE_END";
3224
- AgUiEventType2["TEXT_MESSAGE_CHUNK"] = "TEXT_MESSAGE_CHUNK";
3225
- AgUiEventType2["TOOL_CALL_START"] = "TOOL_CALL_START";
3226
- AgUiEventType2["TOOL_CALL_ARGS"] = "TOOL_CALL_ARGS";
3227
- AgUiEventType2["TOOL_CALL_END"] = "TOOL_CALL_END";
3228
- AgUiEventType2["TOOL_CALL_RESULT"] = "TOOL_CALL_RESULT";
3229
- AgUiEventType2["TOOL_CALL_CHUNK"] = "TOOL_CALL_CHUNK";
3230
- AgUiEventType2["STATE_SNAPSHOT"] = "STATE_SNAPSHOT";
3231
- AgUiEventType2["STATE_DELTA"] = "STATE_DELTA";
3232
- AgUiEventType2["MESSAGES_SNAPSHOT"] = "MESSAGES_SNAPSHOT";
3233
- AgUiEventType2["RAW"] = "RAW";
3234
- AgUiEventType2["CUSTOM"] = "CUSTOM";
3235
- return AgUiEventType2;
3236
- })(AgUiEventType || {});
3237
- function generateId() {
3238
- return Math.random().toString(36).substring(2, 11);
3239
- }
3240
- function addConversationToSession(sessions, sessionId, conversation) {
3241
- return sessions.map((s) => {
3242
- if (s.id !== sessionId) return s;
3243
- return {
3244
- ...s,
3245
- updatedAt: conversation.createdAt,
3246
- conversations: [...s.conversations, conversation]
3247
- };
3248
- });
3249
- }
3250
- function updateConversationInSession(sessions, sessionId, conversationId, response) {
3251
- return sessions.map((s) => {
3252
- if (s.id !== sessionId) return s;
3253
- return {
3254
- ...s,
3255
- updatedAt: /* @__PURE__ */ new Date(),
3256
- conversations: s.conversations.map((c) => {
3257
- if (c.id !== conversationId) return c;
3258
- return { ...c, response, updatedAt: /* @__PURE__ */ new Date() };
3259
- })
3260
- };
3261
- });
3262
- }
3263
- function sessionsToAgUiMessages(session) {
3264
- const messages = [];
3265
- for (const conv of session.conversations) {
3266
- messages.push({
3267
- id: `${conv.id}-q`,
3268
- role: "user",
3269
- content: conv.question
3270
- });
3271
- if (conv.response) {
3272
- messages.push({
3273
- id: `${conv.id}-r`,
3274
- role: "assistant",
3275
- content: conv.response
3276
- });
3277
- }
3278
- }
3279
- return messages;
3280
- }
3281
- function parseSSELine(line) {
3282
- const trimmed = line.trim();
3283
- if (!trimmed || trimmed.startsWith(":")) return null;
3284
- if (trimmed.startsWith("data:")) {
3285
- const data = trimmed.slice(5).trim();
3286
- if (data === "[DONE]") return null;
3287
- try {
3288
- return JSON.parse(data);
3289
- } catch (err) {
3290
- return new Error(
3291
- `Failed to parse AG-UI event: ${err instanceof Error ? err.message : err}`
3292
- );
3293
- }
3294
- }
3295
- return null;
3296
- }
3297
- async function* parseSSE(response, signal) {
3298
- const reader = response.body?.getReader();
3299
- if (!reader) {
3300
- throw new Error("Response body is not readable");
3301
- }
3302
- const decoder = new TextDecoder();
3303
- let buffer = "";
3304
- try {
3305
- while (!signal.aborted) {
3306
- const { done, value } = await reader.read();
3307
- if (done) break;
3308
- buffer += decoder.decode(value, { stream: true });
3309
- const lines = buffer.split("\n");
3310
- buffer = lines.pop() || "";
3311
- for (const line of lines) {
3312
- const result = parseSSELine(line);
3313
- if (result !== null) yield result;
3314
- }
3315
- }
3316
- if (buffer.trim()) {
3317
- const result = parseSSELine(buffer);
3318
- if (result !== null) yield result;
3319
- }
3320
- } finally {
3321
- reader.releaseLock();
3322
- }
3323
- }
3324
- function useAgUi({
3325
- agent,
3326
- initialSessions = [],
3327
- initialActiveSessionId,
3328
- tools = [],
3329
- context = [],
3330
- forwardedProps = {},
3331
- headers = {},
3332
- onToolCall,
3333
- onError,
3334
- onEvent
3335
- }) {
3336
- const [sessions, setSessions] = useState(initialSessions);
3337
- const [activeSessionId, setActiveSessionId] = useState(
3338
- initialActiveSessionId
3339
- );
3340
- const [isLoading, setIsLoading] = useState(false);
3341
- const abortRef = useRef(null);
3342
- const onToolCallRef = useRef(onToolCall);
3343
- onToolCallRef.current = onToolCall;
3344
- const onErrorRef = useRef(onError);
3345
- onErrorRef.current = onError;
3346
- const onEventRef = useRef(onEvent);
3347
- onEventRef.current = onEvent;
3348
- useEffect(() => {
3349
- return () => {
3350
- abortRef.current?.abort();
3351
- };
3352
- }, []);
3353
- const selectSession = useCallback((sessionId) => {
3354
- setActiveSessionId(sessionId);
3355
- }, []);
3356
- const deleteSession = useCallback(
3357
- (sessionId) => {
3358
- setSessions((prev) => prev.filter((s) => s.id !== sessionId));
3359
- if (activeSessionId === sessionId) {
3360
- setActiveSessionId(void 0);
3361
- }
3362
- },
3363
- [activeSessionId]
3364
- );
3365
- const createSession = useCallback(() => {
3366
- const id = generateId();
3367
- const newSession = {
3368
- id,
3369
- title: "New Session",
3370
- createdAt: /* @__PURE__ */ new Date(),
3371
- updatedAt: /* @__PURE__ */ new Date(),
3372
- conversations: []
3373
- };
3374
- setSessions((prev) => [newSession, ...prev]);
3375
- setActiveSessionId(id);
3376
- }, []);
3377
- const stopMessage = useCallback(() => {
3378
- abortRef.current?.abort();
3379
- abortRef.current = null;
3380
- setIsLoading(false);
3381
- }, []);
3382
- const sendMessage = useCallback(
3383
- async (message) => {
3384
- abortRef.current?.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
- ...sessions.find((s) => s.id === sessionId)?.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
- onErrorRef.current?.(eventOrError);
3460
- continue;
3461
- }
3462
- const event = eventOrError;
3463
- onEventRef.current?.(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
- onErrorRef.current?.(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
- onErrorRef.current?.(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
- const { theme, sendMessage } = useContext(ChatContext);
3656
- const result = useMemo(
3657
- () => validateSpec(raw, definitions),
3658
- [raw, definitions]
3659
- );
3660
- if (!result.ok) {
3661
- const error = result.error;
3662
- const custom = options?.onError?.(error);
3663
- if (custom !== void 0) {
3664
- return /* @__PURE__ */ jsx(Fragment, { children: custom });
3665
- }
3666
- return /* @__PURE__ */ jsx(
3667
- ComponentError,
3668
- {
3669
- title: errorTitle(error.type),
3670
- message: error.message,
3671
- code: error.raw
3672
- }
3673
- );
3674
- }
3675
- const specs = result.specs;
3676
- return /* @__PURE__ */ jsx("div", { className: theme.component?.base, children: specs.map((spec, index) => /* @__PURE__ */ jsx(
3677
- SpecRenderer,
3678
- {
3679
- spec,
3680
- definitions,
3681
- options,
3682
- sendMessage
3683
- },
3684
- `${spec.type}-${index}-${stableKey(spec)}`
3685
- )) });
3686
- };
3687
- const SpecRenderer = ({
3688
- spec,
3689
- definitions,
3690
- options,
3691
- sendMessage
3692
- }) => {
3693
- const definition = definitions[spec.type];
3694
- if (!definition) {
3695
- const error = {
3696
- type: "unknown_component",
3697
- message: `Unknown component "${spec.type}"`,
3698
- raw: JSON.stringify(spec),
3699
- componentType: spec.type
3700
- };
3701
- const custom = options?.onError?.(error);
3702
- if (custom !== void 0) {
3703
- return /* @__PURE__ */ jsx(Fragment, { children: custom });
3704
- }
3705
- return /* @__PURE__ */ jsx(ComponentError, { title: errorTitle(error.type), message: error.message });
3706
- }
3707
- const RenderedComponent = definition.component;
3708
- const children = spec.children?.map((child, index) => /* @__PURE__ */ jsx(
3709
- SpecRenderer,
3710
- {
3711
- spec: child,
3712
- definitions,
3713
- options,
3714
- sendMessage
3715
- },
3716
- `${child.type}-${index}-${stableKey(child)}`
3717
- ));
3718
- return /* @__PURE__ */ jsx(SpecErrorBoundary, { spec, options, children: /* @__PURE__ */ jsx(RenderedComponent, { ...spec.props, sendMessage, children }) });
3719
- };
3720
- class SpecErrorBoundary extends Component {
3721
- constructor() {
3722
- super(...arguments);
3723
- this.state = { error: null };
3724
- }
3725
- static getDerivedStateFromError(error) {
3726
- return { error };
3727
- }
3728
- render() {
3729
- if (this.state.error) {
3730
- const { spec, options } = this.props;
3731
- const catalogError = {
3732
- type: "render_error",
3733
- message: `Error rendering "${spec.type}": ${this.state.error.message}`,
3734
- raw: JSON.stringify(spec),
3735
- componentType: spec.type
3736
- };
3737
- const custom = options?.onError?.(catalogError);
3738
- if (custom !== void 0) {
3739
- return /* @__PURE__ */ jsx(Fragment, { children: custom });
3740
- }
3741
- return /* @__PURE__ */ jsx(
3742
- ComponentError,
3743
- {
3744
- title: errorTitle(catalogError.type),
3745
- message: catalogError.message
3746
- }
3747
- );
3748
- }
3749
- return this.props.children;
3750
- }
3751
- }
3752
- function stableKey(spec) {
3753
- const str = JSON.stringify({
3754
- t: spec.type,
3755
- p: spec.props,
3756
- c: spec.children
3757
- });
3758
- let h = 0;
3759
- for (let i = 0; i < str.length; i++) {
3760
- h = h * 31 + str.charCodeAt(i) | 0;
3761
- }
3762
- return (h >>> 0).toString(36);
3763
- }
3764
- function errorTitle(type) {
3765
- switch (type) {
3766
- case "unknown_component":
3767
- return "Unknown Component";
3768
- case "invalid_props":
3769
- return "Invalid Props";
3770
- case "render_error":
3771
- return "Render Error";
3772
- default:
3773
- return "Invalid Component";
3774
- }
3775
- }
3776
- function getChildText(children) {
3777
- if (children === null || children === void 0) {
3778
- return "";
3779
- }
3780
- if (typeof children === "string") {
3781
- return children;
3782
- }
3783
- if (typeof children === "number") {
3784
- return String(children);
3785
- }
3786
- if (Array.isArray(children)) {
3787
- return children.map(getChildText).join("");
3788
- }
3789
- if (typeof children === "object") {
3790
- if ("props" in children && children.props) {
3791
- const element = children;
3792
- return getChildText(element.props.children);
3793
- }
3794
- }
3795
- return "";
3796
- }
3797
- function createComponentPre(definitions, options) {
3798
- const language = options?.language ?? "component";
3799
- const className = `language-${language}`;
3800
- const ComponentPre = ({ children, ...props }) => {
3801
- if (children && typeof children === "object" && "props" in children) {
3802
- const codeElement = children;
3803
- if (codeElement.props?.className === className) {
3804
- const codeContent = getChildText(codeElement.props?.children);
3805
- if (codeContent) {
3806
- return /* @__PURE__ */ jsx(
3807
- ComponentRenderer,
3808
- {
3809
- raw: codeContent,
3810
- definitions,
3811
- options
3812
- }
3813
- );
3814
- }
3815
- }
3816
- }
3817
- return /* @__PURE__ */ jsx("pre", { ...props, children });
3818
- };
3819
- ComponentPre.displayName = "ComponentPre";
3820
- return ComponentPre;
3821
- }
3822
- function describeJsonSchemaProperty(prop, indent = "") {
3823
- const description = prop.description ? ` // ${prop.description}` : "";
3824
- if (prop.anyOf) {
3825
- const nonNull = prop.anyOf.filter((s) => !(s.type === "null"));
3826
- const hasNull = prop.anyOf.some((s) => s.type === "null");
3827
- if (nonNull.length === 1 && hasNull) {
3828
- return `${describeJsonSchemaProperty(nonNull[0], indent)} | null${description}`;
3829
- }
3830
- const parts = prop.anyOf.map(
3831
- (s) => describeJsonSchemaProperty(s, indent)
3832
- );
3833
- return `${parts.join(" | ")}${description}`;
3834
- }
3835
- if (prop.enum) {
3836
- return `${prop.enum.map((v) => `"${v}"`).join(" | ")}${description}`;
3837
- }
3838
- if (prop.type === "array") {
3839
- const items = prop.items ? describeJsonSchemaProperty(prop.items, indent) : "any";
3840
- return `${items}[]${description}`;
3841
- }
3842
- if (prop.type === "object" && prop.properties) {
3843
- const required = new Set(prop.required ?? []);
3844
- const fields = [];
3845
- for (const [key, value] of Object.entries(prop.properties)) {
3846
- const opt = required.has(key) ? "" : "?";
3847
- fields.push(
3848
- `${indent} ${key}: ${describeJsonSchemaProperty(value, indent + " ")}${opt}`
3849
- );
3850
- }
3851
- return `{
3852
- ${fields.join(",\n")}
3853
- ${indent}}${description}`;
3854
- }
3855
- if (prop.type === "string") return `string${description}`;
3856
- if (prop.type === "number" || prop.type === "integer")
3857
- return `number${description}`;
3858
- if (prop.type === "boolean") return `boolean${description}`;
3859
- if (prop.type === "null") return `null${description}`;
3860
- return `any${description}`;
3861
- }
3862
- function describeProps(schema) {
3863
- try {
3864
- const jsonSchema = z.toJSONSchema(schema);
3865
- if (jsonSchema.type === "object" && jsonSchema.properties) {
3866
- return describeJsonSchemaProperty(jsonSchema);
3867
- }
3868
- return "Record<string, any>";
3869
- } catch {
3870
- return "Record<string, any>";
3871
- }
3872
- }
3873
- function generatePrompt(definitions, language = "component") {
3874
- const names = Object.keys(definitions);
3875
- if (names.length === 0) {
3876
- return "";
3877
- }
3878
- const componentDocs = names.map((name) => {
3879
- const def = definitions[name];
3880
- const propsDesc = describeProps(def.props);
3881
- return `- **${name}**: ${def.description}
3882
- Props: ${propsDesc}`;
3883
- }).join("\n\n");
3884
- 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:
3885
-
3886
- \`\`\`${language}
3887
- { "type": "ComponentName", "props": { ... } }
3888
- \`\`\`
3889
-
3890
- For multiple components, use a JSON array:
3891
-
3892
- \`\`\`${language}
3893
- [
3894
- { "type": "ComponentA", "props": { ... } },
3895
- { "type": "ComponentB", "props": { ... } }
3896
- ]
3897
- \`\`\`
3898
-
3899
- For nested/composed layouts, use the "children" field:
3900
-
3901
- \`\`\`${language}
3902
- {
3903
- "type": "Parent",
3904
- "props": { ... },
3905
- "children": [
3906
- { "type": "Child", "props": { ... } }
3907
- ]
3908
- }
3909
- \`\`\`
3910
-
3911
- Available components:
3912
-
3913
- ${componentDocs}`;
3914
- }
3915
- function componentCatalog(definitions, options) {
3916
- const language = options?.language ?? "component";
3917
- const plugin = remarkComponent.bind(void 0, {
3918
- language
3919
- });
3920
- const Pre = createComponentPre(definitions, options);
3921
- return {
3922
- remarkPlugin: plugin,
3923
- components: { pre: Pre },
3924
- systemPrompt: () => generatePrompt(definitions, language),
3925
- definitions
3926
- };
3927
- }
3928
- function createChartComponentDef() {
3929
- const chartPropsSchema = z.object({
3930
- type: z.enum([
3931
- "bar",
3932
- "line",
3933
- "area",
3934
- "pie",
3935
- "radialBar",
3936
- "radialArea",
3937
- "sparkline"
3938
- ]).describe("Chart type"),
3939
- data: z.array(z.object({ key: z.string(), data: z.number() })).describe("Array of { key, data } data points"),
3940
- width: z.number().describe("Chart width in px").optional(),
3941
- height: z.number().describe("Chart height in px").optional(),
3942
- title: z.string().describe("Chart title").optional()
3943
- });
3944
- return {
3945
- description: "Renders a chart. Supported types: bar, line, area, pie, radialBar, radialArea, sparkline",
3946
- props: chartPropsSchema,
3947
- component: ({
3948
- children: _children,
3949
- sendMessage: _sendMessage,
3950
- ...config
3951
- }) => /* @__PURE__ */ jsx(ChartRenderer, { config })
3952
- };
3953
- }
3954
- export {
3955
- remarkCve as $,
3956
- AgUiEventType as A,
3957
- SessionMessages as B,
3958
- ChartRenderer as C,
3959
- SessionMessagesHeader as D,
3960
- SessionsGroup as E,
3961
- FileInput as F,
3962
- SessionsList as G,
3963
- StatusIcon as H,
3964
- TableDataCell as I,
3965
- TableHeaderCell as J,
3966
- bitcoinMatcher as K,
3967
- chatTheme as L,
3968
- Markdown as M,
3969
- NewSessionButton as N,
3970
- commonRedactMatchers as O,
3971
- componentCatalog as P,
3972
- createChartComponentDef as Q,
3973
- RichTextInput as R,
3974
- SvgFile as S,
3975
- TableComponent as T,
3976
- createComponentPre as U,
3977
- creditCardMatcher as V,
3978
- dark as W,
3979
- generatePrompt as X,
3980
- groupSessionsByDate as Y,
3981
- light as Z,
3982
- remarkComponent as _,
3983
- SvgCopy as a,
3984
- remarkRedact as a0,
3985
- ssnMatcher as a1,
3986
- useAgUi as a2,
3987
- validateSpec as a3,
3988
- AppBar as b,
3989
- Chat as c,
3990
- ChatBubble as d,
3991
- ChatContext as e,
3992
- ChatInput as f,
3993
- ChatSuggestion as g,
3994
- ChatSuggestions as h,
3995
- CodeHighlighter as i,
3996
- ComponentError as j,
3997
- ComponentRenderer as k,
3998
- MentionList as l,
3999
- MessageActions as m,
4000
- MessageFile as n,
4001
- MessageFiles as o,
4002
- MessageQuestion as p,
4003
- MessageResponse as q,
4004
- MessageSource as r,
4005
- MessageSources as s,
4006
- MessageStatus as t,
4007
- MessageStatusItem as u,
4008
- SessionEmpty as v,
4009
- SessionGroups as w,
4010
- SessionListItem as x,
4011
- SessionMessage as y,
4012
- SessionMessagePanel as z
4013
- };
4014
- //# sourceMappingURL=index-BiStNXJ4.js.map