@rodrigocoliveira/agno-react 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +363 -83
- package/dist/components/GenerativeUIRenderer.d.ts +21 -0
- package/dist/components/GenerativeUIRenderer.d.ts.map +1 -0
- package/dist/context/AgnoContext.d.ts +16 -0
- package/dist/context/AgnoContext.d.ts.map +1 -0
- package/dist/context/ToolHandlerContext.d.ts +44 -0
- package/dist/context/ToolHandlerContext.d.ts.map +1 -0
- package/dist/hooks/useAgnoActions.d.ts +25 -0
- package/dist/hooks/useAgnoActions.d.ts.map +1 -0
- package/dist/hooks/useAgnoChat.d.ts +22 -0
- package/dist/hooks/useAgnoChat.d.ts.map +1 -0
- package/dist/hooks/useAgnoCustomEvents.d.ts +38 -0
- package/dist/hooks/useAgnoCustomEvents.d.ts.map +1 -0
- package/dist/hooks/useAgnoEvals.d.ts +39 -0
- package/dist/hooks/useAgnoEvals.d.ts.map +1 -0
- package/dist/hooks/useAgnoKnowledge.d.ts +56 -0
- package/dist/hooks/useAgnoKnowledge.d.ts.map +1 -0
- package/dist/hooks/useAgnoMemory.d.ts +42 -0
- package/dist/hooks/useAgnoMemory.d.ts.map +1 -0
- package/dist/hooks/useAgnoMetrics.d.ts +51 -0
- package/dist/hooks/useAgnoMetrics.d.ts.map +1 -0
- package/dist/hooks/useAgnoSession.d.ts +38 -0
- package/dist/hooks/useAgnoSession.d.ts.map +1 -0
- package/dist/hooks/useAgnoToolExecution.d.ts +70 -0
- package/dist/hooks/useAgnoToolExecution.d.ts.map +1 -0
- package/dist/hooks/useAgnoTraces.d.ts +51 -0
- package/dist/hooks/useAgnoTraces.d.ts.map +1 -0
- package/dist/index.d.ts +27 -723
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +932 -1052
- package/dist/index.js.map +24 -0
- package/dist/index.mjs +816 -909
- package/dist/index.mjs.map +24 -0
- package/dist/ui/components/artifact.d.ts +24 -0
- package/dist/ui/components/artifact.d.ts.map +1 -0
- package/dist/ui/components/audio-recorder.d.ts +32 -0
- package/dist/ui/components/audio-recorder.d.ts.map +1 -0
- package/dist/ui/components/code-block.d.ts +15 -0
- package/dist/ui/components/code-block.d.ts.map +1 -0
- package/dist/ui/components/conversation.d.ts +17 -0
- package/dist/ui/components/conversation.d.ts.map +1 -0
- package/dist/ui/components/file-preview-card.d.ts +13 -0
- package/dist/ui/components/file-preview-card.d.ts.map +1 -0
- package/dist/ui/components/file-preview-modal.d.ts +8 -0
- package/dist/ui/components/file-preview-modal.d.ts.map +1 -0
- package/dist/ui/components/image-lightbox.d.ts +12 -0
- package/dist/ui/components/image-lightbox.d.ts.map +1 -0
- package/dist/ui/components/message.d.ts +19 -0
- package/dist/ui/components/message.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/attachments.d.ts +21 -0
- package/dist/ui/components/prompt-input/attachments.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/buttons.d.ts +19 -0
- package/dist/ui/components/prompt-input/buttons.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/command.d.ts +17 -0
- package/dist/ui/components/prompt-input/command.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/context.d.ts +36 -0
- package/dist/ui/components/prompt-input/context.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/drop-zone.d.ts +7 -0
- package/dist/ui/components/prompt-input/drop-zone.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/footer.d.ts +11 -0
- package/dist/ui/components/prompt-input/footer.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/index.d.ts +25 -0
- package/dist/ui/components/prompt-input/index.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/model-select.d.ts +13 -0
- package/dist/ui/components/prompt-input/model-select.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/prompt-input.d.ts +22 -0
- package/dist/ui/components/prompt-input/prompt-input.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/provider.d.ts +6 -0
- package/dist/ui/components/prompt-input/provider.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/speech.d.ts +51 -0
- package/dist/ui/components/prompt-input/speech.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/tabs.d.ts +12 -0
- package/dist/ui/components/prompt-input/tabs.d.ts.map +1 -0
- package/dist/ui/components/prompt-input/textarea.d.ts +5 -0
- package/dist/ui/components/prompt-input/textarea.d.ts.map +1 -0
- package/dist/ui/components/response.d.ts +5 -0
- package/dist/ui/components/response.d.ts.map +1 -0
- package/dist/ui/components/smart-timestamp.d.ts +8 -0
- package/dist/ui/components/smart-timestamp.d.ts.map +1 -0
- package/dist/ui/components/streaming-indicator.d.ts +8 -0
- package/dist/ui/components/streaming-indicator.d.ts.map +1 -0
- package/dist/ui/components/tool.d.ts +24 -0
- package/dist/ui/components/tool.d.ts.map +1 -0
- package/dist/ui/composed/AgnoChatInput.d.ts +44 -0
- package/dist/ui/composed/AgnoChatInput.d.ts.map +1 -0
- package/dist/ui/composed/AgnoChatInterface.d.ts +49 -0
- package/dist/ui/composed/AgnoChatInterface.d.ts.map +1 -0
- package/dist/ui/composed/AgnoMessageItem.d.ts +38 -0
- package/dist/ui/composed/AgnoMessageItem.d.ts.map +1 -0
- package/dist/ui/composed/agno-chat/agno-chat.d.ts +9 -0
- package/dist/ui/composed/agno-chat/agno-chat.d.ts.map +1 -0
- package/dist/ui/composed/agno-chat/context.d.ts +33 -0
- package/dist/ui/composed/agno-chat/context.d.ts.map +1 -0
- package/dist/ui/composed/agno-chat/empty-state.d.ts +6 -0
- package/dist/ui/composed/agno-chat/empty-state.d.ts.map +1 -0
- package/dist/ui/composed/agno-chat/error-bar.d.ts +5 -0
- package/dist/ui/composed/agno-chat/error-bar.d.ts.map +1 -0
- package/dist/ui/composed/agno-chat/index.d.ts +33 -0
- package/dist/ui/composed/agno-chat/index.d.ts.map +1 -0
- package/dist/ui/composed/agno-chat/input.d.ts +39 -0
- package/dist/ui/composed/agno-chat/input.d.ts.map +1 -0
- package/dist/ui/composed/agno-chat/messages.d.ts +21 -0
- package/dist/ui/composed/agno-chat/messages.d.ts.map +1 -0
- package/dist/ui/composed/agno-chat/suggested-prompts.d.ts +7 -0
- package/dist/ui/composed/agno-chat/suggested-prompts.d.ts.map +1 -0
- package/dist/ui/composed/agno-chat/tool-status.d.ts +5 -0
- package/dist/ui/composed/agno-chat/tool-status.d.ts.map +1 -0
- package/dist/ui/composed/index.d.ts +9 -0
- package/dist/ui/composed/index.d.ts.map +1 -0
- package/dist/ui/index.d.ts +59 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/lib/cn.d.ts +3 -0
- package/dist/ui/lib/cn.d.ts.map +1 -0
- package/dist/ui/lib/file-utils.d.ts +20 -0
- package/dist/ui/lib/file-utils.d.ts.map +1 -0
- package/dist/ui/lib/format-timestamp.d.ts +16 -0
- package/dist/ui/lib/format-timestamp.d.ts.map +1 -0
- package/dist/ui/primitives/accordion.d.ts +8 -0
- package/dist/ui/primitives/accordion.d.ts.map +1 -0
- package/dist/ui/primitives/avatar.d.ts +7 -0
- package/dist/ui/primitives/avatar.d.ts.map +1 -0
- package/dist/ui/primitives/badge.d.ts +10 -0
- package/dist/ui/primitives/badge.d.ts.map +1 -0
- package/dist/ui/primitives/button.d.ts +12 -0
- package/dist/ui/primitives/button.d.ts.map +1 -0
- package/dist/ui/primitives/collapsible.d.ts +6 -0
- package/dist/ui/primitives/collapsible.d.ts.map +1 -0
- package/dist/ui/primitives/command.d.ts +79 -0
- package/dist/ui/primitives/command.d.ts.map +1 -0
- package/dist/ui/primitives/dialog.d.ts +26 -0
- package/dist/ui/primitives/dialog.d.ts.map +1 -0
- package/dist/ui/primitives/dropdown-menu.d.ts +28 -0
- package/dist/ui/primitives/dropdown-menu.d.ts.map +1 -0
- package/dist/ui/primitives/hover-card.d.ts +7 -0
- package/dist/ui/primitives/hover-card.d.ts.map +1 -0
- package/dist/ui/primitives/index.d.ts +16 -0
- package/dist/ui/primitives/index.d.ts.map +1 -0
- package/dist/ui/primitives/input-group.d.ts +17 -0
- package/dist/ui/primitives/input-group.d.ts.map +1 -0
- package/dist/ui/primitives/select.d.ts +14 -0
- package/dist/ui/primitives/select.d.ts.map +1 -0
- package/dist/ui/primitives/tooltip.d.ts +8 -0
- package/dist/ui/primitives/tooltip.d.ts.map +1 -0
- package/dist/ui/types.d.ts +56 -0
- package/dist/ui/types.d.ts.map +1 -0
- package/dist/ui.d.ts +2 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +4059 -0
- package/dist/ui.js.map +60 -0
- package/dist/ui.mjs +4044 -0
- package/dist/ui.mjs.map +60 -0
- package/dist/utils/component-registry.d.ts +63 -0
- package/dist/utils/component-registry.d.ts.map +1 -0
- package/dist/utils/ui-helpers.d.ts +165 -0
- package/dist/utils/ui-helpers.d.ts.map +1 -0
- package/package.json +122 -17
- package/LICENSE +0 -21
- package/dist/index.d.mts +0 -724
package/dist/ui.js
ADDED
|
@@ -0,0 +1,4059 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
9
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
|
+
for (let key of __getOwnPropNames(mod))
|
|
12
|
+
if (!__hasOwnProp.call(to, key))
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: () => mod[key],
|
|
15
|
+
enumerable: true
|
|
16
|
+
});
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
20
|
+
var __toCommonJS = (from) => {
|
|
21
|
+
var entry = __moduleCache.get(from), desc;
|
|
22
|
+
if (entry)
|
|
23
|
+
return entry;
|
|
24
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
25
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
26
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
27
|
+
get: () => from[key],
|
|
28
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
29
|
+
}));
|
|
30
|
+
__moduleCache.set(from, entry);
|
|
31
|
+
return entry;
|
|
32
|
+
};
|
|
33
|
+
var __export = (target, all) => {
|
|
34
|
+
for (var name in all)
|
|
35
|
+
__defProp(target, name, {
|
|
36
|
+
get: all[name],
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
set: (newValue) => all[name] = () => newValue
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// src/ui.ts
|
|
44
|
+
var exports_ui = {};
|
|
45
|
+
__export(exports_ui, {
|
|
46
|
+
useProviderAttachments: () => useProviderAttachments,
|
|
47
|
+
usePromptInputDropZone: () => usePromptInputDropZone,
|
|
48
|
+
usePromptInputController: () => usePromptInputController,
|
|
49
|
+
usePromptInputAttachments: () => usePromptInputAttachments,
|
|
50
|
+
useAgnoChatContext: () => useAgnoChatContext,
|
|
51
|
+
isPreviewable: () => isPreviewable,
|
|
52
|
+
getFilePreviewType: () => getFilePreviewType,
|
|
53
|
+
getFileExtension: () => getFileExtension,
|
|
54
|
+
formatSmartTimestamp: () => formatSmartTimestamp,
|
|
55
|
+
formatFullTimestamp: () => formatFullTimestamp,
|
|
56
|
+
formatFileSize: () => formatFileSize,
|
|
57
|
+
cn: () => cn,
|
|
58
|
+
buttonVariants: () => buttonVariants,
|
|
59
|
+
badgeVariants: () => badgeVariants,
|
|
60
|
+
TooltipTrigger: () => TooltipTrigger,
|
|
61
|
+
TooltipProvider: () => TooltipProvider,
|
|
62
|
+
TooltipContent: () => TooltipContent,
|
|
63
|
+
Tooltip: () => Tooltip,
|
|
64
|
+
ToolOutput: () => ToolOutput,
|
|
65
|
+
ToolInput: () => ToolInput,
|
|
66
|
+
ToolHeader: () => ToolHeader,
|
|
67
|
+
ToolContent: () => ToolContent,
|
|
68
|
+
Tool: () => Tool,
|
|
69
|
+
StreamingIndicator: () => StreamingIndicator,
|
|
70
|
+
SmartTimestamp: () => SmartTimestamp,
|
|
71
|
+
SelectValue: () => SelectValue,
|
|
72
|
+
SelectTrigger: () => SelectTrigger,
|
|
73
|
+
SelectSeparator: () => SelectSeparator,
|
|
74
|
+
SelectScrollUpButton: () => SelectScrollUpButton,
|
|
75
|
+
SelectScrollDownButton: () => SelectScrollDownButton,
|
|
76
|
+
SelectLabel: () => SelectLabel,
|
|
77
|
+
SelectItem: () => SelectItem,
|
|
78
|
+
SelectGroup: () => SelectGroup,
|
|
79
|
+
SelectContent: () => SelectContent,
|
|
80
|
+
Select: () => Select,
|
|
81
|
+
Response: () => Response,
|
|
82
|
+
PromptInputTools: () => PromptInputTools,
|
|
83
|
+
PromptInputTextarea: () => PromptInputTextarea,
|
|
84
|
+
PromptInputTabsList: () => PromptInputTabsList,
|
|
85
|
+
PromptInputTabLabel: () => PromptInputTabLabel,
|
|
86
|
+
PromptInputTabItem: () => PromptInputTabItem,
|
|
87
|
+
PromptInputTabBody: () => PromptInputTabBody,
|
|
88
|
+
PromptInputTab: () => PromptInputTab,
|
|
89
|
+
PromptInputSubmit: () => PromptInputSubmit,
|
|
90
|
+
PromptInputSpeechButton: () => PromptInputSpeechButton,
|
|
91
|
+
PromptInputProvider: () => PromptInputProvider,
|
|
92
|
+
PromptInputModelSelectValue: () => PromptInputModelSelectValue,
|
|
93
|
+
PromptInputModelSelectTrigger: () => PromptInputModelSelectTrigger,
|
|
94
|
+
PromptInputModelSelectItem: () => PromptInputModelSelectItem,
|
|
95
|
+
PromptInputModelSelectContent: () => PromptInputModelSelectContent,
|
|
96
|
+
PromptInputModelSelect: () => PromptInputModelSelect,
|
|
97
|
+
PromptInputHeader: () => PromptInputHeader,
|
|
98
|
+
PromptInputFooter: () => PromptInputFooter,
|
|
99
|
+
PromptInputDropZone: () => PromptInputDropZone,
|
|
100
|
+
PromptInputCommandSeparator: () => PromptInputCommandSeparator,
|
|
101
|
+
PromptInputCommandList: () => PromptInputCommandList,
|
|
102
|
+
PromptInputCommandItem: () => PromptInputCommandItem,
|
|
103
|
+
PromptInputCommandInput: () => PromptInputCommandInput,
|
|
104
|
+
PromptInputCommandGroup: () => PromptInputCommandGroup,
|
|
105
|
+
PromptInputCommandEmpty: () => PromptInputCommandEmpty,
|
|
106
|
+
PromptInputCommand: () => PromptInputCommand,
|
|
107
|
+
PromptInputButton: () => PromptInputButton,
|
|
108
|
+
PromptInputBody: () => PromptInputBody,
|
|
109
|
+
PromptInputAttachments: () => PromptInputAttachments,
|
|
110
|
+
PromptInputAttachment: () => PromptInputAttachment,
|
|
111
|
+
PromptInputActionMenuTrigger: () => PromptInputActionMenuTrigger,
|
|
112
|
+
PromptInputActionMenuItem: () => PromptInputActionMenuItem,
|
|
113
|
+
PromptInputActionMenuContent: () => PromptInputActionMenuContent,
|
|
114
|
+
PromptInputActionMenu: () => PromptInputActionMenu,
|
|
115
|
+
PromptInputActionAddAttachments: () => PromptInputActionAddAttachments,
|
|
116
|
+
PromptInput: () => PromptInput,
|
|
117
|
+
MessageContent: () => MessageContent,
|
|
118
|
+
MessageAvatar: () => MessageAvatar,
|
|
119
|
+
Message: () => Message,
|
|
120
|
+
InputGroupTextarea: () => InputGroupTextarea,
|
|
121
|
+
InputGroupText: () => InputGroupText,
|
|
122
|
+
InputGroupInput: () => InputGroupInput,
|
|
123
|
+
InputGroupButton: () => InputGroupButton,
|
|
124
|
+
InputGroupAddon: () => InputGroupAddon,
|
|
125
|
+
InputGroup: () => InputGroup,
|
|
126
|
+
ImageLightbox: () => ImageLightbox,
|
|
127
|
+
HoverCardTrigger: () => HoverCardTrigger,
|
|
128
|
+
HoverCardContent: () => HoverCardContent,
|
|
129
|
+
HoverCard: () => HoverCard,
|
|
130
|
+
FilePreviewModal: () => FilePreviewModal,
|
|
131
|
+
FilePreviewCard: () => FilePreviewCard,
|
|
132
|
+
DropdownMenuTrigger: () => DropdownMenuTrigger,
|
|
133
|
+
DropdownMenuSubTrigger: () => DropdownMenuSubTrigger,
|
|
134
|
+
DropdownMenuSubContent: () => DropdownMenuSubContent,
|
|
135
|
+
DropdownMenuSub: () => DropdownMenuSub,
|
|
136
|
+
DropdownMenuShortcut: () => DropdownMenuShortcut,
|
|
137
|
+
DropdownMenuSeparator: () => DropdownMenuSeparator,
|
|
138
|
+
DropdownMenuRadioItem: () => DropdownMenuRadioItem,
|
|
139
|
+
DropdownMenuRadioGroup: () => DropdownMenuRadioGroup,
|
|
140
|
+
DropdownMenuPortal: () => DropdownMenuPortal,
|
|
141
|
+
DropdownMenuLabel: () => DropdownMenuLabel,
|
|
142
|
+
DropdownMenuItem: () => DropdownMenuItem,
|
|
143
|
+
DropdownMenuGroup: () => DropdownMenuGroup,
|
|
144
|
+
DropdownMenuContent: () => DropdownMenuContent,
|
|
145
|
+
DropdownMenuCheckboxItem: () => DropdownMenuCheckboxItem,
|
|
146
|
+
DropdownMenu: () => DropdownMenu,
|
|
147
|
+
DialogTrigger: () => DialogTrigger,
|
|
148
|
+
DialogTitle: () => DialogTitle,
|
|
149
|
+
DialogPortal: () => DialogPortal,
|
|
150
|
+
DialogOverlay: () => DialogOverlay,
|
|
151
|
+
DialogHeader: () => DialogHeader,
|
|
152
|
+
DialogFooter: () => DialogFooter,
|
|
153
|
+
DialogDescription: () => DialogDescription,
|
|
154
|
+
DialogContent: () => DialogContent,
|
|
155
|
+
DialogClose: () => DialogClose,
|
|
156
|
+
Dialog: () => Dialog,
|
|
157
|
+
ConversationScrollButton: () => ConversationScrollButton,
|
|
158
|
+
ConversationEmptyState: () => ConversationEmptyState,
|
|
159
|
+
ConversationContent: () => ConversationContent,
|
|
160
|
+
Conversation: () => Conversation,
|
|
161
|
+
CommandShortcut: () => CommandShortcut,
|
|
162
|
+
CommandSeparator: () => CommandSeparator,
|
|
163
|
+
CommandList: () => CommandList,
|
|
164
|
+
CommandItem: () => CommandItem,
|
|
165
|
+
CommandInput: () => CommandInput,
|
|
166
|
+
CommandGroup: () => CommandGroup,
|
|
167
|
+
CommandEmpty: () => CommandEmpty,
|
|
168
|
+
Command: () => Command,
|
|
169
|
+
CollapsibleTrigger: () => CollapsibleTrigger2,
|
|
170
|
+
CollapsibleContent: () => CollapsibleContent2,
|
|
171
|
+
Collapsible: () => Collapsible,
|
|
172
|
+
CodeBlockCopyButton: () => CodeBlockCopyButton,
|
|
173
|
+
CodeBlock: () => CodeBlock,
|
|
174
|
+
Button: () => Button,
|
|
175
|
+
Badge: () => Badge,
|
|
176
|
+
AvatarImage: () => AvatarImage,
|
|
177
|
+
AvatarFallback: () => AvatarFallback,
|
|
178
|
+
Avatar: () => Avatar,
|
|
179
|
+
AudioRecorder: () => AudioRecorder,
|
|
180
|
+
ArtifactTitle: () => ArtifactTitle,
|
|
181
|
+
ArtifactHeader: () => ArtifactHeader,
|
|
182
|
+
ArtifactDescription: () => ArtifactDescription,
|
|
183
|
+
ArtifactContent: () => ArtifactContent,
|
|
184
|
+
ArtifactClose: () => ArtifactClose,
|
|
185
|
+
ArtifactActions: () => ArtifactActions,
|
|
186
|
+
ArtifactAction: () => ArtifactAction,
|
|
187
|
+
Artifact: () => Artifact,
|
|
188
|
+
AgnoMessageItem: () => AgnoMessageItem,
|
|
189
|
+
AgnoChatToolStatus: () => AgnoChatToolStatus,
|
|
190
|
+
AgnoChatSuggestedPrompts: () => AgnoChatSuggestedPrompts,
|
|
191
|
+
AgnoChatRoot: () => AgnoChatRoot,
|
|
192
|
+
AgnoChatMessages: () => AgnoChatMessages,
|
|
193
|
+
AgnoChatInterface: () => AgnoChatInterface,
|
|
194
|
+
AgnoChatInputArea: () => AgnoChatInputArea,
|
|
195
|
+
AgnoChatInput: () => AgnoChatInput,
|
|
196
|
+
AgnoChatErrorBar: () => AgnoChatErrorBar,
|
|
197
|
+
AgnoChatEmptyState: () => AgnoChatEmptyState,
|
|
198
|
+
AgnoChat: () => AgnoChat,
|
|
199
|
+
AccordionTrigger: () => AccordionTrigger,
|
|
200
|
+
AccordionItem: () => AccordionItem,
|
|
201
|
+
AccordionContent: () => AccordionContent,
|
|
202
|
+
Accordion: () => Accordion
|
|
203
|
+
});
|
|
204
|
+
module.exports = __toCommonJS(exports_ui);
|
|
205
|
+
|
|
206
|
+
// src/ui/lib/cn.ts
|
|
207
|
+
var import_clsx = require("clsx");
|
|
208
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
209
|
+
function cn(...inputs) {
|
|
210
|
+
return import_tailwind_merge.twMerge(import_clsx.clsx(inputs));
|
|
211
|
+
}
|
|
212
|
+
// src/ui/lib/format-timestamp.ts
|
|
213
|
+
function formatSmartTimestamp(date) {
|
|
214
|
+
const now = new Date;
|
|
215
|
+
const isToday = date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate();
|
|
216
|
+
if (isToday) {
|
|
217
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
218
|
+
hour: "numeric",
|
|
219
|
+
minute: "2-digit",
|
|
220
|
+
hour12: true
|
|
221
|
+
}).format(date);
|
|
222
|
+
}
|
|
223
|
+
const isSameYear = date.getFullYear() === now.getFullYear();
|
|
224
|
+
if (isSameYear) {
|
|
225
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
226
|
+
month: "short",
|
|
227
|
+
day: "numeric"
|
|
228
|
+
}).format(date);
|
|
229
|
+
}
|
|
230
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
231
|
+
month: "short",
|
|
232
|
+
day: "numeric",
|
|
233
|
+
year: "numeric"
|
|
234
|
+
}).format(date);
|
|
235
|
+
}
|
|
236
|
+
function formatFullTimestamp(date) {
|
|
237
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
238
|
+
month: "short",
|
|
239
|
+
day: "numeric",
|
|
240
|
+
year: "numeric",
|
|
241
|
+
hour: "numeric",
|
|
242
|
+
minute: "2-digit",
|
|
243
|
+
hour12: true
|
|
244
|
+
}).format(date);
|
|
245
|
+
}
|
|
246
|
+
// src/ui/lib/file-utils.ts
|
|
247
|
+
function getFilePreviewType(mimeType) {
|
|
248
|
+
if (!mimeType)
|
|
249
|
+
return "none";
|
|
250
|
+
if (mimeType.startsWith("image/"))
|
|
251
|
+
return "image";
|
|
252
|
+
if (mimeType === "application/pdf")
|
|
253
|
+
return "pdf";
|
|
254
|
+
if (mimeType.startsWith("text/"))
|
|
255
|
+
return "text";
|
|
256
|
+
if (mimeType.startsWith("video/"))
|
|
257
|
+
return "video";
|
|
258
|
+
if (mimeType.startsWith("audio/"))
|
|
259
|
+
return "audio";
|
|
260
|
+
return "none";
|
|
261
|
+
}
|
|
262
|
+
function formatFileSize(bytes) {
|
|
263
|
+
if (bytes === 0)
|
|
264
|
+
return "0 B";
|
|
265
|
+
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
266
|
+
const k = 1024;
|
|
267
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
268
|
+
const value = bytes / Math.pow(k, i);
|
|
269
|
+
return `${value % 1 === 0 ? value : value.toFixed(1)} ${units[i]}`;
|
|
270
|
+
}
|
|
271
|
+
function getFileExtension(filename, mimeType) {
|
|
272
|
+
const lastDot = filename.lastIndexOf(".");
|
|
273
|
+
if (lastDot !== -1 && lastDot !== 0) {
|
|
274
|
+
return filename.slice(lastDot + 1).toLowerCase();
|
|
275
|
+
}
|
|
276
|
+
if (mimeType) {
|
|
277
|
+
return extensionFromMime(mimeType);
|
|
278
|
+
}
|
|
279
|
+
return "";
|
|
280
|
+
}
|
|
281
|
+
var mimeToExt = {
|
|
282
|
+
"application/pdf": "pdf",
|
|
283
|
+
"application/zip": "zip",
|
|
284
|
+
"application/x-rar-compressed": "rar",
|
|
285
|
+
"application/json": "json",
|
|
286
|
+
"application/xml": "xml",
|
|
287
|
+
"application/msword": "doc",
|
|
288
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
|
|
289
|
+
"application/vnd.ms-excel": "xls",
|
|
290
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
|
|
291
|
+
"application/vnd.ms-powerpoint": "ppt",
|
|
292
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx",
|
|
293
|
+
"text/csv": "csv",
|
|
294
|
+
"text/plain": "txt",
|
|
295
|
+
"text/html": "html",
|
|
296
|
+
"text/css": "css",
|
|
297
|
+
"text/javascript": "js"
|
|
298
|
+
};
|
|
299
|
+
function extensionFromMime(mimeType) {
|
|
300
|
+
if (mimeToExt[mimeType])
|
|
301
|
+
return mimeToExt[mimeType];
|
|
302
|
+
const subtype = mimeType.split("/")[1];
|
|
303
|
+
if (subtype && !subtype.includes(".") && !subtype.includes("+")) {
|
|
304
|
+
return subtype.toLowerCase();
|
|
305
|
+
}
|
|
306
|
+
return "";
|
|
307
|
+
}
|
|
308
|
+
function isPreviewable(mimeType) {
|
|
309
|
+
const type = getFilePreviewType(mimeType);
|
|
310
|
+
return type === "image" || type === "pdf";
|
|
311
|
+
}
|
|
312
|
+
// src/ui/primitives/button.tsx
|
|
313
|
+
var React = __toESM(require("react"));
|
|
314
|
+
var import_react_slot = require("@radix-ui/react-slot");
|
|
315
|
+
var import_class_variance_authority = require("class-variance-authority");
|
|
316
|
+
var jsx_dev_runtime = require("react/jsx-dev-runtime");
|
|
317
|
+
var buttonVariants = import_class_variance_authority.cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", {
|
|
318
|
+
variants: {
|
|
319
|
+
variant: {
|
|
320
|
+
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
|
321
|
+
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
322
|
+
outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
323
|
+
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
|
324
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
325
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
326
|
+
},
|
|
327
|
+
size: {
|
|
328
|
+
default: "h-9 px-4 py-2",
|
|
329
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
330
|
+
lg: "h-10 rounded-md px-8",
|
|
331
|
+
icon: "h-9 w-9"
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
defaultVariants: {
|
|
335
|
+
variant: "default",
|
|
336
|
+
size: "default"
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
var Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
340
|
+
const Comp = asChild ? import_react_slot.Slot : "button";
|
|
341
|
+
return /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Comp, {
|
|
342
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
343
|
+
ref,
|
|
344
|
+
...props
|
|
345
|
+
}, undefined, false, undefined, this);
|
|
346
|
+
});
|
|
347
|
+
Button.displayName = "Button";
|
|
348
|
+
// src/ui/primitives/badge.tsx
|
|
349
|
+
var import_class_variance_authority2 = require("class-variance-authority");
|
|
350
|
+
var jsx_dev_runtime2 = require("react/jsx-dev-runtime");
|
|
351
|
+
var badgeVariants = import_class_variance_authority2.cva("inline-flex items-center rounded-md 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", {
|
|
352
|
+
variants: {
|
|
353
|
+
variant: {
|
|
354
|
+
default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
|
|
355
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
356
|
+
destructive: "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
|
|
357
|
+
outline: "text-foreground"
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
defaultVariants: {
|
|
361
|
+
variant: "default"
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
function Badge({ className, variant, ...props }) {
|
|
365
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV("div", {
|
|
366
|
+
className: cn(badgeVariants({ variant }), className),
|
|
367
|
+
...props
|
|
368
|
+
}, undefined, false, undefined, this);
|
|
369
|
+
}
|
|
370
|
+
// src/ui/primitives/avatar.tsx
|
|
371
|
+
var React2 = __toESM(require("react"));
|
|
372
|
+
var AvatarPrimitive = __toESM(require("@radix-ui/react-avatar"));
|
|
373
|
+
var jsx_dev_runtime3 = require("react/jsx-dev-runtime");
|
|
374
|
+
var Avatar = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(AvatarPrimitive.Root, {
|
|
375
|
+
ref,
|
|
376
|
+
className: cn("relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full", className),
|
|
377
|
+
...props
|
|
378
|
+
}, undefined, false, undefined, this));
|
|
379
|
+
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
380
|
+
var AvatarImage = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(AvatarPrimitive.Image, {
|
|
381
|
+
ref,
|
|
382
|
+
className: cn("aspect-square h-full w-full", className),
|
|
383
|
+
...props
|
|
384
|
+
}, undefined, false, undefined, this));
|
|
385
|
+
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
386
|
+
var AvatarFallback = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(AvatarPrimitive.Fallback, {
|
|
387
|
+
ref,
|
|
388
|
+
className: cn("flex h-full w-full items-center justify-center rounded-full bg-muted", className),
|
|
389
|
+
...props
|
|
390
|
+
}, undefined, false, undefined, this));
|
|
391
|
+
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
392
|
+
// src/ui/primitives/input-group.tsx
|
|
393
|
+
var React3 = __toESM(require("react"));
|
|
394
|
+
var import_class_variance_authority3 = require("class-variance-authority");
|
|
395
|
+
var jsx_dev_runtime4 = require("react/jsx-dev-runtime");
|
|
396
|
+
var Input = React3.forwardRef(({ className, type, ...props }, ref) => {
|
|
397
|
+
return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV("input", {
|
|
398
|
+
type,
|
|
399
|
+
className: cn("flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", className),
|
|
400
|
+
ref,
|
|
401
|
+
...props
|
|
402
|
+
}, undefined, false, undefined, this);
|
|
403
|
+
});
|
|
404
|
+
Input.displayName = "Input";
|
|
405
|
+
var Textarea = React3.forwardRef(({ className, ...props }, ref) => {
|
|
406
|
+
return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV("textarea", {
|
|
407
|
+
className: cn("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", className),
|
|
408
|
+
ref,
|
|
409
|
+
...props
|
|
410
|
+
}, undefined, false, undefined, this);
|
|
411
|
+
});
|
|
412
|
+
Textarea.displayName = "Textarea";
|
|
413
|
+
function InputGroup({ className, ...props }) {
|
|
414
|
+
return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV("div", {
|
|
415
|
+
"data-slot": "input-group",
|
|
416
|
+
role: "group",
|
|
417
|
+
className: cn("group/input-group border-input dark:bg-input/30 shadow-xs relative flex w-full items-center rounded-md border outline-none transition-[color,box-shadow]", "h-9 has-[>textarea]:h-auto", "has-[>[data-align=inline-start]]:[&>input]:pl-2", "has-[>[data-align=inline-end]]:[&>input]:pr-2", "has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3", "has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-2.5", "has-[[data-slot=input-group-control]:focus-visible]:ring-ring has-[[data-slot=input-group-control]:focus-visible]:ring-1", "has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40", className),
|
|
418
|
+
...props
|
|
419
|
+
}, undefined, false, undefined, this);
|
|
420
|
+
}
|
|
421
|
+
var inputGroupAddonVariants = import_class_variance_authority3.cva("text-muted-foreground flex h-auto cursor-text select-none items-center justify-center gap-2 py-1.5 text-sm font-medium group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4", {
|
|
422
|
+
variants: {
|
|
423
|
+
align: {
|
|
424
|
+
"inline-start": "order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]",
|
|
425
|
+
"inline-end": "order-last pr-3 has-[>button]:mr-[-0.4rem] has-[>kbd]:mr-[-0.35rem]",
|
|
426
|
+
"block-start": "[.border-b]:pb-3 order-first w-full justify-start px-3 pt-2 pb-0 group-has-[>input]/input-group:pt-2.5",
|
|
427
|
+
"block-end": "[.border-t]:pt-3 order-last w-full justify-start px-3 pb-1.5 group-has-[>input]/input-group:pb-1.5"
|
|
428
|
+
}
|
|
429
|
+
},
|
|
430
|
+
defaultVariants: {
|
|
431
|
+
align: "inline-start"
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
function InputGroupAddon({
|
|
435
|
+
className,
|
|
436
|
+
align = "inline-start",
|
|
437
|
+
...props
|
|
438
|
+
}) {
|
|
439
|
+
return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV("div", {
|
|
440
|
+
role: "group",
|
|
441
|
+
"data-slot": "input-group-addon",
|
|
442
|
+
"data-align": align,
|
|
443
|
+
className: cn(inputGroupAddonVariants({ align }), className),
|
|
444
|
+
onClick: (e) => {
|
|
445
|
+
if (e.target.closest("button")) {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
e.currentTarget.parentElement?.querySelector("input")?.focus();
|
|
449
|
+
},
|
|
450
|
+
...props
|
|
451
|
+
}, undefined, false, undefined, this);
|
|
452
|
+
}
|
|
453
|
+
var inputGroupButtonVariants = import_class_variance_authority3.cva("flex items-center gap-2 text-sm shadow-none", {
|
|
454
|
+
variants: {
|
|
455
|
+
size: {
|
|
456
|
+
xs: "h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-2 has-[>svg]:px-2 [&>svg:not([class*='size-'])]:size-3.5",
|
|
457
|
+
sm: "h-8 gap-1.5 rounded-md px-2.5 has-[>svg]:px-2.5",
|
|
458
|
+
"icon-xs": "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
|
|
459
|
+
"icon-sm": "size-8 p-0 has-[>svg]:p-0"
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
defaultVariants: {
|
|
463
|
+
size: "xs"
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
function InputGroupButton({
|
|
467
|
+
className,
|
|
468
|
+
type = "button",
|
|
469
|
+
variant = "ghost",
|
|
470
|
+
size = "xs",
|
|
471
|
+
...props
|
|
472
|
+
}) {
|
|
473
|
+
return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Button, {
|
|
474
|
+
type,
|
|
475
|
+
"data-size": size,
|
|
476
|
+
variant,
|
|
477
|
+
className: cn(inputGroupButtonVariants({ size }), className),
|
|
478
|
+
...props
|
|
479
|
+
}, undefined, false, undefined, this);
|
|
480
|
+
}
|
|
481
|
+
function InputGroupText({ className, ...props }) {
|
|
482
|
+
return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV("span", {
|
|
483
|
+
className: cn("text-muted-foreground flex items-center gap-2 text-sm [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none", className),
|
|
484
|
+
...props
|
|
485
|
+
}, undefined, false, undefined, this);
|
|
486
|
+
}
|
|
487
|
+
function InputGroupInput({ className, ...props }) {
|
|
488
|
+
return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Input, {
|
|
489
|
+
"data-slot": "input-group-control",
|
|
490
|
+
className: cn("flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent", className),
|
|
491
|
+
...props
|
|
492
|
+
}, undefined, false, undefined, this);
|
|
493
|
+
}
|
|
494
|
+
function InputGroupTextarea({ className, ...props }) {
|
|
495
|
+
return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Textarea, {
|
|
496
|
+
"data-slot": "input-group-control",
|
|
497
|
+
className: cn("flex-1 resize-none rounded-none border-0 bg-transparent min-h-0 pt-3.5 pb-1.5 pl-3.5 shadow-none focus-visible:ring-0 dark:bg-transparent", className),
|
|
498
|
+
...props
|
|
499
|
+
}, undefined, false, undefined, this);
|
|
500
|
+
}
|
|
501
|
+
// src/ui/primitives/collapsible.tsx
|
|
502
|
+
var CollapsiblePrimitive = __toESM(require("@radix-ui/react-collapsible"));
|
|
503
|
+
var Collapsible = CollapsiblePrimitive.Root;
|
|
504
|
+
var CollapsibleTrigger2 = CollapsiblePrimitive.CollapsibleTrigger;
|
|
505
|
+
var CollapsibleContent2 = CollapsiblePrimitive.CollapsibleContent;
|
|
506
|
+
// src/ui/primitives/tooltip.tsx
|
|
507
|
+
var React4 = __toESM(require("react"));
|
|
508
|
+
var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"));
|
|
509
|
+
var jsx_dev_runtime5 = require("react/jsx-dev-runtime");
|
|
510
|
+
var TooltipProvider = TooltipPrimitive.Provider;
|
|
511
|
+
var Tooltip = TooltipPrimitive.Root;
|
|
512
|
+
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
513
|
+
var TooltipContent = React4.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(TooltipPrimitive.Portal, {
|
|
514
|
+
children: /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(TooltipPrimitive.Content, {
|
|
515
|
+
ref,
|
|
516
|
+
sideOffset,
|
|
517
|
+
className: cn("z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-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 origin-[--radix-tooltip-content-transform-origin]", className),
|
|
518
|
+
...props
|
|
519
|
+
}, undefined, false, undefined, this)
|
|
520
|
+
}, undefined, false, undefined, this));
|
|
521
|
+
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
522
|
+
// src/ui/primitives/accordion.tsx
|
|
523
|
+
var React5 = __toESM(require("react"));
|
|
524
|
+
var AccordionPrimitive = __toESM(require("@radix-ui/react-accordion"));
|
|
525
|
+
var import_lucide_react = require("lucide-react");
|
|
526
|
+
var jsx_dev_runtime6 = require("react/jsx-dev-runtime");
|
|
527
|
+
var Accordion = AccordionPrimitive.Root;
|
|
528
|
+
var AccordionItem = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(AccordionPrimitive.Item, {
|
|
529
|
+
ref,
|
|
530
|
+
className: cn("border-b", className),
|
|
531
|
+
...props
|
|
532
|
+
}, undefined, false, undefined, this));
|
|
533
|
+
AccordionItem.displayName = "AccordionItem";
|
|
534
|
+
var AccordionTrigger = React5.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(AccordionPrimitive.Header, {
|
|
535
|
+
className: "flex",
|
|
536
|
+
children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(AccordionPrimitive.Trigger, {
|
|
537
|
+
ref,
|
|
538
|
+
className: cn("flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline text-left [&[data-state=open]>svg]:rotate-180", className),
|
|
539
|
+
...props,
|
|
540
|
+
children: [
|
|
541
|
+
children,
|
|
542
|
+
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV(import_lucide_react.ChevronDown, {
|
|
543
|
+
className: "h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200"
|
|
544
|
+
}, undefined, false, undefined, this)
|
|
545
|
+
]
|
|
546
|
+
}, undefined, true, undefined, this)
|
|
547
|
+
}, undefined, false, undefined, this));
|
|
548
|
+
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
|
|
549
|
+
var AccordionContent = React5.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(AccordionPrimitive.Content, {
|
|
550
|
+
ref,
|
|
551
|
+
className: "overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
|
|
552
|
+
...props,
|
|
553
|
+
children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
|
|
554
|
+
className: cn("pb-4 pt-0", className),
|
|
555
|
+
children
|
|
556
|
+
}, undefined, false, undefined, this)
|
|
557
|
+
}, undefined, false, undefined, this));
|
|
558
|
+
AccordionContent.displayName = AccordionPrimitive.Content.displayName;
|
|
559
|
+
// src/ui/primitives/dropdown-menu.tsx
|
|
560
|
+
var React6 = __toESM(require("react"));
|
|
561
|
+
var DropdownMenuPrimitive = __toESM(require("@radix-ui/react-dropdown-menu"));
|
|
562
|
+
var import_lucide_react2 = require("lucide-react");
|
|
563
|
+
var jsx_dev_runtime7 = require("react/jsx-dev-runtime");
|
|
564
|
+
var DropdownMenu = DropdownMenuPrimitive.Root;
|
|
565
|
+
var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
566
|
+
var DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
567
|
+
var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
568
|
+
var DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
569
|
+
var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
570
|
+
var DropdownMenuSubTrigger = React6.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(DropdownMenuPrimitive.SubTrigger, {
|
|
571
|
+
ref,
|
|
572
|
+
className: cn("flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", inset && "pl-8", className),
|
|
573
|
+
...props,
|
|
574
|
+
children: [
|
|
575
|
+
children,
|
|
576
|
+
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(import_lucide_react2.ChevronRight, {
|
|
577
|
+
className: "ml-auto"
|
|
578
|
+
}, undefined, false, undefined, this)
|
|
579
|
+
]
|
|
580
|
+
}, undefined, true, undefined, this));
|
|
581
|
+
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
582
|
+
var DropdownMenuSubContent = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(DropdownMenuPrimitive.SubContent, {
|
|
583
|
+
ref,
|
|
584
|
+
className: cn("z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]: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 origin-[--radix-dropdown-menu-content-transform-origin]", className),
|
|
585
|
+
...props
|
|
586
|
+
}, undefined, false, undefined, this));
|
|
587
|
+
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
588
|
+
var DropdownMenuContent = React6.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(DropdownMenuPrimitive.Portal, {
|
|
589
|
+
children: /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(DropdownMenuPrimitive.Content, {
|
|
590
|
+
ref,
|
|
591
|
+
sideOffset,
|
|
592
|
+
className: cn("z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md", "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]: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 origin-[--radix-dropdown-menu-content-transform-origin]", className),
|
|
593
|
+
...props
|
|
594
|
+
}, undefined, false, undefined, this)
|
|
595
|
+
}, undefined, false, undefined, this));
|
|
596
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
597
|
+
var DropdownMenuItem = React6.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(DropdownMenuPrimitive.Item, {
|
|
598
|
+
ref,
|
|
599
|
+
className: cn("relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0", inset && "pl-8", className),
|
|
600
|
+
...props
|
|
601
|
+
}, undefined, false, undefined, this));
|
|
602
|
+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
603
|
+
var DropdownMenuCheckboxItem = React6.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(DropdownMenuPrimitive.CheckboxItem, {
|
|
604
|
+
ref,
|
|
605
|
+
className: cn("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
|
|
606
|
+
checked,
|
|
607
|
+
...props,
|
|
608
|
+
children: [
|
|
609
|
+
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
|
|
610
|
+
className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center",
|
|
611
|
+
children: /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(DropdownMenuPrimitive.ItemIndicator, {
|
|
612
|
+
children: /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(import_lucide_react2.Check, {
|
|
613
|
+
className: "h-4 w-4"
|
|
614
|
+
}, undefined, false, undefined, this)
|
|
615
|
+
}, undefined, false, undefined, this)
|
|
616
|
+
}, undefined, false, undefined, this),
|
|
617
|
+
children
|
|
618
|
+
]
|
|
619
|
+
}, undefined, true, undefined, this));
|
|
620
|
+
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
621
|
+
var DropdownMenuRadioItem = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(DropdownMenuPrimitive.RadioItem, {
|
|
622
|
+
ref,
|
|
623
|
+
className: cn("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
|
|
624
|
+
...props,
|
|
625
|
+
children: [
|
|
626
|
+
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
|
|
627
|
+
className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center",
|
|
628
|
+
children: /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(DropdownMenuPrimitive.ItemIndicator, {
|
|
629
|
+
children: /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(import_lucide_react2.Circle, {
|
|
630
|
+
className: "h-2 w-2 fill-current"
|
|
631
|
+
}, undefined, false, undefined, this)
|
|
632
|
+
}, undefined, false, undefined, this)
|
|
633
|
+
}, undefined, false, undefined, this),
|
|
634
|
+
children
|
|
635
|
+
]
|
|
636
|
+
}, undefined, true, undefined, this));
|
|
637
|
+
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
638
|
+
var DropdownMenuLabel = React6.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(DropdownMenuPrimitive.Label, {
|
|
639
|
+
ref,
|
|
640
|
+
className: cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className),
|
|
641
|
+
...props
|
|
642
|
+
}, undefined, false, undefined, this));
|
|
643
|
+
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
644
|
+
var DropdownMenuSeparator = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(DropdownMenuPrimitive.Separator, {
|
|
645
|
+
ref,
|
|
646
|
+
className: cn("-mx-1 my-1 h-px bg-muted", className),
|
|
647
|
+
...props
|
|
648
|
+
}, undefined, false, undefined, this));
|
|
649
|
+
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
650
|
+
var DropdownMenuShortcut = ({ className, ...props }) => {
|
|
651
|
+
return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
|
|
652
|
+
className: cn("ml-auto text-xs tracking-widest opacity-60", className),
|
|
653
|
+
...props
|
|
654
|
+
}, undefined, false, undefined, this);
|
|
655
|
+
};
|
|
656
|
+
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
|
657
|
+
// src/ui/primitives/hover-card.tsx
|
|
658
|
+
var React7 = __toESM(require("react"));
|
|
659
|
+
var HoverCardPrimitive = __toESM(require("@radix-ui/react-hover-card"));
|
|
660
|
+
var jsx_dev_runtime8 = require("react/jsx-dev-runtime");
|
|
661
|
+
var HoverCard = HoverCardPrimitive.Root;
|
|
662
|
+
var HoverCardTrigger = HoverCardPrimitive.Trigger;
|
|
663
|
+
var HoverCardContent = React7.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(HoverCardPrimitive.Content, {
|
|
664
|
+
ref,
|
|
665
|
+
align,
|
|
666
|
+
sideOffset,
|
|
667
|
+
className: cn("z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]: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 origin-[--radix-hover-card-content-transform-origin]", className),
|
|
668
|
+
...props
|
|
669
|
+
}, undefined, false, undefined, this));
|
|
670
|
+
HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
|
|
671
|
+
// src/ui/primitives/select.tsx
|
|
672
|
+
var React8 = __toESM(require("react"));
|
|
673
|
+
var SelectPrimitive = __toESM(require("@radix-ui/react-select"));
|
|
674
|
+
var import_lucide_react3 = require("lucide-react");
|
|
675
|
+
var jsx_dev_runtime9 = require("react/jsx-dev-runtime");
|
|
676
|
+
var Select = SelectPrimitive.Root;
|
|
677
|
+
var SelectGroup = SelectPrimitive.Group;
|
|
678
|
+
var SelectValue = SelectPrimitive.Value;
|
|
679
|
+
var SelectTrigger = React8.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectPrimitive.Trigger, {
|
|
680
|
+
ref,
|
|
681
|
+
className: cn("flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1", className),
|
|
682
|
+
...props,
|
|
683
|
+
children: [
|
|
684
|
+
children,
|
|
685
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectPrimitive.Icon, {
|
|
686
|
+
asChild: true,
|
|
687
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(import_lucide_react3.ChevronDown, {
|
|
688
|
+
className: "h-4 w-4 opacity-50"
|
|
689
|
+
}, undefined, false, undefined, this)
|
|
690
|
+
}, undefined, false, undefined, this)
|
|
691
|
+
]
|
|
692
|
+
}, undefined, true, undefined, this));
|
|
693
|
+
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
694
|
+
var SelectScrollUpButton = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectPrimitive.ScrollUpButton, {
|
|
695
|
+
ref,
|
|
696
|
+
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
697
|
+
...props,
|
|
698
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(import_lucide_react3.ChevronUp, {
|
|
699
|
+
className: "h-4 w-4"
|
|
700
|
+
}, undefined, false, undefined, this)
|
|
701
|
+
}, undefined, false, undefined, this));
|
|
702
|
+
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
703
|
+
var SelectScrollDownButton = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectPrimitive.ScrollDownButton, {
|
|
704
|
+
ref,
|
|
705
|
+
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
706
|
+
...props,
|
|
707
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(import_lucide_react3.ChevronDown, {
|
|
708
|
+
className: "h-4 w-4"
|
|
709
|
+
}, undefined, false, undefined, this)
|
|
710
|
+
}, undefined, false, undefined, this));
|
|
711
|
+
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
712
|
+
var SelectContent = React8.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectPrimitive.Portal, {
|
|
713
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectPrimitive.Content, {
|
|
714
|
+
ref,
|
|
715
|
+
className: cn("relative z-50 max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]: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 origin-[--radix-select-content-transform-origin]", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className),
|
|
716
|
+
position,
|
|
717
|
+
...props,
|
|
718
|
+
children: [
|
|
719
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectScrollUpButton, {}, undefined, false, undefined, this),
|
|
720
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectPrimitive.Viewport, {
|
|
721
|
+
className: cn("p-1", position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),
|
|
722
|
+
children
|
|
723
|
+
}, undefined, false, undefined, this),
|
|
724
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectScrollDownButton, {}, undefined, false, undefined, this)
|
|
725
|
+
]
|
|
726
|
+
}, undefined, true, undefined, this)
|
|
727
|
+
}, undefined, false, undefined, this));
|
|
728
|
+
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
729
|
+
var SelectLabel = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectPrimitive.Label, {
|
|
730
|
+
ref,
|
|
731
|
+
className: cn("px-2 py-1.5 text-sm font-semibold", className),
|
|
732
|
+
...props
|
|
733
|
+
}, undefined, false, undefined, this));
|
|
734
|
+
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
735
|
+
var SelectItem = React8.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectPrimitive.Item, {
|
|
736
|
+
ref,
|
|
737
|
+
className: cn("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
|
|
738
|
+
...props,
|
|
739
|
+
children: [
|
|
740
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV("span", {
|
|
741
|
+
className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
|
|
742
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectPrimitive.ItemIndicator, {
|
|
743
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(import_lucide_react3.Check, {
|
|
744
|
+
className: "h-4 w-4"
|
|
745
|
+
}, undefined, false, undefined, this)
|
|
746
|
+
}, undefined, false, undefined, this)
|
|
747
|
+
}, undefined, false, undefined, this),
|
|
748
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectPrimitive.ItemText, {
|
|
749
|
+
children
|
|
750
|
+
}, undefined, false, undefined, this)
|
|
751
|
+
]
|
|
752
|
+
}, undefined, true, undefined, this));
|
|
753
|
+
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
754
|
+
var SelectSeparator = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SelectPrimitive.Separator, {
|
|
755
|
+
ref,
|
|
756
|
+
className: cn("-mx-1 my-1 h-px bg-muted", className),
|
|
757
|
+
...props
|
|
758
|
+
}, undefined, false, undefined, this));
|
|
759
|
+
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
760
|
+
// src/ui/primitives/command.tsx
|
|
761
|
+
var React9 = __toESM(require("react"));
|
|
762
|
+
var import_cmdk = require("cmdk");
|
|
763
|
+
var import_lucide_react4 = require("lucide-react");
|
|
764
|
+
var jsx_dev_runtime10 = require("react/jsx-dev-runtime");
|
|
765
|
+
var Command = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(import_cmdk.Command, {
|
|
766
|
+
ref,
|
|
767
|
+
className: cn("flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground", className),
|
|
768
|
+
...props
|
|
769
|
+
}, undefined, false, undefined, this));
|
|
770
|
+
Command.displayName = import_cmdk.Command.displayName;
|
|
771
|
+
var CommandInput = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
|
|
772
|
+
className: "flex items-center border-b px-3",
|
|
773
|
+
"cmdk-input-wrapper": "",
|
|
774
|
+
children: [
|
|
775
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(import_lucide_react4.Search, {
|
|
776
|
+
className: "mr-2 h-4 w-4 shrink-0 opacity-50"
|
|
777
|
+
}, undefined, false, undefined, this),
|
|
778
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(import_cmdk.Command.Input, {
|
|
779
|
+
ref,
|
|
780
|
+
className: cn("flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50", className),
|
|
781
|
+
...props
|
|
782
|
+
}, undefined, false, undefined, this)
|
|
783
|
+
]
|
|
784
|
+
}, undefined, true, undefined, this));
|
|
785
|
+
CommandInput.displayName = import_cmdk.Command.Input.displayName;
|
|
786
|
+
var CommandList = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(import_cmdk.Command.List, {
|
|
787
|
+
ref,
|
|
788
|
+
className: cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className),
|
|
789
|
+
...props
|
|
790
|
+
}, undefined, false, undefined, this));
|
|
791
|
+
CommandList.displayName = import_cmdk.Command.List.displayName;
|
|
792
|
+
var CommandEmpty = React9.forwardRef((props, ref) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(import_cmdk.Command.Empty, {
|
|
793
|
+
ref,
|
|
794
|
+
className: "py-6 text-center text-sm",
|
|
795
|
+
...props
|
|
796
|
+
}, undefined, false, undefined, this));
|
|
797
|
+
CommandEmpty.displayName = import_cmdk.Command.Empty.displayName;
|
|
798
|
+
var CommandGroup = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(import_cmdk.Command.Group, {
|
|
799
|
+
ref,
|
|
800
|
+
className: cn("overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground", className),
|
|
801
|
+
...props
|
|
802
|
+
}, undefined, false, undefined, this));
|
|
803
|
+
CommandGroup.displayName = import_cmdk.Command.Group.displayName;
|
|
804
|
+
var CommandSeparator = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(import_cmdk.Command.Separator, {
|
|
805
|
+
ref,
|
|
806
|
+
className: cn("-mx-1 h-px bg-border", className),
|
|
807
|
+
...props
|
|
808
|
+
}, undefined, false, undefined, this));
|
|
809
|
+
CommandSeparator.displayName = import_cmdk.Command.Separator.displayName;
|
|
810
|
+
var CommandItem = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(import_cmdk.Command.Item, {
|
|
811
|
+
ref,
|
|
812
|
+
className: cn("relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", className),
|
|
813
|
+
...props
|
|
814
|
+
}, undefined, false, undefined, this));
|
|
815
|
+
CommandItem.displayName = import_cmdk.Command.Item.displayName;
|
|
816
|
+
var CommandShortcut = ({ className, ...props }) => {
|
|
817
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("span", {
|
|
818
|
+
className: cn("ml-auto text-xs tracking-widest text-muted-foreground", className),
|
|
819
|
+
...props
|
|
820
|
+
}, undefined, false, undefined, this);
|
|
821
|
+
};
|
|
822
|
+
CommandShortcut.displayName = "CommandShortcut";
|
|
823
|
+
// src/ui/primitives/dialog.tsx
|
|
824
|
+
var React10 = __toESM(require("react"));
|
|
825
|
+
var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"));
|
|
826
|
+
var import_class_variance_authority4 = require("class-variance-authority");
|
|
827
|
+
var import_lucide_react5 = require("lucide-react");
|
|
828
|
+
var jsx_dev_runtime11 = require("react/jsx-dev-runtime");
|
|
829
|
+
var Dialog = DialogPrimitive.Root;
|
|
830
|
+
var DialogTrigger = DialogPrimitive.Trigger;
|
|
831
|
+
var DialogPortal = DialogPrimitive.Portal;
|
|
832
|
+
var DialogClose = DialogPrimitive.Close;
|
|
833
|
+
var DialogOverlay = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(DialogPrimitive.Overlay, {
|
|
834
|
+
ref,
|
|
835
|
+
className: cn("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", className),
|
|
836
|
+
...props
|
|
837
|
+
}, undefined, false, undefined, this));
|
|
838
|
+
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
839
|
+
var dialogContentVariants = import_class_variance_authority4.cva("fixed left-[50%] top-[50%] z-50 grid translate-x-[-50%] translate-y-[-50%] gap-4 border shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg", {
|
|
840
|
+
variants: {
|
|
841
|
+
variant: {
|
|
842
|
+
default: "w-full max-w-lg bg-background p-6",
|
|
843
|
+
lightbox: "max-w-[90vw] max-h-[90vh] bg-background/95 backdrop-blur-sm p-2"
|
|
844
|
+
}
|
|
845
|
+
},
|
|
846
|
+
defaultVariants: {
|
|
847
|
+
variant: "default"
|
|
848
|
+
}
|
|
849
|
+
});
|
|
850
|
+
var DialogContent = React10.forwardRef(({ className, variant, children, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(DialogPortal, {
|
|
851
|
+
children: [
|
|
852
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(DialogOverlay, {}, undefined, false, undefined, this),
|
|
853
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(DialogPrimitive.Content, {
|
|
854
|
+
ref,
|
|
855
|
+
className: cn(dialogContentVariants({ variant }), className),
|
|
856
|
+
...props,
|
|
857
|
+
children: [
|
|
858
|
+
children,
|
|
859
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(DialogPrimitive.Close, {
|
|
860
|
+
className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",
|
|
861
|
+
children: [
|
|
862
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(import_lucide_react5.X, {
|
|
863
|
+
className: "h-4 w-4"
|
|
864
|
+
}, undefined, false, undefined, this),
|
|
865
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV("span", {
|
|
866
|
+
className: "sr-only",
|
|
867
|
+
children: "Close"
|
|
868
|
+
}, undefined, false, undefined, this)
|
|
869
|
+
]
|
|
870
|
+
}, undefined, true, undefined, this)
|
|
871
|
+
]
|
|
872
|
+
}, undefined, true, undefined, this)
|
|
873
|
+
]
|
|
874
|
+
}, undefined, true, undefined, this));
|
|
875
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
876
|
+
var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("div", {
|
|
877
|
+
className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className),
|
|
878
|
+
...props
|
|
879
|
+
}, undefined, false, undefined, this);
|
|
880
|
+
DialogHeader.displayName = "DialogHeader";
|
|
881
|
+
var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("div", {
|
|
882
|
+
className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
|
|
883
|
+
...props
|
|
884
|
+
}, undefined, false, undefined, this);
|
|
885
|
+
DialogFooter.displayName = "DialogFooter";
|
|
886
|
+
var DialogTitle = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(DialogPrimitive.Title, {
|
|
887
|
+
ref,
|
|
888
|
+
className: cn("text-lg font-semibold leading-none tracking-tight", className),
|
|
889
|
+
...props
|
|
890
|
+
}, undefined, false, undefined, this));
|
|
891
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
892
|
+
var DialogDescription = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(DialogPrimitive.Description, {
|
|
893
|
+
ref,
|
|
894
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
895
|
+
...props
|
|
896
|
+
}, undefined, false, undefined, this));
|
|
897
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
898
|
+
// src/ui/components/message.tsx
|
|
899
|
+
var import_class_variance_authority5 = require("class-variance-authority");
|
|
900
|
+
var jsx_dev_runtime12 = require("react/jsx-dev-runtime");
|
|
901
|
+
var Message = ({ className, from, ...props }) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
|
|
902
|
+
className: cn("group flex w-full items-end justify-end gap-2 py-4", from === "user" ? "is-user" : "is-assistant flex-row-reverse justify-end", className),
|
|
903
|
+
...props
|
|
904
|
+
}, undefined, false, undefined, this);
|
|
905
|
+
var messageContentVariants = import_class_variance_authority5.cva("flex flex-col gap-2 overflow-hidden rounded-lg text-sm", {
|
|
906
|
+
variants: {
|
|
907
|
+
variant: {
|
|
908
|
+
contained: [
|
|
909
|
+
"max-w-[80%] px-4 py-3",
|
|
910
|
+
"group-[.is-user]:bg-primary group-[.is-user]:text-primary-foreground",
|
|
911
|
+
"group-[.is-assistant]:bg-secondary group-[.is-assistant]:text-foreground"
|
|
912
|
+
],
|
|
913
|
+
flat: [
|
|
914
|
+
"group-[.is-user]:max-w-[80%] group-[.is-user]:bg-secondary group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-foreground",
|
|
915
|
+
"group-[.is-assistant]:text-foreground"
|
|
916
|
+
]
|
|
917
|
+
}
|
|
918
|
+
},
|
|
919
|
+
defaultVariants: {
|
|
920
|
+
variant: "contained"
|
|
921
|
+
}
|
|
922
|
+
});
|
|
923
|
+
var MessageContent = ({ children, className, variant, ...props }) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
|
|
924
|
+
className: cn(messageContentVariants({ variant, className })),
|
|
925
|
+
...props,
|
|
926
|
+
children
|
|
927
|
+
}, undefined, false, undefined, this);
|
|
928
|
+
var MessageAvatar = ({ src, name, className, ...props }) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Avatar, {
|
|
929
|
+
className: cn("size-8 ring-1 ring-border", className),
|
|
930
|
+
...props,
|
|
931
|
+
children: [
|
|
932
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(AvatarImage, {
|
|
933
|
+
alt: "",
|
|
934
|
+
className: "mt-0 mb-0",
|
|
935
|
+
src
|
|
936
|
+
}, undefined, false, undefined, this),
|
|
937
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(AvatarFallback, {
|
|
938
|
+
children: name?.slice(0, 2) || "ME"
|
|
939
|
+
}, undefined, false, undefined, this)
|
|
940
|
+
]
|
|
941
|
+
}, undefined, true, undefined, this);
|
|
942
|
+
// src/ui/components/conversation.tsx
|
|
943
|
+
var import_lucide_react6 = require("lucide-react");
|
|
944
|
+
var import_react = require("react");
|
|
945
|
+
var import_use_stick_to_bottom = require("use-stick-to-bottom");
|
|
946
|
+
var import_use_stick_to_bottom2 = require("use-stick-to-bottom");
|
|
947
|
+
var jsx_dev_runtime13 = require("react/jsx-dev-runtime");
|
|
948
|
+
var Conversation = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(import_use_stick_to_bottom.StickToBottom, {
|
|
949
|
+
className: cn("relative flex-1 overflow-y-auto", className),
|
|
950
|
+
initial: "smooth",
|
|
951
|
+
role: "log",
|
|
952
|
+
...props
|
|
953
|
+
}, undefined, false, undefined, this);
|
|
954
|
+
var ConversationContent = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(import_use_stick_to_bottom.StickToBottom.Content, {
|
|
955
|
+
className: cn("p-4", className),
|
|
956
|
+
...props
|
|
957
|
+
}, undefined, false, undefined, this);
|
|
958
|
+
var ConversationEmptyState = ({
|
|
959
|
+
className,
|
|
960
|
+
title = "No messages yet",
|
|
961
|
+
description = "Start a conversation to see messages here",
|
|
962
|
+
icon,
|
|
963
|
+
children,
|
|
964
|
+
...props
|
|
965
|
+
}) => /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
|
|
966
|
+
className: cn("flex size-full flex-col items-center justify-center gap-3 p-8 text-center", className),
|
|
967
|
+
...props,
|
|
968
|
+
children: children ?? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(jsx_dev_runtime13.Fragment, {
|
|
969
|
+
children: [
|
|
970
|
+
icon && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
|
|
971
|
+
className: "text-muted-foreground",
|
|
972
|
+
children: icon
|
|
973
|
+
}, undefined, false, undefined, this),
|
|
974
|
+
/* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
|
|
975
|
+
className: "space-y-1",
|
|
976
|
+
children: [
|
|
977
|
+
/* @__PURE__ */ jsx_dev_runtime13.jsxDEV("h3", {
|
|
978
|
+
className: "font-medium text-sm",
|
|
979
|
+
children: title
|
|
980
|
+
}, undefined, false, undefined, this),
|
|
981
|
+
description && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("p", {
|
|
982
|
+
className: "text-muted-foreground text-sm",
|
|
983
|
+
children: description
|
|
984
|
+
}, undefined, false, undefined, this)
|
|
985
|
+
]
|
|
986
|
+
}, undefined, true, undefined, this)
|
|
987
|
+
]
|
|
988
|
+
}, undefined, true, undefined, this)
|
|
989
|
+
}, undefined, false, undefined, this);
|
|
990
|
+
var ConversationScrollButton = ({ className, ...props }) => {
|
|
991
|
+
const { isAtBottom, scrollToBottom } = import_use_stick_to_bottom.useStickToBottomContext();
|
|
992
|
+
const handleScrollToBottom = import_react.useCallback(() => {
|
|
993
|
+
scrollToBottom();
|
|
994
|
+
}, [scrollToBottom]);
|
|
995
|
+
return !isAtBottom && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Button, {
|
|
996
|
+
className: cn("absolute bottom-4 left-[50%] translate-x-[-50%] rounded-full", className),
|
|
997
|
+
onClick: handleScrollToBottom,
|
|
998
|
+
size: "icon",
|
|
999
|
+
type: "button",
|
|
1000
|
+
variant: "outline",
|
|
1001
|
+
...props,
|
|
1002
|
+
children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(import_lucide_react6.ArrowDownIcon, {
|
|
1003
|
+
className: "size-4"
|
|
1004
|
+
}, undefined, false, undefined, this)
|
|
1005
|
+
}, undefined, false, undefined, this);
|
|
1006
|
+
};
|
|
1007
|
+
// src/ui/components/response.tsx
|
|
1008
|
+
var import_react2 = require("react");
|
|
1009
|
+
var import_streamdown = require("streamdown");
|
|
1010
|
+
var jsx_dev_runtime14 = require("react/jsx-dev-runtime");
|
|
1011
|
+
var Response = import_react2.memo(({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(import_streamdown.Streamdown, {
|
|
1012
|
+
className: cn("size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", className),
|
|
1013
|
+
...props
|
|
1014
|
+
}, undefined, false, undefined, this), (prevProps, nextProps) => prevProps.children === nextProps.children);
|
|
1015
|
+
Response.displayName = "Response";
|
|
1016
|
+
// src/ui/components/tool.tsx
|
|
1017
|
+
var import_lucide_react8 = require("lucide-react");
|
|
1018
|
+
var import_react4 = require("react");
|
|
1019
|
+
|
|
1020
|
+
// src/ui/components/code-block.tsx
|
|
1021
|
+
var import_lucide_react7 = require("lucide-react");
|
|
1022
|
+
var import_react3 = require("react");
|
|
1023
|
+
var jsx_dev_runtime15 = require("react/jsx-dev-runtime");
|
|
1024
|
+
var CodeBlockContext = import_react3.createContext({
|
|
1025
|
+
code: ""
|
|
1026
|
+
});
|
|
1027
|
+
async function highlightCode(code, language, showLineNumbers = false) {
|
|
1028
|
+
try {
|
|
1029
|
+
const shiki = await import("shiki");
|
|
1030
|
+
const lineNumberTransformer = showLineNumbers ? [
|
|
1031
|
+
{
|
|
1032
|
+
name: "line-numbers",
|
|
1033
|
+
line(node, line) {
|
|
1034
|
+
node.children.unshift({
|
|
1035
|
+
type: "element",
|
|
1036
|
+
tagName: "span",
|
|
1037
|
+
properties: {
|
|
1038
|
+
className: ["inline-block", "min-w-10", "mr-4", "text-right", "select-none", "text-muted-foreground"]
|
|
1039
|
+
},
|
|
1040
|
+
children: [{ type: "text", value: String(line) }]
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
] : [];
|
|
1045
|
+
const [light, dark] = await Promise.all([
|
|
1046
|
+
shiki.codeToHtml(code, { lang: language, theme: "one-light", transformers: lineNumberTransformer }),
|
|
1047
|
+
shiki.codeToHtml(code, { lang: language, theme: "one-dark-pro", transformers: lineNumberTransformer })
|
|
1048
|
+
]);
|
|
1049
|
+
return [light, dark];
|
|
1050
|
+
} catch {
|
|
1051
|
+
return ["", ""];
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
var CodeBlock = ({
|
|
1055
|
+
code,
|
|
1056
|
+
language,
|
|
1057
|
+
showLineNumbers = false,
|
|
1058
|
+
className,
|
|
1059
|
+
children,
|
|
1060
|
+
...props
|
|
1061
|
+
}) => {
|
|
1062
|
+
const [html, setHtml] = import_react3.useState("");
|
|
1063
|
+
const [darkHtml, setDarkHtml] = import_react3.useState("");
|
|
1064
|
+
const effectIdRef = import_react3.useRef(0);
|
|
1065
|
+
import_react3.useEffect(() => {
|
|
1066
|
+
const id = ++effectIdRef.current;
|
|
1067
|
+
highlightCode(code, language, showLineNumbers).then(([light, dark]) => {
|
|
1068
|
+
if (id === effectIdRef.current) {
|
|
1069
|
+
setHtml(light);
|
|
1070
|
+
setDarkHtml(dark);
|
|
1071
|
+
}
|
|
1072
|
+
});
|
|
1073
|
+
}, [code, language, showLineNumbers]);
|
|
1074
|
+
const useFallback = !html && !darkHtml;
|
|
1075
|
+
return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(CodeBlockContext.Provider, {
|
|
1076
|
+
value: { code },
|
|
1077
|
+
children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
|
|
1078
|
+
className: cn("group relative w-full overflow-hidden rounded-md border bg-background text-foreground", className),
|
|
1079
|
+
...props,
|
|
1080
|
+
children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
|
|
1081
|
+
className: "relative",
|
|
1082
|
+
children: [
|
|
1083
|
+
useFallback ? /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("pre", {
|
|
1084
|
+
className: "m-0 overflow-auto bg-background p-4 text-foreground text-sm",
|
|
1085
|
+
children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("code", {
|
|
1086
|
+
className: "font-mono text-sm",
|
|
1087
|
+
children: code
|
|
1088
|
+
}, undefined, false, undefined, this)
|
|
1089
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(jsx_dev_runtime15.Fragment, {
|
|
1090
|
+
children: [
|
|
1091
|
+
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
|
|
1092
|
+
className: "overflow-hidden dark:hidden [&>pre]:m-0 [&>pre]:bg-background! [&>pre]:p-4 [&>pre]:text-foreground! [&>pre]:text-sm [&_code]:font-mono [&_code]:text-sm",
|
|
1093
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
1094
|
+
}, undefined, false, undefined, this),
|
|
1095
|
+
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
|
|
1096
|
+
className: "hidden overflow-hidden dark:block [&>pre]:m-0 [&>pre]:bg-background! [&>pre]:p-4 [&>pre]:text-foreground! [&>pre]:text-sm [&_code]:font-mono [&_code]:text-sm",
|
|
1097
|
+
dangerouslySetInnerHTML: { __html: darkHtml }
|
|
1098
|
+
}, undefined, false, undefined, this)
|
|
1099
|
+
]
|
|
1100
|
+
}, undefined, true, undefined, this),
|
|
1101
|
+
children && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
|
|
1102
|
+
className: "absolute top-2 right-2 flex items-center gap-2",
|
|
1103
|
+
children
|
|
1104
|
+
}, undefined, false, undefined, this)
|
|
1105
|
+
]
|
|
1106
|
+
}, undefined, true, undefined, this)
|
|
1107
|
+
}, undefined, false, undefined, this)
|
|
1108
|
+
}, undefined, false, undefined, this);
|
|
1109
|
+
};
|
|
1110
|
+
var CodeBlockCopyButton = ({
|
|
1111
|
+
onCopy,
|
|
1112
|
+
onError,
|
|
1113
|
+
timeout = 2000,
|
|
1114
|
+
children,
|
|
1115
|
+
className,
|
|
1116
|
+
...props
|
|
1117
|
+
}) => {
|
|
1118
|
+
const [isCopied, setIsCopied] = import_react3.useState(false);
|
|
1119
|
+
const { code } = import_react3.useContext(CodeBlockContext);
|
|
1120
|
+
const copyToClipboard = async () => {
|
|
1121
|
+
if (typeof window === "undefined" || !navigator?.clipboard?.writeText) {
|
|
1122
|
+
onError?.(new Error("Clipboard API not available"));
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1125
|
+
try {
|
|
1126
|
+
await navigator.clipboard.writeText(code);
|
|
1127
|
+
setIsCopied(true);
|
|
1128
|
+
onCopy?.();
|
|
1129
|
+
setTimeout(() => setIsCopied(false), timeout);
|
|
1130
|
+
} catch (error) {
|
|
1131
|
+
onError?.(error);
|
|
1132
|
+
}
|
|
1133
|
+
};
|
|
1134
|
+
const Icon2 = isCopied ? import_lucide_react7.CheckIcon : import_lucide_react7.CopyIcon;
|
|
1135
|
+
return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Button, {
|
|
1136
|
+
className: cn("shrink-0", className),
|
|
1137
|
+
onClick: copyToClipboard,
|
|
1138
|
+
size: "icon",
|
|
1139
|
+
variant: "ghost",
|
|
1140
|
+
...props,
|
|
1141
|
+
children: children ?? /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Icon2, {
|
|
1142
|
+
size: 14
|
|
1143
|
+
}, undefined, false, undefined, this)
|
|
1144
|
+
}, undefined, false, undefined, this);
|
|
1145
|
+
};
|
|
1146
|
+
|
|
1147
|
+
// src/ui/components/tool.tsx
|
|
1148
|
+
var jsx_dev_runtime16 = require("react/jsx-dev-runtime");
|
|
1149
|
+
var Tool = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Collapsible, {
|
|
1150
|
+
className: cn("not-prose mb-4 w-full rounded-md border", className),
|
|
1151
|
+
...props
|
|
1152
|
+
}, undefined, false, undefined, this);
|
|
1153
|
+
var getStatusBadge = (status) => {
|
|
1154
|
+
const labels = {
|
|
1155
|
+
"input-streaming": "Pending",
|
|
1156
|
+
"input-available": "Running",
|
|
1157
|
+
"approval-requested": "Awaiting Approval",
|
|
1158
|
+
"approval-responded": "Responded",
|
|
1159
|
+
"output-available": "Completed",
|
|
1160
|
+
"output-error": "Error",
|
|
1161
|
+
"output-denied": "Denied"
|
|
1162
|
+
};
|
|
1163
|
+
const icons = {
|
|
1164
|
+
"input-streaming": /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(import_lucide_react8.CircleIcon, {
|
|
1165
|
+
className: "size-4"
|
|
1166
|
+
}, undefined, false, undefined, this),
|
|
1167
|
+
"input-available": /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(import_lucide_react8.ClockIcon, {
|
|
1168
|
+
className: "size-4 animate-pulse"
|
|
1169
|
+
}, undefined, false, undefined, this),
|
|
1170
|
+
"approval-requested": /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(import_lucide_react8.ClockIcon, {
|
|
1171
|
+
className: "size-4 text-yellow-600"
|
|
1172
|
+
}, undefined, false, undefined, this),
|
|
1173
|
+
"approval-responded": /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(import_lucide_react8.CheckCircleIcon, {
|
|
1174
|
+
className: "size-4 text-blue-600"
|
|
1175
|
+
}, undefined, false, undefined, this),
|
|
1176
|
+
"output-available": /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(import_lucide_react8.CheckCircleIcon, {
|
|
1177
|
+
className: "size-4 text-green-600"
|
|
1178
|
+
}, undefined, false, undefined, this),
|
|
1179
|
+
"output-error": /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(import_lucide_react8.XCircleIcon, {
|
|
1180
|
+
className: "size-4 text-red-600"
|
|
1181
|
+
}, undefined, false, undefined, this),
|
|
1182
|
+
"output-denied": /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(import_lucide_react8.XCircleIcon, {
|
|
1183
|
+
className: "size-4 text-orange-600"
|
|
1184
|
+
}, undefined, false, undefined, this)
|
|
1185
|
+
};
|
|
1186
|
+
return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Badge, {
|
|
1187
|
+
className: "gap-1.5 rounded-full text-xs",
|
|
1188
|
+
variant: "secondary",
|
|
1189
|
+
children: [
|
|
1190
|
+
icons[status],
|
|
1191
|
+
labels[status]
|
|
1192
|
+
]
|
|
1193
|
+
}, undefined, true, undefined, this);
|
|
1194
|
+
};
|
|
1195
|
+
var ToolHeader = ({ className, title, type, state, ...props }) => /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(CollapsibleTrigger2, {
|
|
1196
|
+
className: cn("group flex w-full items-center justify-between gap-4 p-3", className),
|
|
1197
|
+
...props,
|
|
1198
|
+
children: [
|
|
1199
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
1200
|
+
className: "flex items-center gap-2",
|
|
1201
|
+
children: [
|
|
1202
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(import_lucide_react8.WrenchIcon, {
|
|
1203
|
+
className: "size-4 text-muted-foreground"
|
|
1204
|
+
}, undefined, false, undefined, this),
|
|
1205
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
|
|
1206
|
+
className: "font-medium text-sm",
|
|
1207
|
+
children: title ?? type?.split("-").slice(1).join("-") ?? "Tool"
|
|
1208
|
+
}, undefined, false, undefined, this),
|
|
1209
|
+
getStatusBadge(state)
|
|
1210
|
+
]
|
|
1211
|
+
}, undefined, true, undefined, this),
|
|
1212
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(import_lucide_react8.ChevronDownIcon, {
|
|
1213
|
+
className: "size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180"
|
|
1214
|
+
}, undefined, false, undefined, this)
|
|
1215
|
+
]
|
|
1216
|
+
}, undefined, true, undefined, this);
|
|
1217
|
+
var ToolContent = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(CollapsibleContent2, {
|
|
1218
|
+
className: cn("data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in", className),
|
|
1219
|
+
...props
|
|
1220
|
+
}, undefined, false, undefined, this);
|
|
1221
|
+
var ToolInput = ({ className, input, ...props }) => /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
1222
|
+
className: cn("space-y-2 overflow-hidden p-4", className),
|
|
1223
|
+
...props,
|
|
1224
|
+
children: [
|
|
1225
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV("h4", {
|
|
1226
|
+
className: "font-medium text-muted-foreground text-xs uppercase tracking-wide",
|
|
1227
|
+
children: "Parameters"
|
|
1228
|
+
}, undefined, false, undefined, this),
|
|
1229
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
1230
|
+
className: "rounded-md bg-muted/50",
|
|
1231
|
+
children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(CodeBlock, {
|
|
1232
|
+
code: JSON.stringify(input, null, 2),
|
|
1233
|
+
language: "json"
|
|
1234
|
+
}, undefined, false, undefined, this)
|
|
1235
|
+
}, undefined, false, undefined, this)
|
|
1236
|
+
]
|
|
1237
|
+
}, undefined, true, undefined, this);
|
|
1238
|
+
var ToolOutput = ({ className, output, errorText, ...props }) => {
|
|
1239
|
+
if (!(output || errorText)) {
|
|
1240
|
+
return null;
|
|
1241
|
+
}
|
|
1242
|
+
let Output = /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
1243
|
+
children: output
|
|
1244
|
+
}, undefined, false, undefined, this);
|
|
1245
|
+
if (typeof output === "object" && !import_react4.isValidElement(output)) {
|
|
1246
|
+
Output = /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(CodeBlock, {
|
|
1247
|
+
code: JSON.stringify(output, null, 2),
|
|
1248
|
+
language: "json"
|
|
1249
|
+
}, undefined, false, undefined, this);
|
|
1250
|
+
} else if (typeof output === "string") {
|
|
1251
|
+
Output = /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(CodeBlock, {
|
|
1252
|
+
code: output,
|
|
1253
|
+
language: "json"
|
|
1254
|
+
}, undefined, false, undefined, this);
|
|
1255
|
+
}
|
|
1256
|
+
return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
1257
|
+
className: cn("space-y-2 p-4", className),
|
|
1258
|
+
...props,
|
|
1259
|
+
children: [
|
|
1260
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV("h4", {
|
|
1261
|
+
className: "font-medium text-muted-foreground text-xs uppercase tracking-wide",
|
|
1262
|
+
children: errorText ? "Error" : "Result"
|
|
1263
|
+
}, undefined, false, undefined, this),
|
|
1264
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
1265
|
+
className: cn("overflow-x-auto rounded-md text-xs [&_table]:w-full", errorText ? "bg-destructive/10 text-destructive" : "bg-muted/50 text-foreground"),
|
|
1266
|
+
children: [
|
|
1267
|
+
errorText && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
1268
|
+
children: errorText
|
|
1269
|
+
}, undefined, false, undefined, this),
|
|
1270
|
+
Output
|
|
1271
|
+
]
|
|
1272
|
+
}, undefined, true, undefined, this)
|
|
1273
|
+
]
|
|
1274
|
+
}, undefined, true, undefined, this);
|
|
1275
|
+
};
|
|
1276
|
+
// src/ui/components/artifact.tsx
|
|
1277
|
+
var import_lucide_react9 = require("lucide-react");
|
|
1278
|
+
var jsx_dev_runtime17 = require("react/jsx-dev-runtime");
|
|
1279
|
+
var Artifact = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
|
|
1280
|
+
className: cn("flex flex-col overflow-hidden rounded-lg border bg-background shadow-sm", className),
|
|
1281
|
+
...props
|
|
1282
|
+
}, undefined, false, undefined, this);
|
|
1283
|
+
var ArtifactHeader = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
|
|
1284
|
+
className: cn("flex items-center justify-between border-b bg-muted/50 px-4 py-3", className),
|
|
1285
|
+
...props
|
|
1286
|
+
}, undefined, false, undefined, this);
|
|
1287
|
+
var ArtifactClose = ({
|
|
1288
|
+
className,
|
|
1289
|
+
children,
|
|
1290
|
+
size = "sm",
|
|
1291
|
+
variant = "ghost",
|
|
1292
|
+
...props
|
|
1293
|
+
}) => /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Button, {
|
|
1294
|
+
className: cn("size-8 p-0 text-muted-foreground hover:text-foreground", className),
|
|
1295
|
+
size,
|
|
1296
|
+
type: "button",
|
|
1297
|
+
variant,
|
|
1298
|
+
...props,
|
|
1299
|
+
children: [
|
|
1300
|
+
children ?? /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(import_lucide_react9.XIcon, {
|
|
1301
|
+
className: "size-4"
|
|
1302
|
+
}, undefined, false, undefined, this),
|
|
1303
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV("span", {
|
|
1304
|
+
className: "sr-only",
|
|
1305
|
+
children: "Close"
|
|
1306
|
+
}, undefined, false, undefined, this)
|
|
1307
|
+
]
|
|
1308
|
+
}, undefined, true, undefined, this);
|
|
1309
|
+
var ArtifactTitle = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("p", {
|
|
1310
|
+
className: cn("font-medium text-foreground text-sm", className),
|
|
1311
|
+
...props
|
|
1312
|
+
}, undefined, false, undefined, this);
|
|
1313
|
+
var ArtifactDescription = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("p", {
|
|
1314
|
+
className: cn("text-muted-foreground text-sm", className),
|
|
1315
|
+
...props
|
|
1316
|
+
}, undefined, false, undefined, this);
|
|
1317
|
+
var ArtifactActions = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
|
|
1318
|
+
className: cn("flex items-center gap-1", className),
|
|
1319
|
+
...props
|
|
1320
|
+
}, undefined, false, undefined, this);
|
|
1321
|
+
var ArtifactAction = ({
|
|
1322
|
+
tooltip,
|
|
1323
|
+
label,
|
|
1324
|
+
icon: Icon2,
|
|
1325
|
+
children,
|
|
1326
|
+
className,
|
|
1327
|
+
size = "sm",
|
|
1328
|
+
variant = "ghost",
|
|
1329
|
+
...props
|
|
1330
|
+
}) => {
|
|
1331
|
+
const button = /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Button, {
|
|
1332
|
+
className: cn("size-8 p-0 text-muted-foreground hover:text-foreground", className),
|
|
1333
|
+
size,
|
|
1334
|
+
type: "button",
|
|
1335
|
+
variant,
|
|
1336
|
+
...props,
|
|
1337
|
+
children: [
|
|
1338
|
+
Icon2 ? /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Icon2, {
|
|
1339
|
+
className: "size-4"
|
|
1340
|
+
}, undefined, false, undefined, this) : children,
|
|
1341
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV("span", {
|
|
1342
|
+
className: "sr-only",
|
|
1343
|
+
children: label || tooltip
|
|
1344
|
+
}, undefined, false, undefined, this)
|
|
1345
|
+
]
|
|
1346
|
+
}, undefined, true, undefined, this);
|
|
1347
|
+
if (tooltip) {
|
|
1348
|
+
return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(TooltipProvider, {
|
|
1349
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Tooltip, {
|
|
1350
|
+
children: [
|
|
1351
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(TooltipTrigger, {
|
|
1352
|
+
asChild: true,
|
|
1353
|
+
children: button
|
|
1354
|
+
}, undefined, false, undefined, this),
|
|
1355
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(TooltipContent, {
|
|
1356
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("p", {
|
|
1357
|
+
children: tooltip
|
|
1358
|
+
}, undefined, false, undefined, this)
|
|
1359
|
+
}, undefined, false, undefined, this)
|
|
1360
|
+
]
|
|
1361
|
+
}, undefined, true, undefined, this)
|
|
1362
|
+
}, undefined, false, undefined, this);
|
|
1363
|
+
}
|
|
1364
|
+
return button;
|
|
1365
|
+
};
|
|
1366
|
+
var ArtifactContent = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
|
|
1367
|
+
className: cn("flex-1 overflow-auto p-4", className),
|
|
1368
|
+
...props
|
|
1369
|
+
}, undefined, false, undefined, this);
|
|
1370
|
+
// src/ui/components/streaming-indicator.tsx
|
|
1371
|
+
var import_lucide_react10 = require("lucide-react");
|
|
1372
|
+
var jsx_dev_runtime18 = require("react/jsx-dev-runtime");
|
|
1373
|
+
function StreamingIndicator({ className, icon, avatar, ...props }) {
|
|
1374
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
1375
|
+
className: cn("flex items-start gap-3 px-1", className),
|
|
1376
|
+
...props,
|
|
1377
|
+
children: [
|
|
1378
|
+
avatar ?? /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
1379
|
+
className: "h-8 w-8 rounded-full bg-primary/10 flex items-center justify-center flex-shrink-0 mt-0.5",
|
|
1380
|
+
children: icon ?? /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(import_lucide_react10.Bot, {
|
|
1381
|
+
className: "h-4 w-4 text-primary"
|
|
1382
|
+
}, undefined, false, undefined, this)
|
|
1383
|
+
}, undefined, false, undefined, this),
|
|
1384
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
1385
|
+
className: "flex items-center gap-1.5 pt-2.5",
|
|
1386
|
+
children: [
|
|
1387
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("span", {
|
|
1388
|
+
className: "h-2 w-2 rounded-full bg-primary/60 animate-pulse"
|
|
1389
|
+
}, undefined, false, undefined, this),
|
|
1390
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("span", {
|
|
1391
|
+
className: "h-2 w-2 rounded-full bg-primary/60 animate-pulse [animation-delay:150ms]"
|
|
1392
|
+
}, undefined, false, undefined, this),
|
|
1393
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("span", {
|
|
1394
|
+
className: "h-2 w-2 rounded-full bg-primary/60 animate-pulse [animation-delay:300ms]"
|
|
1395
|
+
}, undefined, false, undefined, this)
|
|
1396
|
+
]
|
|
1397
|
+
}, undefined, true, undefined, this)
|
|
1398
|
+
]
|
|
1399
|
+
}, undefined, true, undefined, this);
|
|
1400
|
+
}
|
|
1401
|
+
// src/ui/components/audio-recorder.tsx
|
|
1402
|
+
var import_react5 = require("react");
|
|
1403
|
+
var import_lucide_react11 = require("lucide-react");
|
|
1404
|
+
var jsx_dev_runtime19 = require("react/jsx-dev-runtime");
|
|
1405
|
+
function encodeWav(samples, sampleRate) {
|
|
1406
|
+
const numChannels = 1;
|
|
1407
|
+
const bitsPerSample = 16;
|
|
1408
|
+
const byteRate = sampleRate * numChannels * (bitsPerSample / 8);
|
|
1409
|
+
const blockAlign = numChannels * (bitsPerSample / 8);
|
|
1410
|
+
const dataLength = samples.length * (bitsPerSample / 8);
|
|
1411
|
+
const buffer = new ArrayBuffer(44 + dataLength);
|
|
1412
|
+
const view = new DataView(buffer);
|
|
1413
|
+
writeString(view, 0, "RIFF");
|
|
1414
|
+
view.setUint32(4, 36 + dataLength, true);
|
|
1415
|
+
writeString(view, 8, "WAVE");
|
|
1416
|
+
writeString(view, 12, "fmt ");
|
|
1417
|
+
view.setUint32(16, 16, true);
|
|
1418
|
+
view.setUint16(20, 1, true);
|
|
1419
|
+
view.setUint16(22, numChannels, true);
|
|
1420
|
+
view.setUint32(24, sampleRate, true);
|
|
1421
|
+
view.setUint32(28, byteRate, true);
|
|
1422
|
+
view.setUint16(32, blockAlign, true);
|
|
1423
|
+
view.setUint16(34, bitsPerSample, true);
|
|
1424
|
+
writeString(view, 36, "data");
|
|
1425
|
+
view.setUint32(40, dataLength, true);
|
|
1426
|
+
let offset = 44;
|
|
1427
|
+
for (let i = 0;i < samples.length; i++) {
|
|
1428
|
+
const s = Math.max(-1, Math.min(1, samples[i]));
|
|
1429
|
+
view.setInt16(offset, s < 0 ? s * 32768 : s * 32767, true);
|
|
1430
|
+
offset += 2;
|
|
1431
|
+
}
|
|
1432
|
+
return new Blob([buffer], { type: "audio/wav" });
|
|
1433
|
+
}
|
|
1434
|
+
function writeString(view, offset, str) {
|
|
1435
|
+
for (let i = 0;i < str.length; i++) {
|
|
1436
|
+
view.setUint8(offset + i, str.charCodeAt(i));
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
function createWorkletUrl() {
|
|
1440
|
+
const code = `
|
|
1441
|
+
class RecorderProcessor extends AudioWorkletProcessor {
|
|
1442
|
+
constructor() {
|
|
1443
|
+
super();
|
|
1444
|
+
this._stopped = false;
|
|
1445
|
+
this.port.onmessage = (e) => {
|
|
1446
|
+
if (e.data === 'stop') this._stopped = true;
|
|
1447
|
+
};
|
|
1448
|
+
}
|
|
1449
|
+
process(inputs) {
|
|
1450
|
+
if (this._stopped) return false;
|
|
1451
|
+
const input = inputs[0];
|
|
1452
|
+
if (input && input[0]) {
|
|
1453
|
+
this.port.postMessage(new Float32Array(input[0]));
|
|
1454
|
+
}
|
|
1455
|
+
return true;
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
registerProcessor('recorder-processor', RecorderProcessor);
|
|
1459
|
+
`;
|
|
1460
|
+
const blob = new Blob([code], { type: "application/javascript" });
|
|
1461
|
+
return URL.createObjectURL(blob);
|
|
1462
|
+
}
|
|
1463
|
+
function AudioRecorder({
|
|
1464
|
+
onRecordingComplete,
|
|
1465
|
+
disabled,
|
|
1466
|
+
className,
|
|
1467
|
+
mode = "send",
|
|
1468
|
+
transcriptionEndpoint,
|
|
1469
|
+
transcriptionHeaders,
|
|
1470
|
+
onTranscriptionComplete,
|
|
1471
|
+
transcriptionFieldName = "file",
|
|
1472
|
+
parseTranscriptionResponse,
|
|
1473
|
+
onRequestPermission,
|
|
1474
|
+
labels
|
|
1475
|
+
}) {
|
|
1476
|
+
const [isRecording, setIsRecording] = import_react5.useState(false);
|
|
1477
|
+
const [isTranscribing, setIsTranscribing] = import_react5.useState(false);
|
|
1478
|
+
const [duration, setDuration] = import_react5.useState(0);
|
|
1479
|
+
const [isSupported, setIsSupported] = import_react5.useState(true);
|
|
1480
|
+
const streamRef = import_react5.useRef(null);
|
|
1481
|
+
const audioContextRef = import_react5.useRef(null);
|
|
1482
|
+
const workletNodeRef = import_react5.useRef(null);
|
|
1483
|
+
const chunksRef = import_react5.useRef([]);
|
|
1484
|
+
const timerRef = import_react5.useRef(null);
|
|
1485
|
+
const workletUrlRef = import_react5.useRef(null);
|
|
1486
|
+
const onTranscriptionCompleteRef = import_react5.useRef(onTranscriptionComplete);
|
|
1487
|
+
onTranscriptionCompleteRef.current = onTranscriptionComplete;
|
|
1488
|
+
import_react5.useEffect(() => {
|
|
1489
|
+
if (typeof window === "undefined" || !navigator.mediaDevices?.getUserMedia) {
|
|
1490
|
+
setIsSupported(false);
|
|
1491
|
+
}
|
|
1492
|
+
return () => {
|
|
1493
|
+
if (timerRef.current)
|
|
1494
|
+
clearInterval(timerRef.current);
|
|
1495
|
+
if (workletNodeRef.current) {
|
|
1496
|
+
workletNodeRef.current.port.postMessage("stop");
|
|
1497
|
+
workletNodeRef.current.disconnect();
|
|
1498
|
+
workletNodeRef.current = null;
|
|
1499
|
+
}
|
|
1500
|
+
if (audioContextRef.current) {
|
|
1501
|
+
audioContextRef.current.close();
|
|
1502
|
+
audioContextRef.current = null;
|
|
1503
|
+
}
|
|
1504
|
+
if (streamRef.current) {
|
|
1505
|
+
streamRef.current.getTracks().forEach((track) => track.stop());
|
|
1506
|
+
streamRef.current = null;
|
|
1507
|
+
}
|
|
1508
|
+
if (workletUrlRef.current)
|
|
1509
|
+
URL.revokeObjectURL(workletUrlRef.current);
|
|
1510
|
+
};
|
|
1511
|
+
}, []);
|
|
1512
|
+
const startRecording = import_react5.useCallback(async () => {
|
|
1513
|
+
try {
|
|
1514
|
+
if (onRequestPermission) {
|
|
1515
|
+
const granted = await onRequestPermission();
|
|
1516
|
+
if (!granted)
|
|
1517
|
+
return;
|
|
1518
|
+
}
|
|
1519
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
1520
|
+
streamRef.current = stream;
|
|
1521
|
+
const audioContext = new AudioContext;
|
|
1522
|
+
audioContextRef.current = audioContext;
|
|
1523
|
+
const workletUrl = createWorkletUrl();
|
|
1524
|
+
workletUrlRef.current = workletUrl;
|
|
1525
|
+
await audioContext.audioWorklet.addModule(workletUrl);
|
|
1526
|
+
const source = audioContext.createMediaStreamSource(stream);
|
|
1527
|
+
const workletNode = new AudioWorkletNode(audioContext, "recorder-processor");
|
|
1528
|
+
workletNodeRef.current = workletNode;
|
|
1529
|
+
chunksRef.current = [];
|
|
1530
|
+
workletNode.port.onmessage = (e) => {
|
|
1531
|
+
if (e.data instanceof Float32Array) {
|
|
1532
|
+
chunksRef.current.push(e.data);
|
|
1533
|
+
}
|
|
1534
|
+
};
|
|
1535
|
+
source.connect(workletNode);
|
|
1536
|
+
workletNode.connect(audioContext.destination);
|
|
1537
|
+
setIsRecording(true);
|
|
1538
|
+
setDuration(0);
|
|
1539
|
+
timerRef.current = setInterval(() => {
|
|
1540
|
+
setDuration((prev) => prev + 1);
|
|
1541
|
+
}, 1000);
|
|
1542
|
+
} catch {
|
|
1543
|
+
console.error("Failed to start recording");
|
|
1544
|
+
}
|
|
1545
|
+
}, [onRequestPermission]);
|
|
1546
|
+
const stopRecording = import_react5.useCallback(async () => {
|
|
1547
|
+
if (workletNodeRef.current) {
|
|
1548
|
+
workletNodeRef.current.port.postMessage("stop");
|
|
1549
|
+
workletNodeRef.current.disconnect();
|
|
1550
|
+
workletNodeRef.current = null;
|
|
1551
|
+
}
|
|
1552
|
+
const audioContext = audioContextRef.current;
|
|
1553
|
+
let wavBlob = null;
|
|
1554
|
+
if (audioContext) {
|
|
1555
|
+
const sampleRate = audioContext.sampleRate;
|
|
1556
|
+
const totalLength = chunksRef.current.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
1557
|
+
const merged = new Float32Array(totalLength);
|
|
1558
|
+
let offset = 0;
|
|
1559
|
+
for (const chunk of chunksRef.current) {
|
|
1560
|
+
merged.set(chunk, offset);
|
|
1561
|
+
offset += chunk.length;
|
|
1562
|
+
}
|
|
1563
|
+
chunksRef.current = [];
|
|
1564
|
+
wavBlob = encodeWav(merged, sampleRate);
|
|
1565
|
+
audioContext.close();
|
|
1566
|
+
audioContextRef.current = null;
|
|
1567
|
+
}
|
|
1568
|
+
if (streamRef.current) {
|
|
1569
|
+
streamRef.current.getTracks().forEach((track) => track.stop());
|
|
1570
|
+
streamRef.current = null;
|
|
1571
|
+
}
|
|
1572
|
+
if (workletUrlRef.current) {
|
|
1573
|
+
URL.revokeObjectURL(workletUrlRef.current);
|
|
1574
|
+
workletUrlRef.current = null;
|
|
1575
|
+
}
|
|
1576
|
+
setIsRecording(false);
|
|
1577
|
+
if (timerRef.current) {
|
|
1578
|
+
clearInterval(timerRef.current);
|
|
1579
|
+
timerRef.current = null;
|
|
1580
|
+
}
|
|
1581
|
+
if (!wavBlob)
|
|
1582
|
+
return;
|
|
1583
|
+
if (mode === "transcribe" && transcriptionEndpoint) {
|
|
1584
|
+
setIsTranscribing(true);
|
|
1585
|
+
const formData = new FormData;
|
|
1586
|
+
formData.append(transcriptionFieldName, wavBlob, "recording.wav");
|
|
1587
|
+
try {
|
|
1588
|
+
const res = await fetch(transcriptionEndpoint, {
|
|
1589
|
+
method: "POST",
|
|
1590
|
+
headers: transcriptionHeaders,
|
|
1591
|
+
credentials: "include",
|
|
1592
|
+
body: formData
|
|
1593
|
+
});
|
|
1594
|
+
const data = await res.json();
|
|
1595
|
+
const text = parseTranscriptionResponse ? parseTranscriptionResponse(data) : data.text || data.transcript || data.transcription || (typeof data === "string" ? data : "");
|
|
1596
|
+
if (text)
|
|
1597
|
+
onTranscriptionCompleteRef.current?.(text);
|
|
1598
|
+
} catch (err) {
|
|
1599
|
+
console.error("Transcription failed:", err);
|
|
1600
|
+
} finally {
|
|
1601
|
+
setIsTranscribing(false);
|
|
1602
|
+
}
|
|
1603
|
+
} else {
|
|
1604
|
+
onRecordingComplete(wavBlob);
|
|
1605
|
+
}
|
|
1606
|
+
}, [onRecordingComplete, mode, transcriptionEndpoint, transcriptionHeaders, transcriptionFieldName, parseTranscriptionResponse]);
|
|
1607
|
+
const resolvedLabels = {
|
|
1608
|
+
recordAudio: labels?.recordAudio ?? "Record audio",
|
|
1609
|
+
stopRecording: labels?.stopRecording ?? "Stop recording",
|
|
1610
|
+
transcribing: labels?.transcribing ?? "Transcribing..."
|
|
1611
|
+
};
|
|
1612
|
+
const formatDuration = (seconds) => {
|
|
1613
|
+
const m = Math.floor(seconds / 60);
|
|
1614
|
+
const s = seconds % 60;
|
|
1615
|
+
return `${m}:${s.toString().padStart(2, "0")}`;
|
|
1616
|
+
};
|
|
1617
|
+
if (!isSupported)
|
|
1618
|
+
return null;
|
|
1619
|
+
return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
1620
|
+
className: cn("flex items-center gap-1", className),
|
|
1621
|
+
children: [
|
|
1622
|
+
isRecording && /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("span", {
|
|
1623
|
+
className: "text-xs text-destructive font-mono animate-pulse",
|
|
1624
|
+
children: formatDuration(duration)
|
|
1625
|
+
}, undefined, false, undefined, this),
|
|
1626
|
+
isTranscribing ? /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("span", {
|
|
1627
|
+
className: "flex items-center gap-1.5 text-xs text-muted-foreground",
|
|
1628
|
+
children: [
|
|
1629
|
+
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV(import_lucide_react11.Loader2, {
|
|
1630
|
+
className: "size-3.5 animate-spin"
|
|
1631
|
+
}, undefined, false, undefined, this),
|
|
1632
|
+
resolvedLabels.transcribing
|
|
1633
|
+
]
|
|
1634
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Button, {
|
|
1635
|
+
type: "button",
|
|
1636
|
+
variant: "ghost",
|
|
1637
|
+
size: "icon",
|
|
1638
|
+
className: cn("h-8 w-8", isRecording && "text-destructive hover:text-destructive"),
|
|
1639
|
+
disabled,
|
|
1640
|
+
onClick: isRecording ? stopRecording : startRecording,
|
|
1641
|
+
title: isRecording ? resolvedLabels.stopRecording : resolvedLabels.recordAudio,
|
|
1642
|
+
children: isRecording ? /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(import_lucide_react11.Square, {
|
|
1643
|
+
className: "size-4 fill-current"
|
|
1644
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(import_lucide_react11.Mic, {
|
|
1645
|
+
className: "size-4"
|
|
1646
|
+
}, undefined, false, undefined, this)
|
|
1647
|
+
}, undefined, false, undefined, this)
|
|
1648
|
+
]
|
|
1649
|
+
}, undefined, true, undefined, this);
|
|
1650
|
+
}
|
|
1651
|
+
// src/ui/components/smart-timestamp.tsx
|
|
1652
|
+
var jsx_dev_runtime20 = require("react/jsx-dev-runtime");
|
|
1653
|
+
function SmartTimestamp({ date, formatShort, className }) {
|
|
1654
|
+
const shortText = formatShort ? formatShort(date) : formatSmartTimestamp(date);
|
|
1655
|
+
const fullText = formatFullTimestamp(date);
|
|
1656
|
+
return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(TooltipProvider, {
|
|
1657
|
+
children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Tooltip, {
|
|
1658
|
+
children: [
|
|
1659
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV(TooltipTrigger, {
|
|
1660
|
+
asChild: true,
|
|
1661
|
+
children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("span", {
|
|
1662
|
+
className,
|
|
1663
|
+
children: shortText
|
|
1664
|
+
}, undefined, false, undefined, this)
|
|
1665
|
+
}, undefined, false, undefined, this),
|
|
1666
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV(TooltipContent, {
|
|
1667
|
+
children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("p", {
|
|
1668
|
+
children: fullText
|
|
1669
|
+
}, undefined, false, undefined, this)
|
|
1670
|
+
}, undefined, false, undefined, this)
|
|
1671
|
+
]
|
|
1672
|
+
}, undefined, true, undefined, this)
|
|
1673
|
+
}, undefined, false, undefined, this);
|
|
1674
|
+
}
|
|
1675
|
+
// src/ui/components/file-preview-card.tsx
|
|
1676
|
+
var import_lucide_react12 = require("lucide-react");
|
|
1677
|
+
var jsx_dev_runtime21 = require("react/jsx-dev-runtime");
|
|
1678
|
+
function ExtBadge({ ext }) {
|
|
1679
|
+
if (!ext)
|
|
1680
|
+
return null;
|
|
1681
|
+
return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("span", {
|
|
1682
|
+
className: "absolute bottom-1.5 left-1.5 rounded px-1 py-0.5 text-[9px] font-semibold uppercase leading-none bg-background/80 text-muted-foreground border border-border/50 backdrop-blur-sm",
|
|
1683
|
+
children: ext
|
|
1684
|
+
}, undefined, false, undefined, this);
|
|
1685
|
+
}
|
|
1686
|
+
function FilePreviewCard({ file, onClick, className }) {
|
|
1687
|
+
const previewType = getFilePreviewType(file.type);
|
|
1688
|
+
const isClickable = !!onClick;
|
|
1689
|
+
const ext = getFileExtension(file.name, file.type);
|
|
1690
|
+
const cardBase = cn("group relative flex flex-col overflow-hidden rounded-xl border border-border bg-muted/20 w-28 h-28", isClickable && "cursor-pointer hover:border-foreground/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 transition-colors", className);
|
|
1691
|
+
if (previewType === "image" && file.url) {
|
|
1692
|
+
return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("button", {
|
|
1693
|
+
type: "button",
|
|
1694
|
+
onClick,
|
|
1695
|
+
disabled: !isClickable,
|
|
1696
|
+
className: cardBase,
|
|
1697
|
+
children: [
|
|
1698
|
+
/* @__PURE__ */ jsx_dev_runtime21.jsxDEV("img", {
|
|
1699
|
+
src: file.url,
|
|
1700
|
+
alt: file.name,
|
|
1701
|
+
className: "w-full h-full object-cover"
|
|
1702
|
+
}, undefined, false, undefined, this),
|
|
1703
|
+
/* @__PURE__ */ jsx_dev_runtime21.jsxDEV(ExtBadge, {
|
|
1704
|
+
ext
|
|
1705
|
+
}, undefined, false, undefined, this),
|
|
1706
|
+
isClickable && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
|
|
1707
|
+
className: "absolute inset-0 flex items-center justify-center bg-black/0 group-hover:bg-black/30 transition-colors",
|
|
1708
|
+
children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(import_lucide_react12.Search, {
|
|
1709
|
+
className: "h-5 w-5 text-white opacity-0 group-hover:opacity-100 transition-opacity"
|
|
1710
|
+
}, undefined, false, undefined, this)
|
|
1711
|
+
}, undefined, false, undefined, this)
|
|
1712
|
+
]
|
|
1713
|
+
}, undefined, true, undefined, this);
|
|
1714
|
+
}
|
|
1715
|
+
if (previewType === "pdf" && file.url) {
|
|
1716
|
+
return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("button", {
|
|
1717
|
+
type: "button",
|
|
1718
|
+
onClick,
|
|
1719
|
+
disabled: !isClickable,
|
|
1720
|
+
className: cardBase,
|
|
1721
|
+
children: [
|
|
1722
|
+
/* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
|
|
1723
|
+
className: "w-full h-full overflow-hidden pointer-events-none",
|
|
1724
|
+
children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("object", {
|
|
1725
|
+
data: `${file.url}#page=1&view=FitH`,
|
|
1726
|
+
type: "application/pdf",
|
|
1727
|
+
className: "w-[200%] h-[200%] origin-top-left scale-50",
|
|
1728
|
+
"aria-label": file.name,
|
|
1729
|
+
children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
|
|
1730
|
+
className: "flex items-center justify-center w-full h-full",
|
|
1731
|
+
children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(import_lucide_react12.FileIcon, {
|
|
1732
|
+
className: "h-8 w-8 text-muted-foreground/40"
|
|
1733
|
+
}, undefined, false, undefined, this)
|
|
1734
|
+
}, undefined, false, undefined, this)
|
|
1735
|
+
}, undefined, false, undefined, this)
|
|
1736
|
+
}, undefined, false, undefined, this),
|
|
1737
|
+
/* @__PURE__ */ jsx_dev_runtime21.jsxDEV(ExtBadge, {
|
|
1738
|
+
ext
|
|
1739
|
+
}, undefined, false, undefined, this),
|
|
1740
|
+
isClickable && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
|
|
1741
|
+
className: "absolute inset-0 flex items-center justify-center bg-black/0 group-hover:bg-black/10 transition-colors",
|
|
1742
|
+
children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(import_lucide_react12.Search, {
|
|
1743
|
+
className: "h-5 w-5 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity"
|
|
1744
|
+
}, undefined, false, undefined, this)
|
|
1745
|
+
}, undefined, false, undefined, this)
|
|
1746
|
+
]
|
|
1747
|
+
}, undefined, true, undefined, this);
|
|
1748
|
+
}
|
|
1749
|
+
return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("button", {
|
|
1750
|
+
type: "button",
|
|
1751
|
+
onClick,
|
|
1752
|
+
disabled: !isClickable,
|
|
1753
|
+
className: cardBase,
|
|
1754
|
+
children: [
|
|
1755
|
+
/* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
|
|
1756
|
+
className: "flex-1 flex items-center justify-center",
|
|
1757
|
+
children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(import_lucide_react12.FileIcon, {
|
|
1758
|
+
className: "h-8 w-8 text-muted-foreground/40"
|
|
1759
|
+
}, undefined, false, undefined, this)
|
|
1760
|
+
}, undefined, false, undefined, this),
|
|
1761
|
+
/* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
|
|
1762
|
+
className: "w-full text-center min-w-0 px-2 pb-2 space-y-0.5",
|
|
1763
|
+
children: [
|
|
1764
|
+
/* @__PURE__ */ jsx_dev_runtime21.jsxDEV("p", {
|
|
1765
|
+
className: "text-[10px] text-foreground truncate leading-tight",
|
|
1766
|
+
title: file.name,
|
|
1767
|
+
children: file.name
|
|
1768
|
+
}, undefined, false, undefined, this),
|
|
1769
|
+
file.size != null && file.size > 0 && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("p", {
|
|
1770
|
+
className: "text-[9px] text-muted-foreground leading-tight",
|
|
1771
|
+
children: formatFileSize(file.size)
|
|
1772
|
+
}, undefined, false, undefined, this)
|
|
1773
|
+
]
|
|
1774
|
+
}, undefined, true, undefined, this),
|
|
1775
|
+
/* @__PURE__ */ jsx_dev_runtime21.jsxDEV(ExtBadge, {
|
|
1776
|
+
ext
|
|
1777
|
+
}, undefined, false, undefined, this)
|
|
1778
|
+
]
|
|
1779
|
+
}, undefined, true, undefined, this);
|
|
1780
|
+
}
|
|
1781
|
+
// src/ui/components/file-preview-modal.tsx
|
|
1782
|
+
var import_lucide_react13 = require("lucide-react");
|
|
1783
|
+
var jsx_dev_runtime22 = require("react/jsx-dev-runtime");
|
|
1784
|
+
function FilePreviewModal({ open, onOpenChange, file }) {
|
|
1785
|
+
if (!file)
|
|
1786
|
+
return null;
|
|
1787
|
+
const previewType = getFilePreviewType(file.type);
|
|
1788
|
+
const canPreview = isPreviewable(file.type) && !!file.url;
|
|
1789
|
+
return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Dialog, {
|
|
1790
|
+
open,
|
|
1791
|
+
onOpenChange,
|
|
1792
|
+
children: previewType === "image" && file.url ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(DialogContent, {
|
|
1793
|
+
variant: "lightbox",
|
|
1794
|
+
"aria-describedby": undefined,
|
|
1795
|
+
children: [
|
|
1796
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(DialogTitle, {
|
|
1797
|
+
className: "sr-only",
|
|
1798
|
+
children: file.name
|
|
1799
|
+
}, undefined, false, undefined, this),
|
|
1800
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV("img", {
|
|
1801
|
+
src: file.url,
|
|
1802
|
+
alt: file.name,
|
|
1803
|
+
className: "max-h-[85vh] max-w-full object-contain rounded-md"
|
|
1804
|
+
}, undefined, false, undefined, this)
|
|
1805
|
+
]
|
|
1806
|
+
}, undefined, true, undefined, this) : previewType === "pdf" && file.url ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(DialogContent, {
|
|
1807
|
+
variant: "lightbox",
|
|
1808
|
+
className: "w-[80vw] h-[85vh]",
|
|
1809
|
+
"aria-describedby": undefined,
|
|
1810
|
+
children: [
|
|
1811
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(DialogTitle, {
|
|
1812
|
+
className: "sr-only",
|
|
1813
|
+
children: file.name
|
|
1814
|
+
}, undefined, false, undefined, this),
|
|
1815
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV("object", {
|
|
1816
|
+
data: file.url,
|
|
1817
|
+
type: "application/pdf",
|
|
1818
|
+
className: "w-full h-full rounded-md",
|
|
1819
|
+
children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
|
|
1820
|
+
className: "flex flex-col items-center justify-center h-full gap-3 text-muted-foreground",
|
|
1821
|
+
children: [
|
|
1822
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV("p", {
|
|
1823
|
+
className: "text-sm",
|
|
1824
|
+
children: "Unable to display PDF"
|
|
1825
|
+
}, undefined, false, undefined, this),
|
|
1826
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV("a", {
|
|
1827
|
+
href: file.url,
|
|
1828
|
+
target: "_blank",
|
|
1829
|
+
rel: "noopener noreferrer",
|
|
1830
|
+
className: "inline-flex items-center gap-1.5 text-sm text-primary hover:underline",
|
|
1831
|
+
children: [
|
|
1832
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(import_lucide_react13.Download, {
|
|
1833
|
+
className: "h-4 w-4"
|
|
1834
|
+
}, undefined, false, undefined, this),
|
|
1835
|
+
"Download ",
|
|
1836
|
+
file.name
|
|
1837
|
+
]
|
|
1838
|
+
}, undefined, true, undefined, this)
|
|
1839
|
+
]
|
|
1840
|
+
}, undefined, true, undefined, this)
|
|
1841
|
+
}, undefined, false, undefined, this)
|
|
1842
|
+
]
|
|
1843
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(DialogContent, {
|
|
1844
|
+
children: [
|
|
1845
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(DialogHeader, {
|
|
1846
|
+
children: [
|
|
1847
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(DialogTitle, {
|
|
1848
|
+
className: "flex items-center gap-2",
|
|
1849
|
+
children: [
|
|
1850
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(import_lucide_react13.FileIcon, {
|
|
1851
|
+
className: "h-5 w-5 text-muted-foreground"
|
|
1852
|
+
}, undefined, false, undefined, this),
|
|
1853
|
+
file.name
|
|
1854
|
+
]
|
|
1855
|
+
}, undefined, true, undefined, this),
|
|
1856
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(DialogDescription, {
|
|
1857
|
+
children: [
|
|
1858
|
+
file.size != null && file.size > 0 && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("span", {
|
|
1859
|
+
children: formatFileSize(file.size)
|
|
1860
|
+
}, undefined, false, undefined, this),
|
|
1861
|
+
!canPreview && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("span", {
|
|
1862
|
+
children: " · Preview not available for this file type"
|
|
1863
|
+
}, undefined, false, undefined, this)
|
|
1864
|
+
]
|
|
1865
|
+
}, undefined, true, undefined, this)
|
|
1866
|
+
]
|
|
1867
|
+
}, undefined, true, undefined, this),
|
|
1868
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
|
|
1869
|
+
className: "flex flex-col items-center justify-center py-8 text-muted-foreground gap-3",
|
|
1870
|
+
children: [
|
|
1871
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(import_lucide_react13.FileIcon, {
|
|
1872
|
+
className: "h-12 w-12"
|
|
1873
|
+
}, undefined, false, undefined, this),
|
|
1874
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV("p", {
|
|
1875
|
+
className: "text-sm",
|
|
1876
|
+
children: "Preview not available"
|
|
1877
|
+
}, undefined, false, undefined, this),
|
|
1878
|
+
file.url && /^https?:\/\//i.test(file.url) && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("a", {
|
|
1879
|
+
href: file.url,
|
|
1880
|
+
target: "_blank",
|
|
1881
|
+
rel: "noopener noreferrer",
|
|
1882
|
+
className: "inline-flex items-center gap-1.5 text-sm text-primary hover:underline",
|
|
1883
|
+
children: [
|
|
1884
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(import_lucide_react13.Download, {
|
|
1885
|
+
className: "h-4 w-4"
|
|
1886
|
+
}, undefined, false, undefined, this),
|
|
1887
|
+
"Download file"
|
|
1888
|
+
]
|
|
1889
|
+
}, undefined, true, undefined, this)
|
|
1890
|
+
]
|
|
1891
|
+
}, undefined, true, undefined, this)
|
|
1892
|
+
]
|
|
1893
|
+
}, undefined, true, undefined, this)
|
|
1894
|
+
}, undefined, false, undefined, this);
|
|
1895
|
+
}
|
|
1896
|
+
// src/ui/components/image-lightbox.tsx
|
|
1897
|
+
var import_react6 = require("react");
|
|
1898
|
+
var import_lucide_react14 = require("lucide-react");
|
|
1899
|
+
var jsx_dev_runtime23 = require("react/jsx-dev-runtime");
|
|
1900
|
+
function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
|
|
1901
|
+
const [currentIndex, setCurrentIndex] = import_react6.useState(initialIndex);
|
|
1902
|
+
const hasMultiple = images.length > 1;
|
|
1903
|
+
import_react6.useEffect(() => {
|
|
1904
|
+
if (open)
|
|
1905
|
+
setCurrentIndex(initialIndex);
|
|
1906
|
+
}, [open, initialIndex]);
|
|
1907
|
+
const goNext = import_react6.useCallback(() => {
|
|
1908
|
+
setCurrentIndex((i) => (i + 1) % images.length);
|
|
1909
|
+
}, [images.length]);
|
|
1910
|
+
const goPrev = import_react6.useCallback(() => {
|
|
1911
|
+
setCurrentIndex((i) => (i - 1 + images.length) % images.length);
|
|
1912
|
+
}, [images.length]);
|
|
1913
|
+
import_react6.useEffect(() => {
|
|
1914
|
+
if (!open || !hasMultiple)
|
|
1915
|
+
return;
|
|
1916
|
+
const handler = (e) => {
|
|
1917
|
+
if (e.key === "ArrowRight")
|
|
1918
|
+
goNext();
|
|
1919
|
+
if (e.key === "ArrowLeft")
|
|
1920
|
+
goPrev();
|
|
1921
|
+
};
|
|
1922
|
+
window.addEventListener("keydown", handler);
|
|
1923
|
+
return () => window.removeEventListener("keydown", handler);
|
|
1924
|
+
}, [open, hasMultiple, goNext, goPrev]);
|
|
1925
|
+
if (images.length === 0)
|
|
1926
|
+
return null;
|
|
1927
|
+
const current = images[currentIndex];
|
|
1928
|
+
if (!current)
|
|
1929
|
+
return null;
|
|
1930
|
+
return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Dialog, {
|
|
1931
|
+
open,
|
|
1932
|
+
onOpenChange,
|
|
1933
|
+
children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(DialogContent, {
|
|
1934
|
+
variant: "lightbox",
|
|
1935
|
+
"aria-describedby": undefined,
|
|
1936
|
+
children: [
|
|
1937
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(DialogTitle, {
|
|
1938
|
+
className: "sr-only",
|
|
1939
|
+
children: current.alt || `Image ${currentIndex + 1} of ${images.length}`
|
|
1940
|
+
}, undefined, false, undefined, this),
|
|
1941
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV("div", {
|
|
1942
|
+
className: "relative flex items-center justify-center",
|
|
1943
|
+
children: [
|
|
1944
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV("img", {
|
|
1945
|
+
src: current.url,
|
|
1946
|
+
alt: current.alt || "Image preview",
|
|
1947
|
+
className: "max-h-[85vh] max-w-full object-contain rounded-md"
|
|
1948
|
+
}, undefined, false, undefined, this),
|
|
1949
|
+
hasMultiple && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(jsx_dev_runtime23.Fragment, {
|
|
1950
|
+
children: [
|
|
1951
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV("button", {
|
|
1952
|
+
type: "button",
|
|
1953
|
+
onClick: goPrev,
|
|
1954
|
+
className: cn("absolute left-2 top-1/2 -translate-y-1/2 rounded-full bg-black/50 p-2 text-white", "hover:bg-black/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring transition-colors"),
|
|
1955
|
+
children: [
|
|
1956
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(import_lucide_react14.ChevronLeft, {
|
|
1957
|
+
className: "h-5 w-5"
|
|
1958
|
+
}, undefined, false, undefined, this),
|
|
1959
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV("span", {
|
|
1960
|
+
className: "sr-only",
|
|
1961
|
+
children: "Previous image"
|
|
1962
|
+
}, undefined, false, undefined, this)
|
|
1963
|
+
]
|
|
1964
|
+
}, undefined, true, undefined, this),
|
|
1965
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV("button", {
|
|
1966
|
+
type: "button",
|
|
1967
|
+
onClick: goNext,
|
|
1968
|
+
className: cn("absolute right-2 top-1/2 -translate-y-1/2 rounded-full bg-black/50 p-2 text-white", "hover:bg-black/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring transition-colors"),
|
|
1969
|
+
children: [
|
|
1970
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(import_lucide_react14.ChevronRight, {
|
|
1971
|
+
className: "h-5 w-5"
|
|
1972
|
+
}, undefined, false, undefined, this),
|
|
1973
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV("span", {
|
|
1974
|
+
className: "sr-only",
|
|
1975
|
+
children: "Next image"
|
|
1976
|
+
}, undefined, false, undefined, this)
|
|
1977
|
+
]
|
|
1978
|
+
}, undefined, true, undefined, this),
|
|
1979
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV("div", {
|
|
1980
|
+
className: "absolute bottom-2 left-1/2 -translate-x-1/2 rounded-full bg-black/50 px-3 py-1 text-xs text-white",
|
|
1981
|
+
children: [
|
|
1982
|
+
currentIndex + 1,
|
|
1983
|
+
" / ",
|
|
1984
|
+
images.length
|
|
1985
|
+
]
|
|
1986
|
+
}, undefined, true, undefined, this)
|
|
1987
|
+
]
|
|
1988
|
+
}, undefined, true, undefined, this)
|
|
1989
|
+
]
|
|
1990
|
+
}, undefined, true, undefined, this)
|
|
1991
|
+
]
|
|
1992
|
+
}, undefined, true, undefined, this)
|
|
1993
|
+
}, undefined, false, undefined, this);
|
|
1994
|
+
}
|
|
1995
|
+
// src/ui/components/prompt-input/context.ts
|
|
1996
|
+
var import_react7 = require("react");
|
|
1997
|
+
var PromptInputController = import_react7.createContext(null);
|
|
1998
|
+
var ProviderAttachmentsContext = import_react7.createContext(null);
|
|
1999
|
+
var LocalAttachmentsContext = import_react7.createContext(null);
|
|
2000
|
+
var usePromptInputController = () => {
|
|
2001
|
+
const ctx = import_react7.useContext(PromptInputController);
|
|
2002
|
+
if (!ctx) {
|
|
2003
|
+
throw new Error("Wrap your component inside <PromptInputProvider> to use usePromptInputController().");
|
|
2004
|
+
}
|
|
2005
|
+
return ctx;
|
|
2006
|
+
};
|
|
2007
|
+
var useOptionalPromptInputController = () => import_react7.useContext(PromptInputController);
|
|
2008
|
+
var useProviderAttachments = () => {
|
|
2009
|
+
const ctx = import_react7.useContext(ProviderAttachmentsContext);
|
|
2010
|
+
if (!ctx) {
|
|
2011
|
+
throw new Error("Wrap your component inside <PromptInputProvider> to use useProviderAttachments().");
|
|
2012
|
+
}
|
|
2013
|
+
return ctx;
|
|
2014
|
+
};
|
|
2015
|
+
var useOptionalProviderAttachments = () => import_react7.useContext(ProviderAttachmentsContext);
|
|
2016
|
+
var usePromptInputAttachments = () => {
|
|
2017
|
+
const provider = useOptionalProviderAttachments();
|
|
2018
|
+
const local = import_react7.useContext(LocalAttachmentsContext);
|
|
2019
|
+
const context = provider ?? local;
|
|
2020
|
+
if (!context) {
|
|
2021
|
+
throw new Error("usePromptInputAttachments must be used within a PromptInput or PromptInputProvider");
|
|
2022
|
+
}
|
|
2023
|
+
return context;
|
|
2024
|
+
};
|
|
2025
|
+
var DropZoneContext = import_react7.createContext({ isDraggingOver: false });
|
|
2026
|
+
var usePromptInputDropZone = () => import_react7.useContext(DropZoneContext);
|
|
2027
|
+
// src/ui/components/prompt-input/provider.tsx
|
|
2028
|
+
var import_react8 = require("react");
|
|
2029
|
+
var jsx_dev_runtime24 = require("react/jsx-dev-runtime");
|
|
2030
|
+
function generateId() {
|
|
2031
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
2032
|
+
return crypto.randomUUID();
|
|
2033
|
+
}
|
|
2034
|
+
return Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
2035
|
+
}
|
|
2036
|
+
function PromptInputProvider({ initialInput: initialTextInput = "", children }) {
|
|
2037
|
+
const [textInput, setTextInput] = import_react8.useState(initialTextInput);
|
|
2038
|
+
const clearInput = import_react8.useCallback(() => setTextInput(""), []);
|
|
2039
|
+
const [fileItems, setFileItems] = import_react8.useState([]);
|
|
2040
|
+
const fileInputRef = import_react8.useRef(null);
|
|
2041
|
+
const openRef = import_react8.useRef(() => {});
|
|
2042
|
+
const add = import_react8.useCallback((files) => {
|
|
2043
|
+
const incoming = Array.from(files);
|
|
2044
|
+
if (incoming.length === 0)
|
|
2045
|
+
return;
|
|
2046
|
+
setFileItems((prev) => prev.concat(incoming.map((file) => ({
|
|
2047
|
+
id: generateId(),
|
|
2048
|
+
type: "file",
|
|
2049
|
+
url: URL.createObjectURL(file),
|
|
2050
|
+
mediaType: file.type,
|
|
2051
|
+
filename: file.name
|
|
2052
|
+
}))));
|
|
2053
|
+
}, []);
|
|
2054
|
+
const remove = import_react8.useCallback((id) => {
|
|
2055
|
+
setFileItems((prev) => {
|
|
2056
|
+
const found = prev.find((f) => f.id === id);
|
|
2057
|
+
if (found?.url)
|
|
2058
|
+
URL.revokeObjectURL(found.url);
|
|
2059
|
+
return prev.filter((f) => f.id !== id);
|
|
2060
|
+
});
|
|
2061
|
+
}, []);
|
|
2062
|
+
const clear = import_react8.useCallback(() => {
|
|
2063
|
+
setFileItems((prev) => {
|
|
2064
|
+
for (const f of prev)
|
|
2065
|
+
if (f.url)
|
|
2066
|
+
URL.revokeObjectURL(f.url);
|
|
2067
|
+
return [];
|
|
2068
|
+
});
|
|
2069
|
+
}, []);
|
|
2070
|
+
const openFileDialog = import_react8.useCallback(() => {
|
|
2071
|
+
openRef.current?.();
|
|
2072
|
+
}, []);
|
|
2073
|
+
const attachments = import_react8.useMemo(() => ({
|
|
2074
|
+
files: fileItems,
|
|
2075
|
+
add,
|
|
2076
|
+
remove,
|
|
2077
|
+
clear,
|
|
2078
|
+
openFileDialog,
|
|
2079
|
+
fileInputRef
|
|
2080
|
+
}), [fileItems, add, remove, clear, openFileDialog]);
|
|
2081
|
+
const __registerFileInput = import_react8.useCallback((ref, open) => {
|
|
2082
|
+
fileInputRef.current = ref.current;
|
|
2083
|
+
openRef.current = open;
|
|
2084
|
+
}, []);
|
|
2085
|
+
const controller = import_react8.useMemo(() => ({
|
|
2086
|
+
textInput: { value: textInput, setInput: setTextInput, clear: clearInput },
|
|
2087
|
+
attachments,
|
|
2088
|
+
__registerFileInput
|
|
2089
|
+
}), [textInput, clearInput, attachments, __registerFileInput]);
|
|
2090
|
+
return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(PromptInputController.Provider, {
|
|
2091
|
+
value: controller,
|
|
2092
|
+
children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(ProviderAttachmentsContext.Provider, {
|
|
2093
|
+
value: attachments,
|
|
2094
|
+
children
|
|
2095
|
+
}, undefined, false, undefined, this)
|
|
2096
|
+
}, undefined, false, undefined, this);
|
|
2097
|
+
}
|
|
2098
|
+
// src/ui/components/prompt-input/prompt-input.tsx
|
|
2099
|
+
var import_react9 = require("react");
|
|
2100
|
+
var jsx_dev_runtime25 = require("react/jsx-dev-runtime");
|
|
2101
|
+
function generateId2() {
|
|
2102
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
2103
|
+
return crypto.randomUUID();
|
|
2104
|
+
}
|
|
2105
|
+
return Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
2106
|
+
}
|
|
2107
|
+
var PromptInput = ({
|
|
2108
|
+
className,
|
|
2109
|
+
accept,
|
|
2110
|
+
multiple,
|
|
2111
|
+
globalDrop,
|
|
2112
|
+
syncHiddenInput,
|
|
2113
|
+
maxFiles,
|
|
2114
|
+
maxFileSize,
|
|
2115
|
+
dragListenerTarget,
|
|
2116
|
+
onError,
|
|
2117
|
+
onSubmit,
|
|
2118
|
+
children,
|
|
2119
|
+
...props
|
|
2120
|
+
}) => {
|
|
2121
|
+
const controller = useOptionalPromptInputController();
|
|
2122
|
+
const usingProvider = !!controller;
|
|
2123
|
+
const inputRef = import_react9.useRef(null);
|
|
2124
|
+
const formRef = import_react9.useRef(null);
|
|
2125
|
+
const [items, setItems] = import_react9.useState([]);
|
|
2126
|
+
const files = usingProvider ? controller.attachments.files : items;
|
|
2127
|
+
const [isDraggingOver, setIsDraggingOver] = import_react9.useState(false);
|
|
2128
|
+
const dragCounter = import_react9.useRef(0);
|
|
2129
|
+
const openFileDialogLocal = import_react9.useCallback(() => {
|
|
2130
|
+
inputRef.current?.click();
|
|
2131
|
+
}, []);
|
|
2132
|
+
const matchesAccept = import_react9.useCallback((f) => {
|
|
2133
|
+
if (!accept || accept.trim() === "")
|
|
2134
|
+
return true;
|
|
2135
|
+
const patterns = accept.split(",").map((p) => p.trim()).filter(Boolean);
|
|
2136
|
+
for (const pattern of patterns) {
|
|
2137
|
+
if (pattern.endsWith("/*")) {
|
|
2138
|
+
const prefix = pattern.slice(0, -1);
|
|
2139
|
+
if (f.type.startsWith(prefix))
|
|
2140
|
+
return true;
|
|
2141
|
+
} else if (pattern.startsWith(".")) {
|
|
2142
|
+
const ext = f.name.toLowerCase().split(".").pop();
|
|
2143
|
+
if (ext && `.${ext}` === pattern.toLowerCase())
|
|
2144
|
+
return true;
|
|
2145
|
+
} else if (f.type === pattern) {
|
|
2146
|
+
return true;
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
return false;
|
|
2150
|
+
}, [accept]);
|
|
2151
|
+
const addLocal = import_react9.useCallback((fileList) => {
|
|
2152
|
+
const incoming = Array.from(fileList);
|
|
2153
|
+
const accepted = incoming.filter((f) => matchesAccept(f));
|
|
2154
|
+
if (incoming.length && accepted.length === 0) {
|
|
2155
|
+
onError?.({ code: "accept", message: "No files match the accepted types." });
|
|
2156
|
+
return;
|
|
2157
|
+
}
|
|
2158
|
+
const withinSize = (f) => maxFileSize ? f.size <= maxFileSize : true;
|
|
2159
|
+
const sized = accepted.filter(withinSize);
|
|
2160
|
+
if (accepted.length > 0 && sized.length === 0) {
|
|
2161
|
+
onError?.({ code: "max_file_size", message: "All files exceed the maximum size." });
|
|
2162
|
+
return;
|
|
2163
|
+
}
|
|
2164
|
+
setItems((prev) => {
|
|
2165
|
+
const capacity = typeof maxFiles === "number" ? Math.max(0, maxFiles - prev.length) : undefined;
|
|
2166
|
+
const capped = typeof capacity === "number" ? sized.slice(0, capacity) : sized;
|
|
2167
|
+
if (typeof capacity === "number" && sized.length > capacity) {
|
|
2168
|
+
onError?.({ code: "max_files", message: "Too many files. Some were not added." });
|
|
2169
|
+
}
|
|
2170
|
+
const next = [];
|
|
2171
|
+
for (const file of capped) {
|
|
2172
|
+
next.push({
|
|
2173
|
+
id: generateId2(),
|
|
2174
|
+
type: "file",
|
|
2175
|
+
url: URL.createObjectURL(file),
|
|
2176
|
+
mediaType: file.type,
|
|
2177
|
+
filename: file.name
|
|
2178
|
+
});
|
|
2179
|
+
}
|
|
2180
|
+
return prev.concat(next);
|
|
2181
|
+
});
|
|
2182
|
+
}, [matchesAccept, maxFiles, maxFileSize, onError]);
|
|
2183
|
+
const add = usingProvider ? (fileList) => controller.attachments.add(fileList) : addLocal;
|
|
2184
|
+
const remove = usingProvider ? (id) => controller.attachments.remove(id) : (id) => setItems((prev) => {
|
|
2185
|
+
const found = prev.find((file) => file.id === id);
|
|
2186
|
+
if (found?.url)
|
|
2187
|
+
URL.revokeObjectURL(found.url);
|
|
2188
|
+
return prev.filter((file) => file.id !== id);
|
|
2189
|
+
});
|
|
2190
|
+
const clear = usingProvider ? () => controller.attachments.clear() : () => setItems((prev) => {
|
|
2191
|
+
for (const file of prev)
|
|
2192
|
+
if (file.url)
|
|
2193
|
+
URL.revokeObjectURL(file.url);
|
|
2194
|
+
return [];
|
|
2195
|
+
});
|
|
2196
|
+
const openFileDialog = usingProvider ? () => controller.attachments.openFileDialog() : openFileDialogLocal;
|
|
2197
|
+
import_react9.useEffect(() => {
|
|
2198
|
+
if (!usingProvider)
|
|
2199
|
+
return;
|
|
2200
|
+
controller.__registerFileInput(inputRef, () => inputRef.current?.click());
|
|
2201
|
+
}, [usingProvider, controller]);
|
|
2202
|
+
import_react9.useEffect(() => {
|
|
2203
|
+
if (syncHiddenInput && inputRef.current && files.length === 0) {
|
|
2204
|
+
inputRef.current.value = "";
|
|
2205
|
+
}
|
|
2206
|
+
}, [files, syncHiddenInput]);
|
|
2207
|
+
import_react9.useEffect(() => {
|
|
2208
|
+
if (globalDrop)
|
|
2209
|
+
return;
|
|
2210
|
+
const form = formRef.current;
|
|
2211
|
+
if (!form)
|
|
2212
|
+
return;
|
|
2213
|
+
const onDragOver = (e) => {
|
|
2214
|
+
if (e.dataTransfer?.types?.includes("Files"))
|
|
2215
|
+
e.preventDefault();
|
|
2216
|
+
};
|
|
2217
|
+
const onDragEnter = (e) => {
|
|
2218
|
+
if (e.dataTransfer?.types?.includes("Files")) {
|
|
2219
|
+
e.preventDefault();
|
|
2220
|
+
dragCounter.current++;
|
|
2221
|
+
if (dragCounter.current === 1)
|
|
2222
|
+
setIsDraggingOver(true);
|
|
2223
|
+
}
|
|
2224
|
+
};
|
|
2225
|
+
const onDragLeave = (_e) => {
|
|
2226
|
+
dragCounter.current--;
|
|
2227
|
+
if (dragCounter.current === 0)
|
|
2228
|
+
setIsDraggingOver(false);
|
|
2229
|
+
};
|
|
2230
|
+
const onDrop = (e) => {
|
|
2231
|
+
if (e.dataTransfer?.types?.includes("Files"))
|
|
2232
|
+
e.preventDefault();
|
|
2233
|
+
dragCounter.current = 0;
|
|
2234
|
+
setIsDraggingOver(false);
|
|
2235
|
+
if (e.dataTransfer?.files && e.dataTransfer.files.length > 0)
|
|
2236
|
+
add(e.dataTransfer.files);
|
|
2237
|
+
};
|
|
2238
|
+
form.addEventListener("dragover", onDragOver);
|
|
2239
|
+
form.addEventListener("dragenter", onDragEnter);
|
|
2240
|
+
form.addEventListener("dragleave", onDragLeave);
|
|
2241
|
+
form.addEventListener("drop", onDrop);
|
|
2242
|
+
return () => {
|
|
2243
|
+
form.removeEventListener("dragover", onDragOver);
|
|
2244
|
+
form.removeEventListener("dragenter", onDragEnter);
|
|
2245
|
+
form.removeEventListener("dragleave", onDragLeave);
|
|
2246
|
+
form.removeEventListener("drop", onDrop);
|
|
2247
|
+
};
|
|
2248
|
+
}, [add, globalDrop]);
|
|
2249
|
+
import_react9.useEffect(() => {
|
|
2250
|
+
if (!globalDrop)
|
|
2251
|
+
return;
|
|
2252
|
+
const target = dragListenerTarget?.current ?? document;
|
|
2253
|
+
const onDragOver = (e) => {
|
|
2254
|
+
if (e.dataTransfer?.types?.includes("Files"))
|
|
2255
|
+
e.preventDefault();
|
|
2256
|
+
};
|
|
2257
|
+
const onDragEnter = (e) => {
|
|
2258
|
+
if (e.dataTransfer?.types?.includes("Files")) {
|
|
2259
|
+
e.preventDefault();
|
|
2260
|
+
dragCounter.current++;
|
|
2261
|
+
if (dragCounter.current === 1)
|
|
2262
|
+
setIsDraggingOver(true);
|
|
2263
|
+
}
|
|
2264
|
+
};
|
|
2265
|
+
const onDragLeave = (_e) => {
|
|
2266
|
+
dragCounter.current--;
|
|
2267
|
+
if (dragCounter.current === 0)
|
|
2268
|
+
setIsDraggingOver(false);
|
|
2269
|
+
};
|
|
2270
|
+
const onDrop = (e) => {
|
|
2271
|
+
if (e.dataTransfer?.types?.includes("Files"))
|
|
2272
|
+
e.preventDefault();
|
|
2273
|
+
dragCounter.current = 0;
|
|
2274
|
+
setIsDraggingOver(false);
|
|
2275
|
+
if (e.dataTransfer?.files && e.dataTransfer.files.length > 0)
|
|
2276
|
+
add(e.dataTransfer.files);
|
|
2277
|
+
};
|
|
2278
|
+
target.addEventListener("dragover", onDragOver);
|
|
2279
|
+
target.addEventListener("dragenter", onDragEnter);
|
|
2280
|
+
target.addEventListener("dragleave", onDragLeave);
|
|
2281
|
+
target.addEventListener("drop", onDrop);
|
|
2282
|
+
return () => {
|
|
2283
|
+
target.removeEventListener("dragover", onDragOver);
|
|
2284
|
+
target.removeEventListener("dragenter", onDragEnter);
|
|
2285
|
+
target.removeEventListener("dragleave", onDragLeave);
|
|
2286
|
+
target.removeEventListener("drop", onDrop);
|
|
2287
|
+
};
|
|
2288
|
+
}, [add, globalDrop, dragListenerTarget]);
|
|
2289
|
+
const filesRef = import_react9.useRef(files);
|
|
2290
|
+
filesRef.current = files;
|
|
2291
|
+
import_react9.useEffect(() => () => {
|
|
2292
|
+
if (!usingProvider) {
|
|
2293
|
+
for (const f of filesRef.current)
|
|
2294
|
+
if (f.url)
|
|
2295
|
+
URL.revokeObjectURL(f.url);
|
|
2296
|
+
}
|
|
2297
|
+
}, [usingProvider]);
|
|
2298
|
+
const handleChange = (event) => {
|
|
2299
|
+
if (event.currentTarget.files)
|
|
2300
|
+
add(event.currentTarget.files);
|
|
2301
|
+
};
|
|
2302
|
+
const convertBlobUrlToDataUrl = async (url) => {
|
|
2303
|
+
const response = await fetch(url);
|
|
2304
|
+
const blob = await response.blob();
|
|
2305
|
+
return new Promise((resolve, reject) => {
|
|
2306
|
+
const reader = new FileReader;
|
|
2307
|
+
reader.onloadend = () => resolve(reader.result);
|
|
2308
|
+
reader.onerror = reject;
|
|
2309
|
+
reader.readAsDataURL(blob);
|
|
2310
|
+
});
|
|
2311
|
+
};
|
|
2312
|
+
const ctx = import_react9.useMemo(() => ({
|
|
2313
|
+
files: files.map((item) => ({ ...item, id: item.id })),
|
|
2314
|
+
add,
|
|
2315
|
+
remove,
|
|
2316
|
+
clear,
|
|
2317
|
+
openFileDialog,
|
|
2318
|
+
fileInputRef: inputRef
|
|
2319
|
+
}), [files, add, remove, clear, openFileDialog]);
|
|
2320
|
+
const handleSubmit = (event) => {
|
|
2321
|
+
event.preventDefault();
|
|
2322
|
+
const form = event.currentTarget;
|
|
2323
|
+
const text = usingProvider ? controller.textInput.value : (() => {
|
|
2324
|
+
const formData = new FormData(form);
|
|
2325
|
+
return formData.get("message") || "";
|
|
2326
|
+
})();
|
|
2327
|
+
if (!usingProvider)
|
|
2328
|
+
form.reset();
|
|
2329
|
+
Promise.all(files.map(async ({ id, ...item }) => {
|
|
2330
|
+
if (item.url && item.url.startsWith("blob:")) {
|
|
2331
|
+
return { ...item, url: await convertBlobUrlToDataUrl(item.url) };
|
|
2332
|
+
}
|
|
2333
|
+
return item;
|
|
2334
|
+
})).then((convertedFiles) => {
|
|
2335
|
+
try {
|
|
2336
|
+
const result = onSubmit({ text, files: convertedFiles }, event);
|
|
2337
|
+
if (result instanceof Promise) {
|
|
2338
|
+
result.then(() => {
|
|
2339
|
+
clear();
|
|
2340
|
+
if (usingProvider)
|
|
2341
|
+
controller.textInput.clear();
|
|
2342
|
+
}).catch(() => {});
|
|
2343
|
+
} else {
|
|
2344
|
+
clear();
|
|
2345
|
+
if (usingProvider)
|
|
2346
|
+
controller.textInput.clear();
|
|
2347
|
+
}
|
|
2348
|
+
} catch {}
|
|
2349
|
+
});
|
|
2350
|
+
};
|
|
2351
|
+
const dropZoneValue = import_react9.useMemo(() => ({ isDraggingOver }), [isDraggingOver]);
|
|
2352
|
+
const inner = /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(DropZoneContext.Provider, {
|
|
2353
|
+
value: dropZoneValue,
|
|
2354
|
+
children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV("form", {
|
|
2355
|
+
className: cn("relative w-full", className),
|
|
2356
|
+
onSubmit: handleSubmit,
|
|
2357
|
+
ref: formRef,
|
|
2358
|
+
...props,
|
|
2359
|
+
children: [
|
|
2360
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV("input", {
|
|
2361
|
+
accept,
|
|
2362
|
+
"aria-label": "Upload files",
|
|
2363
|
+
className: "hidden",
|
|
2364
|
+
multiple,
|
|
2365
|
+
onChange: handleChange,
|
|
2366
|
+
ref: inputRef,
|
|
2367
|
+
title: "Upload files",
|
|
2368
|
+
type: "file"
|
|
2369
|
+
}, undefined, false, undefined, this),
|
|
2370
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(InputGroup, {
|
|
2371
|
+
children
|
|
2372
|
+
}, undefined, false, undefined, this)
|
|
2373
|
+
]
|
|
2374
|
+
}, undefined, true, undefined, this)
|
|
2375
|
+
}, undefined, false, undefined, this);
|
|
2376
|
+
return usingProvider ? inner : /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(LocalAttachmentsContext.Provider, {
|
|
2377
|
+
value: ctx,
|
|
2378
|
+
children: inner
|
|
2379
|
+
}, undefined, false, undefined, this);
|
|
2380
|
+
};
|
|
2381
|
+
// src/ui/components/prompt-input/textarea.tsx
|
|
2382
|
+
var import_react10 = require("react");
|
|
2383
|
+
var jsx_dev_runtime26 = require("react/jsx-dev-runtime");
|
|
2384
|
+
var PromptInputTextarea = ({
|
|
2385
|
+
onChange,
|
|
2386
|
+
className,
|
|
2387
|
+
placeholder = "What would you like to know?",
|
|
2388
|
+
...props
|
|
2389
|
+
}) => {
|
|
2390
|
+
const controller = useOptionalPromptInputController();
|
|
2391
|
+
const attachments = usePromptInputAttachments();
|
|
2392
|
+
const [isComposing, setIsComposing] = import_react10.useState(false);
|
|
2393
|
+
const handleKeyDown = (e) => {
|
|
2394
|
+
if (e.key === "Enter") {
|
|
2395
|
+
if (isComposing || e.nativeEvent.isComposing)
|
|
2396
|
+
return;
|
|
2397
|
+
if (e.shiftKey)
|
|
2398
|
+
return;
|
|
2399
|
+
e.preventDefault();
|
|
2400
|
+
e.currentTarget.form?.requestSubmit();
|
|
2401
|
+
}
|
|
2402
|
+
if (e.key === "Backspace" && e.currentTarget.value === "" && attachments.files.length > 0) {
|
|
2403
|
+
e.preventDefault();
|
|
2404
|
+
const lastAttachment = attachments.files.at(-1);
|
|
2405
|
+
if (lastAttachment)
|
|
2406
|
+
attachments.remove(lastAttachment.id);
|
|
2407
|
+
}
|
|
2408
|
+
};
|
|
2409
|
+
const handlePaste = (event) => {
|
|
2410
|
+
const items = event.clipboardData?.items;
|
|
2411
|
+
if (!items)
|
|
2412
|
+
return;
|
|
2413
|
+
const files = [];
|
|
2414
|
+
for (const item of items) {
|
|
2415
|
+
if (item.kind === "file") {
|
|
2416
|
+
const file = item.getAsFile();
|
|
2417
|
+
if (file)
|
|
2418
|
+
files.push(file);
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
if (files.length > 0) {
|
|
2422
|
+
event.preventDefault();
|
|
2423
|
+
attachments.add(files);
|
|
2424
|
+
}
|
|
2425
|
+
};
|
|
2426
|
+
const controlledProps = controller ? {
|
|
2427
|
+
value: controller.textInput.value,
|
|
2428
|
+
onChange: (e) => {
|
|
2429
|
+
controller.textInput.setInput(e.currentTarget.value);
|
|
2430
|
+
onChange?.(e);
|
|
2431
|
+
}
|
|
2432
|
+
} : { onChange };
|
|
2433
|
+
return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(InputGroupTextarea, {
|
|
2434
|
+
className: cn("[field-sizing:content] max-h-48 text-base", className),
|
|
2435
|
+
rows: 1,
|
|
2436
|
+
name: "message",
|
|
2437
|
+
onCompositionEnd: () => setIsComposing(false),
|
|
2438
|
+
onCompositionStart: () => setIsComposing(true),
|
|
2439
|
+
onKeyDown: handleKeyDown,
|
|
2440
|
+
onPaste: handlePaste,
|
|
2441
|
+
placeholder,
|
|
2442
|
+
...props,
|
|
2443
|
+
...controlledProps
|
|
2444
|
+
}, undefined, false, undefined, this);
|
|
2445
|
+
};
|
|
2446
|
+
// src/ui/components/prompt-input/attachments.tsx
|
|
2447
|
+
var import_lucide_react15 = require("lucide-react");
|
|
2448
|
+
var import_react11 = require("react");
|
|
2449
|
+
var jsx_dev_runtime27 = require("react/jsx-dev-runtime");
|
|
2450
|
+
function PromptInputAttachment({ data, className, ...props }) {
|
|
2451
|
+
const attachments = usePromptInputAttachments();
|
|
2452
|
+
const filename = data.filename || "";
|
|
2453
|
+
const isImage = data.mediaType?.startsWith("image/") && data.url;
|
|
2454
|
+
const isAudio = data.mediaType?.startsWith("audio/");
|
|
2455
|
+
const attachmentLabel = filename || (isImage ? "Image" : isAudio ? "Audio" : "Attachment");
|
|
2456
|
+
return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(HoverCard, {
|
|
2457
|
+
openDelay: 0,
|
|
2458
|
+
closeDelay: 0,
|
|
2459
|
+
children: [
|
|
2460
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV(HoverCardTrigger, {
|
|
2461
|
+
asChild: true,
|
|
2462
|
+
children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
2463
|
+
className: cn("group relative flex h-8 cursor-default select-none items-center gap-1.5 rounded-md border border-border px-1.5 font-medium text-sm transition-all hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", className),
|
|
2464
|
+
...props,
|
|
2465
|
+
children: [
|
|
2466
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
2467
|
+
className: "relative size-5 shrink-0",
|
|
2468
|
+
children: [
|
|
2469
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
2470
|
+
className: "absolute inset-0 flex size-5 items-center justify-center overflow-hidden rounded bg-background transition-opacity group-hover:opacity-0",
|
|
2471
|
+
children: isImage ? /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("img", {
|
|
2472
|
+
alt: filename || "attachment",
|
|
2473
|
+
className: "size-5 object-cover",
|
|
2474
|
+
height: 20,
|
|
2475
|
+
src: data.url,
|
|
2476
|
+
width: 20
|
|
2477
|
+
}, undefined, false, undefined, this) : isAudio ? /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
2478
|
+
className: "flex size-5 items-center justify-center text-muted-foreground",
|
|
2479
|
+
children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(import_lucide_react15.MicIcon, {
|
|
2480
|
+
className: "size-3"
|
|
2481
|
+
}, undefined, false, undefined, this)
|
|
2482
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
2483
|
+
className: "flex size-5 items-center justify-center text-muted-foreground",
|
|
2484
|
+
children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(import_lucide_react15.PaperclipIcon, {
|
|
2485
|
+
className: "size-3"
|
|
2486
|
+
}, undefined, false, undefined, this)
|
|
2487
|
+
}, undefined, false, undefined, this)
|
|
2488
|
+
}, undefined, false, undefined, this),
|
|
2489
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Button, {
|
|
2490
|
+
"aria-label": "Remove attachment",
|
|
2491
|
+
className: "absolute inset-0 size-5 cursor-pointer rounded p-0 opacity-0 transition-opacity group-hover:pointer-events-auto group-hover:opacity-100 [&>svg]:size-2.5",
|
|
2492
|
+
onClick: (e) => {
|
|
2493
|
+
e.stopPropagation();
|
|
2494
|
+
attachments.remove(data.id);
|
|
2495
|
+
},
|
|
2496
|
+
type: "button",
|
|
2497
|
+
variant: "ghost",
|
|
2498
|
+
children: [
|
|
2499
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV(import_lucide_react15.XIcon, {}, undefined, false, undefined, this),
|
|
2500
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("span", {
|
|
2501
|
+
className: "sr-only",
|
|
2502
|
+
children: "Remove"
|
|
2503
|
+
}, undefined, false, undefined, this)
|
|
2504
|
+
]
|
|
2505
|
+
}, undefined, true, undefined, this)
|
|
2506
|
+
]
|
|
2507
|
+
}, undefined, true, undefined, this),
|
|
2508
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("span", {
|
|
2509
|
+
className: "flex-1 truncate",
|
|
2510
|
+
children: attachmentLabel
|
|
2511
|
+
}, undefined, false, undefined, this)
|
|
2512
|
+
]
|
|
2513
|
+
}, data.id, true, undefined, this)
|
|
2514
|
+
}, undefined, false, undefined, this),
|
|
2515
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV(HoverCardContent, {
|
|
2516
|
+
align: "start",
|
|
2517
|
+
className: "w-auto p-2",
|
|
2518
|
+
children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
2519
|
+
className: "w-auto space-y-3",
|
|
2520
|
+
children: [
|
|
2521
|
+
isImage && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
2522
|
+
className: "flex max-h-96 w-96 items-center justify-center overflow-hidden rounded-md border",
|
|
2523
|
+
children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("img", {
|
|
2524
|
+
alt: filename || "attachment preview",
|
|
2525
|
+
className: "max-h-full max-w-full object-contain",
|
|
2526
|
+
height: 384,
|
|
2527
|
+
src: data.url,
|
|
2528
|
+
width: 448
|
|
2529
|
+
}, undefined, false, undefined, this)
|
|
2530
|
+
}, undefined, false, undefined, this),
|
|
2531
|
+
isAudio && data.url && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
2532
|
+
className: "w-64",
|
|
2533
|
+
children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("audio", {
|
|
2534
|
+
src: data.url,
|
|
2535
|
+
controls: true,
|
|
2536
|
+
className: "w-full"
|
|
2537
|
+
}, undefined, false, undefined, this)
|
|
2538
|
+
}, undefined, false, undefined, this),
|
|
2539
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
2540
|
+
className: "flex items-center gap-2.5",
|
|
2541
|
+
children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
2542
|
+
className: "min-w-0 flex-1 space-y-1 px-0.5",
|
|
2543
|
+
children: [
|
|
2544
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("h4", {
|
|
2545
|
+
className: "truncate font-semibold text-sm leading-none",
|
|
2546
|
+
children: filename || (isImage ? "Image" : "Attachment")
|
|
2547
|
+
}, undefined, false, undefined, this),
|
|
2548
|
+
data.mediaType && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("p", {
|
|
2549
|
+
className: "truncate font-mono text-muted-foreground text-xs",
|
|
2550
|
+
children: data.mediaType
|
|
2551
|
+
}, undefined, false, undefined, this)
|
|
2552
|
+
]
|
|
2553
|
+
}, undefined, true, undefined, this)
|
|
2554
|
+
}, undefined, false, undefined, this)
|
|
2555
|
+
]
|
|
2556
|
+
}, undefined, true, undefined, this)
|
|
2557
|
+
}, undefined, false, undefined, this)
|
|
2558
|
+
]
|
|
2559
|
+
}, undefined, true, undefined, this);
|
|
2560
|
+
}
|
|
2561
|
+
function PromptInputAttachments({ children }) {
|
|
2562
|
+
const attachments = usePromptInputAttachments();
|
|
2563
|
+
if (!attachments.files.length)
|
|
2564
|
+
return null;
|
|
2565
|
+
return attachments.files.map((file) => /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(import_react11.Fragment, {
|
|
2566
|
+
children: children(file)
|
|
2567
|
+
}, file.id, false, undefined, this));
|
|
2568
|
+
}
|
|
2569
|
+
var PromptInputActionAddAttachments = ({
|
|
2570
|
+
label = "Add photos or files",
|
|
2571
|
+
...props
|
|
2572
|
+
}) => {
|
|
2573
|
+
const attachments = usePromptInputAttachments();
|
|
2574
|
+
return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(DropdownMenuItem, {
|
|
2575
|
+
...props,
|
|
2576
|
+
onSelect: () => {
|
|
2577
|
+
attachments.openFileDialog();
|
|
2578
|
+
},
|
|
2579
|
+
children: [
|
|
2580
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV(import_lucide_react15.ImageIcon, {
|
|
2581
|
+
className: "mr-2 size-4"
|
|
2582
|
+
}, undefined, false, undefined, this),
|
|
2583
|
+
" ",
|
|
2584
|
+
label
|
|
2585
|
+
]
|
|
2586
|
+
}, undefined, true, undefined, this);
|
|
2587
|
+
};
|
|
2588
|
+
// src/ui/components/prompt-input/footer.tsx
|
|
2589
|
+
var jsx_dev_runtime28 = require("react/jsx-dev-runtime");
|
|
2590
|
+
var PromptInputBody = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime28.jsxDEV("div", {
|
|
2591
|
+
className: cn("contents", className),
|
|
2592
|
+
...props
|
|
2593
|
+
}, undefined, false, undefined, this);
|
|
2594
|
+
var PromptInputHeader = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(InputGroupAddon, {
|
|
2595
|
+
align: "block-start",
|
|
2596
|
+
className: cn("flex-wrap gap-1 empty:hidden empty:p-0", className),
|
|
2597
|
+
...props
|
|
2598
|
+
}, undefined, false, undefined, this);
|
|
2599
|
+
var PromptInputFooter = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(InputGroupAddon, {
|
|
2600
|
+
align: "block-end",
|
|
2601
|
+
className: cn("justify-between gap-1", className),
|
|
2602
|
+
...props
|
|
2603
|
+
}, undefined, false, undefined, this);
|
|
2604
|
+
var PromptInputTools = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime28.jsxDEV("div", {
|
|
2605
|
+
className: cn("flex items-center gap-1", className),
|
|
2606
|
+
...props
|
|
2607
|
+
}, undefined, false, undefined, this);
|
|
2608
|
+
// src/ui/components/prompt-input/buttons.tsx
|
|
2609
|
+
var import_lucide_react16 = require("lucide-react");
|
|
2610
|
+
var import_react12 = require("react");
|
|
2611
|
+
var jsx_dev_runtime29 = require("react/jsx-dev-runtime");
|
|
2612
|
+
var PromptInputButton = ({
|
|
2613
|
+
variant = "ghost",
|
|
2614
|
+
className,
|
|
2615
|
+
size,
|
|
2616
|
+
...props
|
|
2617
|
+
}) => {
|
|
2618
|
+
const newSize = size ?? (import_react12.Children.count(props.children) > 1 ? "sm" : "icon-sm");
|
|
2619
|
+
return /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(InputGroupButton, {
|
|
2620
|
+
className: cn(className),
|
|
2621
|
+
size: newSize,
|
|
2622
|
+
type: "button",
|
|
2623
|
+
variant,
|
|
2624
|
+
...props
|
|
2625
|
+
}, undefined, false, undefined, this);
|
|
2626
|
+
};
|
|
2627
|
+
var PromptInputSubmit = ({
|
|
2628
|
+
className,
|
|
2629
|
+
variant = "default",
|
|
2630
|
+
size = "icon-sm",
|
|
2631
|
+
status,
|
|
2632
|
+
children,
|
|
2633
|
+
...props
|
|
2634
|
+
}) => {
|
|
2635
|
+
let Icon2 = /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(import_lucide_react16.SendIcon, {
|
|
2636
|
+
className: "size-4"
|
|
2637
|
+
}, undefined, false, undefined, this);
|
|
2638
|
+
if (status === "submitted") {
|
|
2639
|
+
Icon2 = /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(import_lucide_react16.Loader2Icon, {
|
|
2640
|
+
className: "size-4 animate-spin"
|
|
2641
|
+
}, undefined, false, undefined, this);
|
|
2642
|
+
} else if (status === "streaming") {
|
|
2643
|
+
Icon2 = /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(import_lucide_react16.SquareIcon, {
|
|
2644
|
+
className: "size-4"
|
|
2645
|
+
}, undefined, false, undefined, this);
|
|
2646
|
+
} else if (status === "error") {
|
|
2647
|
+
Icon2 = /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(import_lucide_react16.XIcon, {
|
|
2648
|
+
className: "size-4"
|
|
2649
|
+
}, undefined, false, undefined, this);
|
|
2650
|
+
}
|
|
2651
|
+
return /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(InputGroupButton, {
|
|
2652
|
+
"aria-label": "Submit",
|
|
2653
|
+
className: cn(className),
|
|
2654
|
+
size,
|
|
2655
|
+
type: "submit",
|
|
2656
|
+
variant,
|
|
2657
|
+
...props,
|
|
2658
|
+
children: children ?? Icon2
|
|
2659
|
+
}, undefined, false, undefined, this);
|
|
2660
|
+
};
|
|
2661
|
+
var PromptInputActionMenu = (props) => /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(DropdownMenu, {
|
|
2662
|
+
...props
|
|
2663
|
+
}, undefined, false, undefined, this);
|
|
2664
|
+
var PromptInputActionMenuTrigger = ({
|
|
2665
|
+
className,
|
|
2666
|
+
children,
|
|
2667
|
+
...props
|
|
2668
|
+
}) => /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(DropdownMenuTrigger, {
|
|
2669
|
+
asChild: true,
|
|
2670
|
+
children: /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(PromptInputButton, {
|
|
2671
|
+
className,
|
|
2672
|
+
...props,
|
|
2673
|
+
children: children ?? /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(import_lucide_react16.PlusIcon, {
|
|
2674
|
+
className: "size-4"
|
|
2675
|
+
}, undefined, false, undefined, this)
|
|
2676
|
+
}, undefined, false, undefined, this)
|
|
2677
|
+
}, undefined, false, undefined, this);
|
|
2678
|
+
var PromptInputActionMenuContent = ({
|
|
2679
|
+
className,
|
|
2680
|
+
...props
|
|
2681
|
+
}) => /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(DropdownMenuContent, {
|
|
2682
|
+
align: "start",
|
|
2683
|
+
className: cn(className),
|
|
2684
|
+
...props
|
|
2685
|
+
}, undefined, false, undefined, this);
|
|
2686
|
+
var PromptInputActionMenuItem = ({
|
|
2687
|
+
className,
|
|
2688
|
+
...props
|
|
2689
|
+
}) => /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(DropdownMenuItem, {
|
|
2690
|
+
className: cn(className),
|
|
2691
|
+
...props
|
|
2692
|
+
}, undefined, false, undefined, this);
|
|
2693
|
+
// src/ui/components/prompt-input/drop-zone.tsx
|
|
2694
|
+
var import_lucide_react17 = require("lucide-react");
|
|
2695
|
+
var import_react_dom = require("react-dom");
|
|
2696
|
+
var jsx_dev_runtime30 = require("react/jsx-dev-runtime");
|
|
2697
|
+
var PromptInputDropZone = ({
|
|
2698
|
+
label = "Drop files here",
|
|
2699
|
+
className,
|
|
2700
|
+
container,
|
|
2701
|
+
...props
|
|
2702
|
+
}) => {
|
|
2703
|
+
const { isDraggingOver } = usePromptInputDropZone();
|
|
2704
|
+
const overlay = /* @__PURE__ */ jsx_dev_runtime30.jsxDEV("div", {
|
|
2705
|
+
className: cn("absolute inset-0 z-10 pointer-events-none", "flex flex-col items-center justify-center gap-2", "border-2 border-dashed border-primary rounded-xl", "bg-primary/5 backdrop-blur-[2px] text-primary", "transition-opacity duration-200", isDraggingOver ? "opacity-100" : "opacity-0", className),
|
|
2706
|
+
"aria-hidden": !isDraggingOver,
|
|
2707
|
+
...props,
|
|
2708
|
+
children: [
|
|
2709
|
+
/* @__PURE__ */ jsx_dev_runtime30.jsxDEV(import_lucide_react17.Upload, {
|
|
2710
|
+
className: "size-14"
|
|
2711
|
+
}, undefined, false, undefined, this),
|
|
2712
|
+
/* @__PURE__ */ jsx_dev_runtime30.jsxDEV("span", {
|
|
2713
|
+
className: "text-sm font-medium mt-2",
|
|
2714
|
+
children: label
|
|
2715
|
+
}, undefined, false, undefined, this)
|
|
2716
|
+
]
|
|
2717
|
+
}, undefined, true, undefined, this);
|
|
2718
|
+
if (container?.current) {
|
|
2719
|
+
return import_react_dom.createPortal(overlay, container.current);
|
|
2720
|
+
}
|
|
2721
|
+
return overlay;
|
|
2722
|
+
};
|
|
2723
|
+
// src/ui/components/prompt-input/speech.tsx
|
|
2724
|
+
var import_lucide_react18 = require("lucide-react");
|
|
2725
|
+
var import_react13 = require("react");
|
|
2726
|
+
var jsx_dev_runtime31 = require("react/jsx-dev-runtime");
|
|
2727
|
+
var PromptInputSpeechButton = ({
|
|
2728
|
+
className,
|
|
2729
|
+
onTranscriptionChange,
|
|
2730
|
+
lang = "en-US",
|
|
2731
|
+
...props
|
|
2732
|
+
}) => {
|
|
2733
|
+
const [isListening, setIsListening] = import_react13.useState(false);
|
|
2734
|
+
const [recognition, setRecognition] = import_react13.useState(null);
|
|
2735
|
+
const recognitionRef = import_react13.useRef(null);
|
|
2736
|
+
const onTranscriptionChangeRef = import_react13.useRef(onTranscriptionChange);
|
|
2737
|
+
onTranscriptionChangeRef.current = onTranscriptionChange;
|
|
2738
|
+
const controller = useOptionalPromptInputController();
|
|
2739
|
+
import_react13.useEffect(() => {
|
|
2740
|
+
if (typeof window !== "undefined" && (("SpeechRecognition" in window) || ("webkitSpeechRecognition" in window))) {
|
|
2741
|
+
const SpeechRecognitionCtor = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
2742
|
+
const speechRecognition = new SpeechRecognitionCtor;
|
|
2743
|
+
speechRecognition.continuous = true;
|
|
2744
|
+
speechRecognition.interimResults = true;
|
|
2745
|
+
speechRecognition.lang = lang;
|
|
2746
|
+
speechRecognition.onstart = () => setIsListening(true);
|
|
2747
|
+
speechRecognition.onend = () => setIsListening(false);
|
|
2748
|
+
speechRecognition.onresult = (event) => {
|
|
2749
|
+
let finalTranscript = "";
|
|
2750
|
+
const results = Array.from(event.results);
|
|
2751
|
+
for (const result of results) {
|
|
2752
|
+
if (result.isFinal)
|
|
2753
|
+
finalTranscript += result[0]?.transcript ?? "";
|
|
2754
|
+
}
|
|
2755
|
+
if (finalTranscript) {
|
|
2756
|
+
if (controller) {
|
|
2757
|
+
const current = controller.textInput.value;
|
|
2758
|
+
const newValue = current + (current ? " " : "") + finalTranscript;
|
|
2759
|
+
controller.textInput.setInput(newValue);
|
|
2760
|
+
}
|
|
2761
|
+
onTranscriptionChangeRef.current?.(finalTranscript);
|
|
2762
|
+
}
|
|
2763
|
+
};
|
|
2764
|
+
speechRecognition.onerror = (event) => {
|
|
2765
|
+
console.error("Speech recognition error:", event.error);
|
|
2766
|
+
setIsListening(false);
|
|
2767
|
+
};
|
|
2768
|
+
recognitionRef.current = speechRecognition;
|
|
2769
|
+
setRecognition(speechRecognition);
|
|
2770
|
+
}
|
|
2771
|
+
return () => {
|
|
2772
|
+
if (recognitionRef.current)
|
|
2773
|
+
recognitionRef.current.stop();
|
|
2774
|
+
};
|
|
2775
|
+
}, [lang]);
|
|
2776
|
+
const toggleListening = import_react13.useCallback(() => {
|
|
2777
|
+
if (!recognition)
|
|
2778
|
+
return;
|
|
2779
|
+
if (isListening)
|
|
2780
|
+
recognition.stop();
|
|
2781
|
+
else
|
|
2782
|
+
recognition.start();
|
|
2783
|
+
}, [recognition, isListening]);
|
|
2784
|
+
return /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(PromptInputButton, {
|
|
2785
|
+
className: cn("relative transition-all duration-200", isListening && "animate-pulse bg-accent text-accent-foreground", className),
|
|
2786
|
+
disabled: !recognition,
|
|
2787
|
+
onClick: toggleListening,
|
|
2788
|
+
...props,
|
|
2789
|
+
children: /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(import_lucide_react18.MicIcon, {
|
|
2790
|
+
className: "size-4"
|
|
2791
|
+
}, undefined, false, undefined, this)
|
|
2792
|
+
}, undefined, false, undefined, this);
|
|
2793
|
+
};
|
|
2794
|
+
// src/ui/components/prompt-input/model-select.tsx
|
|
2795
|
+
var jsx_dev_runtime32 = require("react/jsx-dev-runtime");
|
|
2796
|
+
var PromptInputModelSelect = (props) => /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Select, {
|
|
2797
|
+
...props
|
|
2798
|
+
}, undefined, false, undefined, this);
|
|
2799
|
+
var PromptInputModelSelectTrigger = ({
|
|
2800
|
+
className,
|
|
2801
|
+
...props
|
|
2802
|
+
}) => /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(SelectTrigger, {
|
|
2803
|
+
className: cn("border-none bg-transparent font-medium text-muted-foreground shadow-none transition-colors", 'hover:bg-accent hover:text-foreground [&[aria-expanded="true"]]:bg-accent [&[aria-expanded="true"]]:text-foreground', className),
|
|
2804
|
+
...props
|
|
2805
|
+
}, undefined, false, undefined, this);
|
|
2806
|
+
var PromptInputModelSelectContent = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(SelectContent, {
|
|
2807
|
+
className: cn(className),
|
|
2808
|
+
...props
|
|
2809
|
+
}, undefined, false, undefined, this);
|
|
2810
|
+
var PromptInputModelSelectItem = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(SelectItem, {
|
|
2811
|
+
className: cn(className),
|
|
2812
|
+
...props
|
|
2813
|
+
}, undefined, false, undefined, this);
|
|
2814
|
+
var PromptInputModelSelectValue = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(SelectValue, {
|
|
2815
|
+
className: cn(className),
|
|
2816
|
+
...props
|
|
2817
|
+
}, undefined, false, undefined, this);
|
|
2818
|
+
// src/ui/components/prompt-input/tabs.tsx
|
|
2819
|
+
var jsx_dev_runtime33 = require("react/jsx-dev-runtime");
|
|
2820
|
+
var PromptInputTabsList = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime33.jsxDEV("div", {
|
|
2821
|
+
className: cn(className),
|
|
2822
|
+
...props
|
|
2823
|
+
}, undefined, false, undefined, this);
|
|
2824
|
+
var PromptInputTab = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime33.jsxDEV("div", {
|
|
2825
|
+
className: cn(className),
|
|
2826
|
+
...props
|
|
2827
|
+
}, undefined, false, undefined, this);
|
|
2828
|
+
var PromptInputTabLabel = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime33.jsxDEV("h3", {
|
|
2829
|
+
className: cn("mb-2 px-3 font-medium text-muted-foreground text-xs", className),
|
|
2830
|
+
...props
|
|
2831
|
+
}, undefined, false, undefined, this);
|
|
2832
|
+
var PromptInputTabBody = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime33.jsxDEV("div", {
|
|
2833
|
+
className: cn("space-y-1", className),
|
|
2834
|
+
...props
|
|
2835
|
+
}, undefined, false, undefined, this);
|
|
2836
|
+
var PromptInputTabItem = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime33.jsxDEV("div", {
|
|
2837
|
+
className: cn("flex items-center gap-2 px-3 py-2 text-xs hover:bg-accent", className),
|
|
2838
|
+
...props
|
|
2839
|
+
}, undefined, false, undefined, this);
|
|
2840
|
+
// src/ui/components/prompt-input/command.tsx
|
|
2841
|
+
var jsx_dev_runtime34 = require("react/jsx-dev-runtime");
|
|
2842
|
+
var PromptInputCommand = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime34.jsxDEV(Command, {
|
|
2843
|
+
className: cn(className),
|
|
2844
|
+
...props
|
|
2845
|
+
}, undefined, false, undefined, this);
|
|
2846
|
+
var PromptInputCommandInput = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime34.jsxDEV(CommandInput, {
|
|
2847
|
+
className: cn(className),
|
|
2848
|
+
...props
|
|
2849
|
+
}, undefined, false, undefined, this);
|
|
2850
|
+
var PromptInputCommandList = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime34.jsxDEV(CommandList, {
|
|
2851
|
+
className: cn(className),
|
|
2852
|
+
...props
|
|
2853
|
+
}, undefined, false, undefined, this);
|
|
2854
|
+
var PromptInputCommandEmpty = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime34.jsxDEV(CommandEmpty, {
|
|
2855
|
+
className: cn(className),
|
|
2856
|
+
...props
|
|
2857
|
+
}, undefined, false, undefined, this);
|
|
2858
|
+
var PromptInputCommandGroup = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime34.jsxDEV(CommandGroup, {
|
|
2859
|
+
className: cn(className),
|
|
2860
|
+
...props
|
|
2861
|
+
}, undefined, false, undefined, this);
|
|
2862
|
+
var PromptInputCommandItem = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime34.jsxDEV(CommandItem, {
|
|
2863
|
+
className: cn(className),
|
|
2864
|
+
...props
|
|
2865
|
+
}, undefined, false, undefined, this);
|
|
2866
|
+
var PromptInputCommandSeparator = ({ className, ...props }) => /* @__PURE__ */ jsx_dev_runtime34.jsxDEV(CommandSeparator, {
|
|
2867
|
+
className: cn(className),
|
|
2868
|
+
...props
|
|
2869
|
+
}, undefined, false, undefined, this);
|
|
2870
|
+
// src/ui/composed/agno-chat/agno-chat.tsx
|
|
2871
|
+
var import_react15 = require("react");
|
|
2872
|
+
var import_agno_react = require("@rodrigocoliveira/agno-react");
|
|
2873
|
+
|
|
2874
|
+
// src/ui/composed/agno-chat/context.ts
|
|
2875
|
+
var import_react14 = require("react");
|
|
2876
|
+
var AgnoChatContext = import_react14.createContext(null);
|
|
2877
|
+
function useAgnoChatContext() {
|
|
2878
|
+
const ctx = import_react14.useContext(AgnoChatContext);
|
|
2879
|
+
if (!ctx) {
|
|
2880
|
+
throw new Error("useAgnoChatContext must be used within an <AgnoChat> provider. " + "Wrap your component tree with <AgnoChat>.");
|
|
2881
|
+
}
|
|
2882
|
+
return ctx;
|
|
2883
|
+
}
|
|
2884
|
+
|
|
2885
|
+
// src/ui/composed/agno-chat/agno-chat.tsx
|
|
2886
|
+
var jsx_dev_runtime35 = require("react/jsx-dev-runtime");
|
|
2887
|
+
function AgnoChatRoot({
|
|
2888
|
+
children,
|
|
2889
|
+
toolHandlers = {},
|
|
2890
|
+
autoExecuteTools = true,
|
|
2891
|
+
className,
|
|
2892
|
+
...divProps
|
|
2893
|
+
}) {
|
|
2894
|
+
const chat = import_agno_react.useAgnoChat();
|
|
2895
|
+
const toolExec = import_agno_react.useAgnoToolExecution(toolHandlers, autoExecuteTools);
|
|
2896
|
+
const containerRef = import_react15.useRef(null);
|
|
2897
|
+
const sendRef = import_react15.useRef(chat.sendMessage);
|
|
2898
|
+
sendRef.current = chat.sendMessage;
|
|
2899
|
+
const handleSend = import_react15.useCallback(async (message) => {
|
|
2900
|
+
try {
|
|
2901
|
+
await sendRef.current(message);
|
|
2902
|
+
} catch {}
|
|
2903
|
+
}, []);
|
|
2904
|
+
const {
|
|
2905
|
+
messages,
|
|
2906
|
+
sendMessage,
|
|
2907
|
+
clearMessages,
|
|
2908
|
+
cancelRun,
|
|
2909
|
+
isStreaming,
|
|
2910
|
+
isRefreshing,
|
|
2911
|
+
isCancelling,
|
|
2912
|
+
currentRunId,
|
|
2913
|
+
error,
|
|
2914
|
+
state
|
|
2915
|
+
} = chat;
|
|
2916
|
+
const {
|
|
2917
|
+
isPaused,
|
|
2918
|
+
isExecuting,
|
|
2919
|
+
pendingTools,
|
|
2920
|
+
executeAndContinue,
|
|
2921
|
+
executeTools,
|
|
2922
|
+
continueWithResults,
|
|
2923
|
+
executionError
|
|
2924
|
+
} = toolExec;
|
|
2925
|
+
const contextValue = import_react15.useMemo(() => ({
|
|
2926
|
+
messages,
|
|
2927
|
+
sendMessage,
|
|
2928
|
+
clearMessages,
|
|
2929
|
+
cancelRun,
|
|
2930
|
+
isStreaming,
|
|
2931
|
+
isRefreshing,
|
|
2932
|
+
isCancelling: isCancelling ?? false,
|
|
2933
|
+
currentRunId,
|
|
2934
|
+
error,
|
|
2935
|
+
state,
|
|
2936
|
+
isPaused,
|
|
2937
|
+
isExecuting,
|
|
2938
|
+
pendingTools,
|
|
2939
|
+
executeAndContinue,
|
|
2940
|
+
executeTools,
|
|
2941
|
+
continueWithResults,
|
|
2942
|
+
executionError,
|
|
2943
|
+
handleSend,
|
|
2944
|
+
inputDisabled: isStreaming || isPaused,
|
|
2945
|
+
dropZoneContainerRef: containerRef
|
|
2946
|
+
}), [
|
|
2947
|
+
messages,
|
|
2948
|
+
sendMessage,
|
|
2949
|
+
clearMessages,
|
|
2950
|
+
cancelRun,
|
|
2951
|
+
isStreaming,
|
|
2952
|
+
isRefreshing,
|
|
2953
|
+
isCancelling,
|
|
2954
|
+
currentRunId,
|
|
2955
|
+
error,
|
|
2956
|
+
state,
|
|
2957
|
+
isPaused,
|
|
2958
|
+
isExecuting,
|
|
2959
|
+
pendingTools,
|
|
2960
|
+
executeAndContinue,
|
|
2961
|
+
executeTools,
|
|
2962
|
+
continueWithResults,
|
|
2963
|
+
executionError,
|
|
2964
|
+
handleSend
|
|
2965
|
+
]);
|
|
2966
|
+
return /* @__PURE__ */ jsx_dev_runtime35.jsxDEV(AgnoChatContext.Provider, {
|
|
2967
|
+
value: contextValue,
|
|
2968
|
+
children: /* @__PURE__ */ jsx_dev_runtime35.jsxDEV("div", {
|
|
2969
|
+
ref: containerRef,
|
|
2970
|
+
className: cn("relative h-full flex flex-col", className),
|
|
2971
|
+
...divProps,
|
|
2972
|
+
children
|
|
2973
|
+
}, undefined, false, undefined, this)
|
|
2974
|
+
}, undefined, false, undefined, this);
|
|
2975
|
+
}
|
|
2976
|
+
|
|
2977
|
+
// src/ui/composed/agno-chat/messages.tsx
|
|
2978
|
+
var import_react17 = require("react");
|
|
2979
|
+
|
|
2980
|
+
// src/ui/composed/AgnoMessageItem.tsx
|
|
2981
|
+
var import_react16 = require("react");
|
|
2982
|
+
var import_agno_react2 = require("@rodrigocoliveira/agno-react");
|
|
2983
|
+
var import_lucide_react19 = require("lucide-react");
|
|
2984
|
+
var jsx_dev_runtime36 = require("react/jsx-dev-runtime");
|
|
2985
|
+
var defaultFormatTimestamp = formatSmartTimestamp;
|
|
2986
|
+
var getToolState = (tool) => {
|
|
2987
|
+
return tool.tool_call_error ? "output-error" : "output-available";
|
|
2988
|
+
};
|
|
2989
|
+
function AgnoMessageItem({
|
|
2990
|
+
message,
|
|
2991
|
+
className,
|
|
2992
|
+
classNames,
|
|
2993
|
+
renderContent,
|
|
2994
|
+
renderToolCall,
|
|
2995
|
+
renderMedia,
|
|
2996
|
+
renderActions,
|
|
2997
|
+
userAvatar,
|
|
2998
|
+
assistantAvatar,
|
|
2999
|
+
showReasoning = true,
|
|
3000
|
+
showReferences = true,
|
|
3001
|
+
showTimestamp = true,
|
|
3002
|
+
showGenerativeUI = true,
|
|
3003
|
+
showToolCalls = true,
|
|
3004
|
+
showFilePreview = true,
|
|
3005
|
+
showImageLightbox = true,
|
|
3006
|
+
formatTimestamp
|
|
3007
|
+
}) {
|
|
3008
|
+
const isUser = message.role === "user";
|
|
3009
|
+
const hasError = message.streamingError;
|
|
3010
|
+
const toolsWithUI = message.tool_calls?.filter((tool) => tool.ui_component) || [];
|
|
3011
|
+
const [preview, setPreview] = import_react16.useState(null);
|
|
3012
|
+
const isCustomTimestamp = !!formatTimestamp;
|
|
3013
|
+
const resolvedFormatTimestamp = formatTimestamp ?? defaultFormatTimestamp;
|
|
3014
|
+
const openImageLightbox = (images, index) => {
|
|
3015
|
+
if (!showImageLightbox)
|
|
3016
|
+
return;
|
|
3017
|
+
setPreview({ type: "image", images, initialIndex: index });
|
|
3018
|
+
};
|
|
3019
|
+
const openFilePreview = (file) => {
|
|
3020
|
+
if (!showFilePreview)
|
|
3021
|
+
return;
|
|
3022
|
+
setPreview({ type: "file", file });
|
|
3023
|
+
};
|
|
3024
|
+
const closePreview = () => setPreview(null);
|
|
3025
|
+
return /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3026
|
+
className: cn("py-5 first:pt-2", isUser ? "flex justify-end" : "", classNames?.root, className),
|
|
3027
|
+
children: [
|
|
3028
|
+
isUser ? /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3029
|
+
className: "flex items-start gap-2.5 max-w-[80%] flex-row-reverse",
|
|
3030
|
+
children: [
|
|
3031
|
+
userAvatar,
|
|
3032
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3033
|
+
className: "space-y-1.5 flex flex-col items-end min-w-0",
|
|
3034
|
+
children: [
|
|
3035
|
+
(message.images && message.images.length > 0 || message.audio && message.audio.length > 0 || message.files && message.files.length > 0) && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3036
|
+
className: "flex flex-wrap gap-2 justify-end",
|
|
3037
|
+
children: [
|
|
3038
|
+
message.images?.map((img, idx) => /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(FilePreviewCard, {
|
|
3039
|
+
file: { name: img.revised_prompt || `Image ${idx + 1}`, type: "image/png", url: img.url },
|
|
3040
|
+
onClick: showImageLightbox ? () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx) : undefined
|
|
3041
|
+
}, `img-${idx}`, false, undefined, this)),
|
|
3042
|
+
message.audio?.map((audio, idx) => /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3043
|
+
className: "flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-2.5 py-1.5 text-xs text-foreground self-end",
|
|
3044
|
+
children: [
|
|
3045
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_lucide_react19.Music, {
|
|
3046
|
+
className: "h-3.5 w-3.5 text-muted-foreground"
|
|
3047
|
+
}, undefined, false, undefined, this),
|
|
3048
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("span", {
|
|
3049
|
+
className: "truncate max-w-[150px]",
|
|
3050
|
+
children: audio.id || `Audio ${idx + 1}`
|
|
3051
|
+
}, undefined, false, undefined, this)
|
|
3052
|
+
]
|
|
3053
|
+
}, `audio-${idx}`, true, undefined, this)),
|
|
3054
|
+
message.files?.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(FilePreviewCard, {
|
|
3055
|
+
file: { name: file.name, type: file.type, url: file.url, size: file.size },
|
|
3056
|
+
onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
|
|
3057
|
+
}, `file-${idx}`, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3058
|
+
className: "flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-2.5 py-1.5 text-xs text-foreground self-end",
|
|
3059
|
+
children: [
|
|
3060
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_lucide_react19.FileIcon, {
|
|
3061
|
+
className: "h-3.5 w-3.5 text-muted-foreground"
|
|
3062
|
+
}, undefined, false, undefined, this),
|
|
3063
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("span", {
|
|
3064
|
+
className: "truncate max-w-[150px]",
|
|
3065
|
+
children: file.name
|
|
3066
|
+
}, undefined, false, undefined, this)
|
|
3067
|
+
]
|
|
3068
|
+
}, `file-${idx}`, true, undefined, this))
|
|
3069
|
+
]
|
|
3070
|
+
}, undefined, true, undefined, this),
|
|
3071
|
+
message.content && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3072
|
+
className: cn("rounded-2xl rounded-br-md px-4 py-2.5", classNames?.userBubble ?? "bg-primary text-primary-foreground", hasError && "opacity-70"),
|
|
3073
|
+
children: /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("p", {
|
|
3074
|
+
className: "text-sm whitespace-pre-wrap",
|
|
3075
|
+
children: message.content
|
|
3076
|
+
}, undefined, false, undefined, this)
|
|
3077
|
+
}, undefined, false, undefined, this),
|
|
3078
|
+
showTimestamp && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3079
|
+
className: "flex items-center justify-end gap-1.5 px-1",
|
|
3080
|
+
children: [
|
|
3081
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(SmartTimestamp, {
|
|
3082
|
+
date: new Date(message.created_at * 1000),
|
|
3083
|
+
formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
|
|
3084
|
+
className: "text-[11px] text-muted-foreground"
|
|
3085
|
+
}, undefined, false, undefined, this),
|
|
3086
|
+
hasError && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_lucide_react19.AlertCircle, {
|
|
3087
|
+
className: "h-3 w-3 text-destructive"
|
|
3088
|
+
}, undefined, false, undefined, this)
|
|
3089
|
+
]
|
|
3090
|
+
}, undefined, true, undefined, this)
|
|
3091
|
+
]
|
|
3092
|
+
}, undefined, true, undefined, this)
|
|
3093
|
+
]
|
|
3094
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3095
|
+
className: "flex items-start gap-3",
|
|
3096
|
+
children: [
|
|
3097
|
+
assistantAvatar,
|
|
3098
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3099
|
+
className: cn("flex-1 min-w-0 space-y-3", classNames?.assistantContainer),
|
|
3100
|
+
children: [
|
|
3101
|
+
renderContent ? renderContent(message) : /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(jsx_dev_runtime36.Fragment, {
|
|
3102
|
+
children: [
|
|
3103
|
+
showReasoning && message.extra_data?.reasoning_steps && message.extra_data.reasoning_steps.length > 0 && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3104
|
+
className: cn("space-y-2 pt-1", classNames?.reasoning),
|
|
3105
|
+
children: [
|
|
3106
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3107
|
+
className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
|
|
3108
|
+
children: [
|
|
3109
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_lucide_react19.Lightbulb, {
|
|
3110
|
+
className: "h-3.5 w-3.5"
|
|
3111
|
+
}, undefined, false, undefined, this),
|
|
3112
|
+
"Reasoning (",
|
|
3113
|
+
message.extra_data.reasoning_steps.length,
|
|
3114
|
+
" steps)"
|
|
3115
|
+
]
|
|
3116
|
+
}, undefined, true, undefined, this),
|
|
3117
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(Accordion, {
|
|
3118
|
+
type: "multiple",
|
|
3119
|
+
className: "w-full",
|
|
3120
|
+
children: message.extra_data.reasoning_steps.map((step, idx) => /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(AccordionItem, {
|
|
3121
|
+
value: `reasoning-${idx}`,
|
|
3122
|
+
className: "border-muted",
|
|
3123
|
+
children: [
|
|
3124
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(AccordionTrigger, {
|
|
3125
|
+
className: "text-xs py-1.5 hover:no-underline",
|
|
3126
|
+
children: step.title || `Step ${idx + 1}`
|
|
3127
|
+
}, undefined, false, undefined, this),
|
|
3128
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(AccordionContent, {
|
|
3129
|
+
className: "space-y-1.5 text-xs text-muted-foreground",
|
|
3130
|
+
children: [
|
|
3131
|
+
step.action && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3132
|
+
children: [
|
|
3133
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("span", {
|
|
3134
|
+
className: "font-medium text-foreground",
|
|
3135
|
+
children: "Action:"
|
|
3136
|
+
}, undefined, false, undefined, this),
|
|
3137
|
+
" ",
|
|
3138
|
+
step.action
|
|
3139
|
+
]
|
|
3140
|
+
}, undefined, true, undefined, this),
|
|
3141
|
+
step.reasoning && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3142
|
+
children: [
|
|
3143
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("span", {
|
|
3144
|
+
className: "font-medium text-foreground",
|
|
3145
|
+
children: "Reasoning:"
|
|
3146
|
+
}, undefined, false, undefined, this),
|
|
3147
|
+
" ",
|
|
3148
|
+
step.reasoning
|
|
3149
|
+
]
|
|
3150
|
+
}, undefined, true, undefined, this),
|
|
3151
|
+
step.result && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3152
|
+
children: [
|
|
3153
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("span", {
|
|
3154
|
+
className: "font-medium text-foreground",
|
|
3155
|
+
children: "Result:"
|
|
3156
|
+
}, undefined, false, undefined, this),
|
|
3157
|
+
" ",
|
|
3158
|
+
step.result
|
|
3159
|
+
]
|
|
3160
|
+
}, undefined, true, undefined, this),
|
|
3161
|
+
step.confidence !== undefined && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3162
|
+
children: [
|
|
3163
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("span", {
|
|
3164
|
+
className: "font-medium text-foreground",
|
|
3165
|
+
children: "Confidence:"
|
|
3166
|
+
}, undefined, false, undefined, this),
|
|
3167
|
+
" ",
|
|
3168
|
+
(step.confidence * 100).toFixed(1),
|
|
3169
|
+
"%"
|
|
3170
|
+
]
|
|
3171
|
+
}, undefined, true, undefined, this)
|
|
3172
|
+
]
|
|
3173
|
+
}, undefined, true, undefined, this)
|
|
3174
|
+
]
|
|
3175
|
+
}, idx, true, undefined, this))
|
|
3176
|
+
}, undefined, false, undefined, this)
|
|
3177
|
+
]
|
|
3178
|
+
}, undefined, true, undefined, this),
|
|
3179
|
+
message.content && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3180
|
+
className: "prose prose-sm dark:prose-invert max-w-none prose-p:leading-relaxed prose-pre:bg-muted prose-pre:border prose-pre:border-border",
|
|
3181
|
+
children: /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(Response, {
|
|
3182
|
+
children: message.content
|
|
3183
|
+
}, undefined, false, undefined, this)
|
|
3184
|
+
}, undefined, false, undefined, this),
|
|
3185
|
+
showGenerativeUI && toolsWithUI.length > 0 && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3186
|
+
className: "space-y-3",
|
|
3187
|
+
children: toolsWithUI.map((tool) => {
|
|
3188
|
+
const uiComponent = tool.ui_component;
|
|
3189
|
+
return /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3190
|
+
children: uiComponent.layout === "artifact" ? /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(Artifact, {
|
|
3191
|
+
children: /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_agno_react2.GenerativeUIRenderer, {
|
|
3192
|
+
spec: uiComponent,
|
|
3193
|
+
className: "w-full p-2"
|
|
3194
|
+
}, undefined, false, undefined, this)
|
|
3195
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_agno_react2.GenerativeUIRenderer, {
|
|
3196
|
+
spec: uiComponent,
|
|
3197
|
+
className: "w-full"
|
|
3198
|
+
}, undefined, false, undefined, this)
|
|
3199
|
+
}, tool.tool_call_id, false, undefined, this);
|
|
3200
|
+
})
|
|
3201
|
+
}, undefined, false, undefined, this),
|
|
3202
|
+
renderMedia ? renderMedia(message) : (() => {
|
|
3203
|
+
const mediaClassName = classNames?.media;
|
|
3204
|
+
return /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(jsx_dev_runtime36.Fragment, {
|
|
3205
|
+
children: [
|
|
3206
|
+
message.images && message.images.length > 0 && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3207
|
+
className: cn("space-y-2 pt-1", mediaClassName),
|
|
3208
|
+
children: [
|
|
3209
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3210
|
+
className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
|
|
3211
|
+
children: [
|
|
3212
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_lucide_react19.Image, {
|
|
3213
|
+
className: "h-3.5 w-3.5"
|
|
3214
|
+
}, undefined, false, undefined, this),
|
|
3215
|
+
"Images (",
|
|
3216
|
+
message.images.length,
|
|
3217
|
+
")"
|
|
3218
|
+
]
|
|
3219
|
+
}, undefined, true, undefined, this),
|
|
3220
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3221
|
+
className: "grid grid-cols-2 gap-2",
|
|
3222
|
+
children: message.images.map((img, idx) => /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3223
|
+
className: "space-y-1",
|
|
3224
|
+
children: [
|
|
3225
|
+
showImageLightbox ? /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("button", {
|
|
3226
|
+
type: "button",
|
|
3227
|
+
onClick: () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx),
|
|
3228
|
+
className: "group relative w-full overflow-hidden rounded-lg border border-border cursor-pointer hover:border-primary/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring transition-colors",
|
|
3229
|
+
children: /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("img", {
|
|
3230
|
+
src: img.url,
|
|
3231
|
+
alt: img.revised_prompt || "Generated image",
|
|
3232
|
+
className: "w-full rounded-lg"
|
|
3233
|
+
}, undefined, false, undefined, this)
|
|
3234
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("img", {
|
|
3235
|
+
src: img.url,
|
|
3236
|
+
alt: img.revised_prompt || "Generated image",
|
|
3237
|
+
className: "w-full rounded-lg border border-border"
|
|
3238
|
+
}, undefined, false, undefined, this),
|
|
3239
|
+
img.revised_prompt && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("p", {
|
|
3240
|
+
className: "text-[11px] text-muted-foreground italic px-0.5",
|
|
3241
|
+
children: img.revised_prompt
|
|
3242
|
+
}, undefined, false, undefined, this)
|
|
3243
|
+
]
|
|
3244
|
+
}, idx, true, undefined, this))
|
|
3245
|
+
}, undefined, false, undefined, this)
|
|
3246
|
+
]
|
|
3247
|
+
}, undefined, true, undefined, this),
|
|
3248
|
+
message.videos && message.videos.length > 0 && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3249
|
+
className: cn("space-y-2 pt-1", mediaClassName),
|
|
3250
|
+
children: [
|
|
3251
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3252
|
+
className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
|
|
3253
|
+
children: [
|
|
3254
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_lucide_react19.Video, {
|
|
3255
|
+
className: "h-3.5 w-3.5"
|
|
3256
|
+
}, undefined, false, undefined, this),
|
|
3257
|
+
"Videos (",
|
|
3258
|
+
message.videos.length,
|
|
3259
|
+
")"
|
|
3260
|
+
]
|
|
3261
|
+
}, undefined, true, undefined, this),
|
|
3262
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3263
|
+
className: "space-y-2",
|
|
3264
|
+
children: message.videos.map((video, idx) => /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3265
|
+
children: video.url ? /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("video", {
|
|
3266
|
+
src: video.url,
|
|
3267
|
+
controls: true,
|
|
3268
|
+
className: "w-full rounded-lg border border-border"
|
|
3269
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3270
|
+
className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
|
|
3271
|
+
children: [
|
|
3272
|
+
"Video ID: ",
|
|
3273
|
+
video.id,
|
|
3274
|
+
" (ETA: ",
|
|
3275
|
+
video.eta,
|
|
3276
|
+
"s)"
|
|
3277
|
+
]
|
|
3278
|
+
}, undefined, true, undefined, this)
|
|
3279
|
+
}, idx, false, undefined, this))
|
|
3280
|
+
}, undefined, false, undefined, this)
|
|
3281
|
+
]
|
|
3282
|
+
}, undefined, true, undefined, this),
|
|
3283
|
+
message.audio && message.audio.length > 0 && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3284
|
+
className: cn("space-y-2 pt-1", mediaClassName),
|
|
3285
|
+
children: [
|
|
3286
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3287
|
+
className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
|
|
3288
|
+
children: [
|
|
3289
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_lucide_react19.Music, {
|
|
3290
|
+
className: "h-3.5 w-3.5"
|
|
3291
|
+
}, undefined, false, undefined, this),
|
|
3292
|
+
"Audio (",
|
|
3293
|
+
message.audio.length,
|
|
3294
|
+
")"
|
|
3295
|
+
]
|
|
3296
|
+
}, undefined, true, undefined, this),
|
|
3297
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3298
|
+
className: "space-y-2",
|
|
3299
|
+
children: message.audio.map((audio, idx) => /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3300
|
+
children: audio.url ? /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("audio", {
|
|
3301
|
+
src: audio.url,
|
|
3302
|
+
controls: true,
|
|
3303
|
+
className: "w-full"
|
|
3304
|
+
}, undefined, false, undefined, this) : audio.base64_audio ? /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("audio", {
|
|
3305
|
+
src: `data:${audio.mime_type || "audio/wav"};base64,${audio.base64_audio}`,
|
|
3306
|
+
controls: true,
|
|
3307
|
+
className: "w-full"
|
|
3308
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3309
|
+
className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
|
|
3310
|
+
children: "Audio data unavailable"
|
|
3311
|
+
}, undefined, false, undefined, this)
|
|
3312
|
+
}, idx, false, undefined, this))
|
|
3313
|
+
}, undefined, false, undefined, this)
|
|
3314
|
+
]
|
|
3315
|
+
}, undefined, true, undefined, this),
|
|
3316
|
+
message.files && message.files.length > 0 && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3317
|
+
className: cn("space-y-2 pt-1", mediaClassName),
|
|
3318
|
+
children: [
|
|
3319
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3320
|
+
className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
|
|
3321
|
+
children: [
|
|
3322
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_lucide_react19.Paperclip, {
|
|
3323
|
+
className: "h-3.5 w-3.5"
|
|
3324
|
+
}, undefined, false, undefined, this),
|
|
3325
|
+
"Files (",
|
|
3326
|
+
message.files.length,
|
|
3327
|
+
")"
|
|
3328
|
+
]
|
|
3329
|
+
}, undefined, true, undefined, this),
|
|
3330
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3331
|
+
className: "flex flex-wrap gap-2",
|
|
3332
|
+
children: message.files.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(FilePreviewCard, {
|
|
3333
|
+
file: { name: file.name, type: file.type, url: file.url, size: file.size },
|
|
3334
|
+
onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
|
|
3335
|
+
}, idx, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3336
|
+
className: "flex items-center gap-2 rounded-lg border border-border px-3 py-2 text-xs bg-muted/30 hover:bg-muted/50 transition-colors",
|
|
3337
|
+
children: [
|
|
3338
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_lucide_react19.FileIcon, {
|
|
3339
|
+
className: "h-3.5 w-3.5 shrink-0 text-muted-foreground"
|
|
3340
|
+
}, undefined, false, undefined, this),
|
|
3341
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("span", {
|
|
3342
|
+
className: "truncate max-w-[180px]",
|
|
3343
|
+
children: file.name
|
|
3344
|
+
}, undefined, false, undefined, this),
|
|
3345
|
+
file.size && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("span", {
|
|
3346
|
+
className: "text-muted-foreground/70",
|
|
3347
|
+
children: [
|
|
3348
|
+
"(",
|
|
3349
|
+
(file.size / 1024).toFixed(1),
|
|
3350
|
+
"KB)"
|
|
3351
|
+
]
|
|
3352
|
+
}, undefined, true, undefined, this),
|
|
3353
|
+
file.url && /^https?:\/\//i.test(file.url) && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("a", {
|
|
3354
|
+
href: file.url,
|
|
3355
|
+
target: "_blank",
|
|
3356
|
+
rel: "noopener noreferrer",
|
|
3357
|
+
className: "text-primary hover:underline font-medium",
|
|
3358
|
+
children: "View"
|
|
3359
|
+
}, undefined, false, undefined, this)
|
|
3360
|
+
]
|
|
3361
|
+
}, idx, true, undefined, this))
|
|
3362
|
+
}, undefined, false, undefined, this)
|
|
3363
|
+
]
|
|
3364
|
+
}, undefined, true, undefined, this),
|
|
3365
|
+
message.response_audio && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3366
|
+
className: cn("space-y-2 pt-1", mediaClassName),
|
|
3367
|
+
children: [
|
|
3368
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3369
|
+
className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
|
|
3370
|
+
children: [
|
|
3371
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_lucide_react19.Music, {
|
|
3372
|
+
className: "h-3.5 w-3.5"
|
|
3373
|
+
}, undefined, false, undefined, this),
|
|
3374
|
+
"Response Audio"
|
|
3375
|
+
]
|
|
3376
|
+
}, undefined, true, undefined, this),
|
|
3377
|
+
message.response_audio.transcript && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3378
|
+
className: "text-xs italic bg-muted/50 border border-border p-2.5 rounded-lg text-muted-foreground",
|
|
3379
|
+
children: [
|
|
3380
|
+
'"',
|
|
3381
|
+
message.response_audio.transcript,
|
|
3382
|
+
'"'
|
|
3383
|
+
]
|
|
3384
|
+
}, undefined, true, undefined, this),
|
|
3385
|
+
message.response_audio.content && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("audio", {
|
|
3386
|
+
src: `data:audio/wav;base64,${message.response_audio.content}`,
|
|
3387
|
+
controls: true,
|
|
3388
|
+
className: "w-full"
|
|
3389
|
+
}, undefined, false, undefined, this)
|
|
3390
|
+
]
|
|
3391
|
+
}, undefined, true, undefined, this)
|
|
3392
|
+
]
|
|
3393
|
+
}, undefined, true, undefined, this);
|
|
3394
|
+
})(),
|
|
3395
|
+
showToolCalls && message.tool_calls && message.tool_calls.length > 0 && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3396
|
+
className: cn("space-y-2 pt-1", classNames?.toolCalls),
|
|
3397
|
+
children: message.tool_calls.map((tool, idx) => renderToolCall ? renderToolCall(tool, idx) : /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(Tool, {
|
|
3398
|
+
defaultOpen: idx === 0,
|
|
3399
|
+
children: [
|
|
3400
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(ToolHeader, {
|
|
3401
|
+
title: tool.tool_name,
|
|
3402
|
+
type: "tool-use",
|
|
3403
|
+
state: getToolState(tool)
|
|
3404
|
+
}, undefined, false, undefined, this),
|
|
3405
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(ToolContent, {
|
|
3406
|
+
children: [
|
|
3407
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(ToolInput, {
|
|
3408
|
+
input: tool.tool_args
|
|
3409
|
+
}, undefined, false, undefined, this),
|
|
3410
|
+
tool.content && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(ToolOutput, {
|
|
3411
|
+
output: tool.content,
|
|
3412
|
+
errorText: tool.tool_call_error ? "Tool execution failed" : undefined
|
|
3413
|
+
}, undefined, false, undefined, this)
|
|
3414
|
+
]
|
|
3415
|
+
}, undefined, true, undefined, this)
|
|
3416
|
+
]
|
|
3417
|
+
}, tool.tool_call_id || idx, true, undefined, this))
|
|
3418
|
+
}, undefined, false, undefined, this),
|
|
3419
|
+
showReferences && message.extra_data?.references && message.extra_data.references.length > 0 && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3420
|
+
className: cn("space-y-2 pt-1", classNames?.references),
|
|
3421
|
+
children: [
|
|
3422
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3423
|
+
className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
|
|
3424
|
+
children: [
|
|
3425
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_lucide_react19.FileText, {
|
|
3426
|
+
className: "h-3.5 w-3.5"
|
|
3427
|
+
}, undefined, false, undefined, this),
|
|
3428
|
+
"References (",
|
|
3429
|
+
message.extra_data.references.length,
|
|
3430
|
+
")"
|
|
3431
|
+
]
|
|
3432
|
+
}, undefined, true, undefined, this),
|
|
3433
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3434
|
+
className: "space-y-2",
|
|
3435
|
+
children: message.extra_data.references.map((refData, idx) => /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3436
|
+
className: "text-xs space-y-1.5",
|
|
3437
|
+
children: [
|
|
3438
|
+
refData.query && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3439
|
+
className: "font-medium text-foreground",
|
|
3440
|
+
children: [
|
|
3441
|
+
"Query: ",
|
|
3442
|
+
refData.query
|
|
3443
|
+
]
|
|
3444
|
+
}, undefined, true, undefined, this),
|
|
3445
|
+
refData.references.map((ref, refIdx) => /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3446
|
+
className: "bg-muted/50 border border-border p-2.5 rounded-lg",
|
|
3447
|
+
children: [
|
|
3448
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3449
|
+
className: "italic text-muted-foreground mb-1",
|
|
3450
|
+
children: [
|
|
3451
|
+
'"',
|
|
3452
|
+
ref.content,
|
|
3453
|
+
'"'
|
|
3454
|
+
]
|
|
3455
|
+
}, undefined, true, undefined, this),
|
|
3456
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3457
|
+
className: "text-muted-foreground/70",
|
|
3458
|
+
children: [
|
|
3459
|
+
"Source: ",
|
|
3460
|
+
ref.name,
|
|
3461
|
+
" (chunk ",
|
|
3462
|
+
ref.meta_data.chunk,
|
|
3463
|
+
"/",
|
|
3464
|
+
ref.meta_data.chunk_size,
|
|
3465
|
+
")"
|
|
3466
|
+
]
|
|
3467
|
+
}, undefined, true, undefined, this)
|
|
3468
|
+
]
|
|
3469
|
+
}, refIdx, true, undefined, this))
|
|
3470
|
+
]
|
|
3471
|
+
}, idx, true, undefined, this))
|
|
3472
|
+
}, undefined, false, undefined, this)
|
|
3473
|
+
]
|
|
3474
|
+
}, undefined, true, undefined, this)
|
|
3475
|
+
]
|
|
3476
|
+
}, undefined, true, undefined, this),
|
|
3477
|
+
(renderActions || showTimestamp || hasError) && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3478
|
+
className: "flex items-center gap-2 pt-1",
|
|
3479
|
+
children: [
|
|
3480
|
+
renderActions && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("div", {
|
|
3481
|
+
className: cn("flex items-center gap-1", classNames?.actions),
|
|
3482
|
+
children: renderActions(message)
|
|
3483
|
+
}, undefined, false, undefined, this),
|
|
3484
|
+
hasError && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV("span", {
|
|
3485
|
+
className: "flex items-center gap-1 text-[11px] text-destructive",
|
|
3486
|
+
children: [
|
|
3487
|
+
/* @__PURE__ */ jsx_dev_runtime36.jsxDEV(import_lucide_react19.AlertCircle, {
|
|
3488
|
+
className: "h-3 w-3"
|
|
3489
|
+
}, undefined, false, undefined, this),
|
|
3490
|
+
"Error"
|
|
3491
|
+
]
|
|
3492
|
+
}, undefined, true, undefined, this),
|
|
3493
|
+
showTimestamp && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(SmartTimestamp, {
|
|
3494
|
+
date: new Date(message.created_at * 1000),
|
|
3495
|
+
formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
|
|
3496
|
+
className: "text-[11px] text-muted-foreground"
|
|
3497
|
+
}, undefined, false, undefined, this)
|
|
3498
|
+
]
|
|
3499
|
+
}, undefined, true, undefined, this)
|
|
3500
|
+
]
|
|
3501
|
+
}, undefined, true, undefined, this)
|
|
3502
|
+
]
|
|
3503
|
+
}, undefined, true, undefined, this),
|
|
3504
|
+
preview?.type === "image" && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(ImageLightbox, {
|
|
3505
|
+
open: true,
|
|
3506
|
+
onOpenChange: (open) => {
|
|
3507
|
+
if (!open)
|
|
3508
|
+
closePreview();
|
|
3509
|
+
},
|
|
3510
|
+
images: preview.images,
|
|
3511
|
+
initialIndex: preview.initialIndex
|
|
3512
|
+
}, undefined, false, undefined, this),
|
|
3513
|
+
preview?.type === "file" && /* @__PURE__ */ jsx_dev_runtime36.jsxDEV(FilePreviewModal, {
|
|
3514
|
+
open: true,
|
|
3515
|
+
onOpenChange: (open) => {
|
|
3516
|
+
if (!open)
|
|
3517
|
+
closePreview();
|
|
3518
|
+
},
|
|
3519
|
+
file: preview.file
|
|
3520
|
+
}, undefined, false, undefined, this)
|
|
3521
|
+
]
|
|
3522
|
+
}, undefined, true, undefined, this);
|
|
3523
|
+
}
|
|
3524
|
+
|
|
3525
|
+
// src/ui/composed/agno-chat/suggested-prompts.tsx
|
|
3526
|
+
var jsx_dev_runtime37 = require("react/jsx-dev-runtime");
|
|
3527
|
+
function AgnoChatSuggestedPrompts({ className, prompts }) {
|
|
3528
|
+
const { handleSend } = useAgnoChatContext();
|
|
3529
|
+
if (prompts.length === 0)
|
|
3530
|
+
return null;
|
|
3531
|
+
return /* @__PURE__ */ jsx_dev_runtime37.jsxDEV("div", {
|
|
3532
|
+
className: cn("grid grid-cols-2 gap-2 w-full max-w-md", className),
|
|
3533
|
+
children: prompts.map((prompt, idx) => /* @__PURE__ */ jsx_dev_runtime37.jsxDEV("button", {
|
|
3534
|
+
onClick: () => handleSend(prompt.text),
|
|
3535
|
+
className: "flex items-center gap-2 px-3 py-2.5 rounded-xl border border-border bg-card hover:bg-accent/50 hover:border-primary/20 transition-all duration-200 text-left text-sm group",
|
|
3536
|
+
children: [
|
|
3537
|
+
prompt.icon && /* @__PURE__ */ jsx_dev_runtime37.jsxDEV("span", {
|
|
3538
|
+
className: "text-muted-foreground group-hover:text-primary transition-colors",
|
|
3539
|
+
children: prompt.icon
|
|
3540
|
+
}, undefined, false, undefined, this),
|
|
3541
|
+
/* @__PURE__ */ jsx_dev_runtime37.jsxDEV("span", {
|
|
3542
|
+
className: "text-muted-foreground group-hover:text-foreground transition-colors text-xs leading-snug",
|
|
3543
|
+
children: prompt.text
|
|
3544
|
+
}, undefined, false, undefined, this)
|
|
3545
|
+
]
|
|
3546
|
+
}, idx, true, undefined, this))
|
|
3547
|
+
}, undefined, false, undefined, this);
|
|
3548
|
+
}
|
|
3549
|
+
|
|
3550
|
+
// src/ui/composed/agno-chat/messages.tsx
|
|
3551
|
+
var import_lucide_react20 = require("lucide-react");
|
|
3552
|
+
var jsx_dev_runtime38 = require("react/jsx-dev-runtime");
|
|
3553
|
+
function ScrollOnNewUserMessage({ messageCount }) {
|
|
3554
|
+
const { scrollToBottom } = import_use_stick_to_bottom2.useStickToBottomContext();
|
|
3555
|
+
const prevCount = import_react17.useRef(messageCount);
|
|
3556
|
+
import_react17.useEffect(() => {
|
|
3557
|
+
if (messageCount > prevCount.current) {
|
|
3558
|
+
scrollToBottom("smooth");
|
|
3559
|
+
}
|
|
3560
|
+
prevCount.current = messageCount;
|
|
3561
|
+
}, [messageCount, scrollToBottom]);
|
|
3562
|
+
return null;
|
|
3563
|
+
}
|
|
3564
|
+
var DEFAULT_PROMPTS = [
|
|
3565
|
+
{ text: "What can you help me with?" },
|
|
3566
|
+
{ text: "Explain how you work" }
|
|
3567
|
+
];
|
|
3568
|
+
function AgnoChatMessages({
|
|
3569
|
+
className,
|
|
3570
|
+
renderMessage,
|
|
3571
|
+
userAvatar,
|
|
3572
|
+
assistantAvatar,
|
|
3573
|
+
messageItemProps,
|
|
3574
|
+
emptyState,
|
|
3575
|
+
suggestedPrompts = DEFAULT_PROMPTS,
|
|
3576
|
+
children,
|
|
3577
|
+
showThinkingIndicator = true,
|
|
3578
|
+
renderThinkingIndicator
|
|
3579
|
+
}) {
|
|
3580
|
+
const { messages, isStreaming } = useAgnoChatContext();
|
|
3581
|
+
const lastMessage = messages[messages.length - 1];
|
|
3582
|
+
const isThinking = showThinkingIndicator && isStreaming && (!lastMessage || lastMessage.role !== "user") && !lastMessage?.content;
|
|
3583
|
+
const resolvedEmptyState = children ?? emptyState ?? /* @__PURE__ */ jsx_dev_runtime38.jsxDEV("div", {
|
|
3584
|
+
className: "flex flex-col items-center gap-6",
|
|
3585
|
+
children: [
|
|
3586
|
+
/* @__PURE__ */ jsx_dev_runtime38.jsxDEV("div", {
|
|
3587
|
+
className: "relative",
|
|
3588
|
+
children: [
|
|
3589
|
+
/* @__PURE__ */ jsx_dev_runtime38.jsxDEV("div", {
|
|
3590
|
+
className: "h-16 w-16 rounded-2xl bg-primary/10 flex items-center justify-center",
|
|
3591
|
+
children: /* @__PURE__ */ jsx_dev_runtime38.jsxDEV(import_lucide_react20.Bot, {
|
|
3592
|
+
className: "h-8 w-8 text-primary"
|
|
3593
|
+
}, undefined, false, undefined, this)
|
|
3594
|
+
}, undefined, false, undefined, this),
|
|
3595
|
+
/* @__PURE__ */ jsx_dev_runtime38.jsxDEV("div", {
|
|
3596
|
+
className: "absolute -bottom-1 -right-1 h-5 w-5 rounded-full bg-green-500 border-2 border-background flex items-center justify-center",
|
|
3597
|
+
children: /* @__PURE__ */ jsx_dev_runtime38.jsxDEV("span", {
|
|
3598
|
+
className: "h-2 w-2 rounded-full bg-white animate-pulse"
|
|
3599
|
+
}, undefined, false, undefined, this)
|
|
3600
|
+
}, undefined, false, undefined, this)
|
|
3601
|
+
]
|
|
3602
|
+
}, undefined, true, undefined, this),
|
|
3603
|
+
/* @__PURE__ */ jsx_dev_runtime38.jsxDEV("div", {
|
|
3604
|
+
className: "space-y-2 text-center",
|
|
3605
|
+
children: [
|
|
3606
|
+
/* @__PURE__ */ jsx_dev_runtime38.jsxDEV("h3", {
|
|
3607
|
+
className: "text-xl font-semibold tracking-tight",
|
|
3608
|
+
children: "Welcome to Agno Chat"
|
|
3609
|
+
}, undefined, false, undefined, this),
|
|
3610
|
+
/* @__PURE__ */ jsx_dev_runtime38.jsxDEV("p", {
|
|
3611
|
+
className: "text-muted-foreground text-sm max-w-sm",
|
|
3612
|
+
children: "Start a conversation with your AI agent. Ask questions, explore ideas, or run tools."
|
|
3613
|
+
}, undefined, false, undefined, this)
|
|
3614
|
+
]
|
|
3615
|
+
}, undefined, true, undefined, this),
|
|
3616
|
+
suggestedPrompts.length > 0 && /* @__PURE__ */ jsx_dev_runtime38.jsxDEV(AgnoChatSuggestedPrompts, {
|
|
3617
|
+
prompts: suggestedPrompts
|
|
3618
|
+
}, undefined, false, undefined, this)
|
|
3619
|
+
]
|
|
3620
|
+
}, undefined, true, undefined, this);
|
|
3621
|
+
return /* @__PURE__ */ jsx_dev_runtime38.jsxDEV(Conversation, {
|
|
3622
|
+
className: cn("relative flex-1 w-full", className),
|
|
3623
|
+
children: [
|
|
3624
|
+
/* @__PURE__ */ jsx_dev_runtime38.jsxDEV(ScrollOnNewUserMessage, {
|
|
3625
|
+
messageCount: messages.length
|
|
3626
|
+
}, undefined, false, undefined, this),
|
|
3627
|
+
/* @__PURE__ */ jsx_dev_runtime38.jsxDEV(ConversationContent, {
|
|
3628
|
+
className: "max-w-3xl mx-auto",
|
|
3629
|
+
children: [
|
|
3630
|
+
messages.length === 0 ? /* @__PURE__ */ jsx_dev_runtime38.jsxDEV(ConversationEmptyState, {
|
|
3631
|
+
children: resolvedEmptyState
|
|
3632
|
+
}, undefined, false, undefined, this) : messages.map((message, index) => {
|
|
3633
|
+
if (isThinking && index === messages.length - 1 && message === lastMessage)
|
|
3634
|
+
return null;
|
|
3635
|
+
return renderMessage ? renderMessage(message, index) : /* @__PURE__ */ jsx_dev_runtime38.jsxDEV(AgnoMessageItem, {
|
|
3636
|
+
message,
|
|
3637
|
+
userAvatar,
|
|
3638
|
+
assistantAvatar,
|
|
3639
|
+
...messageItemProps
|
|
3640
|
+
}, `msg-${index}-${message.created_at}`, false, undefined, this);
|
|
3641
|
+
}),
|
|
3642
|
+
isThinking && /* @__PURE__ */ jsx_dev_runtime38.jsxDEV("div", {
|
|
3643
|
+
className: "py-2",
|
|
3644
|
+
children: renderThinkingIndicator ?? /* @__PURE__ */ jsx_dev_runtime38.jsxDEV(StreamingIndicator, {
|
|
3645
|
+
avatar: assistantAvatar
|
|
3646
|
+
}, undefined, false, undefined, this)
|
|
3647
|
+
}, undefined, false, undefined, this)
|
|
3648
|
+
]
|
|
3649
|
+
}, undefined, true, undefined, this),
|
|
3650
|
+
/* @__PURE__ */ jsx_dev_runtime38.jsxDEV(ConversationScrollButton, {}, undefined, false, undefined, this)
|
|
3651
|
+
]
|
|
3652
|
+
}, undefined, true, undefined, this);
|
|
3653
|
+
}
|
|
3654
|
+
|
|
3655
|
+
// src/ui/composed/agno-chat/empty-state.tsx
|
|
3656
|
+
var jsx_dev_runtime39 = require("react/jsx-dev-runtime");
|
|
3657
|
+
function AgnoChatEmptyState({ children, className, ...props }) {
|
|
3658
|
+
return /* @__PURE__ */ jsx_dev_runtime39.jsxDEV("div", {
|
|
3659
|
+
className: cn("flex flex-col items-center gap-6", className),
|
|
3660
|
+
...props,
|
|
3661
|
+
children
|
|
3662
|
+
}, undefined, false, undefined, this);
|
|
3663
|
+
}
|
|
3664
|
+
|
|
3665
|
+
// src/ui/composed/agno-chat/tool-status.tsx
|
|
3666
|
+
var import_lucide_react21 = require("lucide-react");
|
|
3667
|
+
var jsx_dev_runtime40 = require("react/jsx-dev-runtime");
|
|
3668
|
+
function AgnoChatToolStatus({ className }) {
|
|
3669
|
+
const { isPaused, isExecuting, pendingTools } = useAgnoChatContext();
|
|
3670
|
+
if (!isPaused && !isExecuting)
|
|
3671
|
+
return null;
|
|
3672
|
+
return /* @__PURE__ */ jsx_dev_runtime40.jsxDEV("div", {
|
|
3673
|
+
className: cn("px-4 py-2.5 border-t border-border bg-primary/5", className),
|
|
3674
|
+
children: /* @__PURE__ */ jsx_dev_runtime40.jsxDEV("div", {
|
|
3675
|
+
className: "flex items-center gap-2.5 text-sm max-w-3xl mx-auto",
|
|
3676
|
+
children: isExecuting ? /* @__PURE__ */ jsx_dev_runtime40.jsxDEV(jsx_dev_runtime40.Fragment, {
|
|
3677
|
+
children: [
|
|
3678
|
+
/* @__PURE__ */ jsx_dev_runtime40.jsxDEV("div", {
|
|
3679
|
+
className: "h-5 w-5 rounded-full bg-primary/10 flex items-center justify-center",
|
|
3680
|
+
children: /* @__PURE__ */ jsx_dev_runtime40.jsxDEV(import_lucide_react21.Loader2, {
|
|
3681
|
+
className: "h-3 w-3 animate-spin text-primary"
|
|
3682
|
+
}, undefined, false, undefined, this)
|
|
3683
|
+
}, undefined, false, undefined, this),
|
|
3684
|
+
/* @__PURE__ */ jsx_dev_runtime40.jsxDEV("span", {
|
|
3685
|
+
className: "text-muted-foreground",
|
|
3686
|
+
children: [
|
|
3687
|
+
"Executing",
|
|
3688
|
+
" ",
|
|
3689
|
+
/* @__PURE__ */ jsx_dev_runtime40.jsxDEV("span", {
|
|
3690
|
+
className: "font-medium text-foreground",
|
|
3691
|
+
children: pendingTools.length
|
|
3692
|
+
}, undefined, false, undefined, this),
|
|
3693
|
+
" tool",
|
|
3694
|
+
pendingTools.length !== 1 ? "s" : "",
|
|
3695
|
+
"..."
|
|
3696
|
+
]
|
|
3697
|
+
}, undefined, true, undefined, this)
|
|
3698
|
+
]
|
|
3699
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime40.jsxDEV(jsx_dev_runtime40.Fragment, {
|
|
3700
|
+
children: [
|
|
3701
|
+
/* @__PURE__ */ jsx_dev_runtime40.jsxDEV("div", {
|
|
3702
|
+
className: "h-5 w-5 rounded-full bg-amber-500/10 flex items-center justify-center",
|
|
3703
|
+
children: /* @__PURE__ */ jsx_dev_runtime40.jsxDEV(import_lucide_react21.Wrench, {
|
|
3704
|
+
className: "h-3 w-3 text-amber-600 dark:text-amber-400"
|
|
3705
|
+
}, undefined, false, undefined, this)
|
|
3706
|
+
}, undefined, false, undefined, this),
|
|
3707
|
+
/* @__PURE__ */ jsx_dev_runtime40.jsxDEV("span", {
|
|
3708
|
+
className: "text-muted-foreground",
|
|
3709
|
+
children: [
|
|
3710
|
+
"Preparing",
|
|
3711
|
+
" ",
|
|
3712
|
+
/* @__PURE__ */ jsx_dev_runtime40.jsxDEV("span", {
|
|
3713
|
+
className: "font-medium text-foreground",
|
|
3714
|
+
children: pendingTools.length
|
|
3715
|
+
}, undefined, false, undefined, this),
|
|
3716
|
+
" tool",
|
|
3717
|
+
pendingTools.length !== 1 ? "s" : "",
|
|
3718
|
+
"..."
|
|
3719
|
+
]
|
|
3720
|
+
}, undefined, true, undefined, this)
|
|
3721
|
+
]
|
|
3722
|
+
}, undefined, true, undefined, this)
|
|
3723
|
+
}, undefined, false, undefined, this)
|
|
3724
|
+
}, undefined, false, undefined, this);
|
|
3725
|
+
}
|
|
3726
|
+
|
|
3727
|
+
// src/ui/composed/agno-chat/error-bar.tsx
|
|
3728
|
+
var jsx_dev_runtime41 = require("react/jsx-dev-runtime");
|
|
3729
|
+
function AgnoChatErrorBar({ className }) {
|
|
3730
|
+
const { error, executionError } = useAgnoChatContext();
|
|
3731
|
+
const message = error || executionError;
|
|
3732
|
+
if (!message)
|
|
3733
|
+
return null;
|
|
3734
|
+
return /* @__PURE__ */ jsx_dev_runtime41.jsxDEV("div", {
|
|
3735
|
+
className: cn("px-4 py-2.5 bg-destructive/5 border-t border-destructive/20", className),
|
|
3736
|
+
children: /* @__PURE__ */ jsx_dev_runtime41.jsxDEV("p", {
|
|
3737
|
+
className: "text-sm text-destructive max-w-3xl mx-auto",
|
|
3738
|
+
children: message
|
|
3739
|
+
}, undefined, false, undefined, this)
|
|
3740
|
+
}, undefined, false, undefined, this);
|
|
3741
|
+
}
|
|
3742
|
+
|
|
3743
|
+
// src/ui/composed/AgnoChatInput.tsx
|
|
3744
|
+
var import_lucide_react22 = require("lucide-react");
|
|
3745
|
+
var jsx_dev_runtime42 = require("react/jsx-dev-runtime");
|
|
3746
|
+
var DEFAULT_ACCEPTED_FILE_TYPES = "image/*,audio/*,.pdf,.doc,.docx,.txt,.csv,.xlsx,.xls,.ppt,.pptx,.md,.json,.xml";
|
|
3747
|
+
function dataUrlToBlob(dataUrl) {
|
|
3748
|
+
const [header, base64] = dataUrl.split(",");
|
|
3749
|
+
const mime = header.match(/:(.*?);/)?.[1] || "application/octet-stream";
|
|
3750
|
+
const bytes = atob(base64);
|
|
3751
|
+
const buf = new Uint8Array(bytes.length);
|
|
3752
|
+
for (let i = 0;i < bytes.length; i++) {
|
|
3753
|
+
buf[i] = bytes.charCodeAt(i);
|
|
3754
|
+
}
|
|
3755
|
+
return new Blob([buf], { type: mime });
|
|
3756
|
+
}
|
|
3757
|
+
function CancelButton({ onCancel }) {
|
|
3758
|
+
return /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(Button, {
|
|
3759
|
+
type: "button",
|
|
3760
|
+
variant: "destructive",
|
|
3761
|
+
size: "icon",
|
|
3762
|
+
className: "h-8 w-8 rounded-lg",
|
|
3763
|
+
onClick: onCancel,
|
|
3764
|
+
"aria-label": "Stop",
|
|
3765
|
+
children: /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(import_lucide_react22.CircleStop, {
|
|
3766
|
+
className: "size-4"
|
|
3767
|
+
}, undefined, false, undefined, this)
|
|
3768
|
+
}, undefined, false, undefined, this);
|
|
3769
|
+
}
|
|
3770
|
+
function SubmitButton({ disabled, status }) {
|
|
3771
|
+
const { textInput } = usePromptInputController();
|
|
3772
|
+
const hasText = textInput.value.trim().length > 0;
|
|
3773
|
+
return /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputSubmit, {
|
|
3774
|
+
disabled: disabled || !hasText,
|
|
3775
|
+
status
|
|
3776
|
+
}, undefined, false, undefined, this);
|
|
3777
|
+
}
|
|
3778
|
+
function AttachmentHeader() {
|
|
3779
|
+
const { files } = usePromptInputAttachments();
|
|
3780
|
+
if (files.length === 0)
|
|
3781
|
+
return null;
|
|
3782
|
+
return /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputHeader, {
|
|
3783
|
+
children: /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputAttachments, {
|
|
3784
|
+
children: (attachment) => /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputAttachment, {
|
|
3785
|
+
data: attachment
|
|
3786
|
+
}, undefined, false, undefined, this)
|
|
3787
|
+
}, undefined, false, undefined, this)
|
|
3788
|
+
}, undefined, false, undefined, this);
|
|
3789
|
+
}
|
|
3790
|
+
function TranscribeAudioRecorder({
|
|
3791
|
+
endpoint,
|
|
3792
|
+
headers,
|
|
3793
|
+
disabled,
|
|
3794
|
+
parseResponse,
|
|
3795
|
+
onRequestPermission,
|
|
3796
|
+
labels
|
|
3797
|
+
}) {
|
|
3798
|
+
const { textInput } = usePromptInputController();
|
|
3799
|
+
return /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(AudioRecorder, {
|
|
3800
|
+
mode: "transcribe",
|
|
3801
|
+
transcriptionEndpoint: endpoint,
|
|
3802
|
+
transcriptionHeaders: headers,
|
|
3803
|
+
parseTranscriptionResponse: parseResponse,
|
|
3804
|
+
onRequestPermission,
|
|
3805
|
+
onRecordingComplete: () => {},
|
|
3806
|
+
onTranscriptionComplete: (text) => {
|
|
3807
|
+
const current = textInput.value;
|
|
3808
|
+
textInput.setInput(current + (current ? " " : "") + text);
|
|
3809
|
+
},
|
|
3810
|
+
disabled,
|
|
3811
|
+
labels
|
|
3812
|
+
}, undefined, false, undefined, this);
|
|
3813
|
+
}
|
|
3814
|
+
function AgnoChatInput({
|
|
3815
|
+
onSend,
|
|
3816
|
+
disabled,
|
|
3817
|
+
placeholder,
|
|
3818
|
+
className,
|
|
3819
|
+
fileUpload,
|
|
3820
|
+
showAudioRecorder = false,
|
|
3821
|
+
showAttachments = true,
|
|
3822
|
+
status,
|
|
3823
|
+
isStreaming,
|
|
3824
|
+
onCancel,
|
|
3825
|
+
allowCancelRun = false,
|
|
3826
|
+
extraTools,
|
|
3827
|
+
audioMode = "send",
|
|
3828
|
+
transcriptionEndpoint,
|
|
3829
|
+
transcriptionHeaders,
|
|
3830
|
+
parseTranscriptionResponse,
|
|
3831
|
+
onRequestPermission,
|
|
3832
|
+
audioRecorderLabels,
|
|
3833
|
+
dropZoneContainerRef,
|
|
3834
|
+
dropZoneProps
|
|
3835
|
+
}) {
|
|
3836
|
+
const handleSubmit = (message) => {
|
|
3837
|
+
const text = message.text?.trim() || "";
|
|
3838
|
+
const files = message.files || [];
|
|
3839
|
+
if (!text)
|
|
3840
|
+
return;
|
|
3841
|
+
if (files.length === 0) {
|
|
3842
|
+
onSend(text);
|
|
3843
|
+
return;
|
|
3844
|
+
}
|
|
3845
|
+
const formData = new FormData;
|
|
3846
|
+
formData.append("message", text);
|
|
3847
|
+
for (const file of files) {
|
|
3848
|
+
if (!file.url)
|
|
3849
|
+
continue;
|
|
3850
|
+
const blob = file.url.startsWith("data:") ? dataUrlToBlob(file.url) : null;
|
|
3851
|
+
if (!blob)
|
|
3852
|
+
continue;
|
|
3853
|
+
const fileName = file.filename || "file";
|
|
3854
|
+
formData.append("files", blob, fileName);
|
|
3855
|
+
}
|
|
3856
|
+
onSend(formData);
|
|
3857
|
+
};
|
|
3858
|
+
const handleAudioRecording = (blob) => {
|
|
3859
|
+
const formData = new FormData;
|
|
3860
|
+
formData.append("message", "Audio message");
|
|
3861
|
+
formData.append("files", blob, `recording-${Date.now()}.wav`);
|
|
3862
|
+
onSend(formData);
|
|
3863
|
+
};
|
|
3864
|
+
const computedStatus = status ?? (disabled ? "submitted" : undefined);
|
|
3865
|
+
const showCancelButton = allowCancelRun && isStreaming && onCancel;
|
|
3866
|
+
return /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputProvider, {
|
|
3867
|
+
children: /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInput, {
|
|
3868
|
+
onSubmit: handleSubmit,
|
|
3869
|
+
accept: fileUpload?.accept ?? DEFAULT_ACCEPTED_FILE_TYPES,
|
|
3870
|
+
multiple: fileUpload?.multiple ?? true,
|
|
3871
|
+
maxFiles: fileUpload?.maxFiles,
|
|
3872
|
+
maxFileSize: fileUpload?.maxFileSize,
|
|
3873
|
+
globalDrop: !!dropZoneContainerRef,
|
|
3874
|
+
dragListenerTarget: dropZoneContainerRef,
|
|
3875
|
+
className: cn("w-full", className),
|
|
3876
|
+
children: [
|
|
3877
|
+
/* @__PURE__ */ jsx_dev_runtime42.jsxDEV(AttachmentHeader, {}, undefined, false, undefined, this),
|
|
3878
|
+
/* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputBody, {
|
|
3879
|
+
children: /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputTextarea, {
|
|
3880
|
+
placeholder: placeholder || "Type your message... (Enter to send, Shift+Enter for new line)",
|
|
3881
|
+
disabled
|
|
3882
|
+
}, undefined, false, undefined, this)
|
|
3883
|
+
}, undefined, false, undefined, this),
|
|
3884
|
+
/* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputFooter, {
|
|
3885
|
+
children: [
|
|
3886
|
+
/* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputTools, {
|
|
3887
|
+
children: [
|
|
3888
|
+
showAttachments && /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputActionMenu, {
|
|
3889
|
+
children: [
|
|
3890
|
+
/* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputActionMenuTrigger, {}, undefined, false, undefined, this),
|
|
3891
|
+
/* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputActionMenuContent, {
|
|
3892
|
+
children: /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputActionAddAttachments, {
|
|
3893
|
+
label: "Add files"
|
|
3894
|
+
}, undefined, false, undefined, this)
|
|
3895
|
+
}, undefined, false, undefined, this)
|
|
3896
|
+
]
|
|
3897
|
+
}, undefined, true, undefined, this),
|
|
3898
|
+
showAudioRecorder && (audioMode === "transcribe" && transcriptionEndpoint ? /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(TranscribeAudioRecorder, {
|
|
3899
|
+
endpoint: transcriptionEndpoint,
|
|
3900
|
+
headers: transcriptionHeaders,
|
|
3901
|
+
disabled,
|
|
3902
|
+
parseResponse: parseTranscriptionResponse,
|
|
3903
|
+
onRequestPermission,
|
|
3904
|
+
labels: audioRecorderLabels
|
|
3905
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(AudioRecorder, {
|
|
3906
|
+
onRecordingComplete: handleAudioRecording,
|
|
3907
|
+
disabled,
|
|
3908
|
+
onRequestPermission,
|
|
3909
|
+
labels: audioRecorderLabels
|
|
3910
|
+
}, undefined, false, undefined, this)),
|
|
3911
|
+
extraTools
|
|
3912
|
+
]
|
|
3913
|
+
}, undefined, true, undefined, this),
|
|
3914
|
+
showCancelButton ? /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(CancelButton, {
|
|
3915
|
+
onCancel
|
|
3916
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(SubmitButton, {
|
|
3917
|
+
disabled,
|
|
3918
|
+
status: computedStatus
|
|
3919
|
+
}, undefined, false, undefined, this)
|
|
3920
|
+
]
|
|
3921
|
+
}, undefined, true, undefined, this),
|
|
3922
|
+
showAttachments && /* @__PURE__ */ jsx_dev_runtime42.jsxDEV(PromptInputDropZone, {
|
|
3923
|
+
...dropZoneProps,
|
|
3924
|
+
container: dropZoneContainerRef
|
|
3925
|
+
}, undefined, false, undefined, this)
|
|
3926
|
+
]
|
|
3927
|
+
}, undefined, true, undefined, this)
|
|
3928
|
+
}, undefined, false, undefined, this);
|
|
3929
|
+
}
|
|
3930
|
+
|
|
3931
|
+
// src/ui/composed/agno-chat/input.tsx
|
|
3932
|
+
var jsx_dev_runtime43 = require("react/jsx-dev-runtime");
|
|
3933
|
+
function AgnoChatInputArea({
|
|
3934
|
+
className,
|
|
3935
|
+
children,
|
|
3936
|
+
placeholder,
|
|
3937
|
+
fileUpload,
|
|
3938
|
+
showAudioRecorder = false,
|
|
3939
|
+
showAttachments,
|
|
3940
|
+
extraTools,
|
|
3941
|
+
chatInputProps,
|
|
3942
|
+
audioMode,
|
|
3943
|
+
transcriptionEndpoint,
|
|
3944
|
+
transcriptionHeaders,
|
|
3945
|
+
parseTranscriptionResponse,
|
|
3946
|
+
onRequestPermission,
|
|
3947
|
+
audioRecorderLabels,
|
|
3948
|
+
allowCancelRun = false,
|
|
3949
|
+
dropZoneProps
|
|
3950
|
+
}) {
|
|
3951
|
+
const { handleSend, inputDisabled, isStreaming, isPaused, cancelRun, dropZoneContainerRef } = useAgnoChatContext();
|
|
3952
|
+
return /* @__PURE__ */ jsx_dev_runtime43.jsxDEV("div", {
|
|
3953
|
+
className: cn("border-t border-border bg-background/80 backdrop-blur-sm", className),
|
|
3954
|
+
children: /* @__PURE__ */ jsx_dev_runtime43.jsxDEV("div", {
|
|
3955
|
+
className: "mx-auto px-4 py-2",
|
|
3956
|
+
children: children ? children({ onSend: handleSend, disabled: inputDisabled, isStreaming, isPaused }) : /* @__PURE__ */ jsx_dev_runtime43.jsxDEV(AgnoChatInput, {
|
|
3957
|
+
...chatInputProps,
|
|
3958
|
+
onSend: handleSend,
|
|
3959
|
+
disabled: inputDisabled,
|
|
3960
|
+
isStreaming,
|
|
3961
|
+
onCancel: cancelRun,
|
|
3962
|
+
allowCancelRun,
|
|
3963
|
+
placeholder: placeholder ?? chatInputProps?.placeholder ?? "Message your agent...",
|
|
3964
|
+
fileUpload,
|
|
3965
|
+
showAudioRecorder,
|
|
3966
|
+
showAttachments,
|
|
3967
|
+
extraTools,
|
|
3968
|
+
audioMode,
|
|
3969
|
+
transcriptionEndpoint,
|
|
3970
|
+
transcriptionHeaders,
|
|
3971
|
+
parseTranscriptionResponse,
|
|
3972
|
+
onRequestPermission,
|
|
3973
|
+
audioRecorderLabels,
|
|
3974
|
+
dropZoneContainerRef,
|
|
3975
|
+
dropZoneProps
|
|
3976
|
+
}, undefined, false, undefined, this)
|
|
3977
|
+
}, undefined, false, undefined, this)
|
|
3978
|
+
}, undefined, false, undefined, this);
|
|
3979
|
+
}
|
|
3980
|
+
|
|
3981
|
+
// src/ui/composed/agno-chat/index.ts
|
|
3982
|
+
var AgnoChat = Object.assign(AgnoChatRoot, {
|
|
3983
|
+
Messages: AgnoChatMessages,
|
|
3984
|
+
EmptyState: AgnoChatEmptyState,
|
|
3985
|
+
SuggestedPrompts: AgnoChatSuggestedPrompts,
|
|
3986
|
+
ToolStatus: AgnoChatToolStatus,
|
|
3987
|
+
ErrorBar: AgnoChatErrorBar,
|
|
3988
|
+
Input: AgnoChatInputArea
|
|
3989
|
+
});
|
|
3990
|
+
|
|
3991
|
+
// src/ui/composed/AgnoChatInterface.tsx
|
|
3992
|
+
var import_lucide_react23 = require("lucide-react");
|
|
3993
|
+
var jsx_dev_runtime44 = require("react/jsx-dev-runtime");
|
|
3994
|
+
var DEFAULT_PROMPTS2 = [
|
|
3995
|
+
{ icon: /* @__PURE__ */ jsx_dev_runtime44.jsxDEV(import_lucide_react23.Sparkles, {
|
|
3996
|
+
className: "h-3.5 w-3.5"
|
|
3997
|
+
}, undefined, false, undefined, this), text: "What can you help me with?" },
|
|
3998
|
+
{ icon: /* @__PURE__ */ jsx_dev_runtime44.jsxDEV(import_lucide_react23.Bot, {
|
|
3999
|
+
className: "h-3.5 w-3.5"
|
|
4000
|
+
}, undefined, false, undefined, this), text: "Explain how you work" }
|
|
4001
|
+
];
|
|
4002
|
+
function AgnoChatInterface({
|
|
4003
|
+
className,
|
|
4004
|
+
classNames,
|
|
4005
|
+
renderMessage,
|
|
4006
|
+
renderInput,
|
|
4007
|
+
emptyState,
|
|
4008
|
+
headerSlot,
|
|
4009
|
+
inputToolbarSlot,
|
|
4010
|
+
suggestedPrompts = DEFAULT_PROMPTS2,
|
|
4011
|
+
toolHandlers = {},
|
|
4012
|
+
autoExecuteTools = true,
|
|
4013
|
+
placeholder,
|
|
4014
|
+
userAvatar,
|
|
4015
|
+
assistantAvatar,
|
|
4016
|
+
fileUpload,
|
|
4017
|
+
showAudioRecorder = true,
|
|
4018
|
+
showAttachments = true,
|
|
4019
|
+
messageItemProps,
|
|
4020
|
+
chatInputProps,
|
|
4021
|
+
dropZoneLabel
|
|
4022
|
+
}) {
|
|
4023
|
+
return /* @__PURE__ */ jsx_dev_runtime44.jsxDEV(AgnoChat, {
|
|
4024
|
+
toolHandlers,
|
|
4025
|
+
autoExecuteTools,
|
|
4026
|
+
className: cn(classNames?.root, className),
|
|
4027
|
+
children: [
|
|
4028
|
+
headerSlot,
|
|
4029
|
+
/* @__PURE__ */ jsx_dev_runtime44.jsxDEV(AgnoChat.Messages, {
|
|
4030
|
+
className: classNames?.messagesArea,
|
|
4031
|
+
renderMessage,
|
|
4032
|
+
userAvatar,
|
|
4033
|
+
assistantAvatar,
|
|
4034
|
+
messageItemProps,
|
|
4035
|
+
emptyState,
|
|
4036
|
+
suggestedPrompts
|
|
4037
|
+
}, undefined, false, undefined, this),
|
|
4038
|
+
/* @__PURE__ */ jsx_dev_runtime44.jsxDEV(AgnoChat.ToolStatus, {
|
|
4039
|
+
className: classNames?.toolStatusBar
|
|
4040
|
+
}, undefined, false, undefined, this),
|
|
4041
|
+
/* @__PURE__ */ jsx_dev_runtime44.jsxDEV(AgnoChat.ErrorBar, {
|
|
4042
|
+
className: classNames?.errorBar
|
|
4043
|
+
}, undefined, false, undefined, this),
|
|
4044
|
+
/* @__PURE__ */ jsx_dev_runtime44.jsxDEV(AgnoChat.Input, {
|
|
4045
|
+
className: classNames?.inputArea,
|
|
4046
|
+
placeholder,
|
|
4047
|
+
fileUpload,
|
|
4048
|
+
showAudioRecorder,
|
|
4049
|
+
showAttachments,
|
|
4050
|
+
extraTools: inputToolbarSlot,
|
|
4051
|
+
chatInputProps,
|
|
4052
|
+
dropZoneProps: { className: classNames?.dropZone, label: dropZoneLabel },
|
|
4053
|
+
children: renderInput ? ({ onSend, disabled }) => renderInput({ onSend, disabled }) : undefined
|
|
4054
|
+
}, undefined, false, undefined, this)
|
|
4055
|
+
]
|
|
4056
|
+
}, undefined, true, undefined, this);
|
|
4057
|
+
}
|
|
4058
|
+
|
|
4059
|
+
//# debugId=128E98AEB83ACE9C64756E2164756E21
|