@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/README.md +23 -292
- package/dist/index.cjs +3780 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +302 -0
- package/dist/index.d.ts +277 -791
- package/dist/index.js +3654 -3247
- package/dist/index.js.map +1 -1
- package/dist/styles.css +168 -0
- package/package.json +91 -72
- package/dist/core/AomiChatWidget.d.ts +0 -41
- package/dist/core/AomiChatWidget.d.ts.map +0 -1
- package/dist/core/ChatManager.d.ts +0 -81
- package/dist/core/ChatManager.d.ts.map +0 -1
- package/dist/core/ThemeManager.d.ts +0 -80
- package/dist/core/ThemeManager.d.ts.map +0 -1
- package/dist/core/WalletManager.d.ts +0 -105
- package/dist/core/WalletManager.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.mjs +0 -3215
- package/dist/index.mjs.map +0 -1
- package/dist/index.umd.js +0 -3295
- package/dist/index.umd.js.map +0 -1
- package/dist/types/constants.d.ts +0 -91
- package/dist/types/constants.d.ts.map +0 -1
- package/dist/types/errors.d.ts +0 -102
- package/dist/types/errors.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -263
- package/dist/types/index.d.ts.map +0 -1
- package/dist/utils/index.d.ts +0 -99
- package/dist/utils/index.d.ts.map +0 -1
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
|