@aomi-labs/widget-lib 0.2.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,3780 @@
1
+ "use client";
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __defProps = Object.defineProperties;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
8
+ var __getOwnPropNames = Object.getOwnPropertyNames;
9
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
10
+ var __getProtoOf = Object.getPrototypeOf;
11
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
12
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
13
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
14
+ var __spreadValues = (a, b) => {
15
+ for (var prop in b || (b = {}))
16
+ if (__hasOwnProp.call(b, prop))
17
+ __defNormalProp(a, prop, b[prop]);
18
+ if (__getOwnPropSymbols)
19
+ for (var prop of __getOwnPropSymbols(b)) {
20
+ if (__propIsEnum.call(b, prop))
21
+ __defNormalProp(a, prop, b[prop]);
22
+ }
23
+ return a;
24
+ };
25
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
26
+ var __objRest = (source, exclude) => {
27
+ var target = {};
28
+ for (var prop in source)
29
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
30
+ target[prop] = source[prop];
31
+ if (source != null && __getOwnPropSymbols)
32
+ for (var prop of __getOwnPropSymbols(source)) {
33
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
34
+ target[prop] = source[prop];
35
+ }
36
+ return target;
37
+ };
38
+ var __export = (target, all) => {
39
+ for (var name in all)
40
+ __defProp(target, name, { get: all[name], enumerable: true });
41
+ };
42
+ var __copyProps = (to, from, except, desc) => {
43
+ if (from && typeof from === "object" || typeof from === "function") {
44
+ for (let key of __getOwnPropNames(from))
45
+ if (!__hasOwnProp.call(to, key) && key !== except)
46
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
47
+ }
48
+ return to;
49
+ };
50
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
51
+ // If the importer is in node compatibility mode or this is not an ESM
52
+ // file that has been converted to a CommonJS file using a Babel-
53
+ // compatible transform (i.e. "__esModule" has not been set), then set
54
+ // "default" to the CommonJS "module.exports" for node compatibility.
55
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
56
+ mod
57
+ ));
58
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
59
+
60
+ // src/index.ts
61
+ var index_exports = {};
62
+ __export(index_exports, {
63
+ AomiFrame: () => AomiFrame,
64
+ AomiRuntimeProvider: () => AomiRuntimeProvider,
65
+ Avatar: () => Avatar,
66
+ AvatarFallback: () => AvatarFallback,
67
+ AvatarImage: () => AvatarImage,
68
+ Badge: () => Badge,
69
+ BaseSidebar: () => BaseSidebar,
70
+ Breadcrumb: () => Breadcrumb,
71
+ BreadcrumbEllipsis: () => BreadcrumbEllipsis,
72
+ BreadcrumbItem: () => BreadcrumbItem,
73
+ BreadcrumbLink: () => BreadcrumbLink,
74
+ BreadcrumbList: () => BreadcrumbList,
75
+ BreadcrumbPage: () => BreadcrumbPage,
76
+ BreadcrumbSeparator: () => BreadcrumbSeparator,
77
+ Button: () => Button,
78
+ Card: () => Card,
79
+ CardContent: () => CardContent,
80
+ CardDescription: () => CardDescription,
81
+ CardFooter: () => CardFooter,
82
+ CardHeader: () => CardHeader,
83
+ CardTitle: () => CardTitle,
84
+ ComposerAttachments: () => ComposerAttachments,
85
+ Dialog: () => Dialog,
86
+ DialogClose: () => DialogClose,
87
+ DialogContent: () => DialogContent,
88
+ DialogDescription: () => DialogDescription,
89
+ DialogFooter: () => DialogFooter,
90
+ DialogHeader: () => DialogHeader,
91
+ DialogOverlay: () => DialogOverlay,
92
+ DialogPortal: () => DialogPortal,
93
+ DialogTitle: () => DialogTitle,
94
+ DialogTrigger: () => DialogTrigger,
95
+ Input: () => Input,
96
+ Label: () => Label,
97
+ MarkdownText: () => MarkdownText,
98
+ Separator: () => Separator,
99
+ Sheet: () => Sheet,
100
+ SheetClose: () => SheetClose,
101
+ SheetContent: () => SheetContent,
102
+ SheetDescription: () => SheetDescription,
103
+ SheetFooter: () => SheetFooter,
104
+ SheetHeader: () => SheetHeader,
105
+ SheetTitle: () => SheetTitle,
106
+ SheetTrigger: () => SheetTrigger,
107
+ Sidebar: () => Sidebar,
108
+ SidebarContent: () => SidebarContent,
109
+ SidebarFooter: () => SidebarFooter,
110
+ SidebarGroup: () => SidebarGroup,
111
+ SidebarGroupAction: () => SidebarGroupAction,
112
+ SidebarGroupContent: () => SidebarGroupContent,
113
+ SidebarGroupLabel: () => SidebarGroupLabel,
114
+ SidebarHeader: () => SidebarHeader,
115
+ SidebarInset: () => SidebarInset,
116
+ SidebarMenu: () => SidebarMenu,
117
+ SidebarMenuAction: () => SidebarMenuAction,
118
+ SidebarMenuBadge: () => SidebarMenuBadge,
119
+ SidebarMenuButton: () => SidebarMenuButton,
120
+ SidebarMenuItem: () => SidebarMenuItem,
121
+ SidebarMenuSub: () => SidebarMenuSub,
122
+ SidebarMenuSubButton: () => SidebarMenuSubButton,
123
+ SidebarMenuSubItem: () => SidebarMenuSubItem,
124
+ SidebarProvider: () => SidebarProvider,
125
+ SidebarRail: () => SidebarRail,
126
+ SidebarSeparator: () => SidebarSeparator,
127
+ SidebarTrigger: () => SidebarTrigger,
128
+ Skeleton: () => Skeleton,
129
+ Thread: () => Thread,
130
+ ThreadContextProvider: () => ThreadContextProvider,
131
+ ThreadList: () => ThreadList,
132
+ ThreadListSidebar: () => ThreadListSidebar,
133
+ ToolFallback: () => ToolFallback,
134
+ Tooltip: () => Tooltip,
135
+ TooltipContent: () => TooltipContent,
136
+ TooltipIconButton: () => TooltipIconButton,
137
+ TooltipProvider: () => TooltipProvider,
138
+ TooltipTrigger: () => TooltipTrigger,
139
+ UserMessageAttachments: () => UserMessageAttachments,
140
+ badgeVariants: () => badgeVariants,
141
+ buttonVariants: () => buttonVariants,
142
+ cn: () => cn,
143
+ formatAddress: () => formatAddress,
144
+ getNetworkName: () => getNetworkName,
145
+ useIsMobile: () => useIsMobile,
146
+ useRuntimeActions: () => useRuntimeActions,
147
+ useSidebar: () => useSidebar,
148
+ useThreadContext: () => useThreadContext
149
+ });
150
+ module.exports = __toCommonJS(index_exports);
151
+
152
+ // src/components/aomi-frame.tsx
153
+ var import_react15 = require("react");
154
+
155
+ // src/components/assistant-ui/thread.tsx
156
+ var import_lucide_react5 = require("lucide-react");
157
+ var import_react7 = require("@assistant-ui/react");
158
+ var import_react8 = require("react");
159
+ var import_react9 = require("motion/react");
160
+ var m = __toESM(require("motion/react-m"), 1);
161
+
162
+ // src/components/ui/button.tsx
163
+ var import_react_slot = require("@radix-ui/react-slot");
164
+ var import_class_variance_authority = require("class-variance-authority");
165
+
166
+ // src/lib/utils.ts
167
+ var import_clsx = require("clsx");
168
+ var import_tailwind_merge = require("tailwind-merge");
169
+ function cn(...inputs) {
170
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
171
+ }
172
+
173
+ // src/components/ui/button.tsx
174
+ var import_jsx_runtime = require("react/jsx-runtime");
175
+ var buttonVariants = (0, import_class_variance_authority.cva)(
176
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
177
+ {
178
+ variants: {
179
+ variant: {
180
+ default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
181
+ destructive: "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
182
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
183
+ secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
184
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
185
+ link: "text-primary underline-offset-4 hover:underline"
186
+ },
187
+ size: {
188
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
189
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
190
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
191
+ icon: "size-9"
192
+ }
193
+ },
194
+ defaultVariants: {
195
+ variant: "default",
196
+ size: "default"
197
+ }
198
+ }
199
+ );
200
+ function Button(_a) {
201
+ var _b = _a, {
202
+ className,
203
+ variant,
204
+ size,
205
+ asChild = false
206
+ } = _b, props = __objRest(_b, [
207
+ "className",
208
+ "variant",
209
+ "size",
210
+ "asChild"
211
+ ]);
212
+ const Comp = asChild ? import_react_slot.Slot : "button";
213
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
214
+ Comp,
215
+ __spreadValues({
216
+ "data-slot": "button",
217
+ className: cn(buttonVariants({ variant, size, className }))
218
+ }, props)
219
+ );
220
+ }
221
+
222
+ // src/components/assistant-ui/markdown-text.tsx
223
+ var import_dot = require("@assistant-ui/react-markdown/styles/dot.css");
224
+ var import_react_markdown = require("@assistant-ui/react-markdown");
225
+ var import_remark_gfm = __toESM(require("remark-gfm"), 1);
226
+ var import_react2 = require("react");
227
+ var import_lucide_react = require("lucide-react");
228
+
229
+ // src/components/assistant-ui/tooltip-icon-button.tsx
230
+ var import_react = require("react");
231
+ var import_react_slot2 = require("@radix-ui/react-slot");
232
+
233
+ // src/components/ui/tooltip.tsx
234
+ var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"), 1);
235
+ var import_jsx_runtime2 = require("react/jsx-runtime");
236
+ function TooltipProvider(_a) {
237
+ var _b = _a, {
238
+ delayDuration = 0
239
+ } = _b, props = __objRest(_b, [
240
+ "delayDuration"
241
+ ]);
242
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
243
+ TooltipPrimitive.Provider,
244
+ __spreadValues({
245
+ "data-slot": "tooltip-provider",
246
+ delayDuration
247
+ }, props)
248
+ );
249
+ }
250
+ function Tooltip(_a) {
251
+ var props = __objRest(_a, []);
252
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TooltipPrimitive.Root, __spreadValues({ "data-slot": "tooltip" }, props)) });
253
+ }
254
+ function TooltipTrigger(_a) {
255
+ var props = __objRest(_a, []);
256
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TooltipPrimitive.Trigger, __spreadValues({ "data-slot": "tooltip-trigger" }, props));
257
+ }
258
+ function TooltipContent(_a) {
259
+ var _b = _a, {
260
+ className,
261
+ sideOffset = 0,
262
+ children
263
+ } = _b, props = __objRest(_b, [
264
+ "className",
265
+ "sideOffset",
266
+ "children"
267
+ ]);
268
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TooltipPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
269
+ TooltipPrimitive.Content,
270
+ __spreadProps(__spreadValues({
271
+ "data-slot": "tooltip-content",
272
+ sideOffset,
273
+ className: cn(
274
+ "z-50 w-fit origin-(--radix-tooltip-content-transform-origin) animate-in rounded-md bg-primary px-3 py-1.5 text-xs text-balance text-primary-foreground fade-in-0 zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
275
+ className
276
+ )
277
+ }, props), {
278
+ children: [
279
+ children,
280
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TooltipPrimitive.Arrow, { className: "z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" })
281
+ ]
282
+ })
283
+ ) });
284
+ }
285
+
286
+ // src/components/assistant-ui/tooltip-icon-button.tsx
287
+ var import_jsx_runtime3 = require("react/jsx-runtime");
288
+ var TooltipIconButton = (0, import_react.forwardRef)((_a, ref) => {
289
+ var _b = _a, { children, tooltip, side = "bottom", className } = _b, rest = __objRest(_b, ["children", "tooltip", "side", "className"]);
290
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Tooltip, { children: [
291
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
292
+ Button,
293
+ __spreadProps(__spreadValues({
294
+ variant: "ghost",
295
+ size: "icon"
296
+ }, rest), {
297
+ className: cn("aui-button-icon size-6 p-1", className),
298
+ ref,
299
+ children: [
300
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_slot2.Slottable, { children }),
301
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "aui-sr-only sr-only", children: tooltip })
302
+ ]
303
+ })
304
+ ) }),
305
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TooltipContent, { side, children: tooltip })
306
+ ] });
307
+ });
308
+ TooltipIconButton.displayName = "TooltipIconButton";
309
+
310
+ // src/components/assistant-ui/markdown-text.tsx
311
+ var import_jsx_runtime4 = require("react/jsx-runtime");
312
+ var MarkdownTextImpl = () => {
313
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
314
+ import_react_markdown.MarkdownTextPrimitive,
315
+ {
316
+ remarkPlugins: [import_remark_gfm.default],
317
+ className: "aui-md",
318
+ components: defaultComponents
319
+ }
320
+ );
321
+ };
322
+ var MarkdownText = (0, import_react2.memo)(MarkdownTextImpl);
323
+ var CodeHeader = ({ language, code }) => {
324
+ const { isCopied, copyToClipboard } = useCopyToClipboard();
325
+ const onCopy = () => {
326
+ if (!code || isCopied) return;
327
+ copyToClipboard(code);
328
+ };
329
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "aui-code-header-root mt-4 flex items-center justify-between gap-4 rounded-t-lg bg-muted-foreground/15 px-4 py-2 text-sm font-semibold text-foreground dark:bg-muted-foreground/20", children: [
330
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "aui-code-header-language lowercase [&>span]:text-xs", children: language }),
331
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(TooltipIconButton, { tooltip: "Copy", onClick: onCopy, children: [
332
+ !isCopied && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react.CopyIcon, {}),
333
+ isCopied && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react.CheckIcon, {})
334
+ ] })
335
+ ] });
336
+ };
337
+ var useCopyToClipboard = ({
338
+ copiedDuration = 3e3
339
+ } = {}) => {
340
+ const [isCopied, setIsCopied] = (0, import_react2.useState)(false);
341
+ const copyToClipboard = (value) => {
342
+ if (!value) return;
343
+ navigator.clipboard.writeText(value).then(() => {
344
+ setIsCopied(true);
345
+ setTimeout(() => setIsCopied(false), copiedDuration);
346
+ });
347
+ };
348
+ return { isCopied, copyToClipboard };
349
+ };
350
+ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownComponents)({
351
+ h1: (_a) => {
352
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
353
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
354
+ "h1",
355
+ __spreadValues({
356
+ className: cn(
357
+ "aui-md-h1 mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
358
+ className
359
+ )
360
+ }, props)
361
+ );
362
+ },
363
+ h2: (_c) => {
364
+ var _d = _c, { className } = _d, props = __objRest(_d, ["className"]);
365
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
366
+ "h2",
367
+ __spreadValues({
368
+ className: cn(
369
+ "aui-md-h2 mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
370
+ className
371
+ )
372
+ }, props)
373
+ );
374
+ },
375
+ h3: (_e) => {
376
+ var _f = _e, { className } = _f, props = __objRest(_f, ["className"]);
377
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
378
+ "h3",
379
+ __spreadValues({
380
+ className: cn(
381
+ "aui-md-h3 mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
382
+ className
383
+ )
384
+ }, props)
385
+ );
386
+ },
387
+ h4: (_g) => {
388
+ var _h = _g, { className } = _h, props = __objRest(_h, ["className"]);
389
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
390
+ "h4",
391
+ __spreadValues({
392
+ className: cn(
393
+ "aui-md-h4 mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
394
+ className
395
+ )
396
+ }, props)
397
+ );
398
+ },
399
+ h5: (_i) => {
400
+ var _j = _i, { className } = _j, props = __objRest(_j, ["className"]);
401
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
402
+ "h5",
403
+ __spreadValues({
404
+ className: cn(
405
+ "aui-md-h5 my-4 text-lg font-semibold first:mt-0 last:mb-0",
406
+ className
407
+ )
408
+ }, props)
409
+ );
410
+ },
411
+ h6: (_k) => {
412
+ var _l = _k, { className } = _l, props = __objRest(_l, ["className"]);
413
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
414
+ "h6",
415
+ __spreadValues({
416
+ className: cn(
417
+ "aui-md-h6 my-4 font-semibold first:mt-0 last:mb-0",
418
+ className
419
+ )
420
+ }, props)
421
+ );
422
+ },
423
+ p: (_m) => {
424
+ var _n = _m, { className } = _n, props = __objRest(_n, ["className"]);
425
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
426
+ "p",
427
+ __spreadValues({
428
+ className: cn(
429
+ "aui-md-p mt-5 mb-5 leading-7 first:mt-0 last:mb-0",
430
+ className
431
+ )
432
+ }, props)
433
+ );
434
+ },
435
+ a: (_o) => {
436
+ var _p = _o, { className } = _p, props = __objRest(_p, ["className"]);
437
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
438
+ "a",
439
+ __spreadValues({
440
+ className: cn(
441
+ "aui-md-a font-medium text-primary underline underline-offset-4",
442
+ className
443
+ )
444
+ }, props)
445
+ );
446
+ },
447
+ blockquote: (_q) => {
448
+ var _r = _q, { className } = _r, props = __objRest(_r, ["className"]);
449
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
450
+ "blockquote",
451
+ __spreadValues({
452
+ className: cn("aui-md-blockquote border-l-2 pl-6 italic", className)
453
+ }, props)
454
+ );
455
+ },
456
+ ul: (_s) => {
457
+ var _t = _s, { className } = _t, props = __objRest(_t, ["className"]);
458
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
459
+ "ul",
460
+ __spreadValues({
461
+ className: cn("aui-md-ul my-5 ml-6 list-disc [&>li]:mt-2", className)
462
+ }, props)
463
+ );
464
+ },
465
+ ol: (_u) => {
466
+ var _v = _u, { className } = _v, props = __objRest(_v, ["className"]);
467
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
468
+ "ol",
469
+ __spreadValues({
470
+ className: cn("aui-md-ol my-5 ml-6 list-decimal [&>li]:mt-2", className)
471
+ }, props)
472
+ );
473
+ },
474
+ hr: (_w) => {
475
+ var _x = _w, { className } = _x, props = __objRest(_x, ["className"]);
476
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("hr", __spreadValues({ className: cn("aui-md-hr my-5 border-b", className) }, props));
477
+ },
478
+ table: (_y) => {
479
+ var _z = _y, { className } = _z, props = __objRest(_z, ["className"]);
480
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
481
+ "table",
482
+ __spreadValues({
483
+ className: cn(
484
+ "aui-md-table my-5 w-full border-separate border-spacing-0 overflow-y-auto",
485
+ className
486
+ )
487
+ }, props)
488
+ );
489
+ },
490
+ th: (_A) => {
491
+ var _B = _A, { className } = _B, props = __objRest(_B, ["className"]);
492
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
493
+ "th",
494
+ __spreadValues({
495
+ className: cn(
496
+ "aui-md-th bg-muted px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg [&[align=center]]:text-center [&[align=right]]:text-right",
497
+ className
498
+ )
499
+ }, props)
500
+ );
501
+ },
502
+ td: (_C) => {
503
+ var _D = _C, { className } = _D, props = __objRest(_D, ["className"]);
504
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
505
+ "td",
506
+ __spreadValues({
507
+ className: cn(
508
+ "aui-md-td border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
509
+ className
510
+ )
511
+ }, props)
512
+ );
513
+ },
514
+ tr: (_E) => {
515
+ var _F = _E, { className } = _F, props = __objRest(_F, ["className"]);
516
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
517
+ "tr",
518
+ __spreadValues({
519
+ className: cn(
520
+ "aui-md-tr m-0 border-b p-0 first:border-t [&:last-child>td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg",
521
+ className
522
+ )
523
+ }, props)
524
+ );
525
+ },
526
+ sup: (_G) => {
527
+ var _H = _G, { className } = _H, props = __objRest(_H, ["className"]);
528
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
529
+ "sup",
530
+ __spreadValues({
531
+ className: cn("aui-md-sup [&>a]:text-xs [&>a]:no-underline", className)
532
+ }, props)
533
+ );
534
+ },
535
+ pre: (_I) => {
536
+ var _J = _I, { className } = _J, props = __objRest(_J, ["className"]);
537
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
538
+ "pre",
539
+ __spreadValues({
540
+ className: cn(
541
+ "aui-md-pre overflow-x-auto !rounded-t-none rounded-b-lg bg-accent p-6 text-black text-[12px]",
542
+ className
543
+ )
544
+ }, props)
545
+ );
546
+ },
547
+ code: function Code(_K) {
548
+ var _L = _K, { className } = _L, props = __objRest(_L, ["className"]);
549
+ const isCodeBlock = (0, import_react_markdown.useIsMarkdownCodeBlock)();
550
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
551
+ "code",
552
+ __spreadValues({
553
+ className: cn(
554
+ !isCodeBlock && "aui-md-inline-code rounded border bg-muted text-[12px]",
555
+ className
556
+ )
557
+ }, props)
558
+ );
559
+ },
560
+ CodeHeader
561
+ });
562
+
563
+ // src/components/assistant-ui/tool-fallback.tsx
564
+ var import_lucide_react2 = require("lucide-react");
565
+ var import_react3 = require("react");
566
+ var import_jsx_runtime5 = require("react/jsx-runtime");
567
+ var ToolFallback = ({
568
+ toolName,
569
+ argsText,
570
+ result
571
+ }) => {
572
+ const [isCollapsed, setIsCollapsed] = (0, import_react3.useState)(true);
573
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3", children: [
574
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "aui-tool-fallback-header flex items-center gap-2 px-4", children: [
575
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react2.CheckIcon, { className: "aui-tool-fallback-icon size-4" }),
576
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "aui-tool-fallback-title flex-grow", children: [
577
+ "Used tool: ",
578
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("b", { children: toolName })
579
+ ] }),
580
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { onClick: () => setIsCollapsed(!isCollapsed), children: isCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react2.ChevronUpIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react2.ChevronDownIcon, {}) })
581
+ ] }),
582
+ !isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "aui-tool-fallback-content flex flex-col gap-2 border-t pt-2 bg-muted", children: [
583
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "aui-tool-fallback-args-root px-4", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("pre", { className: "aui-tool-fallback-args-value whitespace-pre-wrap", children: argsText }) }),
584
+ result !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "aui-tool-fallback-result-root border-t border-dashed px-4 pt-2", children: [
585
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "aui-tool-fallback-result-header font-semibold", children: "Result:" }),
586
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("pre", { className: "aui-tool-fallback-result-content whitespace-pre-wrap text-[012px]", children: typeof result === "string" ? result : JSON.stringify(result, null, 2) })
587
+ ] })
588
+ ] })
589
+ ] });
590
+ };
591
+
592
+ // src/components/assistant-ui/attachment.tsx
593
+ var import_react4 = require("react");
594
+ var import_image = __toESM(require("next/image"), 1);
595
+ var import_lucide_react4 = require("lucide-react");
596
+ var import_react5 = require("@assistant-ui/react");
597
+ var import_shallow = require("zustand/shallow");
598
+
599
+ // src/components/ui/dialog.tsx
600
+ var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
601
+ var import_lucide_react3 = require("lucide-react");
602
+ var import_jsx_runtime6 = require("react/jsx-runtime");
603
+ function Dialog(_a) {
604
+ var props = __objRest(_a, []);
605
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogPrimitive.Root, __spreadValues({ "data-slot": "dialog" }, props));
606
+ }
607
+ function DialogTrigger(_a) {
608
+ var props = __objRest(_a, []);
609
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogPrimitive.Trigger, __spreadValues({ "data-slot": "dialog-trigger" }, props));
610
+ }
611
+ function DialogPortal(_a) {
612
+ var props = __objRest(_a, []);
613
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogPrimitive.Portal, __spreadValues({ "data-slot": "dialog-portal" }, props));
614
+ }
615
+ function DialogClose(_a) {
616
+ var props = __objRest(_a, []);
617
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogPrimitive.Close, __spreadValues({ "data-slot": "dialog-close" }, props));
618
+ }
619
+ function DialogOverlay(_a) {
620
+ var _b = _a, {
621
+ className
622
+ } = _b, props = __objRest(_b, [
623
+ "className"
624
+ ]);
625
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
626
+ DialogPrimitive.Overlay,
627
+ __spreadValues({
628
+ "data-slot": "dialog-overlay",
629
+ className: cn(
630
+ "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
631
+ className
632
+ )
633
+ }, props)
634
+ );
635
+ }
636
+ function DialogContent(_a) {
637
+ var _b = _a, {
638
+ className,
639
+ children,
640
+ showCloseButton = true
641
+ } = _b, props = __objRest(_b, [
642
+ "className",
643
+ "children",
644
+ "showCloseButton"
645
+ ]);
646
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogPortal, { "data-slot": "dialog-portal", children: [
647
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogOverlay, {}),
648
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
649
+ DialogPrimitive.Content,
650
+ __spreadProps(__spreadValues({
651
+ "data-slot": "dialog-content",
652
+ className: cn(
653
+ "fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg",
654
+ className
655
+ )
656
+ }, props), {
657
+ children: [
658
+ children,
659
+ showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
660
+ DialogPrimitive.Close,
661
+ {
662
+ "data-slot": "dialog-close",
663
+ className: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
664
+ children: [
665
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.XIcon, {}),
666
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "sr-only", children: "Close" })
667
+ ]
668
+ }
669
+ )
670
+ ]
671
+ })
672
+ )
673
+ ] });
674
+ }
675
+ function DialogHeader(_a) {
676
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
677
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
678
+ "div",
679
+ __spreadValues({
680
+ "data-slot": "dialog-header",
681
+ className: cn("flex flex-col gap-2 text-center sm:text-left", className)
682
+ }, props)
683
+ );
684
+ }
685
+ function DialogFooter(_a) {
686
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
687
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
688
+ "div",
689
+ __spreadValues({
690
+ "data-slot": "dialog-footer",
691
+ className: cn(
692
+ "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
693
+ className
694
+ )
695
+ }, props)
696
+ );
697
+ }
698
+ function DialogTitle(_a) {
699
+ var _b = _a, {
700
+ className
701
+ } = _b, props = __objRest(_b, [
702
+ "className"
703
+ ]);
704
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
705
+ DialogPrimitive.Title,
706
+ __spreadValues({
707
+ "data-slot": "dialog-title",
708
+ className: cn("text-lg leading-none font-semibold", className)
709
+ }, props)
710
+ );
711
+ }
712
+ function DialogDescription(_a) {
713
+ var _b = _a, {
714
+ className
715
+ } = _b, props = __objRest(_b, [
716
+ "className"
717
+ ]);
718
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
719
+ DialogPrimitive.Description,
720
+ __spreadValues({
721
+ "data-slot": "dialog-description",
722
+ className: cn("text-sm text-muted-foreground", className)
723
+ }, props)
724
+ );
725
+ }
726
+
727
+ // src/components/ui/avatar.tsx
728
+ var AvatarPrimitive = __toESM(require("@radix-ui/react-avatar"), 1);
729
+ var import_jsx_runtime7 = require("react/jsx-runtime");
730
+ function Avatar(_a) {
731
+ var _b = _a, {
732
+ className
733
+ } = _b, props = __objRest(_b, [
734
+ "className"
735
+ ]);
736
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
737
+ AvatarPrimitive.Root,
738
+ __spreadValues({
739
+ "data-slot": "avatar",
740
+ className: cn(
741
+ "relative flex size-8 shrink-0 overflow-hidden rounded-full",
742
+ className
743
+ )
744
+ }, props)
745
+ );
746
+ }
747
+ function AvatarImage(_a) {
748
+ var _b = _a, {
749
+ className
750
+ } = _b, props = __objRest(_b, [
751
+ "className"
752
+ ]);
753
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
754
+ AvatarPrimitive.Image,
755
+ __spreadValues({
756
+ "data-slot": "avatar-image",
757
+ className: cn("aspect-square size-full", className)
758
+ }, props)
759
+ );
760
+ }
761
+ function AvatarFallback(_a) {
762
+ var _b = _a, {
763
+ className
764
+ } = _b, props = __objRest(_b, [
765
+ "className"
766
+ ]);
767
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
768
+ AvatarPrimitive.Fallback,
769
+ __spreadValues({
770
+ "data-slot": "avatar-fallback",
771
+ className: cn(
772
+ "flex size-full items-center justify-center rounded-full bg-muted",
773
+ className
774
+ )
775
+ }, props)
776
+ );
777
+ }
778
+
779
+ // src/components/assistant-ui/attachment.tsx
780
+ var import_jsx_runtime8 = require("react/jsx-runtime");
781
+ var useFileSrc = (file) => {
782
+ const [src, setSrc] = (0, import_react4.useState)(void 0);
783
+ (0, import_react4.useEffect)(() => {
784
+ if (!file) {
785
+ setSrc(void 0);
786
+ return;
787
+ }
788
+ const objectUrl = URL.createObjectURL(file);
789
+ setSrc(objectUrl);
790
+ return () => {
791
+ URL.revokeObjectURL(objectUrl);
792
+ };
793
+ }, [file]);
794
+ return src;
795
+ };
796
+ var useAttachmentSrc = () => {
797
+ var _a;
798
+ const { file, src } = (0, import_react5.useAssistantState)(
799
+ (0, import_shallow.useShallow)(({ attachment }) => {
800
+ var _a2, _b;
801
+ if (attachment.type !== "image") return {};
802
+ if (attachment.file) return { file: attachment.file };
803
+ const src2 = (_b = (_a2 = attachment.content) == null ? void 0 : _a2.filter((c) => c.type === "image")[0]) == null ? void 0 : _b.image;
804
+ if (!src2) return {};
805
+ return { src: src2 };
806
+ })
807
+ );
808
+ return (_a = useFileSrc(file)) != null ? _a : src;
809
+ };
810
+ var AttachmentPreview = ({ src }) => {
811
+ const [isLoaded, setIsLoaded] = (0, import_react4.useState)(false);
812
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
813
+ import_image.default,
814
+ {
815
+ src,
816
+ alt: "Image Preview",
817
+ width: 1,
818
+ height: 1,
819
+ className: isLoaded ? "aui-attachment-preview-image-loaded block h-auto max-h-[80vh] w-auto max-w-full object-contain" : "aui-attachment-preview-image-loading hidden",
820
+ onLoadingComplete: () => setIsLoaded(true),
821
+ priority: false
822
+ }
823
+ );
824
+ };
825
+ var AttachmentPreviewDialog = ({ children }) => {
826
+ const src = useAttachmentSrc();
827
+ if (!src) return children;
828
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Dialog, { children: [
829
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
830
+ DialogTrigger,
831
+ {
832
+ className: "aui-attachment-preview-trigger cursor-pointer transition-colors hover:bg-accent/50",
833
+ asChild: true,
834
+ children
835
+ }
836
+ ),
837
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(DialogContent, { className: "aui-attachment-preview-dialog-content p-2 sm:max-w-3xl [&_svg]:text-background [&>button]:rounded-full [&>button]:bg-foreground/60 [&>button]:p-1 [&>button]:opacity-100 [&>button]:!ring-0 [&>button]:hover:[&_svg]:text-destructive", children: [
838
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DialogTitle, { className: "aui-sr-only sr-only", children: "Image Attachment Preview" }),
839
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "aui-attachment-preview relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden bg-background", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(AttachmentPreview, { src }) })
840
+ ] })
841
+ ] });
842
+ };
843
+ var AttachmentThumb = () => {
844
+ const isImage = (0, import_react5.useAssistantState)(
845
+ ({ attachment }) => attachment.type === "image"
846
+ );
847
+ const src = useAttachmentSrc();
848
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Avatar, { className: "aui-attachment-tile-avatar h-full w-full rounded-none", children: [
849
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
850
+ AvatarImage,
851
+ {
852
+ src,
853
+ alt: "Attachment preview",
854
+ className: "aui-attachment-tile-image object-cover"
855
+ }
856
+ ),
857
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(AvatarFallback, { delayMs: isImage ? 200 : 0, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.FileText, { className: "aui-attachment-tile-fallback-icon size-8 text-muted-foreground" }) })
858
+ ] });
859
+ };
860
+ var AttachmentUI = () => {
861
+ const api = (0, import_react5.useAssistantApi)();
862
+ const isComposer = api.attachment.source === "composer";
863
+ const isImage = (0, import_react5.useAssistantState)(
864
+ ({ attachment }) => attachment.type === "image"
865
+ );
866
+ const typeLabel = (0, import_react5.useAssistantState)(({ attachment }) => {
867
+ const type = attachment.type;
868
+ switch (type) {
869
+ case "image":
870
+ return "Image";
871
+ case "document":
872
+ return "Document";
873
+ case "file":
874
+ return "File";
875
+ default:
876
+ const _exhaustiveCheck = type;
877
+ throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);
878
+ }
879
+ });
880
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Tooltip, { children: [
881
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
882
+ import_react5.AttachmentPrimitive.Root,
883
+ {
884
+ className: cn(
885
+ "aui-attachment-root relative",
886
+ isImage && "aui-attachment-root-composer only:[&>#attachment-tile]:size-24"
887
+ ),
888
+ children: [
889
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(AttachmentPreviewDialog, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
890
+ "div",
891
+ {
892
+ className: cn(
893
+ "aui-attachment-tile size-14 cursor-pointer overflow-hidden rounded-[14px] border bg-muted transition-opacity hover:opacity-75",
894
+ isComposer && "aui-attachment-tile-composer border-foreground/20"
895
+ ),
896
+ role: "button",
897
+ id: "attachment-tile",
898
+ "aria-label": `${typeLabel} attachment`,
899
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(AttachmentThumb, {})
900
+ }
901
+ ) }) }),
902
+ isComposer && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(AttachmentRemove, {})
903
+ ]
904
+ }
905
+ ),
906
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipContent, { side: "top", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react5.AttachmentPrimitive.Name, {}) })
907
+ ] });
908
+ };
909
+ var AttachmentRemove = () => {
910
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react5.AttachmentPrimitive.Remove, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
911
+ TooltipIconButton,
912
+ {
913
+ tooltip: "Remove file",
914
+ className: "aui-attachment-tile-remove absolute top-1.5 right-1.5 size-3.5 rounded-full bg-white text-muted-foreground opacity-100 shadow-sm hover:!bg-white [&_svg]:text-black hover:[&_svg]:text-destructive",
915
+ side: "top",
916
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.XIcon, { className: "aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" })
917
+ }
918
+ ) });
919
+ };
920
+ var UserMessageAttachments = () => {
921
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "aui-user-message-attachments-end col-span-full col-start-1 row-start-1 flex w-full flex-row justify-end gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react5.MessagePrimitive.Attachments, { components: { Attachment: AttachmentUI } }) });
922
+ };
923
+ var ComposerAttachments = () => {
924
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "aui-composer-attachments mb-2 flex w-full flex-row items-center gap-2 overflow-x-auto px-1.5 pt-0.5 pb-1 empty:hidden", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
925
+ import_react5.ComposerPrimitive.Attachments,
926
+ {
927
+ components: { Attachment: AttachmentUI }
928
+ }
929
+ ) });
930
+ };
931
+ var ComposerAddAttachment = () => {
932
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react5.ComposerPrimitive.AddAttachment, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
933
+ TooltipIconButton,
934
+ {
935
+ tooltip: "Add Attachment",
936
+ side: "bottom",
937
+ variant: "ghost",
938
+ size: "icon",
939
+ className: "aui-composer-add-attachment size-[34px] rounded-full p-1 text-xs font-semibold hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30",
940
+ "aria-label": "Add Attachment",
941
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.PlusIcon, { className: "aui-attachment-add-icon size-5 stroke-[1.5px]" })
942
+ }
943
+ ) });
944
+ };
945
+
946
+ // src/lib/thread-context.tsx
947
+ var import_react6 = require("react");
948
+ var import_jsx_runtime9 = require("react/jsx-runtime");
949
+ function generateSessionId() {
950
+ return crypto.randomUUID();
951
+ }
952
+ var ThreadContext = (0, import_react6.createContext)(null);
953
+ function useThreadContext() {
954
+ const context = (0, import_react6.useContext)(ThreadContext);
955
+ if (!context) {
956
+ throw new Error(
957
+ "useThreadContext must be used within ThreadContextProvider. Wrap your app with <ThreadContextProvider>...</ThreadContextProvider>"
958
+ );
959
+ }
960
+ return context;
961
+ }
962
+ function ThreadContextProvider({
963
+ children,
964
+ initialThreadId
965
+ }) {
966
+ const [generateThreadId] = (0, import_react6.useState)(() => {
967
+ const id = initialThreadId || generateSessionId();
968
+ console.log("\u{1F535} [ThreadContext] Initialized with thread ID:", id);
969
+ return id;
970
+ });
971
+ const [threadCnt, setThreadCnt] = (0, import_react6.useState)(1);
972
+ const [threads, setThreads] = (0, import_react6.useState)(
973
+ () => /* @__PURE__ */ new Map([[generateThreadId, []]])
974
+ );
975
+ const [threadMetadata, setThreadMetadata] = (0, import_react6.useState)(
976
+ () => /* @__PURE__ */ new Map([
977
+ [
978
+ generateThreadId,
979
+ { title: "New Chat", status: "pending", lastActiveAt: (/* @__PURE__ */ new Date()).toISOString() }
980
+ ]
981
+ ])
982
+ );
983
+ const ensureThreadExists = (0, import_react6.useCallback)(
984
+ (threadId) => {
985
+ setThreadMetadata((prev) => {
986
+ if (prev.has(threadId)) return prev;
987
+ const next = new Map(prev);
988
+ next.set(threadId, { title: "New Chat", status: "regular", lastActiveAt: (/* @__PURE__ */ new Date()).toISOString() });
989
+ return next;
990
+ });
991
+ setThreads((prev) => {
992
+ if (prev.has(threadId)) return prev;
993
+ const next = new Map(prev);
994
+ next.set(threadId, []);
995
+ return next;
996
+ });
997
+ },
998
+ []
999
+ );
1000
+ const [currentThreadId, _setCurrentThreadId] = (0, import_react6.useState)(generateThreadId);
1001
+ const [threadViewKey, setThreadViewKey] = (0, import_react6.useState)(0);
1002
+ const bumpThreadViewKey = (0, import_react6.useCallback)(() => {
1003
+ setThreadViewKey((prev) => prev + 1);
1004
+ }, []);
1005
+ const setCurrentThreadId = (0, import_react6.useCallback)(
1006
+ (threadId) => {
1007
+ ensureThreadExists(threadId);
1008
+ _setCurrentThreadId(threadId);
1009
+ },
1010
+ [ensureThreadExists]
1011
+ );
1012
+ const getThreadMessages = (0, import_react6.useCallback)(
1013
+ (threadId) => {
1014
+ return threads.get(threadId) || [];
1015
+ },
1016
+ [threads]
1017
+ );
1018
+ const setThreadMessages = (0, import_react6.useCallback)(
1019
+ (threadId, messages) => {
1020
+ setThreads((prev) => {
1021
+ const next = new Map(prev);
1022
+ next.set(threadId, messages);
1023
+ return next;
1024
+ });
1025
+ },
1026
+ []
1027
+ );
1028
+ const getThreadMetadata = (0, import_react6.useCallback)(
1029
+ (threadId) => {
1030
+ return threadMetadata.get(threadId);
1031
+ },
1032
+ [threadMetadata]
1033
+ );
1034
+ const updateThreadMetadata = (0, import_react6.useCallback)(
1035
+ (threadId, updates) => {
1036
+ setThreadMetadata((prev) => {
1037
+ const existing = prev.get(threadId);
1038
+ if (!existing) {
1039
+ console.warn(`Thread metadata not found for threadId: ${threadId}`);
1040
+ return prev;
1041
+ }
1042
+ const next = new Map(prev);
1043
+ next.set(threadId, __spreadValues(__spreadValues({}, existing), updates));
1044
+ return next;
1045
+ });
1046
+ },
1047
+ []
1048
+ );
1049
+ const value = {
1050
+ currentThreadId,
1051
+ setCurrentThreadId,
1052
+ threadViewKey,
1053
+ bumpThreadViewKey,
1054
+ threads,
1055
+ setThreads,
1056
+ threadMetadata,
1057
+ setThreadMetadata,
1058
+ threadCnt,
1059
+ setThreadCnt,
1060
+ getThreadMessages,
1061
+ setThreadMessages,
1062
+ getThreadMetadata,
1063
+ updateThreadMetadata
1064
+ };
1065
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ThreadContext.Provider, { value, children });
1066
+ }
1067
+ function useCurrentThreadMetadata() {
1068
+ const { currentThreadId, getThreadMetadata } = useThreadContext();
1069
+ return getThreadMetadata(currentThreadId);
1070
+ }
1071
+
1072
+ // src/components/assistant-ui/thread.tsx
1073
+ var import_react10 = require("@assistant-ui/react");
1074
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1075
+ var Thread = () => {
1076
+ const api = (0, import_react10.useAssistantApi)();
1077
+ const { threadViewKey } = useThreadContext();
1078
+ (0, import_react8.useEffect)(() => {
1079
+ var _a;
1080
+ try {
1081
+ const composer = api.composer();
1082
+ composer.setText("");
1083
+ void ((_a = composer.clearAttachments) == null ? void 0 : _a.call(composer));
1084
+ } catch (error) {
1085
+ console.error("Failed to reset composer input:", error);
1086
+ }
1087
+ }, [api, threadViewKey]);
1088
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react9.LazyMotion, { features: import_react9.domAnimation, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react9.MotionConfig, { reducedMotion: "user", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1089
+ import_react7.ThreadPrimitive.Root,
1090
+ {
1091
+ className: "aui-root aui-thread-root @container flex h-full flex-col bg-background",
1092
+ style: {
1093
+ ["--thread-max-width"]: "44rem"
1094
+ },
1095
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react7.ThreadPrimitive.Viewport, { className: "aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll px-4", children: [
1096
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ThreadPrimitive.If, { empty: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ThreadWelcome, {}) }),
1097
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1098
+ import_react7.ThreadPrimitive.Messages,
1099
+ {
1100
+ components: {
1101
+ UserMessage,
1102
+ EditComposer,
1103
+ AssistantMessage,
1104
+ SystemMessage
1105
+ }
1106
+ }
1107
+ ),
1108
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ThreadPrimitive.If, { empty: false, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "aui-thread-viewport-spacer min-h-8 grow" }) }),
1109
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Composer, {})
1110
+ ] })
1111
+ }
1112
+ ) }) });
1113
+ };
1114
+ var ThreadScrollToBottom = () => {
1115
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ThreadPrimitive.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1116
+ TooltipIconButton,
1117
+ {
1118
+ tooltip: "Scroll to bottom",
1119
+ variant: "outline",
1120
+ className: "aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center rounded-full p-4 disabled:invisible dark:bg-background dark:hover:bg-accent",
1121
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.ArrowDownIcon, {})
1122
+ }
1123
+ ) });
1124
+ };
1125
+ var ThreadWelcome = () => {
1126
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "aui-thread-welcome-root mx-auto my-auto flex w-full max-w-[var(--thread-max-width)] flex-grow flex-col", children: [
1127
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "aui-thread-welcome-center flex w-full flex-grow flex-col items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "aui-thread-welcome-message flex size-full flex-col justify-center px-8", children: [
1128
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1129
+ m.div,
1130
+ {
1131
+ initial: { opacity: 0, y: 10 },
1132
+ animate: { opacity: 1, y: 0 },
1133
+ exit: { opacity: 0, y: 10 },
1134
+ className: "aui-thread-welcome-message-motion-1 text-2xl font-semibold",
1135
+ children: "Hello there!"
1136
+ }
1137
+ ),
1138
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1139
+ m.div,
1140
+ {
1141
+ initial: { opacity: 0, y: 10 },
1142
+ animate: { opacity: 1, y: 0 },
1143
+ exit: { opacity: 0, y: 10 },
1144
+ transition: { delay: 0.1 },
1145
+ className: "aui-thread-welcome-message-motion-2 text-2xl text-muted-foreground/65",
1146
+ children: "How can I help you today?"
1147
+ }
1148
+ )
1149
+ ] }) }),
1150
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ThreadSuggestions, {})
1151
+ ] });
1152
+ };
1153
+ var ThreadSuggestions = () => {
1154
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "aui-thread-welcome-suggestions grid w-full gap-2 pb-4 @md:grid-cols-2", children: [
1155
+ {
1156
+ title: "Show my wallet balances",
1157
+ label: "and positions",
1158
+ action: "Show my wallet balances and positions"
1159
+ },
1160
+ {
1161
+ title: "Swap 1 ETH to USDC",
1162
+ label: "with the best price",
1163
+ action: "Swap 1 ETH to USDC with the best price"
1164
+ },
1165
+ {
1166
+ title: "Stake half of my ETH",
1167
+ label: "in the highest yield pool",
1168
+ action: "Stake half of my ETH in the highest yield pool"
1169
+ },
1170
+ {
1171
+ title: "Bridge 100 USDC",
1172
+ label: "from Ethereum to Arbitrum",
1173
+ action: "Bridge 100 USDC from Ethereum to Arbitrum"
1174
+ }
1175
+ ].map((suggestedAction, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1176
+ m.div,
1177
+ {
1178
+ initial: { opacity: 0, y: 20 },
1179
+ animate: { opacity: 1, y: 0 },
1180
+ exit: { opacity: 0, y: 20 },
1181
+ transition: { delay: 0.05 * index },
1182
+ className: "aui-thread-welcome-suggestion-display [&:nth-child(n+3)]:hidden @md:[&:nth-child(n+3)]:block",
1183
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1184
+ import_react7.ThreadPrimitive.Suggestion,
1185
+ {
1186
+ prompt: suggestedAction.action,
1187
+ send: true,
1188
+ asChild: true,
1189
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1190
+ Button,
1191
+ {
1192
+ variant: "ghost",
1193
+ className: "aui-thread-welcome-suggestion h-auto w-full flex-1 flex-wrap items-start justify-start gap-1 rounded-3xl border px-5 py-4 text-left text-sm @md:flex-col dark:hover:bg-accent/60",
1194
+ "aria-label": suggestedAction.action,
1195
+ children: [
1196
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "aui-thread-welcome-suggestion-text-1 font-medium", children: suggestedAction.title }),
1197
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "aui-thread-welcome-suggestion-text-2 text-muted-foreground", children: suggestedAction.label })
1198
+ ]
1199
+ }
1200
+ )
1201
+ }
1202
+ )
1203
+ },
1204
+ `suggested-action-${suggestedAction.title}-${index}`
1205
+ )) });
1206
+ };
1207
+ var Composer = () => {
1208
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "aui-composer-wrapper sticky bottom-0 mx-auto flex w-full max-w-[var(--thread-max-width)] flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4 md:pb-6", children: [
1209
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ThreadScrollToBottom, {}),
1210
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react7.ComposerPrimitive.Root, { className: "aui-composer-root relative flex w-full flex-col rounded-4xl border bg-white px-1 pt-2 shadow-[0_9px_9px_0px_rgba(0,0,0,0.01),0_2px_5px_0px_rgba(0,0,0,0.06)] dark:border-muted-foreground/15", children: [
1211
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ComposerAttachments, {}),
1212
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1213
+ import_react7.ComposerPrimitive.Input,
1214
+ {
1215
+ placeholder: "Send a message...",
1216
+ className: "aui-composer-input ml-3 mt-2 max-h-32 min-h-16 w-full resize-none bg-transparent px-3.5 pt-1.5 pb-3 text-sm outline-none placeholder:text-muted-foreground focus:outline-primary",
1217
+ rows: 1,
1218
+ autoFocus: true,
1219
+ "aria-label": "Message input"
1220
+ }
1221
+ ),
1222
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ComposerAction, {})
1223
+ ] })
1224
+ ] });
1225
+ };
1226
+ var ComposerAction = () => {
1227
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "aui-composer-action-wrapper relative mx-1 mt-2 mb-2 flex items-center justify-between", children: [
1228
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ComposerAddAttachment, {}),
1229
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ThreadPrimitive.If, { running: false, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ComposerPrimitive.Send, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1230
+ TooltipIconButton,
1231
+ {
1232
+ tooltip: "Send message",
1233
+ side: "bottom",
1234
+ type: "submit",
1235
+ variant: "default",
1236
+ size: "icon",
1237
+ className: "aui-composer-send mr-3 mb-3 size-[34px] rounded-full p-1",
1238
+ "aria-label": "Send message",
1239
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.ArrowUpIcon, { className: "aui-composer-send-icon size-5" })
1240
+ }
1241
+ ) }) }),
1242
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ThreadPrimitive.If, { running: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1243
+ Button,
1244
+ {
1245
+ type: "button",
1246
+ variant: "default",
1247
+ size: "icon",
1248
+ className: "aui-composer-cancel size-[34px] rounded-full border border-muted-foreground/60 hover:bg-primary/75 dark:border-muted-foreground/90",
1249
+ "aria-label": "Stop generating",
1250
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.Square, { className: "aui-composer-cancel-icon size-3.5 fill-white dark:fill-black" })
1251
+ }
1252
+ ) }) })
1253
+ ] });
1254
+ };
1255
+ var MessageError = () => {
1256
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.MessagePrimitive.Error, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ErrorPrimitive.Root, { className: "aui-message-error-root mt-2 rounded-md border border-destructive bg-destructive/10 p-3 text-sm text-destructive dark:bg-destructive/5 dark:text-red-200", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ErrorPrimitive.Message, { className: "aui-message-error-message line-clamp-2" }) }) });
1257
+ };
1258
+ var AssistantMessage = () => {
1259
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.MessagePrimitive.Root, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1260
+ "div",
1261
+ {
1262
+ className: "aui-assistant-message-root relative mx-auto w-full max-w-[var(--thread-max-width)] animate-in py-4 duration-150 ease-out fade-in slide-in-from-bottom-1 last:mb-24",
1263
+ "data-role": "assistant",
1264
+ children: [
1265
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "aui-assistant-message-content text-sm mx-2 leading-5 break-words text-foreground", children: [
1266
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1267
+ import_react7.MessagePrimitive.Parts,
1268
+ {
1269
+ components: {
1270
+ Text: MarkdownText,
1271
+ tools: { Fallback: ToolFallback }
1272
+ }
1273
+ }
1274
+ ),
1275
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageError, {})
1276
+ ] }),
1277
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "aui-assistant-message-footer mt-2 ml-2 flex", children: [
1278
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BranchPicker, {}),
1279
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AssistantActionBar, {})
1280
+ ] })
1281
+ ]
1282
+ }
1283
+ ) });
1284
+ };
1285
+ var AssistantActionBar = () => {
1286
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1287
+ import_react7.ActionBarPrimitive.Root,
1288
+ {
1289
+ hideWhenRunning: true,
1290
+ autohide: "not-last",
1291
+ autohideFloat: "single-branch",
1292
+ className: "aui-assistant-action-bar-root col-start-3 row-start-2 -ml-1 flex gap-1 text-muted-foreground data-floating:absolute data-floating:rounded-md data-floating:border data-floating:bg-background data-floating:p-1 data-floating:shadow-sm",
1293
+ children: [
1294
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ActionBarPrimitive.Copy, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(TooltipIconButton, { tooltip: "Copy", children: [
1295
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.MessagePrimitive.If, { copied: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.CheckIcon, {}) }),
1296
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.MessagePrimitive.If, { copied: false, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.CopyIcon, {}) })
1297
+ ] }) }),
1298
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ActionBarPrimitive.Reload, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipIconButton, { tooltip: "Refresh", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.RefreshCwIcon, {}) }) })
1299
+ ]
1300
+ }
1301
+ );
1302
+ };
1303
+ var UserMessage = () => {
1304
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.MessagePrimitive.Root, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1305
+ "div",
1306
+ {
1307
+ className: "aui-user-message-root mx-auto grid w-full max-w-[var(--thread-max-width)] animate-in auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] gap-y-2 px-2 py-4 duration-150 ease-out fade-in slide-in-from-bottom-1 first:mt-3 last:mb-5 [&:where(>*)]:col-start-2",
1308
+ "data-role": "user",
1309
+ children: [
1310
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(UserMessageAttachments, {}),
1311
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "aui-user-message-content-wrapper relative col-start-2 min-w-0", children: [
1312
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "aui-user-message-content text-sm rounded-3xl bg-muted px-5 py-2.5 break-words text-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.MessagePrimitive.Parts, {}) }),
1313
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(UserActionBar, {}) })
1314
+ ] }),
1315
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BranchPicker, { className: "aui-user-branch-picker col-span-full col-start-1 row-start-3 -mr-1 justify-end" })
1316
+ ]
1317
+ }
1318
+ ) });
1319
+ };
1320
+ var UserActionBar = () => {
1321
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1322
+ import_react7.ActionBarPrimitive.Root,
1323
+ {
1324
+ hideWhenRunning: true,
1325
+ autohide: "not-last",
1326
+ className: "aui-user-action-bar-root flex flex-col items-end",
1327
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ActionBarPrimitive.Edit, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipIconButton, { tooltip: "Edit", className: "aui-user-action-edit p-4", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.PencilIcon, {}) }) })
1328
+ }
1329
+ );
1330
+ };
1331
+ var EditComposer = () => {
1332
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "aui-edit-composer-wrapper mx-auto flex w-full max-w-[var(--thread-max-width)] flex-col gap-4 px-2 first:mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react7.ComposerPrimitive.Root, { className: "aui-edit-composer-root ml-auto flex w-full max-w-7/8 flex-col rounded-xl bg-muted", children: [
1333
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1334
+ import_react7.ComposerPrimitive.Input,
1335
+ {
1336
+ className: "aui-edit-composer-input flex min-h-[60px] w-full resize-none bg-transparent p-4 text-foreground outline-none",
1337
+ autoFocus: true
1338
+ }
1339
+ ),
1340
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "aui-edit-composer-footer mx-3 mb-3 flex items-center justify-center gap-2 self-end", children: [
1341
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { variant: "ghost", size: "sm", "aria-label": "Cancel edit", children: "Cancel" }) }),
1342
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.ComposerPrimitive.Send, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { size: "sm", "aria-label": "Update message", children: "Update" }) })
1343
+ ] })
1344
+ ] }) });
1345
+ };
1346
+ var BranchPicker = (_a) => {
1347
+ var _b = _a, {
1348
+ className
1349
+ } = _b, rest = __objRest(_b, [
1350
+ "className"
1351
+ ]);
1352
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1353
+ import_react7.BranchPickerPrimitive.Root,
1354
+ __spreadProps(__spreadValues({
1355
+ hideWhenSingleBranch: true,
1356
+ className: cn(
1357
+ "aui-branch-picker-root mr-2 -ml-2 inline-flex items-center text-xs text-muted-foreground",
1358
+ className
1359
+ )
1360
+ }, rest), {
1361
+ children: [
1362
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.BranchPickerPrimitive.Previous, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipIconButton, { tooltip: "Previous", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.ChevronLeftIcon, {}) }) }),
1363
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "aui-branch-picker-state font-medium", children: [
1364
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.BranchPickerPrimitive.Number, {}),
1365
+ " / ",
1366
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.BranchPickerPrimitive.Count, {})
1367
+ ] }),
1368
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.BranchPickerPrimitive.Next, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipIconButton, { tooltip: "Next", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.ChevronRightIcon, {}) }) })
1369
+ ]
1370
+ })
1371
+ );
1372
+ };
1373
+ var SystemMessage = () => {
1374
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.MessagePrimitive.Root, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1375
+ "div",
1376
+ {
1377
+ className: "aui-system-message-root mx-auto w-full max-w-[var(--thread-max-width)] px-2 py-4 animate-in fade-in slide-in-from-bottom-1",
1378
+ "data-role": "system",
1379
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "aui-system-message-card flex w-full flex-wrap items-start gap-3 rounded-3xl border px-5 py-4 text-left text-sm bg-background/70 dark:bg-muted/30", children: [
1380
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.AlertCircleIcon, { className: "aui-system-message-icon mt-0.5 size-4 shrink-0 text-blue-500 dark:text-blue-300" }),
1381
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "aui-system-message-body flex flex-col gap-1", children: [
1382
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "aui-system-message-title font-medium text-foreground", children: "System notice" }),
1383
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "aui-system-message-content leading-relaxed text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react7.MessagePrimitive.Parts, { components: { Text: MarkdownText } }) })
1384
+ ] })
1385
+ ] })
1386
+ }
1387
+ ) });
1388
+ };
1389
+
1390
+ // src/components/assistant-ui/threadlist-sidebar.tsx
1391
+ var import_link = __toESM(require("next/link"), 1);
1392
+ var import_image2 = __toESM(require("next/image"), 1);
1393
+
1394
+ // src/components/ui/sidebar.tsx
1395
+ var React2 = __toESM(require("react"), 1);
1396
+ var import_react_slot3 = require("@radix-ui/react-slot");
1397
+ var import_class_variance_authority2 = require("class-variance-authority");
1398
+ var import_lucide_react7 = require("lucide-react");
1399
+
1400
+ // src/hooks/use-mobile.ts
1401
+ var React = __toESM(require("react"), 1);
1402
+ var MOBILE_BREAKPOINT = 768;
1403
+ function useIsMobile() {
1404
+ const [isMobile, setIsMobile] = React.useState(
1405
+ void 0
1406
+ );
1407
+ React.useEffect(() => {
1408
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
1409
+ const onChange = () => {
1410
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
1411
+ };
1412
+ mql.addEventListener("change", onChange);
1413
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
1414
+ return () => mql.removeEventListener("change", onChange);
1415
+ }, []);
1416
+ return !!isMobile;
1417
+ }
1418
+
1419
+ // src/components/ui/input.tsx
1420
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1421
+ function Input(_a) {
1422
+ var _b = _a, { className, type } = _b, props = __objRest(_b, ["className", "type"]);
1423
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1424
+ "input",
1425
+ __spreadValues({
1426
+ type,
1427
+ "data-slot": "input",
1428
+ className: cn(
1429
+ "flex h-9 w-full min-w-0 rounded-md border-sm border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30",
1430
+ "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
1431
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",
1432
+ className
1433
+ )
1434
+ }, props)
1435
+ );
1436
+ }
1437
+
1438
+ // src/components/ui/separator.tsx
1439
+ var SeparatorPrimitive = __toESM(require("@radix-ui/react-separator"), 1);
1440
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1441
+ function Separator(_a) {
1442
+ var _b = _a, {
1443
+ className,
1444
+ orientation = "horizontal",
1445
+ decorative = true
1446
+ } = _b, props = __objRest(_b, [
1447
+ "className",
1448
+ "orientation",
1449
+ "decorative"
1450
+ ]);
1451
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1452
+ SeparatorPrimitive.Root,
1453
+ __spreadValues({
1454
+ "data-slot": "separator",
1455
+ decorative,
1456
+ orientation,
1457
+ className: cn(
1458
+ "shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
1459
+ className
1460
+ )
1461
+ }, props)
1462
+ );
1463
+ }
1464
+
1465
+ // src/components/ui/sheet.tsx
1466
+ var SheetPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
1467
+ var import_lucide_react6 = require("lucide-react");
1468
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1469
+ function Sheet(_a) {
1470
+ var props = __objRest(_a, []);
1471
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SheetPrimitive.Root, __spreadValues({ "data-slot": "sheet" }, props));
1472
+ }
1473
+ function SheetTrigger(_a) {
1474
+ var props = __objRest(_a, []);
1475
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SheetPrimitive.Trigger, __spreadValues({ "data-slot": "sheet-trigger" }, props));
1476
+ }
1477
+ function SheetClose(_a) {
1478
+ var props = __objRest(_a, []);
1479
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SheetPrimitive.Close, __spreadValues({ "data-slot": "sheet-close" }, props));
1480
+ }
1481
+ function SheetPortal(_a) {
1482
+ var props = __objRest(_a, []);
1483
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SheetPrimitive.Portal, __spreadValues({ "data-slot": "sheet-portal" }, props));
1484
+ }
1485
+ function SheetOverlay(_a) {
1486
+ var _b = _a, {
1487
+ className
1488
+ } = _b, props = __objRest(_b, [
1489
+ "className"
1490
+ ]);
1491
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1492
+ SheetPrimitive.Overlay,
1493
+ __spreadValues({
1494
+ "data-slot": "sheet-overlay",
1495
+ className: cn(
1496
+ "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
1497
+ className
1498
+ )
1499
+ }, props)
1500
+ );
1501
+ }
1502
+ function SheetContent(_a) {
1503
+ var _b = _a, {
1504
+ className,
1505
+ children,
1506
+ side = "right"
1507
+ } = _b, props = __objRest(_b, [
1508
+ "className",
1509
+ "children",
1510
+ "side"
1511
+ ]);
1512
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(SheetPortal, { children: [
1513
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SheetOverlay, {}),
1514
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1515
+ SheetPrimitive.Content,
1516
+ __spreadProps(__spreadValues({
1517
+ "data-slot": "sheet-content",
1518
+ className: cn(
1519
+ "fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:animate-in data-[state=open]:duration-500",
1520
+ side === "right" && "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
1521
+ side === "left" && "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
1522
+ side === "top" && "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
1523
+ side === "bottom" && "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
1524
+ className
1525
+ )
1526
+ }, props), {
1527
+ children: [
1528
+ children,
1529
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(SheetPrimitive.Close, { className: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary", children: [
1530
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.XIcon, { className: "size-4" }),
1531
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sr-only", children: "Close" })
1532
+ ] })
1533
+ ]
1534
+ })
1535
+ )
1536
+ ] });
1537
+ }
1538
+ function SheetHeader(_a) {
1539
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1540
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1541
+ "div",
1542
+ __spreadValues({
1543
+ "data-slot": "sheet-header",
1544
+ className: cn("flex flex-col gap-1.5 p-4", className)
1545
+ }, props)
1546
+ );
1547
+ }
1548
+ function SheetFooter(_a) {
1549
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1550
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1551
+ "div",
1552
+ __spreadValues({
1553
+ "data-slot": "sheet-footer",
1554
+ className: cn("mt-auto flex flex-col gap-2 p-4", className)
1555
+ }, props)
1556
+ );
1557
+ }
1558
+ function SheetTitle(_a) {
1559
+ var _b = _a, {
1560
+ className
1561
+ } = _b, props = __objRest(_b, [
1562
+ "className"
1563
+ ]);
1564
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1565
+ SheetPrimitive.Title,
1566
+ __spreadValues({
1567
+ "data-slot": "sheet-title",
1568
+ className: cn("font-semibold text-foreground", className)
1569
+ }, props)
1570
+ );
1571
+ }
1572
+ function SheetDescription(_a) {
1573
+ var _b = _a, {
1574
+ className
1575
+ } = _b, props = __objRest(_b, [
1576
+ "className"
1577
+ ]);
1578
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1579
+ SheetPrimitive.Description,
1580
+ __spreadValues({
1581
+ "data-slot": "sheet-description",
1582
+ className: cn("text-sm text-muted-foreground", className)
1583
+ }, props)
1584
+ );
1585
+ }
1586
+
1587
+ // src/components/ui/skeleton.tsx
1588
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1589
+ function Skeleton(_a) {
1590
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1591
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1592
+ "div",
1593
+ __spreadValues({
1594
+ "data-slot": "skeleton",
1595
+ className: cn("animate-pulse rounded-md bg-accent", className)
1596
+ }, props)
1597
+ );
1598
+ }
1599
+
1600
+ // src/components/ui/sidebar.tsx
1601
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1602
+ var SIDEBAR_COOKIE_NAME = "sidebar_state";
1603
+ var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
1604
+ var SIDEBAR_WIDTH_MOBILE = "18rem";
1605
+ var SIDEBAR_WIDTH_ICON = "3rem";
1606
+ var SIDEBAR_KEYBOARD_SHORTCUT = "b";
1607
+ var SIDEBAR_MIN_WIDTH = 100;
1608
+ var SIDEBAR_MAX_WIDTH = 200;
1609
+ var SidebarContext = React2.createContext(null);
1610
+ function useSidebar() {
1611
+ const context = React2.useContext(SidebarContext);
1612
+ if (!context) {
1613
+ throw new Error("useSidebar must be used within a SidebarProvider.");
1614
+ }
1615
+ return context;
1616
+ }
1617
+ function SidebarProvider(_a) {
1618
+ var _b = _a, {
1619
+ defaultOpen = true,
1620
+ open: openProp,
1621
+ onOpenChange: setOpenProp,
1622
+ className,
1623
+ style,
1624
+ children
1625
+ } = _b, props = __objRest(_b, [
1626
+ "defaultOpen",
1627
+ "open",
1628
+ "onOpenChange",
1629
+ "className",
1630
+ "style",
1631
+ "children"
1632
+ ]);
1633
+ const isMobile = useIsMobile();
1634
+ const [openMobile, setOpenMobile] = React2.useState(false);
1635
+ const [_open, _setOpen] = React2.useState(defaultOpen);
1636
+ const open = openProp != null ? openProp : _open;
1637
+ const [sidebarWidth, setSidebarWidth] = React2.useState(256);
1638
+ const setOpen = React2.useCallback(
1639
+ (value) => {
1640
+ const openState = typeof value === "function" ? value(open) : value;
1641
+ if (setOpenProp) {
1642
+ setOpenProp(openState);
1643
+ } else {
1644
+ _setOpen(openState);
1645
+ }
1646
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
1647
+ },
1648
+ [setOpenProp, open]
1649
+ );
1650
+ const toggleSidebar = React2.useCallback(() => {
1651
+ return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
1652
+ }, [isMobile, setOpen, setOpenMobile]);
1653
+ React2.useEffect(() => {
1654
+ const handleKeyDown = (event) => {
1655
+ if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
1656
+ event.preventDefault();
1657
+ toggleSidebar();
1658
+ }
1659
+ };
1660
+ window.addEventListener("keydown", handleKeyDown);
1661
+ return () => window.removeEventListener("keydown", handleKeyDown);
1662
+ }, [toggleSidebar]);
1663
+ const state = open ? "expanded" : "collapsed";
1664
+ const contextValue = React2.useMemo(
1665
+ () => ({
1666
+ state,
1667
+ open,
1668
+ setOpen,
1669
+ isMobile,
1670
+ openMobile,
1671
+ setOpenMobile,
1672
+ toggleSidebar,
1673
+ sidebarWidth,
1674
+ setSidebarWidth
1675
+ }),
1676
+ [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar, sidebarWidth]
1677
+ );
1678
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1679
+ "div",
1680
+ __spreadProps(__spreadValues({
1681
+ "data-slot": "sidebar-wrapper",
1682
+ style: __spreadValues({
1683
+ "--sidebar-width": `${sidebarWidth}px`,
1684
+ "--sidebar-width-icon": SIDEBAR_WIDTH_ICON
1685
+ }, style),
1686
+ className: cn(
1687
+ "group/sidebar-wrapper flex h-full w-full has-data-[variant=offcanvas]:bg-sidebar",
1688
+ className
1689
+ )
1690
+ }, props), {
1691
+ children
1692
+ })
1693
+ ) }) });
1694
+ }
1695
+ function Sidebar(_a) {
1696
+ var _b = _a, {
1697
+ side = "left",
1698
+ variant = "sidebar",
1699
+ collapsible = "offcanvas",
1700
+ className,
1701
+ children
1702
+ } = _b, props = __objRest(_b, [
1703
+ "side",
1704
+ "variant",
1705
+ "collapsible",
1706
+ "className",
1707
+ "children"
1708
+ ]);
1709
+ const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
1710
+ if (collapsible === "none") {
1711
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1712
+ "div",
1713
+ __spreadProps(__spreadValues({
1714
+ "data-slot": "sidebar",
1715
+ className: cn(
1716
+ "flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground",
1717
+ className
1718
+ )
1719
+ }, props), {
1720
+ children
1721
+ })
1722
+ );
1723
+ }
1724
+ if (isMobile) {
1725
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Sheet, __spreadProps(__spreadValues({ open: openMobile, onOpenChange: setOpenMobile }, props), { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1726
+ SheetContent,
1727
+ {
1728
+ "data-sidebar": "sidebar",
1729
+ "data-slot": "sidebar",
1730
+ "data-mobile": "true",
1731
+ className: "w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden",
1732
+ style: {
1733
+ "--sidebar-width": SIDEBAR_WIDTH_MOBILE
1734
+ },
1735
+ side,
1736
+ children: [
1737
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(SheetHeader, { className: "sr-only", children: [
1738
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SheetTitle, { children: "Sidebar" }),
1739
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SheetDescription, { children: "Displays the mobile sidebar." })
1740
+ ] }),
1741
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex h-full w-full flex-col", children })
1742
+ ]
1743
+ }
1744
+ ) }));
1745
+ }
1746
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1747
+ "div",
1748
+ {
1749
+ className: cn(
1750
+ "relative group peer hidden text-sidebar-foreground md:block",
1751
+ "w-[var(--sidebar-width)]",
1752
+ "data-[collapsible=offcanvas]:w-0",
1753
+ "transition-[width] duration-200 ease-linear"
1754
+ ),
1755
+ "data-state": state,
1756
+ "data-collapsible": state === "collapsed" ? collapsible : "",
1757
+ "data-variant": variant,
1758
+ "data-side": side,
1759
+ "data-slot": "sidebar",
1760
+ children: [
1761
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1762
+ "div",
1763
+ {
1764
+ "data-slot": "sidebar-gap",
1765
+ className: cn(
1766
+ "relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear",
1767
+ "group-data-[collapsible=offcanvas]:w-0",
1768
+ "group-data-[side=right]:rotate-180",
1769
+ variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
1770
+ )
1771
+ }
1772
+ ),
1773
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1774
+ "div",
1775
+ __spreadProps(__spreadValues({
1776
+ "data-slot": "sidebar-container",
1777
+ className: cn(
1778
+ "fixed inset-y-0 z-10 hidden h-full w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex",
1779
+ side === "left" ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]" : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
1780
+ // Adjust the padding for floating and inset variants.
1781
+ variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
1782
+ className
1783
+ )
1784
+ }, props), {
1785
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1786
+ "div",
1787
+ {
1788
+ "data-sidebar": "sidebar",
1789
+ "data-slot": "sidebar-inner",
1790
+ className: "flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow-sm",
1791
+ children
1792
+ }
1793
+ )
1794
+ })
1795
+ )
1796
+ ]
1797
+ }
1798
+ );
1799
+ }
1800
+ function SidebarTrigger(_a) {
1801
+ var _b = _a, {
1802
+ className,
1803
+ onClick
1804
+ } = _b, props = __objRest(_b, [
1805
+ "className",
1806
+ "onClick"
1807
+ ]);
1808
+ const { toggleSidebar } = useSidebar();
1809
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1810
+ Button,
1811
+ __spreadProps(__spreadValues({
1812
+ "data-sidebar": "trigger",
1813
+ "data-slot": "sidebar-trigger",
1814
+ variant: "ghost",
1815
+ size: "icon",
1816
+ className: cn("size-7", className),
1817
+ onClick: (event) => {
1818
+ onClick == null ? void 0 : onClick(event);
1819
+ toggleSidebar();
1820
+ }
1821
+ }, props), {
1822
+ children: [
1823
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react7.PanelLeftIcon, {}),
1824
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sr-only", children: "Toggle Sidebar" })
1825
+ ]
1826
+ })
1827
+ );
1828
+ }
1829
+ function SidebarRail(_a) {
1830
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1831
+ const { toggleSidebar, sidebarWidth, setSidebarWidth, setOpen } = useSidebar();
1832
+ const isDraggingRef = React2.useRef(false);
1833
+ const startXRef = React2.useRef(0);
1834
+ const startWidthRef = React2.useRef(0);
1835
+ const hasDraggedRef = React2.useRef(false);
1836
+ const rafRef = React2.useRef(null);
1837
+ const handleMouseDown = React2.useCallback(
1838
+ (e) => {
1839
+ e.preventDefault();
1840
+ isDraggingRef.current = true;
1841
+ hasDraggedRef.current = false;
1842
+ startXRef.current = e.clientX;
1843
+ startWidthRef.current = sidebarWidth;
1844
+ document.body.style.cursor = "ew-resize";
1845
+ document.body.style.userSelect = "none";
1846
+ },
1847
+ [sidebarWidth]
1848
+ );
1849
+ React2.useEffect(() => {
1850
+ const handleMouseMove = (e) => {
1851
+ if (!isDraggingRef.current) return;
1852
+ if (rafRef.current) {
1853
+ cancelAnimationFrame(rafRef.current);
1854
+ }
1855
+ rafRef.current = requestAnimationFrame(() => {
1856
+ const deltaX = e.clientX - startXRef.current;
1857
+ if (Math.abs(deltaX) > 5) {
1858
+ hasDraggedRef.current = true;
1859
+ }
1860
+ const rawWidth = startWidthRef.current + deltaX;
1861
+ if (rawWidth < SIDEBAR_MIN_WIDTH) {
1862
+ setOpen(false);
1863
+ } else {
1864
+ setOpen(true);
1865
+ setSidebarWidth(Math.min(SIDEBAR_MAX_WIDTH, rawWidth));
1866
+ }
1867
+ });
1868
+ };
1869
+ const handleMouseUp = () => {
1870
+ if (!isDraggingRef.current) return;
1871
+ isDraggingRef.current = false;
1872
+ document.body.style.cursor = "";
1873
+ document.body.style.userSelect = "";
1874
+ if (rafRef.current) {
1875
+ cancelAnimationFrame(rafRef.current);
1876
+ }
1877
+ };
1878
+ document.addEventListener("mousemove", handleMouseMove);
1879
+ document.addEventListener("mouseup", handleMouseUp);
1880
+ return () => {
1881
+ document.removeEventListener("mousemove", handleMouseMove);
1882
+ document.removeEventListener("mouseup", handleMouseUp);
1883
+ };
1884
+ }, [setSidebarWidth, setOpen]);
1885
+ const handleClick = React2.useCallback(() => {
1886
+ if (!hasDraggedRef.current) {
1887
+ toggleSidebar();
1888
+ }
1889
+ }, [toggleSidebar]);
1890
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1891
+ "button",
1892
+ __spreadValues({
1893
+ "data-sidebar": "rail",
1894
+ "data-slot": "sidebar-rail",
1895
+ "aria-label": "Toggle Sidebar",
1896
+ tabIndex: -1,
1897
+ onMouseDown: handleMouseDown,
1898
+ onClick: handleClick,
1899
+ title: "Drag to resize, click to toggle",
1900
+ className: cn(
1901
+ "absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex",
1902
+ "cursor-ew-resize",
1903
+ "group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar",
1904
+ "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
1905
+ "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
1906
+ className
1907
+ )
1908
+ }, props)
1909
+ );
1910
+ }
1911
+ function SidebarInset(_a) {
1912
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1913
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1914
+ "main",
1915
+ __spreadValues({
1916
+ "data-slot": "sidebar-inset",
1917
+ className: cn("relative flex w-full flex-1 flex-col bg-background", className)
1918
+ }, props)
1919
+ );
1920
+ }
1921
+ function SidebarHeader(_a) {
1922
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1923
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1924
+ "div",
1925
+ __spreadValues({
1926
+ "data-slot": "sidebar-header",
1927
+ "data-sidebar": "header",
1928
+ className: cn("flex flex-col gap-2 p-2", className)
1929
+ }, props)
1930
+ );
1931
+ }
1932
+ function SidebarFooter(_a) {
1933
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1934
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1935
+ "div",
1936
+ __spreadValues({
1937
+ "data-slot": "sidebar-footer",
1938
+ "data-sidebar": "footer",
1939
+ className: cn("flex mr-2 flex-col gap-2 p-2", className)
1940
+ }, props)
1941
+ );
1942
+ }
1943
+ function SidebarSeparator(_a) {
1944
+ var _b = _a, {
1945
+ className
1946
+ } = _b, props = __objRest(_b, [
1947
+ "className"
1948
+ ]);
1949
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1950
+ Separator,
1951
+ __spreadValues({
1952
+ "data-slot": "sidebar-separator",
1953
+ "data-sidebar": "separator",
1954
+ className: cn("mx-2 w-auto bg-sidebar-border", className)
1955
+ }, props)
1956
+ );
1957
+ }
1958
+ function SidebarContent(_a) {
1959
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1960
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1961
+ "div",
1962
+ __spreadValues({
1963
+ "data-slot": "sidebar-content",
1964
+ "data-sidebar": "content",
1965
+ className: cn(
1966
+ "flex mr-2 min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
1967
+ className
1968
+ )
1969
+ }, props)
1970
+ );
1971
+ }
1972
+ function SidebarGroup(_a) {
1973
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1974
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1975
+ "div",
1976
+ __spreadValues({
1977
+ "data-slot": "sidebar-group",
1978
+ "data-sidebar": "group",
1979
+ className: cn("relative flex w-full min-w-0 flex-col p-2", className)
1980
+ }, props)
1981
+ );
1982
+ }
1983
+ function SidebarGroupLabel(_a) {
1984
+ var _b = _a, {
1985
+ className,
1986
+ asChild = false
1987
+ } = _b, props = __objRest(_b, [
1988
+ "className",
1989
+ "asChild"
1990
+ ]);
1991
+ const Comp = asChild ? import_react_slot3.Slot : "div";
1992
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1993
+ Comp,
1994
+ __spreadValues({
1995
+ "data-slot": "sidebar-group-label",
1996
+ "data-sidebar": "group-label",
1997
+ className: cn(
1998
+ "flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
1999
+ "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
2000
+ className
2001
+ )
2002
+ }, props)
2003
+ );
2004
+ }
2005
+ function SidebarGroupAction(_a) {
2006
+ var _b = _a, {
2007
+ className,
2008
+ asChild = false
2009
+ } = _b, props = __objRest(_b, [
2010
+ "className",
2011
+ "asChild"
2012
+ ]);
2013
+ const Comp = asChild ? import_react_slot3.Slot : "button";
2014
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2015
+ Comp,
2016
+ __spreadValues({
2017
+ "data-slot": "sidebar-group-action",
2018
+ "data-sidebar": "group-action",
2019
+ className: cn(
2020
+ "absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
2021
+ // Increases the hit area of the button on mobile.
2022
+ "after:absolute after:-inset-2 md:after:hidden",
2023
+ "group-data-[collapsible=icon]:hidden",
2024
+ className
2025
+ )
2026
+ }, props)
2027
+ );
2028
+ }
2029
+ function SidebarGroupContent(_a) {
2030
+ var _b = _a, {
2031
+ className
2032
+ } = _b, props = __objRest(_b, [
2033
+ "className"
2034
+ ]);
2035
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2036
+ "div",
2037
+ __spreadValues({
2038
+ "data-slot": "sidebar-group-content",
2039
+ "data-sidebar": "group-content",
2040
+ className: cn("w-full text-sm", className)
2041
+ }, props)
2042
+ );
2043
+ }
2044
+ function SidebarMenu(_a) {
2045
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2046
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2047
+ "ul",
2048
+ __spreadValues({
2049
+ "data-slot": "sidebar-menu",
2050
+ "data-sidebar": "menu",
2051
+ className: cn("flex w-full min-w-0 flex-col gap-1", className)
2052
+ }, props)
2053
+ );
2054
+ }
2055
+ function SidebarMenuItem(_a) {
2056
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2057
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2058
+ "li",
2059
+ __spreadValues({
2060
+ "data-slot": "sidebar-menu-item",
2061
+ "data-sidebar": "menu-item",
2062
+ className: cn("group/menu-item relative", className)
2063
+ }, props)
2064
+ );
2065
+ }
2066
+ var sidebarMenuButtonVariants = (0, import_class_variance_authority2.cva)(
2067
+ "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
2068
+ {
2069
+ variants: {
2070
+ variant: {
2071
+ default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
2072
+ outline: "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]"
2073
+ },
2074
+ size: {
2075
+ default: "h-8 text-sm",
2076
+ sm: "h-7 text-xs",
2077
+ lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!"
2078
+ }
2079
+ },
2080
+ defaultVariants: {
2081
+ variant: "default",
2082
+ size: "default"
2083
+ }
2084
+ }
2085
+ );
2086
+ function SidebarMenuButton(_a) {
2087
+ var _b = _a, {
2088
+ asChild = false,
2089
+ isActive = false,
2090
+ variant = "default",
2091
+ size = "default",
2092
+ tooltip,
2093
+ className
2094
+ } = _b, props = __objRest(_b, [
2095
+ "asChild",
2096
+ "isActive",
2097
+ "variant",
2098
+ "size",
2099
+ "tooltip",
2100
+ "className"
2101
+ ]);
2102
+ const Comp = asChild ? import_react_slot3.Slot : "button";
2103
+ const { isMobile, state } = useSidebar();
2104
+ const button = /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2105
+ Comp,
2106
+ __spreadValues({
2107
+ "data-slot": "sidebar-menu-button",
2108
+ "data-sidebar": "menu-button",
2109
+ "data-size": size,
2110
+ "data-active": isActive,
2111
+ className: cn(sidebarMenuButtonVariants({ variant, size }), className)
2112
+ }, props)
2113
+ );
2114
+ if (!tooltip) {
2115
+ return button;
2116
+ }
2117
+ if (typeof tooltip === "string") {
2118
+ tooltip = {
2119
+ children: tooltip
2120
+ };
2121
+ }
2122
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Tooltip, { children: [
2123
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooltipTrigger, { asChild: true, children: button }),
2124
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2125
+ TooltipContent,
2126
+ __spreadValues({
2127
+ side: "right",
2128
+ align: "center",
2129
+ hidden: state !== "collapsed" || isMobile
2130
+ }, tooltip)
2131
+ )
2132
+ ] });
2133
+ }
2134
+ function SidebarMenuAction(_a) {
2135
+ var _b = _a, {
2136
+ className,
2137
+ asChild = false,
2138
+ showOnHover = false
2139
+ } = _b, props = __objRest(_b, [
2140
+ "className",
2141
+ "asChild",
2142
+ "showOnHover"
2143
+ ]);
2144
+ const Comp = asChild ? import_react_slot3.Slot : "button";
2145
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2146
+ Comp,
2147
+ __spreadValues({
2148
+ "data-slot": "sidebar-menu-action",
2149
+ "data-sidebar": "menu-action",
2150
+ className: cn(
2151
+ "absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform peer-hover/menu-button:text-sidebar-accent-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
2152
+ // Increases the hit area of the button on mobile.
2153
+ "after:absolute after:-inset-2 md:after:hidden",
2154
+ "peer-data-[size=sm]/menu-button:top-1",
2155
+ "peer-data-[size=default]/menu-button:top-1.5",
2156
+ "peer-data-[size=lg]/menu-button:top-2.5",
2157
+ "group-data-[collapsible=icon]:hidden",
2158
+ showOnHover && "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground data-[state=open]:opacity-100 md:opacity-0",
2159
+ className
2160
+ )
2161
+ }, props)
2162
+ );
2163
+ }
2164
+ function SidebarMenuBadge(_a) {
2165
+ var _b = _a, {
2166
+ className
2167
+ } = _b, props = __objRest(_b, [
2168
+ "className"
2169
+ ]);
2170
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2171
+ "div",
2172
+ __spreadValues({
2173
+ "data-slot": "sidebar-menu-badge",
2174
+ "data-sidebar": "menu-badge",
2175
+ className: cn(
2176
+ "pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none",
2177
+ "peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
2178
+ "peer-data-[size=sm]/menu-button:top-1",
2179
+ "peer-data-[size=default]/menu-button:top-1.5",
2180
+ "peer-data-[size=lg]/menu-button:top-2.5",
2181
+ "group-data-[collapsible=icon]:hidden",
2182
+ className
2183
+ )
2184
+ }, props)
2185
+ );
2186
+ }
2187
+ function SidebarMenuSub(_a) {
2188
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2189
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2190
+ "ul",
2191
+ __spreadValues({
2192
+ "data-slot": "sidebar-menu-sub",
2193
+ "data-sidebar": "menu-sub",
2194
+ className: cn(
2195
+ "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5",
2196
+ "group-data-[collapsible=icon]:hidden",
2197
+ className
2198
+ )
2199
+ }, props)
2200
+ );
2201
+ }
2202
+ function SidebarMenuSubItem(_a) {
2203
+ var _b = _a, {
2204
+ className
2205
+ } = _b, props = __objRest(_b, [
2206
+ "className"
2207
+ ]);
2208
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2209
+ "li",
2210
+ __spreadValues({
2211
+ "data-slot": "sidebar-menu-sub-item",
2212
+ "data-sidebar": "menu-sub-item",
2213
+ className: cn("group/menu-sub-item relative", className)
2214
+ }, props)
2215
+ );
2216
+ }
2217
+ function SidebarMenuSubButton(_a) {
2218
+ var _b = _a, {
2219
+ asChild = false,
2220
+ size = "md",
2221
+ isActive = false,
2222
+ className
2223
+ } = _b, props = __objRest(_b, [
2224
+ "asChild",
2225
+ "size",
2226
+ "isActive",
2227
+ "className"
2228
+ ]);
2229
+ const Comp = asChild ? import_react_slot3.Slot : "a";
2230
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2231
+ Comp,
2232
+ __spreadValues({
2233
+ "data-slot": "sidebar-menu-sub-button",
2234
+ "data-sidebar": "menu-sub-button",
2235
+ "data-size": size,
2236
+ "data-active": isActive,
2237
+ className: cn(
2238
+ "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
2239
+ "data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground",
2240
+ size === "sm" && "text-xs",
2241
+ size === "md" && "text-sm",
2242
+ "group-data-[collapsible=icon]:hidden",
2243
+ className
2244
+ )
2245
+ }, props)
2246
+ );
2247
+ }
2248
+
2249
+ // src/components/assistant-ui/thread-list.tsx
2250
+ var import_react11 = require("@assistant-ui/react");
2251
+ var import_lucide_react8 = require("lucide-react");
2252
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2253
+ var ThreadList = () => {
2254
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react11.ThreadListPrimitive.Root, { className: "aui-root aui-thread-list-root flex flex-col items-stretch gap-1.5", children: [
2255
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ThreadListNew, {}),
2256
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ThreadListItems, {})
2257
+ ] });
2258
+ };
2259
+ var ThreadListNew = () => {
2260
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react11.ThreadListPrimitive.New, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2261
+ Button,
2262
+ {
2263
+ className: "aui-thread-list-new flex items-center justify-start gap-1 rounded-lg px-2.5 py-2 text-start hover:bg-muted data-active:bg-muted",
2264
+ variant: "ghost",
2265
+ children: [
2266
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react8.PlusIcon, {}),
2267
+ "New Chat"
2268
+ ]
2269
+ }
2270
+ ) });
2271
+ };
2272
+ var ThreadListItems = () => {
2273
+ const isLoading = (0, import_react11.useAssistantState)(({ threads }) => threads.isLoading);
2274
+ if (isLoading) {
2275
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ThreadListSkeleton, {});
2276
+ }
2277
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react11.ThreadListPrimitive.Items, { components: { ThreadListItem } });
2278
+ };
2279
+ var ThreadListSkeleton = () => {
2280
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: Array.from({ length: 5 }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2281
+ "div",
2282
+ {
2283
+ role: "status",
2284
+ "aria-label": "Loading threads",
2285
+ "aria-live": "polite",
2286
+ className: "aui-thread-list-skeleton-wrapper flex items-center gap-2 rounded-md px-3 py-2",
2287
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Skeleton, { className: "aui-thread-list-skeleton h-[22px] flex-grow" })
2288
+ },
2289
+ i
2290
+ )) });
2291
+ };
2292
+ var ThreadListItem = () => {
2293
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react11.ThreadListItemPrimitive.Root, { className: "aui-thread-list-item flex items-center gap-2 rounded-lg transition-all hover:bg-muted focus-visible:bg-muted focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none data-active:bg-muted", children: [
2294
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react11.ThreadListItemPrimitive.Trigger, { className: "aui-thread-list-item-trigger flex-grow px-3 py-2 text-start", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ThreadListItemTitle, {}) }),
2295
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ThreadListItemDelete, {})
2296
+ ] });
2297
+ };
2298
+ var ThreadListItemTitle = () => {
2299
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "aui-thread-list-item-title text-sm", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react11.ThreadListItemPrimitive.Title, { fallback: "New Chat" }) });
2300
+ };
2301
+ var ThreadListItemDelete = () => {
2302
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react11.ThreadListItemPrimitive.Delete, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2303
+ TooltipIconButton,
2304
+ {
2305
+ className: "aui-thread-list-item-delete mr-3 ml-auto size-4 p-0 text-foreground hover:text-primary",
2306
+ variant: "ghost",
2307
+ tooltip: "Delete thread",
2308
+ onClick: (event) => {
2309
+ const confirmed = window.confirm(
2310
+ "Delete this chat? This action cannot be undone."
2311
+ );
2312
+ if (!confirmed) {
2313
+ event.preventDefault();
2314
+ event.stopPropagation();
2315
+ }
2316
+ },
2317
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react8.TrashIcon, {})
2318
+ }
2319
+ ) });
2320
+ };
2321
+
2322
+ // src/components/assistant-ui/threadlist-sidebar.tsx
2323
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2324
+ function ThreadListSidebar(_a) {
2325
+ var _b = _a, {
2326
+ footer
2327
+ } = _b, props = __objRest(_b, [
2328
+ "footer"
2329
+ ]);
2330
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2331
+ Sidebar,
2332
+ __spreadProps(__spreadValues({
2333
+ collapsible: "offcanvas",
2334
+ variant: "inset",
2335
+ className: "relative"
2336
+ }, props), {
2337
+ children: [
2338
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SidebarHeader, { className: "aomi-sidebar-header", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "aomi-sidebar-header-content flex items-center justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SidebarMenu, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SidebarMenuButton, { size: "lg", asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2339
+ import_link.default,
2340
+ {
2341
+ href: "https://aomi.dev",
2342
+ target: "_blank",
2343
+ rel: "noopener noreferrer",
2344
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "aomi-sidebar-header-icon-wrapper flex aspect-square size-8 items-center justify-center rounded-lg bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2345
+ import_image2.default,
2346
+ {
2347
+ src: "/assets/images/a.svg",
2348
+ alt: "Logo",
2349
+ width: 28,
2350
+ height: 28,
2351
+ className: "aomi-sidebar-header-icon size-7 ml-3",
2352
+ priority: true
2353
+ }
2354
+ ) })
2355
+ }
2356
+ ) }) }) }) }) }),
2357
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SidebarContent, { className: "aomi-sidebar-content", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ThreadList, {}) }),
2358
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SidebarRail, {}),
2359
+ footer && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SidebarFooter, { className: "aomi-sidebar-footer border-t border-sm py-4", children: footer })
2360
+ ]
2361
+ })
2362
+ );
2363
+ }
2364
+
2365
+ // src/components/ui/breadcrumb.tsx
2366
+ var import_react_slot4 = require("@radix-ui/react-slot");
2367
+ var import_lucide_react9 = require("lucide-react");
2368
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2369
+ function Breadcrumb(_a) {
2370
+ var props = __objRest(_a, []);
2371
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("nav", __spreadValues({ "aria-label": "breadcrumb", "data-slot": "breadcrumb" }, props));
2372
+ }
2373
+ function BreadcrumbList(_a) {
2374
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2375
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2376
+ "ol",
2377
+ __spreadValues({
2378
+ "data-slot": "breadcrumb-list",
2379
+ className: cn(
2380
+ "flex flex-wrap items-center gap-1.5 text-sm break-words text-muted-foreground sm:gap-2.5",
2381
+ className
2382
+ )
2383
+ }, props)
2384
+ );
2385
+ }
2386
+ function BreadcrumbItem(_a) {
2387
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2388
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2389
+ "li",
2390
+ __spreadValues({
2391
+ "data-slot": "breadcrumb-item",
2392
+ className: cn("inline-flex items-center gap-1.5", className)
2393
+ }, props)
2394
+ );
2395
+ }
2396
+ function BreadcrumbLink(_a) {
2397
+ var _b = _a, {
2398
+ asChild,
2399
+ className
2400
+ } = _b, props = __objRest(_b, [
2401
+ "asChild",
2402
+ "className"
2403
+ ]);
2404
+ const Comp = asChild ? import_react_slot4.Slot : "a";
2405
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2406
+ Comp,
2407
+ __spreadValues({
2408
+ "data-slot": "breadcrumb-link",
2409
+ className: cn("transition-colors hover:text-foreground", className)
2410
+ }, props)
2411
+ );
2412
+ }
2413
+ function BreadcrumbPage(_a) {
2414
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2415
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2416
+ "span",
2417
+ __spreadValues({
2418
+ "data-slot": "breadcrumb-page",
2419
+ role: "link",
2420
+ "aria-disabled": "true",
2421
+ "aria-current": "page",
2422
+ className: cn("font-normal text-foreground", className)
2423
+ }, props)
2424
+ );
2425
+ }
2426
+ function BreadcrumbSeparator(_a) {
2427
+ var _b = _a, {
2428
+ children,
2429
+ className
2430
+ } = _b, props = __objRest(_b, [
2431
+ "children",
2432
+ "className"
2433
+ ]);
2434
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2435
+ "li",
2436
+ __spreadProps(__spreadValues({
2437
+ "data-slot": "breadcrumb-separator",
2438
+ role: "presentation",
2439
+ "aria-hidden": "true",
2440
+ className: cn("[&>svg]:size-3.5", className)
2441
+ }, props), {
2442
+ children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react9.ChevronRight, {})
2443
+ })
2444
+ );
2445
+ }
2446
+ function BreadcrumbEllipsis(_a) {
2447
+ var _b = _a, {
2448
+ className
2449
+ } = _b, props = __objRest(_b, [
2450
+ "className"
2451
+ ]);
2452
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2453
+ "span",
2454
+ __spreadProps(__spreadValues({
2455
+ "data-slot": "breadcrumb-ellipsis",
2456
+ role: "presentation",
2457
+ "aria-hidden": "true",
2458
+ className: cn("flex size-9 items-center justify-center", className)
2459
+ }, props), {
2460
+ children: [
2461
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react9.MoreHorizontal, { className: "size-4" }),
2462
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sr-only", children: "More" })
2463
+ ]
2464
+ })
2465
+ );
2466
+ }
2467
+
2468
+ // src/components/assistant-ui/runtime.tsx
2469
+ var import_react12 = require("react");
2470
+ var import_react13 = require("@assistant-ui/react");
2471
+
2472
+ // src/lib/backend-api.ts
2473
+ function toQueryString(payload) {
2474
+ const params = new URLSearchParams();
2475
+ for (const [key, value] of Object.entries(payload)) {
2476
+ if (value === void 0 || value === null) continue;
2477
+ params.set(key, String(value));
2478
+ }
2479
+ const qs = params.toString();
2480
+ return qs ? `?${qs}` : "";
2481
+ }
2482
+ async function postState(backendUrl, path, payload) {
2483
+ const query = toQueryString(payload);
2484
+ const url = `${backendUrl}${path}${query}`;
2485
+ console.log("\u{1F535} [postState] URL:", url);
2486
+ console.log("\u{1F535} [postState] Payload:", payload);
2487
+ const response = await fetch(url, {
2488
+ method: "POST"
2489
+ });
2490
+ console.log("\u{1F535} [postState] Response status:", response.status);
2491
+ if (!response.ok) {
2492
+ console.error("\u{1F534} [postState] Error:", response.status, response.statusText);
2493
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
2494
+ }
2495
+ const data = await response.json();
2496
+ console.log("\u{1F7E2} [postState] Success:", data);
2497
+ return data;
2498
+ }
2499
+ var BackendApi = class {
2500
+ constructor(backendUrl) {
2501
+ this.backendUrl = backendUrl;
2502
+ this.connectionStatus = false;
2503
+ this.eventSource = null;
2504
+ this.updatesEventSource = null;
2505
+ }
2506
+ async fetchState(sessionId) {
2507
+ console.log("\u{1F535} [fetchState] Called with sessionId:", sessionId);
2508
+ const url = `${this.backendUrl}/api/state?session_id=${encodeURIComponent(sessionId)}`;
2509
+ console.log("\u{1F535} [fetchState] URL:", url);
2510
+ const response = await fetch(url);
2511
+ console.log("\u{1F535} [fetchState] Response status:", response.status, response.statusText);
2512
+ if (!response.ok) {
2513
+ console.error("\u{1F534} [fetchState] Error:", response.status, response.statusText);
2514
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
2515
+ }
2516
+ const data = await response.json();
2517
+ console.log("\u{1F7E2} [fetchState] Success:", data);
2518
+ return data;
2519
+ }
2520
+ async postChatMessage(sessionId, message) {
2521
+ console.log("\u{1F535} [postChatMessage] Called with sessionId:", sessionId, "message:", message);
2522
+ const result = await postState(this.backendUrl, "/api/chat", { message, session_id: sessionId });
2523
+ console.log("\u{1F7E2} [postChatMessage] Success:", result);
2524
+ return result;
2525
+ }
2526
+ async postSystemMessage(sessionId, message) {
2527
+ console.log("\u{1F535} [postSystemMessage] Called with sessionId:", sessionId, "message:", message);
2528
+ const result = await postState(this.backendUrl, "/api/system", { message, session_id: sessionId });
2529
+ console.log("\u{1F7E2} [postSystemMessage] Success:", result);
2530
+ return result;
2531
+ }
2532
+ async postInterrupt(sessionId) {
2533
+ console.log("\u{1F535} [postInterrupt] Called with sessionId:", sessionId);
2534
+ const result = await postState(this.backendUrl, "/api/interrupt", { session_id: sessionId });
2535
+ console.log("\u{1F7E2} [postInterrupt] Success:", result);
2536
+ return result;
2537
+ }
2538
+ disconnectSSE() {
2539
+ if (this.eventSource) {
2540
+ this.eventSource.close();
2541
+ this.eventSource = null;
2542
+ }
2543
+ this.setConnectionStatus(false);
2544
+ }
2545
+ setConnectionStatus(on) {
2546
+ this.connectionStatus = on;
2547
+ }
2548
+ async connectSSE(sessionId, publicKey) {
2549
+ this.disconnectSSE();
2550
+ try {
2551
+ const url = new URL(`${this.backendUrl}/api/chat/stream`);
2552
+ url.searchParams.set("session_id", sessionId);
2553
+ if (publicKey) {
2554
+ url.searchParams.set("public_key", publicKey);
2555
+ }
2556
+ this.eventSource = new EventSource(url.toString());
2557
+ this.eventSource.onopen = () => {
2558
+ console.log("\u{1F310} SSE connection opened to:", url.toString());
2559
+ this.setConnectionStatus(true);
2560
+ };
2561
+ this.eventSource.onmessage = (event) => {
2562
+ try {
2563
+ const data = JSON.parse(event.data);
2564
+ } catch (error) {
2565
+ console.error("Failed to parse SSE data:", error);
2566
+ }
2567
+ };
2568
+ this.eventSource.onerror = (error) => {
2569
+ console.error("SSE connection error:", error);
2570
+ };
2571
+ } catch (error) {
2572
+ console.error("Failed to establish SSE connection:", error);
2573
+ this.handleConnectionError(sessionId, publicKey);
2574
+ }
2575
+ }
2576
+ handleConnectionError(sessionId, publicKey) {
2577
+ this.setConnectionStatus(false);
2578
+ let attempt = 0;
2579
+ let total = 3;
2580
+ if (attempt < total) {
2581
+ attempt++;
2582
+ console.log(`Attempting to reconnect (${attempt}/${total})...`);
2583
+ setTimeout(() => {
2584
+ this.connectSSE(sessionId, publicKey);
2585
+ }, 100);
2586
+ } else {
2587
+ console.error("Max reconnection attempts reached");
2588
+ this.setConnectionStatus(false);
2589
+ }
2590
+ }
2591
+ subscribeToUpdates(onUpdate, onError) {
2592
+ if (this.updatesEventSource) {
2593
+ this.updatesEventSource.close();
2594
+ }
2595
+ const updatesUrl = new URL("/api/updates", this.backendUrl).toString();
2596
+ this.updatesEventSource = new EventSource(updatesUrl);
2597
+ this.updatesEventSource.onmessage = (event) => {
2598
+ try {
2599
+ const parsed = JSON.parse(event.data);
2600
+ onUpdate(parsed);
2601
+ } catch (error) {
2602
+ console.error("Failed to parse system update SSE:", error);
2603
+ onError == null ? void 0 : onError(error);
2604
+ }
2605
+ };
2606
+ this.updatesEventSource.onerror = (error) => {
2607
+ console.error("System updates SSE error:", error);
2608
+ onError == null ? void 0 : onError(error);
2609
+ };
2610
+ return () => {
2611
+ if (this.updatesEventSource) {
2612
+ this.updatesEventSource.close();
2613
+ this.updatesEventSource = null;
2614
+ }
2615
+ };
2616
+ }
2617
+ // ==================== Thread Management API ====================
2618
+ /**
2619
+ * Fetch all threads/sessions for a given public key
2620
+ * @param publicKey - User's wallet address
2621
+ * @returns Array of thread metadata
2622
+ */
2623
+ async fetchThreads(publicKey) {
2624
+ console.log("\u{1F535} [fetchThreads] Called with publicKey:", publicKey);
2625
+ const url = `${this.backendUrl}/api/sessions?public_key=${encodeURIComponent(publicKey)}`;
2626
+ console.log("\u{1F535} [fetchThreads] URL:", url);
2627
+ const response = await fetch(url);
2628
+ console.log("\u{1F535} [fetchThreads] Response status:", response.status);
2629
+ if (!response.ok) {
2630
+ console.error("\u{1F534} [fetchThreads] Error:", response.status);
2631
+ throw new Error(`Failed to fetch threads: HTTP ${response.status}`);
2632
+ }
2633
+ const data = await response.json();
2634
+ console.log("\u{1F7E2} [fetchThreads] Success:", data);
2635
+ return data;
2636
+ }
2637
+ /**
2638
+ * Create a new thread/session
2639
+ * @param publicKey - Optional user's wallet address
2640
+ * @param title - Thread title (keep empty for backend to own the title)
2641
+ * @returns Created thread information with backend-generated ID
2642
+ */
2643
+ async createThread(publicKey, title) {
2644
+ console.log("\u{1F535} [createThread] Called with publicKey:", publicKey, "title:", title);
2645
+ const body = {};
2646
+ if (publicKey) {
2647
+ body.public_key = publicKey;
2648
+ }
2649
+ if (title) {
2650
+ body.title = title;
2651
+ }
2652
+ console.log("\u{1F535} [createThread] Request body:", body);
2653
+ const url = `${this.backendUrl}/api/sessions`;
2654
+ console.log("\u{1F535} [createThread] URL:", url);
2655
+ const response = await fetch(url, {
2656
+ method: "POST",
2657
+ headers: { "Content-Type": "application/json" },
2658
+ body: JSON.stringify(body)
2659
+ });
2660
+ console.log("\u{1F535} [createThread] Response status:", response.status);
2661
+ if (!response.ok) {
2662
+ console.error("\u{1F534} [createThread] Error:", response.status);
2663
+ throw new Error(`Failed to create thread: HTTP ${response.status}`);
2664
+ }
2665
+ const data = await response.json();
2666
+ console.log("\u{1F7E2} [createThread] Success:", data);
2667
+ return data;
2668
+ }
2669
+ /**
2670
+ * Archive a thread/session
2671
+ * @param sessionId - The session ID to archive
2672
+ */
2673
+ async archiveThread(sessionId) {
2674
+ console.log("\u{1F535} [archiveThread] Called with sessionId:", sessionId);
2675
+ const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}/archive`;
2676
+ console.log("\u{1F535} [archiveThread] URL:", url);
2677
+ const response = await fetch(url, { method: "POST" });
2678
+ console.log("\u{1F535} [archiveThread] Response status:", response.status);
2679
+ if (!response.ok) {
2680
+ console.error("\u{1F534} [archiveThread] Error:", response.status);
2681
+ throw new Error(`Failed to archive thread: HTTP ${response.status}`);
2682
+ }
2683
+ console.log("\u{1F7E2} [archiveThread] Success");
2684
+ }
2685
+ /**
2686
+ * Unarchive a thread/session
2687
+ * @param sessionId - The session ID to unarchive
2688
+ */
2689
+ async unarchiveThread(sessionId) {
2690
+ console.log("\u{1F535} [unarchiveThread] Called with sessionId:", sessionId);
2691
+ const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}/unarchive`;
2692
+ console.log("\u{1F535} [unarchiveThread] URL:", url);
2693
+ const response = await fetch(url, { method: "POST" });
2694
+ console.log("\u{1F535} [unarchiveThread] Response status:", response.status);
2695
+ if (!response.ok) {
2696
+ console.error("\u{1F534} [unarchiveThread] Error:", response.status);
2697
+ throw new Error(`Failed to unarchive thread: HTTP ${response.status}`);
2698
+ }
2699
+ console.log("\u{1F7E2} [unarchiveThread] Success");
2700
+ }
2701
+ /**
2702
+ * Delete a thread/session permanently
2703
+ * @param sessionId - The session ID to delete
2704
+ */
2705
+ async deleteThread(sessionId) {
2706
+ console.log("\u{1F535} [deleteThread] Called with sessionId:", sessionId);
2707
+ const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
2708
+ console.log("\u{1F535} [deleteThread] URL:", url);
2709
+ const response = await fetch(url, { method: "DELETE" });
2710
+ console.log("\u{1F535} [deleteThread] Response status:", response.status);
2711
+ if (!response.ok) {
2712
+ console.error("\u{1F534} [deleteThread] Error:", response.status);
2713
+ throw new Error(`Failed to delete thread: HTTP ${response.status}`);
2714
+ }
2715
+ console.log("\u{1F7E2} [deleteThread] Success");
2716
+ }
2717
+ /**
2718
+ * Rename a thread/session
2719
+ * @param sessionId - The session ID to rename
2720
+ * @param newTitle - The new title for the thread
2721
+ */
2722
+ async renameThread(sessionId, newTitle) {
2723
+ console.log("\u{1F535} [renameThread] Called with sessionId:", sessionId, "newTitle:", newTitle);
2724
+ const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
2725
+ console.log("\u{1F535} [renameThread] URL:", url);
2726
+ const response = await fetch(url, {
2727
+ method: "PATCH",
2728
+ headers: { "Content-Type": "application/json" },
2729
+ body: JSON.stringify({ title: newTitle })
2730
+ });
2731
+ console.log("\u{1F535} [renameThread] Response status:", response.status);
2732
+ if (!response.ok) {
2733
+ console.error("\u{1F534} [renameThread] Error:", response.status);
2734
+ throw new Error(`Failed to rename thread: HTTP ${response.status}`);
2735
+ }
2736
+ console.log("\u{1F7E2} [renameThread] Success");
2737
+ }
2738
+ };
2739
+
2740
+ // src/lib/conversion.ts
2741
+ function constructThreadMessage(msg) {
2742
+ var _a;
2743
+ if (msg.sender === "system") return null;
2744
+ const content = [];
2745
+ const role = msg.sender === "user" ? "user" : "assistant";
2746
+ if (msg.content) {
2747
+ content.push({ type: "text", text: msg.content });
2748
+ }
2749
+ const [topic, toolContent] = (_a = parseToolStream(msg.tool_stream)) != null ? _a : [];
2750
+ if (topic && toolContent) {
2751
+ content.push({
2752
+ type: "tool-call",
2753
+ toolCallId: `tool_${Date.now()}`,
2754
+ toolName: topic,
2755
+ args: void 0,
2756
+ result: (() => {
2757
+ try {
2758
+ return JSON.parse(toolContent);
2759
+ } catch (e) {
2760
+ return { args: toolContent };
2761
+ }
2762
+ })()
2763
+ });
2764
+ }
2765
+ const threadMessage = __spreadValues({
2766
+ role,
2767
+ content: content.length > 0 ? content : [{ type: "text", text: "" }]
2768
+ }, msg.timestamp && { createdAt: new Date(msg.timestamp) });
2769
+ return threadMessage;
2770
+ }
2771
+ function constructSystemMessage(msg) {
2772
+ var _a;
2773
+ const [topic] = (_a = parseToolStream(msg.tool_stream)) != null ? _a : [];
2774
+ const messageText = topic || msg.content || "";
2775
+ const timestamp = parseTimestamp(msg.timestamp);
2776
+ if (!messageText.trim()) return null;
2777
+ return __spreadValues({
2778
+ role: "system",
2779
+ content: [{ type: "text", text: messageText }]
2780
+ }, timestamp && { createdAt: timestamp });
2781
+ }
2782
+ function parseTimestamp(timestamp) {
2783
+ if (!timestamp) return void 0;
2784
+ const parsed = new Date(timestamp);
2785
+ return Number.isNaN(parsed.valueOf()) ? void 0 : parsed;
2786
+ }
2787
+ function parseToolStream(toolStream) {
2788
+ if (!toolStream) return null;
2789
+ if (Array.isArray(toolStream) && toolStream.length === 2) {
2790
+ const [topic, content] = toolStream;
2791
+ return [String(topic), content];
2792
+ } else if (typeof toolStream === "object") {
2793
+ const topic = toolStream.topic;
2794
+ const content = toolStream.content;
2795
+ return topic ? [String(topic), String(content)] : null;
2796
+ }
2797
+ return null;
2798
+ }
2799
+
2800
+ // src/components/assistant-ui/runtime.tsx
2801
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2802
+ var RuntimeActionsContext = (0, import_react12.createContext)(void 0);
2803
+ var isTempThreadId = (id) => id.startsWith("temp-");
2804
+ var parseTimestamp2 = (value) => {
2805
+ if (value === void 0 || value === null) return 0;
2806
+ if (typeof value === "number") {
2807
+ return Number.isFinite(value) ? value < 1e12 ? value * 1e3 : value : 0;
2808
+ }
2809
+ const numeric = Number(value);
2810
+ if (!Number.isNaN(numeric)) {
2811
+ return numeric < 1e12 ? numeric * 1e3 : numeric;
2812
+ }
2813
+ const ts = Date.parse(value);
2814
+ return Number.isNaN(ts) ? 0 : ts;
2815
+ };
2816
+ var isPlaceholderTitle = (title) => {
2817
+ var _a;
2818
+ const normalized = (_a = title == null ? void 0 : title.trim()) != null ? _a : "";
2819
+ return !normalized || normalized.startsWith("#[");
2820
+ };
2821
+ var useRuntimeActions = () => {
2822
+ const context = (0, import_react12.useContext)(RuntimeActionsContext);
2823
+ if (!context) {
2824
+ throw new Error("useRuntimeActions must be used within AomiRuntimeProvider");
2825
+ }
2826
+ return context;
2827
+ };
2828
+ function AomiRuntimeProvider({
2829
+ children,
2830
+ backendUrl = "http://localhost:8080",
2831
+ publicKey
2832
+ }) {
2833
+ const {
2834
+ currentThreadId,
2835
+ setCurrentThreadId,
2836
+ bumpThreadViewKey,
2837
+ threads,
2838
+ setThreads,
2839
+ threadMetadata,
2840
+ setThreadMetadata,
2841
+ threadCnt,
2842
+ setThreadCnt,
2843
+ getThreadMessages,
2844
+ setThreadMessages,
2845
+ updateThreadMetadata
2846
+ } = useThreadContext();
2847
+ const [isRunning, setIsRunning] = (0, import_react12.useState)(false);
2848
+ const backendApiRef = (0, import_react12.useRef)(new BackendApi(backendUrl));
2849
+ const pollingIntervalRef = (0, import_react12.useRef)(null);
2850
+ const pendingSystemMessagesRef = (0, import_react12.useRef)(/* @__PURE__ */ new Map());
2851
+ const pendingChatMessagesRef = (0, import_react12.useRef)(/* @__PURE__ */ new Map());
2852
+ const creatingThreadIdRef = (0, import_react12.useRef)(null);
2853
+ const createThreadPromiseRef = (0, import_react12.useRef)(null);
2854
+ const findPendingThreadId = (0, import_react12.useCallback)(() => {
2855
+ if (creatingThreadIdRef.current) return creatingThreadIdRef.current;
2856
+ for (const [id, meta] of threadMetadata.entries()) {
2857
+ if (meta.status === "pending") return id;
2858
+ }
2859
+ return null;
2860
+ }, [threadMetadata]);
2861
+ const currentMessages = getThreadMessages(currentThreadId);
2862
+ const currentThreadIdRef = (0, import_react12.useRef)(currentThreadId);
2863
+ (0, import_react12.useEffect)(() => {
2864
+ currentThreadIdRef.current = currentThreadId;
2865
+ }, [currentThreadId]);
2866
+ const skipInitialFetchRef = (0, import_react12.useRef)(/* @__PURE__ */ new Set());
2867
+ const tempToBackendIdRef = (0, import_react12.useRef)(/* @__PURE__ */ new Map());
2868
+ const resolveThreadId = (0, import_react12.useCallback)((threadId) => {
2869
+ return tempToBackendIdRef.current.get(threadId) || threadId;
2870
+ }, []);
2871
+ const findTempIdForBackendId = (0, import_react12.useCallback)((backendId) => {
2872
+ for (const [tempId, bId] of tempToBackendIdRef.current.entries()) {
2873
+ if (bId === backendId) return tempId;
2874
+ }
2875
+ return void 0;
2876
+ }, []);
2877
+ const isThreadReady = (0, import_react12.useCallback)((threadId) => {
2878
+ if (!isTempThreadId(threadId)) return true;
2879
+ return tempToBackendIdRef.current.has(threadId);
2880
+ }, []);
2881
+ const applyMessages = (0, import_react12.useCallback)((msgs) => {
2882
+ var _a, _b;
2883
+ if (!msgs) return;
2884
+ const hasPendingMessages = pendingChatMessagesRef.current.has(currentThreadId) && ((_b = (_a = pendingChatMessagesRef.current.get(currentThreadId)) == null ? void 0 : _a.length) != null ? _b : 0) > 0;
2885
+ if (hasPendingMessages) {
2886
+ console.log("Skipping applyMessages - pending messages exist for thread:", currentThreadId);
2887
+ return;
2888
+ }
2889
+ const threadMessages = [];
2890
+ for (const msg of msgs) {
2891
+ if (msg.sender === "system") {
2892
+ const systemMessage = constructSystemMessage(msg);
2893
+ if (systemMessage) {
2894
+ threadMessages.push(systemMessage);
2895
+ }
2896
+ continue;
2897
+ }
2898
+ const threadMessage = constructThreadMessage(msg);
2899
+ if (threadMessage) {
2900
+ threadMessages.push(threadMessage);
2901
+ }
2902
+ }
2903
+ setThreadMessages(currentThreadId, threadMessages);
2904
+ }, [currentThreadId, setThreadMessages]);
2905
+ (0, import_react12.useEffect)(() => {
2906
+ backendApiRef.current = new BackendApi(backendUrl);
2907
+ }, [backendUrl]);
2908
+ const stopPolling = (0, import_react12.useCallback)(() => {
2909
+ if (pollingIntervalRef.current) {
2910
+ clearInterval(pollingIntervalRef.current);
2911
+ pollingIntervalRef.current = null;
2912
+ }
2913
+ }, []);
2914
+ const startPolling = (0, import_react12.useCallback)(() => {
2915
+ if (!isThreadReady(currentThreadId)) return;
2916
+ if (pollingIntervalRef.current) return;
2917
+ const backendThreadId = resolveThreadId(currentThreadId);
2918
+ setIsRunning(true);
2919
+ pollingIntervalRef.current = setInterval(async () => {
2920
+ try {
2921
+ const state = await backendApiRef.current.fetchState(backendThreadId);
2922
+ if (state.session_exists === false) {
2923
+ setIsRunning(false);
2924
+ stopPolling();
2925
+ return;
2926
+ }
2927
+ applyMessages(state.messages);
2928
+ if (!state.is_processing) {
2929
+ setIsRunning(false);
2930
+ stopPolling();
2931
+ }
2932
+ } catch (error) {
2933
+ console.error("Polling error:", error);
2934
+ stopPolling();
2935
+ setIsRunning(false);
2936
+ }
2937
+ }, 500);
2938
+ }, [currentThreadId, applyMessages, stopPolling, isThreadReady, resolveThreadId]);
2939
+ (0, import_react12.useEffect)(() => {
2940
+ const fetchInitialState = async () => {
2941
+ if (isTempThreadId(currentThreadId) && !tempToBackendIdRef.current.has(currentThreadId)) {
2942
+ setIsRunning(false);
2943
+ return;
2944
+ }
2945
+ if (skipInitialFetchRef.current.has(currentThreadId)) {
2946
+ skipInitialFetchRef.current.delete(currentThreadId);
2947
+ setIsRunning(false);
2948
+ return;
2949
+ }
2950
+ const backendThreadId = resolveThreadId(currentThreadId);
2951
+ try {
2952
+ const state = await backendApiRef.current.fetchState(backendThreadId);
2953
+ if (state.session_exists === false) {
2954
+ setIsRunning(false);
2955
+ return;
2956
+ }
2957
+ applyMessages(state.messages);
2958
+ if (state.is_processing) {
2959
+ setIsRunning(true);
2960
+ startPolling();
2961
+ } else {
2962
+ setIsRunning(false);
2963
+ }
2964
+ } catch (error) {
2965
+ console.error("Failed to fetch initial state:", error);
2966
+ }
2967
+ };
2968
+ void fetchInitialState();
2969
+ return () => {
2970
+ stopPolling();
2971
+ };
2972
+ }, [currentThreadId, applyMessages, startPolling, stopPolling, resolveThreadId]);
2973
+ (0, import_react12.useEffect)(() => {
2974
+ if (!publicKey) return;
2975
+ const fetchThreadList = async () => {
2976
+ var _a, _b;
2977
+ try {
2978
+ const threadList = await backendApiRef.current.fetchThreads(publicKey);
2979
+ const newMetadata = new Map(threadMetadata);
2980
+ let maxChatNum = threadCnt;
2981
+ for (const thread of threadList) {
2982
+ const rawTitle = (_a = thread.title) != null ? _a : "";
2983
+ const title = isPlaceholderTitle(rawTitle) ? "" : rawTitle;
2984
+ const lastActive = thread.last_active_at || thread.updated_at || thread.created_at || ((_b = newMetadata.get(thread.session_id)) == null ? void 0 : _b.lastActiveAt) || (/* @__PURE__ */ new Date()).toISOString();
2985
+ newMetadata.set(thread.session_id, {
2986
+ title,
2987
+ status: thread.is_archived ? "archived" : "regular",
2988
+ lastActiveAt: lastActive
2989
+ });
2990
+ const match = title.match(/^Chat (\d+)$/);
2991
+ if (match) {
2992
+ const num = parseInt(match[1], 10);
2993
+ if (num > maxChatNum) {
2994
+ maxChatNum = num;
2995
+ }
2996
+ }
2997
+ }
2998
+ setThreadMetadata(newMetadata);
2999
+ if (maxChatNum > threadCnt) {
3000
+ setThreadCnt(maxChatNum);
3001
+ }
3002
+ } catch (error) {
3003
+ console.error("Failed to fetch thread list:", error);
3004
+ }
3005
+ };
3006
+ void fetchThreadList();
3007
+ }, [publicKey]);
3008
+ const threadListAdapter = (() => {
3009
+ const sortByLastActiveDesc = ([, metaA], [, metaB]) => {
3010
+ const tsA = parseTimestamp2(metaA.lastActiveAt);
3011
+ const tsB = parseTimestamp2(metaB.lastActiveAt);
3012
+ return tsB - tsA;
3013
+ };
3014
+ const regularThreads = Array.from(threadMetadata.entries()).filter(([_, meta]) => meta.status === "regular").filter(([_, meta]) => !isPlaceholderTitle(meta.title)).sort(sortByLastActiveDesc).map(([id, meta]) => ({
3015
+ id,
3016
+ title: meta.title || "New Chat",
3017
+ status: "regular"
3018
+ }));
3019
+ const archivedThreadsArray = Array.from(threadMetadata.entries()).filter(([_, meta]) => meta.status === "archived").filter(([_, meta]) => !isPlaceholderTitle(meta.title)).sort(sortByLastActiveDesc).map(([id, meta]) => ({
3020
+ id,
3021
+ title: meta.title || "New Chat",
3022
+ status: "archived"
3023
+ }));
3024
+ return {
3025
+ threadId: currentThreadId,
3026
+ threads: regularThreads,
3027
+ archivedThreads: archivedThreadsArray,
3028
+ // Create new thread
3029
+ onSwitchToNewThread: async () => {
3030
+ var _a;
3031
+ const preparePendingThread = (newId) => {
3032
+ const previousPendingId = creatingThreadIdRef.current;
3033
+ if (previousPendingId && previousPendingId !== newId) {
3034
+ setThreadMetadata((prev) => {
3035
+ const next = new Map(prev);
3036
+ next.delete(previousPendingId);
3037
+ return next;
3038
+ });
3039
+ setThreads((prev) => {
3040
+ const next = new Map(prev);
3041
+ next.delete(previousPendingId);
3042
+ return next;
3043
+ });
3044
+ pendingChatMessagesRef.current.delete(previousPendingId);
3045
+ pendingSystemMessagesRef.current.delete(previousPendingId);
3046
+ tempToBackendIdRef.current.delete(previousPendingId);
3047
+ skipInitialFetchRef.current.delete(previousPendingId);
3048
+ }
3049
+ creatingThreadIdRef.current = newId;
3050
+ pendingChatMessagesRef.current.delete(newId);
3051
+ pendingSystemMessagesRef.current.delete(newId);
3052
+ setThreadMetadata(
3053
+ (prev) => new Map(prev).set(newId, {
3054
+ title: "New Chat",
3055
+ status: "pending",
3056
+ lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
3057
+ })
3058
+ );
3059
+ setThreadMessages(newId, []);
3060
+ setCurrentThreadId(newId);
3061
+ setIsRunning(false);
3062
+ bumpThreadViewKey();
3063
+ };
3064
+ const existingPendingId = findPendingThreadId();
3065
+ if (existingPendingId) {
3066
+ preparePendingThread(existingPendingId);
3067
+ return;
3068
+ }
3069
+ if (createThreadPromiseRef.current) {
3070
+ preparePendingThread((_a = creatingThreadIdRef.current) != null ? _a : `temp-${crypto.randomUUID()}`);
3071
+ return;
3072
+ }
3073
+ const tempId = `temp-${crypto.randomUUID()}`;
3074
+ preparePendingThread(tempId);
3075
+ const createPromise = backendApiRef.current.createThread(publicKey, void 0).then(async (newThread) => {
3076
+ var _a2;
3077
+ const uiThreadId = (_a2 = creatingThreadIdRef.current) != null ? _a2 : tempId;
3078
+ const backendId = newThread.session_id;
3079
+ tempToBackendIdRef.current.set(uiThreadId, backendId);
3080
+ skipInitialFetchRef.current.add(uiThreadId);
3081
+ const backendTitle = newThread.title;
3082
+ if (backendTitle && !isPlaceholderTitle(backendTitle)) {
3083
+ setThreadMetadata((prev) => {
3084
+ var _a3;
3085
+ const next = new Map(prev);
3086
+ const existing = next.get(uiThreadId);
3087
+ const nextStatus = (existing == null ? void 0 : existing.status) === "archived" ? "archived" : "regular";
3088
+ next.set(uiThreadId, {
3089
+ title: backendTitle,
3090
+ status: nextStatus,
3091
+ lastActiveAt: (_a3 = existing == null ? void 0 : existing.lastActiveAt) != null ? _a3 : (/* @__PURE__ */ new Date()).toISOString()
3092
+ });
3093
+ return next;
3094
+ });
3095
+ if (creatingThreadIdRef.current === uiThreadId) {
3096
+ creatingThreadIdRef.current = null;
3097
+ }
3098
+ }
3099
+ const pendingMessages = pendingChatMessagesRef.current.get(uiThreadId);
3100
+ if (pendingMessages == null ? void 0 : pendingMessages.length) {
3101
+ pendingChatMessagesRef.current.delete(uiThreadId);
3102
+ for (const text of pendingMessages) {
3103
+ try {
3104
+ await backendApiRef.current.postChatMessage(backendId, text);
3105
+ } catch (error) {
3106
+ console.error("Failed to send queued message:", error);
3107
+ }
3108
+ }
3109
+ if (currentThreadIdRef.current === uiThreadId) {
3110
+ startPolling();
3111
+ }
3112
+ }
3113
+ }).catch((error) => {
3114
+ var _a2;
3115
+ console.error("Failed to create new thread:", error);
3116
+ const failedId = (_a2 = creatingThreadIdRef.current) != null ? _a2 : tempId;
3117
+ setThreadMetadata((prev) => {
3118
+ const next = new Map(prev);
3119
+ next.delete(failedId);
3120
+ return next;
3121
+ });
3122
+ setThreads((prev) => {
3123
+ const next = new Map(prev);
3124
+ next.delete(failedId);
3125
+ return next;
3126
+ });
3127
+ if (creatingThreadIdRef.current === failedId) {
3128
+ creatingThreadIdRef.current = null;
3129
+ }
3130
+ }).finally(() => {
3131
+ createThreadPromiseRef.current = null;
3132
+ });
3133
+ createThreadPromiseRef.current = createPromise;
3134
+ },
3135
+ // Switch to existing thread
3136
+ onSwitchToThread: (threadId) => {
3137
+ setCurrentThreadId(threadId);
3138
+ },
3139
+ // Rename thread
3140
+ onRename: async (threadId, newTitle) => {
3141
+ updateThreadMetadata(threadId, { title: isPlaceholderTitle(newTitle) ? "" : newTitle });
3142
+ try {
3143
+ await backendApiRef.current.renameThread(threadId, newTitle);
3144
+ } catch (error) {
3145
+ console.error("Failed to rename thread:", error);
3146
+ }
3147
+ },
3148
+ // Archive thread
3149
+ onArchive: async (threadId) => {
3150
+ updateThreadMetadata(threadId, { status: "archived" });
3151
+ try {
3152
+ await backendApiRef.current.archiveThread(threadId);
3153
+ } catch (error) {
3154
+ console.error("Failed to archive thread:", error);
3155
+ updateThreadMetadata(threadId, { status: "regular" });
3156
+ }
3157
+ },
3158
+ // Unarchive thread
3159
+ onUnarchive: async (threadId) => {
3160
+ updateThreadMetadata(threadId, { status: "regular" });
3161
+ try {
3162
+ await backendApiRef.current.unarchiveThread(threadId);
3163
+ } catch (error) {
3164
+ console.error("Failed to unarchive thread:", error);
3165
+ updateThreadMetadata(threadId, { status: "archived" });
3166
+ }
3167
+ },
3168
+ // Delete thread
3169
+ onDelete: async (threadId) => {
3170
+ try {
3171
+ await backendApiRef.current.deleteThread(threadId);
3172
+ setThreadMetadata((prev) => {
3173
+ const next = new Map(prev);
3174
+ next.delete(threadId);
3175
+ return next;
3176
+ });
3177
+ setThreads((prev) => {
3178
+ const next = new Map(prev);
3179
+ next.delete(threadId);
3180
+ return next;
3181
+ });
3182
+ if (currentThreadId === threadId) {
3183
+ const firstRegularThread = Array.from(threadMetadata.entries()).find(([id, meta]) => meta.status === "regular" && id !== threadId);
3184
+ if (firstRegularThread) {
3185
+ setCurrentThreadId(firstRegularThread[0]);
3186
+ } else {
3187
+ const defaultId = "default-session";
3188
+ setThreadMetadata(
3189
+ (prev) => new Map(prev).set(defaultId, {
3190
+ title: "New Chat",
3191
+ status: "regular",
3192
+ lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
3193
+ })
3194
+ );
3195
+ setThreadMessages(defaultId, []);
3196
+ setCurrentThreadId(defaultId);
3197
+ }
3198
+ }
3199
+ } catch (error) {
3200
+ console.error("Failed to delete thread:", error);
3201
+ throw error;
3202
+ }
3203
+ }
3204
+ };
3205
+ })();
3206
+ const sendSystemMessageNow = (0, import_react12.useCallback)(
3207
+ async (threadId, message) => {
3208
+ const backendThreadId = resolveThreadId(threadId);
3209
+ setIsRunning(true);
3210
+ try {
3211
+ const response = await backendApiRef.current.postSystemMessage(backendThreadId, message);
3212
+ if (response.res) {
3213
+ const systemMessage = constructSystemMessage(response.res);
3214
+ if (systemMessage) {
3215
+ const updatedMessages = [...getThreadMessages(threadId), systemMessage];
3216
+ setThreadMessages(threadId, updatedMessages);
3217
+ }
3218
+ }
3219
+ await startPolling();
3220
+ } catch (error) {
3221
+ console.error("Failed to send system message:", error);
3222
+ setIsRunning(false);
3223
+ }
3224
+ },
3225
+ [getThreadMessages, setThreadMessages, startPolling, resolveThreadId]
3226
+ );
3227
+ const flushPendingSystemMessages = (0, import_react12.useCallback)(
3228
+ async (threadId) => {
3229
+ const pending = pendingSystemMessagesRef.current.get(threadId);
3230
+ if (!(pending == null ? void 0 : pending.length)) return;
3231
+ pendingSystemMessagesRef.current.delete(threadId);
3232
+ for (const pendingMessage of pending) {
3233
+ await sendSystemMessageNow(threadId, pendingMessage);
3234
+ }
3235
+ },
3236
+ [sendSystemMessageNow]
3237
+ );
3238
+ const flushPendingChatMessages = (0, import_react12.useCallback)(
3239
+ async (threadId) => {
3240
+ const pending = pendingChatMessagesRef.current.get(threadId);
3241
+ if (!(pending == null ? void 0 : pending.length)) return;
3242
+ pendingChatMessagesRef.current.delete(threadId);
3243
+ const backendThreadId = resolveThreadId(threadId);
3244
+ for (const text of pending) {
3245
+ try {
3246
+ await backendApiRef.current.postChatMessage(backendThreadId, text);
3247
+ } catch (error) {
3248
+ console.error("Failed to send queued message:", error);
3249
+ }
3250
+ }
3251
+ startPolling();
3252
+ },
3253
+ [resolveThreadId, startPolling]
3254
+ );
3255
+ const onNew = (0, import_react12.useCallback)(
3256
+ async (message) => {
3257
+ const text = message.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
3258
+ if (!text) return;
3259
+ const userMessage = {
3260
+ role: "user",
3261
+ content: [{ type: "text", text }],
3262
+ createdAt: /* @__PURE__ */ new Date()
3263
+ };
3264
+ setThreadMessages(currentThreadId, [...currentMessages, userMessage]);
3265
+ updateThreadMetadata(currentThreadId, { lastActiveAt: (/* @__PURE__ */ new Date()).toISOString() });
3266
+ if (!isThreadReady(currentThreadId)) {
3267
+ console.log("Thread not ready yet; queuing message for later delivery.");
3268
+ setIsRunning(true);
3269
+ const pending = pendingChatMessagesRef.current.get(currentThreadId) || [];
3270
+ pendingChatMessagesRef.current.set(currentThreadId, [...pending, text]);
3271
+ return;
3272
+ }
3273
+ const backendThreadId = resolveThreadId(currentThreadId);
3274
+ try {
3275
+ setIsRunning(true);
3276
+ await backendApiRef.current.postChatMessage(backendThreadId, text);
3277
+ await flushPendingSystemMessages(currentThreadId);
3278
+ startPolling();
3279
+ } catch (error) {
3280
+ console.error("Failed to send message:", error);
3281
+ setIsRunning(false);
3282
+ }
3283
+ },
3284
+ [
3285
+ currentThreadId,
3286
+ currentMessages,
3287
+ flushPendingSystemMessages,
3288
+ setThreadMessages,
3289
+ startPolling,
3290
+ isThreadReady,
3291
+ resolveThreadId,
3292
+ updateThreadMetadata
3293
+ ]
3294
+ );
3295
+ const sendSystemMessage = (0, import_react12.useCallback)(
3296
+ async (message) => {
3297
+ if (!isThreadReady(currentThreadId)) return;
3298
+ const threadMessages = getThreadMessages(currentThreadId);
3299
+ const hasUserMessages = threadMessages.some((msg) => msg.role === "user");
3300
+ if (!hasUserMessages) {
3301
+ const pending = pendingSystemMessagesRef.current.get(currentThreadId) || [];
3302
+ pendingSystemMessagesRef.current.set(currentThreadId, [...pending, message]);
3303
+ return;
3304
+ }
3305
+ await sendSystemMessageNow(currentThreadId, message);
3306
+ },
3307
+ [currentThreadId, getThreadMessages, sendSystemMessageNow, isThreadReady]
3308
+ );
3309
+ const onCancel = (0, import_react12.useCallback)(async () => {
3310
+ if (!isThreadReady(currentThreadId)) return;
3311
+ stopPolling();
3312
+ const backendThreadId = resolveThreadId(currentThreadId);
3313
+ try {
3314
+ await backendApiRef.current.postInterrupt(backendThreadId);
3315
+ setIsRunning(false);
3316
+ } catch (error) {
3317
+ console.error("Failed to cancel:", error);
3318
+ }
3319
+ }, [currentThreadId, stopPolling, isThreadReady, resolveThreadId]);
3320
+ const runtime = (0, import_react13.useExternalStoreRuntime)({
3321
+ messages: currentMessages,
3322
+ setMessages: (msgs) => setThreadMessages(currentThreadId, [...msgs]),
3323
+ isRunning,
3324
+ onNew,
3325
+ onCancel,
3326
+ convertMessage: (msg) => msg,
3327
+ adapters: {
3328
+ threadList: threadListAdapter
3329
+ // 🎯 Thread list adapter enabled!
3330
+ }
3331
+ });
3332
+ (0, import_react12.useEffect)(() => {
3333
+ if (isTempThreadId(currentThreadId)) return;
3334
+ const hasUserMessages = currentMessages.some((msg) => msg.role === "user");
3335
+ if (hasUserMessages) {
3336
+ void flushPendingSystemMessages(currentThreadId);
3337
+ }
3338
+ }, [currentMessages, currentThreadId, flushPendingSystemMessages]);
3339
+ (0, import_react12.useEffect)(() => {
3340
+ const unsubscribe = backendApiRef.current.subscribeToUpdates(
3341
+ (update) => {
3342
+ if (update.type !== "TitleChanged") return;
3343
+ const sessionId = update.data.session_id;
3344
+ const newTitle = update.data.new_title;
3345
+ const tempId = findTempIdForBackendId(sessionId);
3346
+ const threadIdToUpdate = tempId || sessionId;
3347
+ setThreadMetadata((prev) => {
3348
+ var _a;
3349
+ const next = new Map(prev);
3350
+ const existing = next.get(threadIdToUpdate);
3351
+ const normalizedTitle = isPlaceholderTitle(newTitle) ? "" : newTitle;
3352
+ const nextStatus = (existing == null ? void 0 : existing.status) === "archived" ? "archived" : "regular";
3353
+ next.set(threadIdToUpdate, {
3354
+ title: normalizedTitle,
3355
+ status: nextStatus,
3356
+ lastActiveAt: (_a = existing == null ? void 0 : existing.lastActiveAt) != null ? _a : (/* @__PURE__ */ new Date()).toISOString()
3357
+ });
3358
+ return next;
3359
+ });
3360
+ if (!isPlaceholderTitle(newTitle) && creatingThreadIdRef.current === threadIdToUpdate) {
3361
+ creatingThreadIdRef.current = null;
3362
+ }
3363
+ },
3364
+ (error) => {
3365
+ console.error("Failed to handle system update SSE:", error);
3366
+ }
3367
+ );
3368
+ return () => {
3369
+ unsubscribe();
3370
+ };
3371
+ }, [backendUrl, setThreadMetadata, findTempIdForBackendId]);
3372
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RuntimeActionsContext.Provider, { value: { sendSystemMessage }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react13.AssistantRuntimeProvider, { runtime, children }) });
3373
+ }
3374
+
3375
+ // src/utils/wallet.ts
3376
+ var import_react14 = require("react");
3377
+ var getNetworkName = (chainId) => {
3378
+ if (chainId === void 0) return "";
3379
+ const id = typeof chainId === "string" ? Number(chainId) : chainId;
3380
+ switch (id) {
3381
+ case 1:
3382
+ return "ethereum";
3383
+ case 137:
3384
+ return "polygon";
3385
+ case 42161:
3386
+ return "arbitrum";
3387
+ case 8453:
3388
+ return "base";
3389
+ case 10:
3390
+ return "optimism";
3391
+ case 11155111:
3392
+ return "sepolia";
3393
+ case 1337:
3394
+ case 31337:
3395
+ return "testnet";
3396
+ case 59140:
3397
+ return "linea-sepolia";
3398
+ case 59144:
3399
+ return "linea";
3400
+ default:
3401
+ return "testnet";
3402
+ }
3403
+ };
3404
+ var formatAddress = (addr) => addr ? `${addr.slice(0, 6)}...${addr.slice(-4)}` : "Connect Wallet";
3405
+ function WalletSystemMessageEmitter({ wallet }) {
3406
+ const { sendSystemMessage } = useRuntimeActions();
3407
+ const lastWalletRef = (0, import_react14.useRef)({ isConnected: false });
3408
+ (0, import_react14.useEffect)(() => {
3409
+ const prev = lastWalletRef.current;
3410
+ const { address, chainId, isConnected } = wallet;
3411
+ const normalizedAddress = address == null ? void 0 : address.toLowerCase();
3412
+ if (isConnected && normalizedAddress && chainId && (!prev.isConnected || prev.address !== normalizedAddress)) {
3413
+ const networkName = getNetworkName(chainId);
3414
+ const message = `User connected wallet with address ${normalizedAddress} on ${networkName} network (Chain ID: ${chainId}). Ready to help with transactions.`;
3415
+ console.log(message);
3416
+ void sendSystemMessage(message);
3417
+ lastWalletRef.current = { isConnected: true, address: normalizedAddress, chainId };
3418
+ return;
3419
+ }
3420
+ if (!isConnected && prev.isConnected) {
3421
+ void sendSystemMessage("Wallet disconnected by user.");
3422
+ console.log("Wallet disconnected by user.");
3423
+ lastWalletRef.current = { isConnected: false };
3424
+ return;
3425
+ }
3426
+ if (isConnected && normalizedAddress && chainId && prev.isConnected && prev.address === normalizedAddress && prev.chainId !== chainId) {
3427
+ const networkName = getNetworkName(chainId);
3428
+ const message = `User switched wallet to ${networkName} network (Chain ID: ${chainId}).`;
3429
+ console.log(message);
3430
+ void sendSystemMessage(message);
3431
+ lastWalletRef.current = { isConnected: true, address: normalizedAddress, chainId };
3432
+ }
3433
+ }, [wallet, sendSystemMessage]);
3434
+ return null;
3435
+ }
3436
+
3437
+ // src/components/aomi-frame.tsx
3438
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3439
+ var AomiFrame = ({
3440
+ width = "100%",
3441
+ height = "80vh",
3442
+ className,
3443
+ style,
3444
+ walletFooter,
3445
+ children
3446
+ }) => {
3447
+ var _a;
3448
+ const backendUrl = (_a = process.env.NEXT_PUBLIC_BACKEND_URL) != null ? _a : "http://localhost:8080";
3449
+ const frameStyle = __spreadValues({ width, height }, style);
3450
+ const [wallet, setWalletState] = (0, import_react15.useState)({
3451
+ isConnected: false,
3452
+ address: void 0,
3453
+ chainId: void 0,
3454
+ ensName: void 0
3455
+ });
3456
+ const setWallet = (0, import_react15.useCallback)((data) => {
3457
+ setWalletState((prev) => __spreadValues(__spreadValues({}, prev), data));
3458
+ }, []);
3459
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ThreadContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(AomiRuntimeProvider, { backendUrl, publicKey: wallet.address, children: [
3460
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(WalletSystemMessageEmitter, { wallet }),
3461
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3462
+ FrameShell,
3463
+ {
3464
+ className,
3465
+ frameStyle,
3466
+ walletFooter,
3467
+ wallet,
3468
+ setWallet,
3469
+ children
3470
+ }
3471
+ )
3472
+ ] }) });
3473
+ };
3474
+ var FrameShell = ({
3475
+ className,
3476
+ frameStyle,
3477
+ walletFooter,
3478
+ wallet,
3479
+ setWallet,
3480
+ children
3481
+ }) => {
3482
+ var _a, _b;
3483
+ const currentTitle = (_b = (_a = useCurrentThreadMetadata()) == null ? void 0 : _a.title) != null ? _b : "New Chat";
3484
+ const { currentThreadId, threadViewKey } = useThreadContext();
3485
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(SidebarProvider, { children: [
3486
+ children,
3487
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3488
+ "div",
3489
+ {
3490
+ className: cn(
3491
+ "flex h-full w-full overflow-hidden rounded-2xl bg-white shadow-2xl dark:bg-neutral-950",
3492
+ className
3493
+ ),
3494
+ style: frameStyle,
3495
+ children: [
3496
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ThreadListSidebar, { footer: walletFooter == null ? void 0 : walletFooter({ wallet, setWallet }) }),
3497
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(SidebarInset, { className: "relative", children: [
3498
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("header", { className: "flex h-14 mt-1 shrink-0 items-center gap-2 border-b px-3", children: [
3499
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SidebarTrigger, {}),
3500
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Separator, { orientation: "vertical", className: "mr-2 h-4" }),
3501
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Breadcrumb, { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(BreadcrumbList, { children: [
3502
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(BreadcrumbItem, { className: "hidden md:block", children: currentTitle }),
3503
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(BreadcrumbSeparator, { className: "hidden md:block" })
3504
+ ] }) })
3505
+ ] }),
3506
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Thread, {}, `${currentThreadId}-${threadViewKey}`) })
3507
+ ] })
3508
+ ]
3509
+ }
3510
+ )
3511
+ ] });
3512
+ };
3513
+
3514
+ // src/components/assistant-ui/base-sidebar.tsx
3515
+ var import_link2 = __toESM(require("next/link"), 1);
3516
+ var import_image3 = __toESM(require("next/image"), 1);
3517
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3518
+ function BaseSidebar(_a) {
3519
+ var _b = _a, {
3520
+ footerLabel = "Connect Wallet",
3521
+ footerSecondaryLabel,
3522
+ onFooterClick,
3523
+ logoUrl = "/assets/images/a.svg",
3524
+ logoHref = "https://aomi.dev"
3525
+ } = _b, props = __objRest(_b, [
3526
+ "footerLabel",
3527
+ "footerSecondaryLabel",
3528
+ "onFooterClick",
3529
+ "logoUrl",
3530
+ "logoHref"
3531
+ ]);
3532
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
3533
+ Sidebar,
3534
+ __spreadProps(__spreadValues({
3535
+ collapsible: "offcanvas",
3536
+ variant: "inset",
3537
+ className: "relative"
3538
+ }, props), {
3539
+ children: [
3540
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarHeader, { className: "aomi-sidebar-header", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "aomi-sidebar-header-content flex items-center justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarMenu, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarMenuButton, { size: "lg", asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3541
+ import_link2.default,
3542
+ {
3543
+ href: logoHref,
3544
+ target: "_blank",
3545
+ rel: "noopener noreferrer",
3546
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "aomi-sidebar-header-icon-wrapper flex aspect-square size-8 items-center justify-center rounded-lg bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3547
+ import_image3.default,
3548
+ {
3549
+ src: logoUrl,
3550
+ alt: "Logo",
3551
+ width: 28,
3552
+ height: 28,
3553
+ className: "aomi-sidebar-header-icon size-7 ml-3",
3554
+ priority: true
3555
+ }
3556
+ ) })
3557
+ }
3558
+ ) }) }) }) }) }),
3559
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarContent, { className: "aomi-sidebar-content", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ThreadList, {}) }),
3560
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarRail, {}),
3561
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarFooter, { className: "aomi-sidebar-footer border-t border-sm py-4", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarMenu, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarMenuButton, { size: "lg", asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3562
+ Button,
3563
+ {
3564
+ className: "w-full justify-center rounded-full text-white shadow-lg hover:bg-[var(--muted-foreground)] hover:text-white",
3565
+ onClick: onFooterClick,
3566
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2", children: [
3567
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-sm", children: footerLabel }),
3568
+ footerSecondaryLabel ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "text-[11px] text-white/80", children: [
3569
+ "\u2022 ",
3570
+ footerSecondaryLabel
3571
+ ] }) : null
3572
+ ] })
3573
+ }
3574
+ ) }) }) }) })
3575
+ ]
3576
+ })
3577
+ );
3578
+ }
3579
+
3580
+ // src/components/ui/card.tsx
3581
+ var React3 = __toESM(require("react"), 1);
3582
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3583
+ var Card = React3.forwardRef((_a, ref) => {
3584
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3585
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3586
+ "div",
3587
+ __spreadValues({
3588
+ ref,
3589
+ className: cn(
3590
+ "rounded-lg border bg-card text-card-foreground shadow-sm",
3591
+ className
3592
+ )
3593
+ }, props)
3594
+ );
3595
+ });
3596
+ Card.displayName = "Card";
3597
+ var CardHeader = React3.forwardRef((_a, ref) => {
3598
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3599
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3600
+ "div",
3601
+ __spreadValues({
3602
+ ref,
3603
+ className: cn("flex flex-col space-y-1.5 p-6", className)
3604
+ }, props)
3605
+ );
3606
+ });
3607
+ CardHeader.displayName = "CardHeader";
3608
+ var CardTitle = React3.forwardRef((_a, ref) => {
3609
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3610
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3611
+ "h3",
3612
+ __spreadValues({
3613
+ ref,
3614
+ className: cn(
3615
+ "text-2xl font-semibold leading-none tracking-tight",
3616
+ className
3617
+ )
3618
+ }, props)
3619
+ );
3620
+ });
3621
+ CardTitle.displayName = "CardTitle";
3622
+ var CardDescription = React3.forwardRef((_a, ref) => {
3623
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3624
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3625
+ "p",
3626
+ __spreadValues({
3627
+ ref,
3628
+ className: cn("text-sm text-muted-foreground", className)
3629
+ }, props)
3630
+ );
3631
+ });
3632
+ CardDescription.displayName = "CardDescription";
3633
+ var CardContent = React3.forwardRef((_a, ref) => {
3634
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3635
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", __spreadValues({ ref, className: cn("p-6 pt-0", className) }, props));
3636
+ });
3637
+ CardContent.displayName = "CardContent";
3638
+ var CardFooter = React3.forwardRef((_a, ref) => {
3639
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3640
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3641
+ "div",
3642
+ __spreadValues({
3643
+ ref,
3644
+ className: cn("flex items-center p-6 pt-0", className)
3645
+ }, props)
3646
+ );
3647
+ });
3648
+ CardFooter.displayName = "CardFooter";
3649
+
3650
+ // src/components/ui/badge.tsx
3651
+ var import_class_variance_authority3 = require("class-variance-authority");
3652
+ var import_jsx_runtime23 = require("react/jsx-runtime");
3653
+ var badgeVariants = (0, import_class_variance_authority3.cva)(
3654
+ "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
3655
+ {
3656
+ variants: {
3657
+ variant: {
3658
+ default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
3659
+ secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
3660
+ destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
3661
+ outline: "text-foreground"
3662
+ }
3663
+ },
3664
+ defaultVariants: {
3665
+ variant: "default"
3666
+ }
3667
+ }
3668
+ );
3669
+ function Badge(_a) {
3670
+ var _b = _a, { className, variant } = _b, props = __objRest(_b, ["className", "variant"]);
3671
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", __spreadValues({ className: cn(badgeVariants({ variant }), className) }, props));
3672
+ }
3673
+
3674
+ // src/components/ui/label.tsx
3675
+ var React4 = __toESM(require("react"), 1);
3676
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3677
+ var Label = React4.forwardRef((_a, ref) => {
3678
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3679
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3680
+ "label",
3681
+ __spreadValues({
3682
+ ref,
3683
+ className: cn(
3684
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
3685
+ className
3686
+ )
3687
+ }, props)
3688
+ );
3689
+ });
3690
+ Label.displayName = "Label";
3691
+ // Annotate the CommonJS export names for ESM import in node:
3692
+ 0 && (module.exports = {
3693
+ AomiFrame,
3694
+ AomiRuntimeProvider,
3695
+ Avatar,
3696
+ AvatarFallback,
3697
+ AvatarImage,
3698
+ Badge,
3699
+ BaseSidebar,
3700
+ Breadcrumb,
3701
+ BreadcrumbEllipsis,
3702
+ BreadcrumbItem,
3703
+ BreadcrumbLink,
3704
+ BreadcrumbList,
3705
+ BreadcrumbPage,
3706
+ BreadcrumbSeparator,
3707
+ Button,
3708
+ Card,
3709
+ CardContent,
3710
+ CardDescription,
3711
+ CardFooter,
3712
+ CardHeader,
3713
+ CardTitle,
3714
+ ComposerAttachments,
3715
+ Dialog,
3716
+ DialogClose,
3717
+ DialogContent,
3718
+ DialogDescription,
3719
+ DialogFooter,
3720
+ DialogHeader,
3721
+ DialogOverlay,
3722
+ DialogPortal,
3723
+ DialogTitle,
3724
+ DialogTrigger,
3725
+ Input,
3726
+ Label,
3727
+ MarkdownText,
3728
+ Separator,
3729
+ Sheet,
3730
+ SheetClose,
3731
+ SheetContent,
3732
+ SheetDescription,
3733
+ SheetFooter,
3734
+ SheetHeader,
3735
+ SheetTitle,
3736
+ SheetTrigger,
3737
+ Sidebar,
3738
+ SidebarContent,
3739
+ SidebarFooter,
3740
+ SidebarGroup,
3741
+ SidebarGroupAction,
3742
+ SidebarGroupContent,
3743
+ SidebarGroupLabel,
3744
+ SidebarHeader,
3745
+ SidebarInset,
3746
+ SidebarMenu,
3747
+ SidebarMenuAction,
3748
+ SidebarMenuBadge,
3749
+ SidebarMenuButton,
3750
+ SidebarMenuItem,
3751
+ SidebarMenuSub,
3752
+ SidebarMenuSubButton,
3753
+ SidebarMenuSubItem,
3754
+ SidebarProvider,
3755
+ SidebarRail,
3756
+ SidebarSeparator,
3757
+ SidebarTrigger,
3758
+ Skeleton,
3759
+ Thread,
3760
+ ThreadContextProvider,
3761
+ ThreadList,
3762
+ ThreadListSidebar,
3763
+ ToolFallback,
3764
+ Tooltip,
3765
+ TooltipContent,
3766
+ TooltipIconButton,
3767
+ TooltipProvider,
3768
+ TooltipTrigger,
3769
+ UserMessageAttachments,
3770
+ badgeVariants,
3771
+ buttonVariants,
3772
+ cn,
3773
+ formatAddress,
3774
+ getNetworkName,
3775
+ useIsMobile,
3776
+ useRuntimeActions,
3777
+ useSidebar,
3778
+ useThreadContext
3779
+ });
3780
+ //# sourceMappingURL=index.cjs.map