@copilotz/chat-ui 0.2.1 → 0.3.1
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 +3 -34
- package/dist/index.cjs +1063 -710
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +77 -43
- package/dist/index.d.ts +77 -43
- package/dist/index.js +958 -606
- package/dist/index.js.map +1 -1
- package/dist/styles.css +19 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -30,32 +30,33 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
AgentBadge: () => AgentBadge,
|
|
33
34
|
ChatHeader: () => ChatHeader,
|
|
34
35
|
ChatInput: () => ChatInput,
|
|
35
36
|
ChatUI: () => ChatUI,
|
|
36
37
|
ChatUserContextProvider: () => ChatUserContextProvider,
|
|
37
38
|
Message: () => Message,
|
|
39
|
+
ParticipantsSelector: () => ParticipantsSelector,
|
|
38
40
|
Sidebar: () => Sidebar2,
|
|
41
|
+
TargetAgentSelector: () => TargetAgentSelector,
|
|
39
42
|
ThreadManager: () => ThreadManager,
|
|
40
43
|
UserMenu: () => UserMenu,
|
|
41
44
|
UserProfile: () => UserProfile,
|
|
42
|
-
|
|
45
|
+
assignAgentColors: () => assignAgentColors,
|
|
43
46
|
chatUtils: () => chatUtils,
|
|
44
47
|
cn: () => cn,
|
|
45
|
-
configUtils: () => configUtils,
|
|
46
48
|
createObjectUrlFromDataUrl: () => createObjectUrlFromDataUrl,
|
|
47
49
|
defaultChatConfig: () => defaultChatConfig,
|
|
48
|
-
featureFlags: () => featureFlags,
|
|
49
50
|
formatDate: () => formatDate,
|
|
51
|
+
getAgentColor: () => getAgentColor,
|
|
52
|
+
getAgentInitials: () => getAgentInitials,
|
|
50
53
|
mergeConfig: () => mergeConfig,
|
|
51
|
-
|
|
52
|
-
useChatUserContext: () => useChatUserContext,
|
|
53
|
-
validateConfig: () => validateConfig
|
|
54
|
+
useChatUserContext: () => useChatUserContext
|
|
54
55
|
});
|
|
55
56
|
module.exports = __toCommonJS(index_exports);
|
|
56
57
|
|
|
57
58
|
// src/components/chat/ChatUI.tsx
|
|
58
|
-
var
|
|
59
|
+
var import_react8 = require("react");
|
|
59
60
|
var import_react_virtual = require("@tanstack/react-virtual");
|
|
60
61
|
|
|
61
62
|
// src/config/chatConfig.ts
|
|
@@ -224,127 +225,6 @@ function mergeConfig(_baseConfig, userConfig) {
|
|
|
224
225
|
headerActions: userConfig.headerActions || defaultChatConfig.headerActions
|
|
225
226
|
};
|
|
226
227
|
}
|
|
227
|
-
var chatConfigPresets = {
|
|
228
|
-
minimal: {
|
|
229
|
-
features: {
|
|
230
|
-
enableThreads: false,
|
|
231
|
-
enableFileUpload: false,
|
|
232
|
-
enableAudioRecording: false,
|
|
233
|
-
enableMessageEditing: false,
|
|
234
|
-
enableMessageCopy: true,
|
|
235
|
-
enableRegeneration: true,
|
|
236
|
-
enableToolCallsDisplay: false
|
|
237
|
-
},
|
|
238
|
-
ui: {
|
|
239
|
-
compactMode: true,
|
|
240
|
-
showTimestamps: false,
|
|
241
|
-
showAvatars: false
|
|
242
|
-
}
|
|
243
|
-
},
|
|
244
|
-
full: {
|
|
245
|
-
features: {
|
|
246
|
-
enableThreads: true,
|
|
247
|
-
enableFileUpload: true,
|
|
248
|
-
enableAudioRecording: true,
|
|
249
|
-
enableMessageEditing: true,
|
|
250
|
-
enableMessageCopy: true,
|
|
251
|
-
enableRegeneration: true,
|
|
252
|
-
enableToolCallsDisplay: true
|
|
253
|
-
},
|
|
254
|
-
ui: {
|
|
255
|
-
showTimestamps: true,
|
|
256
|
-
showAvatars: true,
|
|
257
|
-
compactMode: false,
|
|
258
|
-
showWordCount: true
|
|
259
|
-
}
|
|
260
|
-
},
|
|
261
|
-
developer: {
|
|
262
|
-
features: {
|
|
263
|
-
enableThreads: true,
|
|
264
|
-
enableFileUpload: true,
|
|
265
|
-
enableAudioRecording: false,
|
|
266
|
-
enableMessageEditing: true,
|
|
267
|
-
enableMessageCopy: true,
|
|
268
|
-
enableRegeneration: true,
|
|
269
|
-
enableToolCallsDisplay: true
|
|
270
|
-
},
|
|
271
|
-
ui: {
|
|
272
|
-
showTimestamps: true,
|
|
273
|
-
showAvatars: true,
|
|
274
|
-
compactMode: false,
|
|
275
|
-
showWordCount: true
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
customer_support: {
|
|
279
|
-
branding: {
|
|
280
|
-
title: "Customer Support",
|
|
281
|
-
subtitle: "How can I help you today?"
|
|
282
|
-
},
|
|
283
|
-
features: {
|
|
284
|
-
enableThreads: true,
|
|
285
|
-
enableFileUpload: true,
|
|
286
|
-
enableAudioRecording: false,
|
|
287
|
-
enableMessageEditing: false,
|
|
288
|
-
enableMessageCopy: true,
|
|
289
|
-
enableRegeneration: false,
|
|
290
|
-
enableToolCallsDisplay: false
|
|
291
|
-
},
|
|
292
|
-
ui: {
|
|
293
|
-
showTimestamps: true,
|
|
294
|
-
showAvatars: true,
|
|
295
|
-
compactMode: false
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
};
|
|
299
|
-
function validateConfig(config) {
|
|
300
|
-
const errors = [];
|
|
301
|
-
if (config.features?.maxAttachments && config.features.maxAttachments < 1) {
|
|
302
|
-
errors.push("maxAttachments must be at least 1");
|
|
303
|
-
}
|
|
304
|
-
if (config.features?.maxFileSize && config.features.maxFileSize < 1024) {
|
|
305
|
-
errors.push("maxFileSize must be at least 1024 bytes (1KB)");
|
|
306
|
-
}
|
|
307
|
-
if (config.branding?.title && typeof config.branding.title !== "string") {
|
|
308
|
-
errors.push("branding.title must be a string");
|
|
309
|
-
}
|
|
310
|
-
return errors;
|
|
311
|
-
}
|
|
312
|
-
var themeUtils = {
|
|
313
|
-
getSystemTheme: () => {
|
|
314
|
-
if (typeof globalThis.matchMedia === "undefined") return "light";
|
|
315
|
-
return globalThis.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
316
|
-
},
|
|
317
|
-
resolveTheme: (theme) => {
|
|
318
|
-
return theme === "auto" ? themeUtils.getSystemTheme() : theme;
|
|
319
|
-
},
|
|
320
|
-
applyTheme: (theme) => {
|
|
321
|
-
if (typeof document === "undefined") return;
|
|
322
|
-
const resolvedTheme = themeUtils.resolveTheme(theme);
|
|
323
|
-
document.documentElement.classList.toggle("dark", resolvedTheme === "dark");
|
|
324
|
-
}
|
|
325
|
-
};
|
|
326
|
-
var featureFlags = {
|
|
327
|
-
isEnabled: (config, feature) => {
|
|
328
|
-
return config.features[feature] === true;
|
|
329
|
-
},
|
|
330
|
-
getEnabledFeatures: (config) => {
|
|
331
|
-
return Object.entries(config.features).filter(([_, enabled]) => enabled === true).map(([feature]) => feature);
|
|
332
|
-
},
|
|
333
|
-
hasAnyFeature: (config, features) => {
|
|
334
|
-
return features.some((feature) => featureFlags.isEnabled(config, feature));
|
|
335
|
-
}
|
|
336
|
-
};
|
|
337
|
-
var configUtils = {
|
|
338
|
-
createConfigHook: (config) => {
|
|
339
|
-
return {
|
|
340
|
-
config,
|
|
341
|
-
isFeatureEnabled: (feature) => featureFlags.isEnabled(config, feature),
|
|
342
|
-
getLabel: (key) => config.labels[key],
|
|
343
|
-
getBranding: () => config.branding,
|
|
344
|
-
getUI: () => config.ui
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
228
|
|
|
349
229
|
// src/components/chat/Message.tsx
|
|
350
230
|
var import_react = __toESM(require("react"), 1);
|
|
@@ -352,6 +232,75 @@ var import_react_markdown = __toESM(require("react-markdown"), 1);
|
|
|
352
232
|
var import_remark_gfm = __toESM(require("remark-gfm"), 1);
|
|
353
233
|
var import_rehype_highlight = __toESM(require("rehype-highlight"), 1);
|
|
354
234
|
|
|
235
|
+
// src/lib/chatUtils.ts
|
|
236
|
+
var chatUtils = {
|
|
237
|
+
generateId: () => globalThis.crypto?.randomUUID?.() ?? `id-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,
|
|
238
|
+
generateMessageId: () => chatUtils.generateId(),
|
|
239
|
+
generateThreadId: () => chatUtils.generateId(),
|
|
240
|
+
createMessage: (role, content, attachments) => ({
|
|
241
|
+
id: chatUtils.generateMessageId(),
|
|
242
|
+
role,
|
|
243
|
+
content,
|
|
244
|
+
timestamp: Date.now(),
|
|
245
|
+
attachments,
|
|
246
|
+
isComplete: true
|
|
247
|
+
}),
|
|
248
|
+
createThread: (title) => ({
|
|
249
|
+
id: chatUtils.generateThreadId(),
|
|
250
|
+
title,
|
|
251
|
+
createdAt: Date.now(),
|
|
252
|
+
updatedAt: Date.now(),
|
|
253
|
+
messageCount: 0
|
|
254
|
+
}),
|
|
255
|
+
generateThreadTitle: (firstMessage) => {
|
|
256
|
+
const cleaned = firstMessage.replace(/[^\w\s]/g, "").trim();
|
|
257
|
+
const words = cleaned.split(/\s+/).slice(0, 6);
|
|
258
|
+
return words.join(" ") || "Nova Conversa";
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
var AGENT_COLORS = [
|
|
262
|
+
"#6366f1",
|
|
263
|
+
// indigo
|
|
264
|
+
"#8b5cf6",
|
|
265
|
+
// violet
|
|
266
|
+
"#ec4899",
|
|
267
|
+
// pink
|
|
268
|
+
"#f59e0b",
|
|
269
|
+
// amber
|
|
270
|
+
"#10b981",
|
|
271
|
+
// emerald
|
|
272
|
+
"#3b82f6",
|
|
273
|
+
// blue
|
|
274
|
+
"#ef4444",
|
|
275
|
+
// red
|
|
276
|
+
"#14b8a6",
|
|
277
|
+
// teal
|
|
278
|
+
"#f97316",
|
|
279
|
+
// orange
|
|
280
|
+
"#84cc16"
|
|
281
|
+
// lime
|
|
282
|
+
];
|
|
283
|
+
function getAgentColor(agentId) {
|
|
284
|
+
let hash = 0;
|
|
285
|
+
for (let i = 0; i < agentId.length; i++) {
|
|
286
|
+
hash = (hash << 5) - hash + agentId.charCodeAt(i) | 0;
|
|
287
|
+
}
|
|
288
|
+
return AGENT_COLORS[Math.abs(hash) % AGENT_COLORS.length];
|
|
289
|
+
}
|
|
290
|
+
function getAgentInitials(name) {
|
|
291
|
+
const parts = name.trim().split(/\s+/);
|
|
292
|
+
if (parts.length >= 2) {
|
|
293
|
+
return (parts[0][0] + parts[1][0]).toUpperCase();
|
|
294
|
+
}
|
|
295
|
+
return name.slice(0, 2).toUpperCase();
|
|
296
|
+
}
|
|
297
|
+
function assignAgentColors(agents) {
|
|
298
|
+
return agents.map((agent) => ({
|
|
299
|
+
...agent,
|
|
300
|
+
color: agent.color || getAgentColor(agent.id)
|
|
301
|
+
}));
|
|
302
|
+
}
|
|
303
|
+
|
|
355
304
|
// src/components/ui/button.tsx
|
|
356
305
|
var import_react_slot = require("@radix-ui/react-slot");
|
|
357
306
|
var import_class_variance_authority = require("class-variance-authority");
|
|
@@ -1020,13 +969,20 @@ var Message = (0, import_react.memo)(({
|
|
|
1020
969
|
markdown,
|
|
1021
970
|
isExpanded = false,
|
|
1022
971
|
onToggleExpanded,
|
|
1023
|
-
isGrouped = false
|
|
972
|
+
isGrouped = false,
|
|
973
|
+
agentOptions = []
|
|
1024
974
|
}) => {
|
|
1025
975
|
const [isEditing, setIsEditing] = (0, import_react.useState)(false);
|
|
1026
976
|
const [editContent, setEditContent] = (0, import_react.useState)(message.content);
|
|
1027
977
|
const [showActions, setShowActions] = (0, import_react.useState)(false);
|
|
1028
978
|
const [copied, setCopied] = (0, import_react.useState)(false);
|
|
1029
979
|
const messageIsUser = isUser ?? message.role === "user";
|
|
980
|
+
const agentSender = !messageIsUser && message.senderAgentId ? agentOptions.find(
|
|
981
|
+
(a) => a.id === message.senderAgentId || a.name.toLowerCase() === (message.senderAgentId ?? "").toLowerCase() || a.name.toLowerCase() === (message.senderName ?? "").toLowerCase()
|
|
982
|
+
) : void 0;
|
|
983
|
+
const isMultiAgent = agentOptions.length > 1;
|
|
984
|
+
const resolvedAssistantName = isMultiAgent && (agentSender?.name || message.senderName) || assistantName;
|
|
985
|
+
const agentColor = agentSender ? agentSender.color || getAgentColor(agentSender.id) : void 0;
|
|
1030
986
|
const canEdit = enableEdit && messageIsUser;
|
|
1031
987
|
const canRegenerate = enableRegenerate && !messageIsUser;
|
|
1032
988
|
const normalizedPreviewChars = Math.max(longMessagePreviewChars, 1);
|
|
@@ -1090,9 +1046,26 @@ var Message = (0, import_react.memo)(({
|
|
|
1090
1046
|
showAvatar && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `flex-shrink-0 ${compactMode ? "mt-1" : "mt-0"}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Avatar, { className: compactMode ? "h-6 w-6" : "h-8 w-8", children: messageIsUser ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1091
1047
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AvatarImage, { src: userAvatar, alt: userName }),
|
|
1092
1048
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AvatarFallback, { className: "bg-primary text-primary-foreground", children: userName.charAt(0).toUpperCase() })
|
|
1049
|
+
] }) : agentSender ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1050
|
+
agentSender.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AvatarImage, { src: agentSender.avatarUrl, alt: agentSender.name }) : null,
|
|
1051
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1052
|
+
AvatarFallback,
|
|
1053
|
+
{
|
|
1054
|
+
style: agentColor ? { backgroundColor: agentColor, color: "white" } : void 0,
|
|
1055
|
+
className: agentColor ? "text-[10px]" : "bg-secondary text-secondary-foreground",
|
|
1056
|
+
children: getAgentInitials(agentSender.name)
|
|
1057
|
+
}
|
|
1058
|
+
)
|
|
1093
1059
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: assistantAvatar || /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AvatarFallback, { className: "bg-secondary text-secondary-foreground", children: "AI" }) }) }) }),
|
|
1094
1060
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `flex items-center gap-2 mb-1 ${messageIsUser ? "flex-row-reverse" : "flex-row"}`, children: [
|
|
1095
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1061
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1062
|
+
"span",
|
|
1063
|
+
{
|
|
1064
|
+
className: `font-medium ${compactMode ? "text-sm" : "text-base"}`,
|
|
1065
|
+
style: !messageIsUser && agentColor ? { color: agentColor } : void 0,
|
|
1066
|
+
children: messageIsUser ? userName : resolvedAssistantName
|
|
1067
|
+
}
|
|
1068
|
+
),
|
|
1096
1069
|
showTimestamp && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-xs text-muted-foreground", children: formatTime(message.timestamp) }),
|
|
1097
1070
|
message.isEdited && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Badge, { variant: "outline", className: "text-xs", children: "editado" })
|
|
1098
1071
|
] })
|
|
@@ -2652,9 +2625,238 @@ var Sidebar2 = ({
|
|
|
2652
2625
|
};
|
|
2653
2626
|
|
|
2654
2627
|
// src/components/chat/ChatHeader.tsx
|
|
2655
|
-
var
|
|
2628
|
+
var import_react4 = __toESM(require("react"), 1);
|
|
2629
|
+
var import_lucide_react9 = require("lucide-react");
|
|
2630
|
+
|
|
2631
|
+
// src/components/chat/AgentSelectors.tsx
|
|
2632
|
+
var import_react3 = require("react");
|
|
2656
2633
|
var import_lucide_react8 = require("lucide-react");
|
|
2657
2634
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2635
|
+
var ParticipantsSelector = (0, import_react3.memo)(({
|
|
2636
|
+
agents,
|
|
2637
|
+
participantIds,
|
|
2638
|
+
onParticipantsChange,
|
|
2639
|
+
label = "Team",
|
|
2640
|
+
maxVisible = 3,
|
|
2641
|
+
disabled = false
|
|
2642
|
+
}) => {
|
|
2643
|
+
const agentsWithColors = (0, import_react3.useMemo)(() => assignAgentColors(agents), [agents]);
|
|
2644
|
+
const selectedAgents = (0, import_react3.useMemo)(
|
|
2645
|
+
() => agentsWithColors.filter((a) => participantIds.includes(a.id)),
|
|
2646
|
+
[agentsWithColors, participantIds]
|
|
2647
|
+
);
|
|
2648
|
+
const toggleParticipant = (agentId) => {
|
|
2649
|
+
if (participantIds.includes(agentId)) {
|
|
2650
|
+
if (participantIds.length > 1) {
|
|
2651
|
+
onParticipantsChange(participantIds.filter((id) => id !== agentId));
|
|
2652
|
+
}
|
|
2653
|
+
} else {
|
|
2654
|
+
onParticipantsChange([...participantIds, agentId]);
|
|
2655
|
+
}
|
|
2656
|
+
};
|
|
2657
|
+
const selectAll = () => {
|
|
2658
|
+
onParticipantsChange(agentsWithColors.map((a) => a.id));
|
|
2659
|
+
};
|
|
2660
|
+
const visibleAgents = selectedAgents.slice(0, maxVisible);
|
|
2661
|
+
const hiddenCount = selectedAgents.length - maxVisible;
|
|
2662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DropdownMenu, { children: [
|
|
2663
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
2664
|
+
Button,
|
|
2665
|
+
{
|
|
2666
|
+
variant: "ghost",
|
|
2667
|
+
className: "h-9 px-2 gap-1.5 text-sm hover:bg-accent/50",
|
|
2668
|
+
disabled,
|
|
2669
|
+
children: [
|
|
2670
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Users, { className: "h-4 w-4 text-muted-foreground" }),
|
|
2671
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex items-center gap-1", children: visibleAgents.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
2672
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex -space-x-1.5", children: visibleAgents.map((agent) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Avatar, { className: "h-5 w-5 border-2 border-background", children: [
|
|
2673
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AvatarImage, { src: agent.avatarUrl, alt: agent.name }),
|
|
2674
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2675
|
+
AvatarFallback,
|
|
2676
|
+
{
|
|
2677
|
+
style: { backgroundColor: agent.color || getAgentColor(agent.id), color: "white" },
|
|
2678
|
+
className: "text-[8px]",
|
|
2679
|
+
children: getAgentInitials(agent.name)
|
|
2680
|
+
}
|
|
2681
|
+
)
|
|
2682
|
+
] }, agent.id)) }),
|
|
2683
|
+
hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
|
|
2684
|
+
"+",
|
|
2685
|
+
hiddenCount
|
|
2686
|
+
] })
|
|
2687
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-muted-foreground", children: label }) }),
|
|
2688
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.ChevronDown, { className: "h-3 w-3 opacity-50" })
|
|
2689
|
+
]
|
|
2690
|
+
}
|
|
2691
|
+
) }),
|
|
2692
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DropdownMenuContent, { align: "start", className: "w-[260px]", children: [
|
|
2693
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DropdownMenuLabel, { className: "flex items-center justify-between", children: [
|
|
2694
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "Participants" }),
|
|
2695
|
+
selectedAgents.length < agentsWithColors.length && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Button, { variant: "ghost", size: "sm", className: "h-6 text-xs", onClick: selectAll, children: "Select All" })
|
|
2696
|
+
] }),
|
|
2697
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DropdownMenuSeparator, {}),
|
|
2698
|
+
agentsWithColors.map((agent) => {
|
|
2699
|
+
const isSelected = participantIds.includes(agent.id);
|
|
2700
|
+
const isLastSelected = isSelected && participantIds.length === 1;
|
|
2701
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
2702
|
+
DropdownMenuItem,
|
|
2703
|
+
{
|
|
2704
|
+
onClick: () => toggleParticipant(agent.id),
|
|
2705
|
+
className: "flex items-center gap-3 p-2 cursor-pointer",
|
|
2706
|
+
disabled: isLastSelected,
|
|
2707
|
+
children: [
|
|
2708
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Avatar, { className: "h-6 w-6", children: [
|
|
2709
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AvatarImage, { src: agent.avatarUrl, alt: agent.name }),
|
|
2710
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2711
|
+
AvatarFallback,
|
|
2712
|
+
{
|
|
2713
|
+
style: { backgroundColor: agent.color || getAgentColor(agent.id), color: "white" },
|
|
2714
|
+
className: "text-[10px]",
|
|
2715
|
+
children: getAgentInitials(agent.name)
|
|
2716
|
+
}
|
|
2717
|
+
)
|
|
2718
|
+
] }),
|
|
2719
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
2720
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "font-medium text-sm truncate", children: agent.name }),
|
|
2721
|
+
agent.description && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "text-xs text-muted-foreground truncate", children: agent.description })
|
|
2722
|
+
] }),
|
|
2723
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Check, { className: "h-4 w-4 text-primary shrink-0" })
|
|
2724
|
+
]
|
|
2725
|
+
},
|
|
2726
|
+
agent.id
|
|
2727
|
+
);
|
|
2728
|
+
})
|
|
2729
|
+
] })
|
|
2730
|
+
] });
|
|
2731
|
+
});
|
|
2732
|
+
ParticipantsSelector.displayName = "ParticipantsSelector";
|
|
2733
|
+
var TargetAgentSelector = (0, import_react3.memo)(({
|
|
2734
|
+
agents,
|
|
2735
|
+
targetAgentId,
|
|
2736
|
+
onTargetChange,
|
|
2737
|
+
label = "Target",
|
|
2738
|
+
placeholder = "Select agent",
|
|
2739
|
+
disabled = false
|
|
2740
|
+
}) => {
|
|
2741
|
+
const agentsWithColors = (0, import_react3.useMemo)(() => assignAgentColors(agents), [agents]);
|
|
2742
|
+
const selectedAgent = (0, import_react3.useMemo)(
|
|
2743
|
+
() => agentsWithColors.find((a) => a.id === targetAgentId),
|
|
2744
|
+
[agentsWithColors, targetAgentId]
|
|
2745
|
+
);
|
|
2746
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DropdownMenu, { children: [
|
|
2747
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
2748
|
+
Button,
|
|
2749
|
+
{
|
|
2750
|
+
variant: "ghost",
|
|
2751
|
+
className: "h-9 px-3 gap-1.5 font-medium text-base hover:bg-accent/50",
|
|
2752
|
+
disabled,
|
|
2753
|
+
children: [
|
|
2754
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.AtSign, { className: "h-4 w-4 text-muted-foreground" }),
|
|
2755
|
+
selectedAgent ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2756
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Avatar, { className: "h-5 w-5", children: [
|
|
2757
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AvatarImage, { src: selectedAgent.avatarUrl, alt: selectedAgent.name }),
|
|
2758
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2759
|
+
AvatarFallback,
|
|
2760
|
+
{
|
|
2761
|
+
style: { backgroundColor: selectedAgent.color || getAgentColor(selectedAgent.id), color: "white" },
|
|
2762
|
+
className: "text-[10px]",
|
|
2763
|
+
children: getAgentInitials(selectedAgent.name)
|
|
2764
|
+
}
|
|
2765
|
+
)
|
|
2766
|
+
] }),
|
|
2767
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "max-w-[150px] truncate", children: selectedAgent.name })
|
|
2768
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-muted-foreground", children: placeholder }),
|
|
2769
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.ChevronDown, { className: "h-4 w-4 opacity-50" })
|
|
2770
|
+
]
|
|
2771
|
+
}
|
|
2772
|
+
) }),
|
|
2773
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DropdownMenuContent, { align: "start", className: "w-[280px]", children: [
|
|
2774
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DropdownMenuLabel, { children: label }),
|
|
2775
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DropdownMenuSeparator, {}),
|
|
2776
|
+
agentsWithColors.map((agent) => {
|
|
2777
|
+
const isSelected = agent.id === targetAgentId;
|
|
2778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
2779
|
+
DropdownMenuItem,
|
|
2780
|
+
{
|
|
2781
|
+
onClick: () => onTargetChange(agent.id),
|
|
2782
|
+
className: "flex items-start gap-3 p-3 cursor-pointer",
|
|
2783
|
+
children: [
|
|
2784
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Avatar, { className: "h-6 w-6 mt-0.5 shrink-0", children: [
|
|
2785
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AvatarImage, { src: agent.avatarUrl, alt: agent.name }),
|
|
2786
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2787
|
+
AvatarFallback,
|
|
2788
|
+
{
|
|
2789
|
+
style: { backgroundColor: agent.color || getAgentColor(agent.id), color: "white" },
|
|
2790
|
+
className: "text-[10px]",
|
|
2791
|
+
children: getAgentInitials(agent.name)
|
|
2792
|
+
}
|
|
2793
|
+
)
|
|
2794
|
+
] }),
|
|
2795
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
2796
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2797
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "font-medium text-sm", children: agent.name }),
|
|
2798
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Check, { className: "h-4 w-4 text-primary shrink-0" })
|
|
2799
|
+
] }),
|
|
2800
|
+
agent.description && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5 line-clamp-2", children: agent.description })
|
|
2801
|
+
] })
|
|
2802
|
+
]
|
|
2803
|
+
},
|
|
2804
|
+
agent.id
|
|
2805
|
+
);
|
|
2806
|
+
})
|
|
2807
|
+
] })
|
|
2808
|
+
] });
|
|
2809
|
+
});
|
|
2810
|
+
TargetAgentSelector.displayName = "TargetAgentSelector";
|
|
2811
|
+
var AgentBadge = (0, import_react3.memo)(({
|
|
2812
|
+
agent,
|
|
2813
|
+
onRemove,
|
|
2814
|
+
showRemove = false,
|
|
2815
|
+
size = "md"
|
|
2816
|
+
}) => {
|
|
2817
|
+
const color = agent.color || getAgentColor(agent.id);
|
|
2818
|
+
const avatarSize = size === "sm" ? "h-4 w-4" : "h-5 w-5";
|
|
2819
|
+
const textSize = size === "sm" ? "text-xs" : "text-sm";
|
|
2820
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
2821
|
+
Badge,
|
|
2822
|
+
{
|
|
2823
|
+
variant: "secondary",
|
|
2824
|
+
className: "flex items-center gap-1.5 pr-1",
|
|
2825
|
+
style: { borderColor: color, borderWidth: 1 },
|
|
2826
|
+
children: [
|
|
2827
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Avatar, { className: avatarSize, children: [
|
|
2828
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AvatarImage, { src: agent.avatarUrl, alt: agent.name }),
|
|
2829
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2830
|
+
AvatarFallback,
|
|
2831
|
+
{
|
|
2832
|
+
style: { backgroundColor: color, color: "white" },
|
|
2833
|
+
className: "text-[8px]",
|
|
2834
|
+
children: getAgentInitials(agent.name)
|
|
2835
|
+
}
|
|
2836
|
+
)
|
|
2837
|
+
] }),
|
|
2838
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: textSize, children: agent.name }),
|
|
2839
|
+
showRemove && onRemove && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2840
|
+
Button,
|
|
2841
|
+
{
|
|
2842
|
+
variant: "ghost",
|
|
2843
|
+
size: "icon",
|
|
2844
|
+
className: "h-4 w-4 ml-0.5 hover:bg-destructive/20",
|
|
2845
|
+
onClick: (e) => {
|
|
2846
|
+
e.stopPropagation();
|
|
2847
|
+
onRemove();
|
|
2848
|
+
},
|
|
2849
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.X, { className: "h-3 w-3" })
|
|
2850
|
+
}
|
|
2851
|
+
)
|
|
2852
|
+
]
|
|
2853
|
+
}
|
|
2854
|
+
);
|
|
2855
|
+
});
|
|
2856
|
+
AgentBadge.displayName = "AgentBadge";
|
|
2857
|
+
|
|
2858
|
+
// src/components/chat/ChatHeader.tsx
|
|
2859
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2658
2860
|
var ChatHeader = ({
|
|
2659
2861
|
config,
|
|
2660
2862
|
currentThreadTitle,
|
|
@@ -2667,16 +2869,19 @@ var ChatHeader = ({
|
|
|
2667
2869
|
showCustomComponentButton,
|
|
2668
2870
|
isMobile,
|
|
2669
2871
|
showAgentSelector = false,
|
|
2872
|
+
isMultiAgentMode = false,
|
|
2670
2873
|
agentOptions = [],
|
|
2671
2874
|
selectedAgentId = null,
|
|
2672
2875
|
onSelectAgent,
|
|
2876
|
+
participantIds,
|
|
2877
|
+
onParticipantsChange,
|
|
2673
2878
|
className = ""
|
|
2674
2879
|
}) => {
|
|
2675
|
-
const [isDarkMode, setIsDarkMode] =
|
|
2880
|
+
const [isDarkMode, setIsDarkMode] = import_react4.default.useState(() => {
|
|
2676
2881
|
if (typeof window === "undefined") return false;
|
|
2677
2882
|
return document.documentElement.classList.contains("dark");
|
|
2678
2883
|
});
|
|
2679
|
-
|
|
2884
|
+
import_react4.default.useEffect(() => {
|
|
2680
2885
|
const observer = new MutationObserver(() => {
|
|
2681
2886
|
setIsDarkMode(document.documentElement.classList.contains("dark"));
|
|
2682
2887
|
});
|
|
@@ -2722,52 +2927,60 @@ var ChatHeader = ({
|
|
|
2722
2927
|
};
|
|
2723
2928
|
const selectedAgent = agentOptions.find((agent) => agent.id === selectedAgentId) || null;
|
|
2724
2929
|
const agentPlaceholder = config.agentSelector?.label || "Select agent";
|
|
2725
|
-
return /* @__PURE__ */ (0,
|
|
2930
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2726
2931
|
Card,
|
|
2727
2932
|
{
|
|
2728
2933
|
"data-chat-header": true,
|
|
2729
2934
|
className: `py-0 border-b rounded-none relative z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 ${className}`,
|
|
2730
2935
|
style: isMobile ? { paddingTop: "env(safe-area-inset-top)" } : void 0,
|
|
2731
|
-
children: /* @__PURE__ */ (0,
|
|
2732
|
-
/* @__PURE__ */ (0,
|
|
2733
|
-
/* @__PURE__ */ (0,
|
|
2734
|
-
/* @__PURE__ */ (0,
|
|
2735
|
-
/* @__PURE__ */ (0,
|
|
2936
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CardHeader, { className: "p-2", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
2937
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
2938
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Tooltip, { children: [
|
|
2939
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SidebarTrigger, { className: "-ml-1" }) }),
|
|
2940
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipContent, { children: config.labels?.sidebarToggle || "Toggle Sidebar" })
|
|
2736
2941
|
] }),
|
|
2737
|
-
showAgentSelector && /* @__PURE__ */ (0,
|
|
2738
|
-
|
|
2942
|
+
showAgentSelector && isMultiAgentMode && onParticipantsChange && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2943
|
+
ParticipantsSelector,
|
|
2944
|
+
{
|
|
2945
|
+
agents: agentOptions,
|
|
2946
|
+
participantIds: participantIds ?? agentOptions.map((a) => a.id),
|
|
2947
|
+
onParticipantsChange
|
|
2948
|
+
}
|
|
2949
|
+
),
|
|
2950
|
+
showAgentSelector && !isMultiAgentMode && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DropdownMenu, { children: [
|
|
2951
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
2739
2952
|
Button,
|
|
2740
2953
|
{
|
|
2741
2954
|
variant: "ghost",
|
|
2742
2955
|
className: "h-9 px-3 gap-1.5 font-medium text-base hover:bg-accent/50",
|
|
2743
2956
|
children: [
|
|
2744
|
-
selectedAgent?.avatarUrl ? /* @__PURE__ */ (0,
|
|
2745
|
-
/* @__PURE__ */ (0,
|
|
2746
|
-
/* @__PURE__ */ (0,
|
|
2957
|
+
selectedAgent?.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Avatar, { className: "h-5 w-5", children: [
|
|
2958
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(AvatarImage, { src: selectedAgent.avatarUrl, alt: selectedAgent.name }),
|
|
2959
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(AvatarFallback, { className: "text-[10px]", children: selectedAgent.name.charAt(0).toUpperCase() })
|
|
2747
2960
|
] }) : null,
|
|
2748
|
-
/* @__PURE__ */ (0,
|
|
2749
|
-
/* @__PURE__ */ (0,
|
|
2961
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "max-w-[200px] truncate", children: selectedAgent?.name || agentPlaceholder }),
|
|
2962
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.ChevronDown, { className: "h-4 w-4 opacity-50" })
|
|
2750
2963
|
]
|
|
2751
2964
|
}
|
|
2752
2965
|
) }),
|
|
2753
|
-
/* @__PURE__ */ (0,
|
|
2966
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DropdownMenuContent, { align: "start", className: "w-[280px]", children: agentOptions.map((agent) => {
|
|
2754
2967
|
const isSelected = agent.id === selectedAgentId;
|
|
2755
|
-
return /* @__PURE__ */ (0,
|
|
2968
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
2756
2969
|
DropdownMenuItem,
|
|
2757
2970
|
{
|
|
2758
2971
|
onClick: () => onSelectAgent?.(agent.id),
|
|
2759
2972
|
className: "flex items-start gap-3 p-3 cursor-pointer",
|
|
2760
2973
|
children: [
|
|
2761
|
-
agent.avatarUrl ? /* @__PURE__ */ (0,
|
|
2762
|
-
/* @__PURE__ */ (0,
|
|
2763
|
-
/* @__PURE__ */ (0,
|
|
2764
|
-
] }) : /* @__PURE__ */ (0,
|
|
2765
|
-
/* @__PURE__ */ (0,
|
|
2766
|
-
/* @__PURE__ */ (0,
|
|
2767
|
-
/* @__PURE__ */ (0,
|
|
2768
|
-
isSelected && /* @__PURE__ */ (0,
|
|
2974
|
+
agent.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Avatar, { className: "h-6 w-6 mt-0.5 shrink-0", children: [
|
|
2975
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(AvatarImage, { src: agent.avatarUrl, alt: agent.name }),
|
|
2976
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(AvatarFallback, { className: "text-[10px]", children: agent.name.charAt(0).toUpperCase() })
|
|
2977
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "h-6 w-6 mt-0.5 shrink-0 flex items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Bot, { className: "h-3.5 w-3.5 text-primary" }) }),
|
|
2978
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
2979
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2980
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "font-medium text-sm", children: agent.name }),
|
|
2981
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Check, { className: "h-4 w-4 text-primary shrink-0" })
|
|
2769
2982
|
] }),
|
|
2770
|
-
agent.description && /* @__PURE__ */ (0,
|
|
2983
|
+
agent.description && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5 line-clamp-2", children: agent.description })
|
|
2771
2984
|
] })
|
|
2772
2985
|
]
|
|
2773
2986
|
},
|
|
@@ -2775,59 +2988,59 @@ var ChatHeader = ({
|
|
|
2775
2988
|
);
|
|
2776
2989
|
}) })
|
|
2777
2990
|
] }),
|
|
2778
|
-
!showAgentSelector && isMobile && /* @__PURE__ */ (0,
|
|
2991
|
+
!showAgentSelector && isMobile && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-sm font-medium truncate max-w-[150px] ml-2", children: currentThreadTitle || config.branding?.title || "Chat" })
|
|
2779
2992
|
] }),
|
|
2780
|
-
/* @__PURE__ */ (0,
|
|
2781
|
-
/* @__PURE__ */ (0,
|
|
2782
|
-
showCustomComponentButton && config.customComponent && /* @__PURE__ */ (0,
|
|
2783
|
-
/* @__PURE__ */ (0,
|
|
2993
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex-1" }),
|
|
2994
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
2995
|
+
showCustomComponentButton && config.customComponent && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Tooltip, { children: [
|
|
2996
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2784
2997
|
Button,
|
|
2785
2998
|
{
|
|
2786
2999
|
variant: "ghost",
|
|
2787
3000
|
size: "icon",
|
|
2788
3001
|
className: "h-8 w-8",
|
|
2789
3002
|
onClick: onCustomComponentToggle,
|
|
2790
|
-
children: config.customComponent.icon || /* @__PURE__ */ (0,
|
|
3003
|
+
children: config.customComponent.icon || /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Menu, { className: "h-4 w-4" })
|
|
2791
3004
|
}
|
|
2792
3005
|
) }),
|
|
2793
|
-
/* @__PURE__ */ (0,
|
|
3006
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipContent, { children: config.customComponent.label || config.labels?.customComponentToggle || "Toggle" })
|
|
2794
3007
|
] }),
|
|
2795
3008
|
config.headerActions,
|
|
2796
|
-
/* @__PURE__ */ (0,
|
|
2797
|
-
/* @__PURE__ */ (0,
|
|
2798
|
-
/* @__PURE__ */ (0,
|
|
2799
|
-
onNewThread && /* @__PURE__ */ (0,
|
|
2800
|
-
/* @__PURE__ */ (0,
|
|
2801
|
-
/* @__PURE__ */ (0,
|
|
3009
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DropdownMenu, { children: [
|
|
3010
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "ghost", size: "icon", className: "h-8 w-8", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.MoreVertical, { className: "h-4 w-4" }) }) }),
|
|
3011
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DropdownMenuContent, { align: "end", children: [
|
|
3012
|
+
onNewThread && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
3013
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DropdownMenuItem, { onClick: () => onNewThread?.(), className: "font-medium text-primary", children: [
|
|
3014
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Plus, { className: "h-4 w-4 mr-2" }),
|
|
2802
3015
|
config.labels?.newThread || "New Thread"
|
|
2803
3016
|
] }),
|
|
2804
|
-
/* @__PURE__ */ (0,
|
|
3017
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DropdownMenuSeparator, {})
|
|
2805
3018
|
] }),
|
|
2806
|
-
onExportData && /* @__PURE__ */ (0,
|
|
2807
|
-
/* @__PURE__ */ (0,
|
|
3019
|
+
onExportData && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DropdownMenuItem, { onClick: onExportData, children: [
|
|
3020
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Download, { className: "h-4 w-4 mr-2" }),
|
|
2808
3021
|
config.labels?.exportData || "Export Data"
|
|
2809
3022
|
] }),
|
|
2810
|
-
onImportData && /* @__PURE__ */ (0,
|
|
2811
|
-
/* @__PURE__ */ (0,
|
|
3023
|
+
onImportData && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DropdownMenuItem, { onClick: handleImportClick, children: [
|
|
3024
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Upload, { className: "h-4 w-4 mr-2" }),
|
|
2812
3025
|
config.labels?.importData || "Import Data"
|
|
2813
3026
|
] }),
|
|
2814
|
-
(onExportData || onImportData) && /* @__PURE__ */ (0,
|
|
2815
|
-
/* @__PURE__ */ (0,
|
|
2816
|
-
/* @__PURE__ */ (0,
|
|
3027
|
+
(onExportData || onImportData) && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DropdownMenuSeparator, {}),
|
|
3028
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DropdownMenuItem, { onClick: toggleDarkMode, children: isDarkMode ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
3029
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Sun, { className: "h-4 w-4 mr-2" }),
|
|
2817
3030
|
config.labels?.lightMode || "Light Mode"
|
|
2818
|
-
] }) : /* @__PURE__ */ (0,
|
|
2819
|
-
/* @__PURE__ */ (0,
|
|
3031
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
3032
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Moon, { className: "h-4 w-4 mr-2" }),
|
|
2820
3033
|
config.labels?.darkMode || "Dark Mode"
|
|
2821
3034
|
] }) }),
|
|
2822
|
-
onClearAll && /* @__PURE__ */ (0,
|
|
2823
|
-
/* @__PURE__ */ (0,
|
|
2824
|
-
/* @__PURE__ */ (0,
|
|
3035
|
+
onClearAll && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
3036
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DropdownMenuSeparator, {}),
|
|
3037
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
2825
3038
|
DropdownMenuItem,
|
|
2826
3039
|
{
|
|
2827
3040
|
onClick: onClearAll,
|
|
2828
3041
|
className: "text-destructive",
|
|
2829
3042
|
children: [
|
|
2830
|
-
/* @__PURE__ */ (0,
|
|
3043
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Trash2, { className: "h-4 w-4 mr-2" }),
|
|
2831
3044
|
config.labels?.clearAll || "Clear All"
|
|
2832
3045
|
]
|
|
2833
3046
|
}
|
|
@@ -2842,18 +3055,18 @@ var ChatHeader = ({
|
|
|
2842
3055
|
};
|
|
2843
3056
|
|
|
2844
3057
|
// src/components/chat/ChatInput.tsx
|
|
2845
|
-
var
|
|
3058
|
+
var import_react6 = __toESM(require("react"), 1);
|
|
2846
3059
|
|
|
2847
3060
|
// src/components/chat/UserContext.tsx
|
|
2848
|
-
var
|
|
2849
|
-
var
|
|
2850
|
-
var Ctx = (0,
|
|
3061
|
+
var import_react5 = require("react");
|
|
3062
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3063
|
+
var Ctx = (0, import_react5.createContext)(void 0);
|
|
2851
3064
|
var ChatUserContextProvider = ({ children, initial }) => {
|
|
2852
|
-
const [ctx, setCtx] = (0,
|
|
3065
|
+
const [ctx, setCtx] = (0, import_react5.useState)(() => ({
|
|
2853
3066
|
updatedAt: Date.now(),
|
|
2854
3067
|
...initial ?? {}
|
|
2855
3068
|
}));
|
|
2856
|
-
(0,
|
|
3069
|
+
(0, import_react5.useEffect)(() => {
|
|
2857
3070
|
if (!initial) return;
|
|
2858
3071
|
setCtx((prev) => {
|
|
2859
3072
|
const keys = Object.keys(initial);
|
|
@@ -2862,21 +3075,21 @@ var ChatUserContextProvider = ({ children, initial }) => {
|
|
|
2862
3075
|
return { ...prev, ...initial, updatedAt: Date.now() };
|
|
2863
3076
|
});
|
|
2864
3077
|
}, [initial]);
|
|
2865
|
-
const setPartial = (0,
|
|
3078
|
+
const setPartial = (0, import_react5.useCallback)((next) => {
|
|
2866
3079
|
setCtx((prev) => {
|
|
2867
3080
|
const partial = typeof next === "function" ? next(prev) : next;
|
|
2868
3081
|
return { ...prev, ...partial, updatedAt: Date.now() };
|
|
2869
3082
|
});
|
|
2870
3083
|
}, []);
|
|
2871
|
-
const value = (0,
|
|
3084
|
+
const value = (0, import_react5.useMemo)(() => ({
|
|
2872
3085
|
context: ctx,
|
|
2873
3086
|
setContext: setPartial,
|
|
2874
3087
|
resetContext: () => setCtx({ updatedAt: Date.now() })
|
|
2875
3088
|
}), [ctx, setPartial]);
|
|
2876
|
-
return /* @__PURE__ */ (0,
|
|
3089
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ctx.Provider, { value, children });
|
|
2877
3090
|
};
|
|
2878
3091
|
function useChatUserContext() {
|
|
2879
|
-
const v = (0,
|
|
3092
|
+
const v = (0, import_react5.useContext)(Ctx);
|
|
2880
3093
|
if (!v) throw new Error("useChatUserContext must be used within ChatUserContextProvider");
|
|
2881
3094
|
return v;
|
|
2882
3095
|
}
|
|
@@ -3207,13 +3420,13 @@ var resolveVoiceProviderFactory = (createProvider) => createProvider ?? createMa
|
|
|
3207
3420
|
|
|
3208
3421
|
// src/components/ui/progress.tsx
|
|
3209
3422
|
var ProgressPrimitive = __toESM(require("@radix-ui/react-progress"), 1);
|
|
3210
|
-
var
|
|
3423
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3211
3424
|
function Progress({
|
|
3212
3425
|
className,
|
|
3213
3426
|
value,
|
|
3214
3427
|
...props
|
|
3215
3428
|
}) {
|
|
3216
|
-
return /* @__PURE__ */ (0,
|
|
3429
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3217
3430
|
ProgressPrimitive.Root,
|
|
3218
3431
|
{
|
|
3219
3432
|
"data-slot": "progress",
|
|
@@ -3222,7 +3435,7 @@ function Progress({
|
|
|
3222
3435
|
className
|
|
3223
3436
|
),
|
|
3224
3437
|
...props,
|
|
3225
|
-
children: /* @__PURE__ */ (0,
|
|
3438
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3226
3439
|
ProgressPrimitive.Indicator,
|
|
3227
3440
|
{
|
|
3228
3441
|
"data-slot": "progress-indicator",
|
|
@@ -3235,8 +3448,8 @@ function Progress({
|
|
|
3235
3448
|
}
|
|
3236
3449
|
|
|
3237
3450
|
// src/components/chat/VoiceComposer.tsx
|
|
3238
|
-
var
|
|
3239
|
-
var
|
|
3451
|
+
var import_lucide_react10 = require("lucide-react");
|
|
3452
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3240
3453
|
var formatDuration = (durationMs) => {
|
|
3241
3454
|
const totalSeconds = Math.max(0, Math.floor(durationMs / 1e3));
|
|
3242
3455
|
const minutes = Math.floor(totalSeconds / 60);
|
|
@@ -3331,13 +3544,13 @@ var VoiceComposer = ({
|
|
|
3331
3544
|
}
|
|
3332
3545
|
onRecordAgain();
|
|
3333
3546
|
};
|
|
3334
|
-
return /* @__PURE__ */ (0,
|
|
3335
|
-
/* @__PURE__ */ (0,
|
|
3336
|
-
/* @__PURE__ */ (0,
|
|
3337
|
-
/* @__PURE__ */ (0,
|
|
3338
|
-
/* @__PURE__ */ (0,
|
|
3547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "w-full max-w-3xl rounded-2xl border bg-background p-3 shadow-sm sm:p-4 md:min-w-3xl", children: [
|
|
3548
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center justify-between gap-2 sm:gap-3", children: [
|
|
3549
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
3550
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Badge, { variant: "outline", children: labels?.voiceTitle || "Voice" }),
|
|
3551
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "truncate rounded-full bg-muted px-2.5 py-1 text-[11px] sm:text-xs text-muted-foreground", children: headerLabel })
|
|
3339
3552
|
] }),
|
|
3340
|
-
/* @__PURE__ */ (0,
|
|
3553
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
3341
3554
|
Button,
|
|
3342
3555
|
{
|
|
3343
3556
|
type: "button",
|
|
@@ -3347,14 +3560,14 @@ var VoiceComposer = ({
|
|
|
3347
3560
|
onClick: onExit,
|
|
3348
3561
|
disabled: disabled || isBusy,
|
|
3349
3562
|
children: [
|
|
3350
|
-
/* @__PURE__ */ (0,
|
|
3351
|
-
/* @__PURE__ */ (0,
|
|
3563
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Keyboard, { className: "h-4 w-4" }),
|
|
3564
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "hidden sm:inline", children: labels?.voiceExit || "Use keyboard" })
|
|
3352
3565
|
]
|
|
3353
3566
|
}
|
|
3354
3567
|
)
|
|
3355
3568
|
] }),
|
|
3356
|
-
!isDraftLayout ? /* @__PURE__ */ (0,
|
|
3357
|
-
/* @__PURE__ */ (0,
|
|
3569
|
+
!isDraftLayout ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mt-3 rounded-xl border border-dashed border-primary/30 bg-primary/5 px-3 py-3 text-center sm:px-4 sm:py-4", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "mx-auto flex w-full max-w-sm flex-col items-center gap-3", children: [
|
|
3570
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3358
3571
|
Button,
|
|
3359
3572
|
{
|
|
3360
3573
|
type: "button",
|
|
@@ -3363,21 +3576,21 @@ var VoiceComposer = ({
|
|
|
3363
3576
|
className: `h-16 w-16 rounded-full sm:h-20 sm:w-20 ${isCapturing ? "bg-red-500 hover:bg-red-600 text-white border-red-500" : "border-red-200 bg-red-50 text-red-600 hover:bg-red-100 hover:text-red-700"}`,
|
|
3364
3577
|
onClick: isCapturing ? onStop : onStart,
|
|
3365
3578
|
disabled: disabled || isBusy,
|
|
3366
|
-
children: isBusy ? /* @__PURE__ */ (0,
|
|
3579
|
+
children: isBusy ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Loader2, { className: "h-7 w-7 animate-spin" }) : isCapturing ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Square, { className: "h-7 w-7" }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Mic, { className: "h-7 w-7" })
|
|
3367
3580
|
}
|
|
3368
3581
|
),
|
|
3369
|
-
/* @__PURE__ */ (0,
|
|
3370
|
-
/* @__PURE__ */ (0,
|
|
3371
|
-
/* @__PURE__ */ (0,
|
|
3372
|
-
/* @__PURE__ */ (0,
|
|
3373
|
-
/* @__PURE__ */ (0,
|
|
3582
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "w-full space-y-2", children: [
|
|
3583
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Progress, { value: levelValue, className: "h-2" }),
|
|
3584
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [
|
|
3585
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: formatDuration(durationMs) }),
|
|
3586
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: isCapturing ? labels?.voiceStop || "Stop recording" : labels?.voiceStart || "Start recording" })
|
|
3374
3587
|
] })
|
|
3375
3588
|
] }),
|
|
3376
|
-
showTranscriptPreview && transcriptMode !== "none" && transcriptText && /* @__PURE__ */ (0,
|
|
3377
|
-
] }) }) : /* @__PURE__ */ (0,
|
|
3378
|
-
/* @__PURE__ */ (0,
|
|
3379
|
-
/* @__PURE__ */ (0,
|
|
3380
|
-
/* @__PURE__ */ (0,
|
|
3589
|
+
showTranscriptPreview && transcriptMode !== "none" && transcriptText && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "w-full rounded-lg border bg-background px-3 py-2 text-left text-sm", children: transcriptText })
|
|
3590
|
+
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "mt-3 rounded-xl border bg-muted/20 p-3 sm:p-4", children: [
|
|
3591
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center justify-between gap-2 text-xs text-muted-foreground", children: [
|
|
3592
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: formatDuration(durationMs) }),
|
|
3593
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3381
3594
|
Button,
|
|
3382
3595
|
{
|
|
3383
3596
|
type: "button",
|
|
@@ -3388,12 +3601,12 @@ var VoiceComposer = ({
|
|
|
3388
3601
|
disabled,
|
|
3389
3602
|
"aria-label": labels?.voiceDiscard || "Delete recording",
|
|
3390
3603
|
title: labels?.voiceDiscard || "Delete recording",
|
|
3391
|
-
children: /* @__PURE__ */ (0,
|
|
3604
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Trash2, { className: "h-4 w-4" })
|
|
3392
3605
|
}
|
|
3393
3606
|
)
|
|
3394
3607
|
] }),
|
|
3395
|
-
/* @__PURE__ */ (0,
|
|
3396
|
-
/* @__PURE__ */ (0,
|
|
3608
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "mt-4 flex flex-col items-center gap-4 text-center", children: [
|
|
3609
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3397
3610
|
Button,
|
|
3398
3611
|
{
|
|
3399
3612
|
type: "button",
|
|
@@ -3402,12 +3615,12 @@ var VoiceComposer = ({
|
|
|
3402
3615
|
className: `h-20 w-20 rounded-full sm:h-24 sm:w-24 ${orbIsListening ? "border-red-500 bg-red-500 text-white hover:bg-red-600" : isArmedDraft ? "border-red-200 bg-red-50 text-red-600 shadow-[0_0_0_10px_rgba(239,68,68,0.08)] hover:bg-red-100 hover:text-red-700" : "border-red-200 bg-red-50 text-red-600 hover:bg-red-100 hover:text-red-700"}`,
|
|
3403
3616
|
onClick: handleReviewOrbClick,
|
|
3404
3617
|
disabled: disabled || orbIsReviewBusy,
|
|
3405
|
-
children: orbIsReviewBusy ? /* @__PURE__ */ (0,
|
|
3618
|
+
children: orbIsReviewBusy ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Loader2, { className: "h-7 w-7 animate-spin" }) : orbIsListening ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Square, { className: "h-7 w-7" }) : isArmedDraft ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Mic, { className: "h-7 w-7 animate-pulse" }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Mic, { className: "h-7 w-7" })
|
|
3406
3619
|
}
|
|
3407
3620
|
),
|
|
3408
|
-
/* @__PURE__ */ (0,
|
|
3409
|
-
/* @__PURE__ */ (0,
|
|
3410
|
-
isCapturing && /* @__PURE__ */ (0,
|
|
3621
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "max-w-sm space-y-1 px-2", children: [
|
|
3622
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-sm text-foreground", children: reviewHelperText }),
|
|
3623
|
+
isCapturing && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mx-auto h-1.5 w-32 overflow-hidden rounded-full bg-red-100", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3411
3624
|
"div",
|
|
3412
3625
|
{
|
|
3413
3626
|
className: "h-full rounded-full bg-red-500 transition-[width] duration-150",
|
|
@@ -3416,28 +3629,51 @@ var VoiceComposer = ({
|
|
|
3416
3629
|
) })
|
|
3417
3630
|
] })
|
|
3418
3631
|
] }),
|
|
3419
|
-
attachment && /* @__PURE__ */ (0,
|
|
3420
|
-
showTranscriptPreview && transcriptMode !== "none" && transcriptText && /* @__PURE__ */ (0,
|
|
3421
|
-
isAutoSendActive && autoSendDelayMs > 0 && /* @__PURE__ */ (0,
|
|
3422
|
-
/* @__PURE__ */ (0,
|
|
3423
|
-
isAutoSendActive && /* @__PURE__ */ (0,
|
|
3424
|
-
/* @__PURE__ */ (0,
|
|
3632
|
+
attachment && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mt-4 rounded-lg border bg-background/90 p-2 shadow-sm", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("audio", { controls: true, preload: "metadata", className: "w-full", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("source", { src: attachment.dataUrl, type: attachment.mimeType }) }) }),
|
|
3633
|
+
showTranscriptPreview && transcriptMode !== "none" && transcriptText && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mt-3 rounded-lg border bg-background px-3 py-2 text-left text-sm", children: transcriptText }),
|
|
3634
|
+
isAutoSendActive && autoSendDelayMs > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mt-3 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "inline-flex items-center rounded-full border bg-background px-3 py-1 text-xs text-muted-foreground", children: interpolateSeconds(labels?.voiceAutoSendIn, countdownSeconds) }) }),
|
|
3635
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "mt-4 grid grid-cols-1 gap-2 sm:flex sm:items-center sm:justify-end", children: [
|
|
3636
|
+
isAutoSendActive && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Button, { type: "button", variant: "ghost", size: "sm", onClick: onCancelAutoSend, disabled, className: "w-full sm:w-auto", children: [
|
|
3637
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.X, { className: "h-4 w-4" }),
|
|
3425
3638
|
labels?.voiceCancel || "Cancel"
|
|
3426
3639
|
] }),
|
|
3427
|
-
/* @__PURE__ */ (0,
|
|
3428
|
-
/* @__PURE__ */ (0,
|
|
3640
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Button, { type: "button", size: "sm", onClick: onSendNow, disabled, className: "w-full sm:w-auto", children: [
|
|
3641
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Send, { className: "h-4 w-4" }),
|
|
3429
3642
|
labels?.voiceSendNow || "Send now"
|
|
3430
3643
|
] })
|
|
3431
3644
|
] })
|
|
3432
3645
|
] }),
|
|
3433
|
-
errorMessage && /* @__PURE__ */ (0,
|
|
3646
|
+
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mt-3 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2 text-sm text-destructive", children: errorMessage })
|
|
3434
3647
|
] });
|
|
3435
3648
|
};
|
|
3436
3649
|
|
|
3437
3650
|
// src/components/chat/ChatInput.tsx
|
|
3438
|
-
var
|
|
3439
|
-
var
|
|
3440
|
-
|
|
3651
|
+
var import_lucide_react11 = require("lucide-react");
|
|
3652
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3653
|
+
function getActiveMentionMatch(value, caret) {
|
|
3654
|
+
const prefix = value.slice(0, caret);
|
|
3655
|
+
const match = /(^|\s)@([\w.-]*)$/.exec(prefix);
|
|
3656
|
+
if (!match) return null;
|
|
3657
|
+
const query = match[2] ?? "";
|
|
3658
|
+
return {
|
|
3659
|
+
start: prefix.length - query.length - 1,
|
|
3660
|
+
end: caret,
|
|
3661
|
+
query
|
|
3662
|
+
};
|
|
3663
|
+
}
|
|
3664
|
+
function resolveTargetFromMentions(value, agents) {
|
|
3665
|
+
const matches = value.matchAll(/(^|\s)@([\w.-]+)/g);
|
|
3666
|
+
for (const match of matches) {
|
|
3667
|
+
const mention = match[2]?.toLowerCase();
|
|
3668
|
+
if (!mention) continue;
|
|
3669
|
+
const agent = agents.find(
|
|
3670
|
+
(candidate) => candidate.id.toLowerCase() === mention || candidate.name.toLowerCase() === mention
|
|
3671
|
+
);
|
|
3672
|
+
if (agent) return agent;
|
|
3673
|
+
}
|
|
3674
|
+
return null;
|
|
3675
|
+
}
|
|
3676
|
+
var FileUploadItem = (0, import_react6.memo)(function FileUploadItem2({ file, progress, onCancel }) {
|
|
3441
3677
|
const guessTypeFromName = (name) => {
|
|
3442
3678
|
const ext = (name || "").split(".").pop()?.toLowerCase();
|
|
3443
3679
|
switch (ext) {
|
|
@@ -3465,10 +3701,10 @@ var FileUploadItem = (0, import_react5.memo)(function FileUploadItem2({ file, pr
|
|
|
3465
3701
|
};
|
|
3466
3702
|
const getFileIcon = (type, name) => {
|
|
3467
3703
|
const t = typeof type === "string" && type.length > 0 ? type : guessTypeFromName(name);
|
|
3468
|
-
if (t.startsWith("image/")) return /* @__PURE__ */ (0,
|
|
3469
|
-
if (t.startsWith("video/")) return /* @__PURE__ */ (0,
|
|
3470
|
-
if (t.startsWith("audio/")) return /* @__PURE__ */ (0,
|
|
3471
|
-
return /* @__PURE__ */ (0,
|
|
3704
|
+
if (t.startsWith("image/")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Image, { className: "h-4 w-4" });
|
|
3705
|
+
if (t.startsWith("video/")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Video, { className: "h-4 w-4" });
|
|
3706
|
+
if (t.startsWith("audio/")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Mic, { className: "h-4 w-4" });
|
|
3707
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.FileText, { className: "h-4 w-4" });
|
|
3472
3708
|
};
|
|
3473
3709
|
const formatFileSize = (bytes) => {
|
|
3474
3710
|
if (bytes === 0) return "0 Bytes";
|
|
@@ -3477,30 +3713,30 @@ var FileUploadItem = (0, import_react5.memo)(function FileUploadItem2({ file, pr
|
|
|
3477
3713
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
3478
3714
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
|
|
3479
3715
|
};
|
|
3480
|
-
return /* @__PURE__ */ (0,
|
|
3716
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Card, { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CardContent, { className: "p-3", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
3481
3717
|
getFileIcon(file.type, file.name),
|
|
3482
|
-
/* @__PURE__ */ (0,
|
|
3483
|
-
/* @__PURE__ */ (0,
|
|
3484
|
-
/* @__PURE__ */ (0,
|
|
3485
|
-
/* @__PURE__ */ (0,
|
|
3718
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
3719
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-sm font-medium truncate", children: file.name }),
|
|
3720
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs text-muted-foreground", children: formatFileSize(file.size ?? 0) }),
|
|
3721
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Progress, { value: progress, className: "h-1 mt-1" })
|
|
3486
3722
|
] }),
|
|
3487
|
-
/* @__PURE__ */ (0,
|
|
3723
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3488
3724
|
Button,
|
|
3489
3725
|
{
|
|
3490
3726
|
variant: "ghost",
|
|
3491
3727
|
size: "icon",
|
|
3492
3728
|
className: "h-6 w-6",
|
|
3493
3729
|
onClick: onCancel,
|
|
3494
|
-
children: /* @__PURE__ */ (0,
|
|
3730
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.X, { className: "h-3 w-3" })
|
|
3495
3731
|
}
|
|
3496
3732
|
)
|
|
3497
3733
|
] }) }) });
|
|
3498
3734
|
});
|
|
3499
|
-
var AttachmentPreview = (0,
|
|
3500
|
-
const [isPlaying, setIsPlaying] = (0,
|
|
3501
|
-
const [audioPlaybackSrc, setAudioPlaybackSrc] = (0,
|
|
3502
|
-
const audioRef = (0,
|
|
3503
|
-
(0,
|
|
3735
|
+
var AttachmentPreview = (0, import_react6.memo)(function AttachmentPreview2({ attachment, onRemove }) {
|
|
3736
|
+
const [isPlaying, setIsPlaying] = (0, import_react6.useState)(false);
|
|
3737
|
+
const [audioPlaybackSrc, setAudioPlaybackSrc] = (0, import_react6.useState)(attachment.dataUrl);
|
|
3738
|
+
const audioRef = (0, import_react6.useRef)(null);
|
|
3739
|
+
(0, import_react6.useEffect)(() => {
|
|
3504
3740
|
if (attachment.kind !== "audio" || !attachment.dataUrl.startsWith("data:")) {
|
|
3505
3741
|
setAudioPlaybackSrc(attachment.dataUrl);
|
|
3506
3742
|
return;
|
|
@@ -3531,9 +3767,9 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
|
|
|
3531
3767
|
const minutes = Math.floor(seconds / 60);
|
|
3532
3768
|
return `${minutes}:${(seconds % 60).toString().padStart(2, "0")}`;
|
|
3533
3769
|
};
|
|
3534
|
-
return /* @__PURE__ */ (0,
|
|
3535
|
-
attachment.kind === "image" && /* @__PURE__ */ (0,
|
|
3536
|
-
/* @__PURE__ */ (0,
|
|
3770
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Card, { className: "relative group", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(CardContent, { className: "p-2", children: [
|
|
3771
|
+
attachment.kind === "image" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "relative", children: [
|
|
3772
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3537
3773
|
"img",
|
|
3538
3774
|
{
|
|
3539
3775
|
src: attachment.dataUrl,
|
|
@@ -3541,19 +3777,19 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
|
|
|
3541
3777
|
className: "w-full h-20 object-cover rounded"
|
|
3542
3778
|
}
|
|
3543
3779
|
),
|
|
3544
|
-
/* @__PURE__ */ (0,
|
|
3780
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3545
3781
|
Button,
|
|
3546
3782
|
{
|
|
3547
3783
|
variant: "destructive",
|
|
3548
3784
|
size: "icon",
|
|
3549
3785
|
className: "h-6 w-6",
|
|
3550
3786
|
onClick: onRemove,
|
|
3551
|
-
children: /* @__PURE__ */ (0,
|
|
3787
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.X, { className: "h-3 w-3" })
|
|
3552
3788
|
}
|
|
3553
3789
|
) })
|
|
3554
3790
|
] }),
|
|
3555
|
-
attachment.kind === "video" && /* @__PURE__ */ (0,
|
|
3556
|
-
/* @__PURE__ */ (0,
|
|
3791
|
+
attachment.kind === "video" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "relative", children: [
|
|
3792
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3557
3793
|
"video",
|
|
3558
3794
|
{
|
|
3559
3795
|
src: attachment.dataUrl,
|
|
@@ -3562,34 +3798,34 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
|
|
|
3562
3798
|
muted: true
|
|
3563
3799
|
}
|
|
3564
3800
|
),
|
|
3565
|
-
/* @__PURE__ */ (0,
|
|
3801
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3566
3802
|
Button,
|
|
3567
3803
|
{
|
|
3568
3804
|
variant: "destructive",
|
|
3569
3805
|
size: "icon",
|
|
3570
3806
|
className: "h-6 w-6",
|
|
3571
3807
|
onClick: onRemove,
|
|
3572
|
-
children: /* @__PURE__ */ (0,
|
|
3808
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.X, { className: "h-3 w-3" })
|
|
3573
3809
|
}
|
|
3574
3810
|
) }),
|
|
3575
|
-
/* @__PURE__ */ (0,
|
|
3811
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Badge, { className: "absolute bottom-1 right-1 text-xs", children: formatDuration2(attachment.durationMs) })
|
|
3576
3812
|
] }),
|
|
3577
|
-
attachment.kind === "audio" && /* @__PURE__ */ (0,
|
|
3578
|
-
/* @__PURE__ */ (0,
|
|
3813
|
+
attachment.kind === "audio" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2 p-2", children: [
|
|
3814
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3579
3815
|
Button,
|
|
3580
3816
|
{
|
|
3581
3817
|
variant: "outline",
|
|
3582
3818
|
size: "icon",
|
|
3583
3819
|
className: "h-8 w-8",
|
|
3584
3820
|
onClick: handlePlayPause,
|
|
3585
|
-
children: isPlaying ? /* @__PURE__ */ (0,
|
|
3821
|
+
children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Pause, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Play, { className: "h-3 w-3" })
|
|
3586
3822
|
}
|
|
3587
3823
|
),
|
|
3588
|
-
/* @__PURE__ */ (0,
|
|
3589
|
-
/* @__PURE__ */ (0,
|
|
3590
|
-
/* @__PURE__ */ (0,
|
|
3824
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1", children: [
|
|
3825
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs font-medium", children: attachment.fileName || "Audio" }),
|
|
3826
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs text-muted-foreground", children: formatDuration2(attachment.durationMs) })
|
|
3591
3827
|
] }),
|
|
3592
|
-
/* @__PURE__ */ (0,
|
|
3828
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3593
3829
|
"audio",
|
|
3594
3830
|
{
|
|
3595
3831
|
ref: audioRef,
|
|
@@ -3597,71 +3833,71 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
|
|
|
3597
3833
|
onPause: () => setIsPlaying(false),
|
|
3598
3834
|
onEnded: () => setIsPlaying(false),
|
|
3599
3835
|
preload: "metadata",
|
|
3600
|
-
children: /* @__PURE__ */ (0,
|
|
3836
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("source", { src: audioPlaybackSrc, type: attachment.mimeType })
|
|
3601
3837
|
}
|
|
3602
3838
|
),
|
|
3603
|
-
/* @__PURE__ */ (0,
|
|
3839
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3604
3840
|
Button,
|
|
3605
3841
|
{
|
|
3606
3842
|
variant: "ghost",
|
|
3607
3843
|
size: "icon",
|
|
3608
3844
|
className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
3609
3845
|
onClick: onRemove,
|
|
3610
|
-
children: /* @__PURE__ */ (0,
|
|
3846
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.X, { className: "h-3 w-3" })
|
|
3611
3847
|
}
|
|
3612
3848
|
)
|
|
3613
3849
|
] }),
|
|
3614
|
-
attachment.fileName && attachment.kind !== "audio" && /* @__PURE__ */ (0,
|
|
3850
|
+
attachment.fileName && attachment.kind !== "audio" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute bottom-0 left-0 right-0 bg-black/70 text-white text-xs p-1 rounded-b", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "truncate", children: attachment.fileName }) })
|
|
3615
3851
|
] }) });
|
|
3616
3852
|
});
|
|
3617
|
-
var AudioRecorder = (0,
|
|
3853
|
+
var AudioRecorder = (0, import_react6.memo)(function AudioRecorder2({ isRecording, onStartRecording, onStopRecording, onCancel, recordingDuration, config }) {
|
|
3618
3854
|
const formatTime = (seconds) => {
|
|
3619
3855
|
const mins = Math.floor(seconds / 60);
|
|
3620
3856
|
const secs = seconds % 60;
|
|
3621
3857
|
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
3622
3858
|
};
|
|
3623
3859
|
if (!isRecording) {
|
|
3624
|
-
return /* @__PURE__ */ (0,
|
|
3625
|
-
/* @__PURE__ */ (0,
|
|
3860
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Tooltip, { children: [
|
|
3861
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3626
3862
|
Button,
|
|
3627
3863
|
{
|
|
3628
3864
|
variant: "outline",
|
|
3629
3865
|
size: "icon",
|
|
3630
3866
|
onClick: onStartRecording,
|
|
3631
3867
|
className: "h-10 w-10",
|
|
3632
|
-
children: /* @__PURE__ */ (0,
|
|
3868
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Mic, { className: "h-4 w-4" })
|
|
3633
3869
|
}
|
|
3634
3870
|
) }),
|
|
3635
|
-
/* @__PURE__ */ (0,
|
|
3871
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipContent, { children: config?.labels?.recordAudioTooltip })
|
|
3636
3872
|
] });
|
|
3637
3873
|
}
|
|
3638
|
-
return /* @__PURE__ */ (0,
|
|
3639
|
-
/* @__PURE__ */ (0,
|
|
3640
|
-
/* @__PURE__ */ (0,
|
|
3641
|
-
/* @__PURE__ */ (0,
|
|
3874
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Card, { className: "border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CardContent, { className: "p-3", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
3875
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3876
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "h-3 w-3 bg-red-500 rounded-full animate-pulse" }),
|
|
3877
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-sm font-medium text-red-700 dark:text-red-300", children: config?.labels?.voiceListening || "Recording" })
|
|
3642
3878
|
] }),
|
|
3643
|
-
/* @__PURE__ */ (0,
|
|
3644
|
-
/* @__PURE__ */ (0,
|
|
3645
|
-
/* @__PURE__ */ (0,
|
|
3879
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Badge, { variant: "outline", className: "text-xs", children: formatTime(recordingDuration) }),
|
|
3880
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-1 ml-auto", children: [
|
|
3881
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
3646
3882
|
Button,
|
|
3647
3883
|
{
|
|
3648
3884
|
variant: "outline",
|
|
3649
3885
|
size: "sm",
|
|
3650
3886
|
onClick: onCancel,
|
|
3651
3887
|
children: [
|
|
3652
|
-
/* @__PURE__ */ (0,
|
|
3888
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.X, { className: "h-3 w-3 mr-1" }),
|
|
3653
3889
|
config?.labels?.cancel || "Cancel"
|
|
3654
3890
|
]
|
|
3655
3891
|
}
|
|
3656
3892
|
),
|
|
3657
|
-
/* @__PURE__ */ (0,
|
|
3893
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
3658
3894
|
Button,
|
|
3659
3895
|
{
|
|
3660
3896
|
variant: "default",
|
|
3661
3897
|
size: "sm",
|
|
3662
3898
|
onClick: onStopRecording,
|
|
3663
3899
|
children: [
|
|
3664
|
-
/* @__PURE__ */ (0,
|
|
3900
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Square, { className: "h-3 w-3 mr-1" }),
|
|
3665
3901
|
config?.labels?.voiceStop || "Stop"
|
|
3666
3902
|
]
|
|
3667
3903
|
}
|
|
@@ -3680,7 +3916,7 @@ var resolveVoiceErrorMessage = (error, config) => {
|
|
|
3680
3916
|
};
|
|
3681
3917
|
var clearVoiceTranscript = () => ({});
|
|
3682
3918
|
var resolveVoiceSegmentDuration = (segment) => segment.attachment.durationMs ?? 0;
|
|
3683
|
-
var ChatInput = (0,
|
|
3919
|
+
var ChatInput = (0, import_react6.memo)(function ChatInput2({
|
|
3684
3920
|
value,
|
|
3685
3921
|
onChange,
|
|
3686
3922
|
onSubmit,
|
|
@@ -3697,7 +3933,9 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
3697
3933
|
// 10MB
|
|
3698
3934
|
acceptedFileTypes = ["image/*", "video/*", "audio/*"],
|
|
3699
3935
|
className = "",
|
|
3700
|
-
config
|
|
3936
|
+
config,
|
|
3937
|
+
mentionAgents = [],
|
|
3938
|
+
onTargetAgentChange
|
|
3701
3939
|
}) {
|
|
3702
3940
|
const voiceComposeEnabled = config?.voiceCompose?.enabled === true;
|
|
3703
3941
|
const voiceDefaultMode = config?.voiceCompose?.defaultMode ?? "text";
|
|
@@ -3707,32 +3945,63 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
3707
3945
|
const voiceShowTranscriptPreview = config?.voiceCompose?.showTranscriptPreview ?? true;
|
|
3708
3946
|
const voiceTranscriptMode = config?.voiceCompose?.transcriptMode ?? "final-only";
|
|
3709
3947
|
const voiceMaxRecordingMs = config?.voiceCompose?.maxRecordingMs;
|
|
3710
|
-
const [isRecording, setIsRecording] = (0,
|
|
3948
|
+
const [isRecording, setIsRecording] = (0, import_react6.useState)(false);
|
|
3711
3949
|
const { setContext } = useChatUserContext();
|
|
3712
|
-
const [recordingDuration, setRecordingDuration] = (0,
|
|
3713
|
-
const [uploadProgress, setUploadProgress] = (0,
|
|
3714
|
-
const [isVoiceComposerOpen, setIsVoiceComposerOpen] = (0,
|
|
3950
|
+
const [recordingDuration, setRecordingDuration] = (0, import_react6.useState)(0);
|
|
3951
|
+
const [uploadProgress, setUploadProgress] = (0, import_react6.useState)(/* @__PURE__ */ new Map());
|
|
3952
|
+
const [isVoiceComposerOpen, setIsVoiceComposerOpen] = (0, import_react6.useState)(
|
|
3715
3953
|
() => voiceComposeEnabled && voiceDefaultMode === "voice"
|
|
3716
3954
|
);
|
|
3717
|
-
const [voiceState, setVoiceState] = (0,
|
|
3718
|
-
const [voiceDraft, setVoiceDraft] = (0,
|
|
3719
|
-
const [voiceTranscript, setVoiceTranscript] = (0,
|
|
3720
|
-
const [voiceDurationMs, setVoiceDurationMs] = (0,
|
|
3721
|
-
const [voiceAudioLevel, setVoiceAudioLevel] = (0,
|
|
3722
|
-
const [voiceCountdownMs, setVoiceCountdownMs] = (0,
|
|
3723
|
-
const [isVoiceAutoSendActive, setIsVoiceAutoSendActive] = (0,
|
|
3724
|
-
const [voiceError, setVoiceError] = (0,
|
|
3725
|
-
const
|
|
3726
|
-
const
|
|
3727
|
-
const
|
|
3728
|
-
const
|
|
3729
|
-
const
|
|
3730
|
-
const
|
|
3731
|
-
const
|
|
3732
|
-
const
|
|
3733
|
-
const
|
|
3734
|
-
const
|
|
3735
|
-
(0,
|
|
3955
|
+
const [voiceState, setVoiceState] = (0, import_react6.useState)("idle");
|
|
3956
|
+
const [voiceDraft, setVoiceDraft] = (0, import_react6.useState)(null);
|
|
3957
|
+
const [voiceTranscript, setVoiceTranscript] = (0, import_react6.useState)(clearVoiceTranscript);
|
|
3958
|
+
const [voiceDurationMs, setVoiceDurationMs] = (0, import_react6.useState)(0);
|
|
3959
|
+
const [voiceAudioLevel, setVoiceAudioLevel] = (0, import_react6.useState)(0);
|
|
3960
|
+
const [voiceCountdownMs, setVoiceCountdownMs] = (0, import_react6.useState)(0);
|
|
3961
|
+
const [isVoiceAutoSendActive, setIsVoiceAutoSendActive] = (0, import_react6.useState)(false);
|
|
3962
|
+
const [voiceError, setVoiceError] = (0, import_react6.useState)(null);
|
|
3963
|
+
const [activeMention, setActiveMention] = (0, import_react6.useState)(null);
|
|
3964
|
+
const [activeMentionIndex, setActiveMentionIndex] = (0, import_react6.useState)(0);
|
|
3965
|
+
const textareaRef = (0, import_react6.useRef)(null);
|
|
3966
|
+
const fileInputRef = (0, import_react6.useRef)(null);
|
|
3967
|
+
const mediaRecorderRef = (0, import_react6.useRef)(null);
|
|
3968
|
+
const recordingStartTime = (0, import_react6.useRef)(0);
|
|
3969
|
+
const recordingInterval = (0, import_react6.useRef)(null);
|
|
3970
|
+
const mediaStreamRef = (0, import_react6.useRef)(null);
|
|
3971
|
+
const voiceProviderRef = (0, import_react6.useRef)(null);
|
|
3972
|
+
const voiceDraftRef = (0, import_react6.useRef)(null);
|
|
3973
|
+
const voiceAppendBaseRef = (0, import_react6.useRef)(null);
|
|
3974
|
+
const voiceAppendBaseDurationRef = (0, import_react6.useRef)(0);
|
|
3975
|
+
const filteredMentionAgents = import_react6.default.useMemo(() => {
|
|
3976
|
+
if (!activeMention || mentionAgents.length === 0) return [];
|
|
3977
|
+
const query = activeMention.query.trim().toLowerCase();
|
|
3978
|
+
const rank = (agent) => {
|
|
3979
|
+
const id = agent.id.toLowerCase();
|
|
3980
|
+
const name = agent.name.toLowerCase();
|
|
3981
|
+
if (!query) return 0;
|
|
3982
|
+
if (name.startsWith(query) || id.startsWith(query)) return 0;
|
|
3983
|
+
if (name.includes(query) || id.includes(query)) return 1;
|
|
3984
|
+
return 2;
|
|
3985
|
+
};
|
|
3986
|
+
return mentionAgents.filter((agent) => rank(agent) < 2).sort((left, right) => {
|
|
3987
|
+
const rankDiff = rank(left) - rank(right);
|
|
3988
|
+
if (rankDiff !== 0) return rankDiff;
|
|
3989
|
+
return left.name.localeCompare(right.name);
|
|
3990
|
+
}).slice(0, 6);
|
|
3991
|
+
}, [activeMention, mentionAgents]);
|
|
3992
|
+
const isMentionMenuOpen = filteredMentionAgents.length > 0;
|
|
3993
|
+
const syncMentionState = (0, import_react6.useCallback)((nextValue, nextCaret) => {
|
|
3994
|
+
const caret = typeof nextCaret === "number" ? nextCaret : textareaRef.current?.selectionStart ?? nextValue.length;
|
|
3995
|
+
const nextMatch = getActiveMentionMatch(nextValue, caret);
|
|
3996
|
+
setActiveMention((prev) => {
|
|
3997
|
+
if (prev?.start === nextMatch?.start && prev?.end === nextMatch?.end && prev?.query === nextMatch?.query) {
|
|
3998
|
+
return prev;
|
|
3999
|
+
}
|
|
4000
|
+
return nextMatch;
|
|
4001
|
+
});
|
|
4002
|
+
setActiveMentionIndex(0);
|
|
4003
|
+
}, []);
|
|
4004
|
+
(0, import_react6.useEffect)(() => {
|
|
3736
4005
|
return () => {
|
|
3737
4006
|
if (mediaStreamRef.current) {
|
|
3738
4007
|
mediaStreamRef.current.getTracks().forEach((track) => track.stop());
|
|
@@ -3746,17 +4015,73 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
3746
4015
|
}
|
|
3747
4016
|
};
|
|
3748
4017
|
}, []);
|
|
3749
|
-
(0,
|
|
4018
|
+
(0, import_react6.useEffect)(() => {
|
|
3750
4019
|
voiceDraftRef.current = voiceDraft;
|
|
3751
4020
|
}, [voiceDraft]);
|
|
4021
|
+
(0, import_react6.useEffect)(() => {
|
|
4022
|
+
if (!isMentionMenuOpen) {
|
|
4023
|
+
setActiveMentionIndex(0);
|
|
4024
|
+
return;
|
|
4025
|
+
}
|
|
4026
|
+
setActiveMentionIndex(
|
|
4027
|
+
(prev) => prev >= filteredMentionAgents.length ? 0 : prev
|
|
4028
|
+
);
|
|
4029
|
+
}, [filteredMentionAgents.length, isMentionMenuOpen]);
|
|
4030
|
+
const selectMentionAgent = (0, import_react6.useCallback)((agent) => {
|
|
4031
|
+
if (!activeMention) return;
|
|
4032
|
+
const replacement = `@${agent.name} `;
|
|
4033
|
+
const nextValue = value.slice(0, activeMention.start) + replacement + value.slice(activeMention.end);
|
|
4034
|
+
const nextCaret = activeMention.start + replacement.length;
|
|
4035
|
+
onChange(nextValue);
|
|
4036
|
+
onTargetAgentChange?.(agent.id);
|
|
4037
|
+
setActiveMention(null);
|
|
4038
|
+
setActiveMentionIndex(0);
|
|
4039
|
+
requestAnimationFrame(() => {
|
|
4040
|
+
textareaRef.current?.focus();
|
|
4041
|
+
textareaRef.current?.setSelectionRange(nextCaret, nextCaret);
|
|
4042
|
+
});
|
|
4043
|
+
}, [activeMention, onChange, onTargetAgentChange, value]);
|
|
3752
4044
|
const handleSubmit = (e) => {
|
|
3753
4045
|
e.preventDefault();
|
|
3754
4046
|
if (!value.trim() && attachments.length === 0 || disabled || isGenerating) return;
|
|
4047
|
+
const mentionedAgent = resolveTargetFromMentions(value, mentionAgents);
|
|
4048
|
+
if (mentionedAgent) {
|
|
4049
|
+
onTargetAgentChange?.(mentionedAgent.id);
|
|
4050
|
+
}
|
|
3755
4051
|
onSubmit(value.trim(), attachments);
|
|
3756
4052
|
onChange("");
|
|
3757
4053
|
onAttachmentsChange([]);
|
|
4054
|
+
setActiveMention(null);
|
|
4055
|
+
setActiveMentionIndex(0);
|
|
3758
4056
|
};
|
|
3759
4057
|
const handleKeyDown = (e) => {
|
|
4058
|
+
if (isMentionMenuOpen) {
|
|
4059
|
+
if (e.key === "ArrowDown") {
|
|
4060
|
+
e.preventDefault();
|
|
4061
|
+
setActiveMentionIndex(
|
|
4062
|
+
(prev) => prev >= filteredMentionAgents.length - 1 ? 0 : prev + 1
|
|
4063
|
+
);
|
|
4064
|
+
return;
|
|
4065
|
+
}
|
|
4066
|
+
if (e.key === "ArrowUp") {
|
|
4067
|
+
e.preventDefault();
|
|
4068
|
+
setActiveMentionIndex(
|
|
4069
|
+
(prev) => prev <= 0 ? filteredMentionAgents.length - 1 : prev - 1
|
|
4070
|
+
);
|
|
4071
|
+
return;
|
|
4072
|
+
}
|
|
4073
|
+
if ((e.key === "Enter" || e.key === "Tab") && filteredMentionAgents[activeMentionIndex]) {
|
|
4074
|
+
e.preventDefault();
|
|
4075
|
+
selectMentionAgent(filteredMentionAgents[activeMentionIndex]);
|
|
4076
|
+
return;
|
|
4077
|
+
}
|
|
4078
|
+
if (e.key === "Escape") {
|
|
4079
|
+
e.preventDefault();
|
|
4080
|
+
setActiveMention(null);
|
|
4081
|
+
setActiveMentionIndex(0);
|
|
4082
|
+
return;
|
|
4083
|
+
}
|
|
4084
|
+
}
|
|
3760
4085
|
if (e.key === "Enter" && !e.shiftKey && !e.ctrlKey && window.innerWidth > 768) {
|
|
3761
4086
|
e.preventDefault();
|
|
3762
4087
|
handleSubmit(e);
|
|
@@ -3840,7 +4165,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
3840
4165
|
}
|
|
3841
4166
|
e.target.value = "";
|
|
3842
4167
|
};
|
|
3843
|
-
const handleDrop = (0,
|
|
4168
|
+
const handleDrop = (0, import_react6.useCallback)(async (e) => {
|
|
3844
4169
|
e.preventDefault();
|
|
3845
4170
|
if (!enableFileUpload) return;
|
|
3846
4171
|
const files = Array.from(e.dataTransfer.files);
|
|
@@ -3853,7 +4178,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
3853
4178
|
}
|
|
3854
4179
|
}
|
|
3855
4180
|
}, [attachments, enableFileUpload, maxAttachments, onAttachmentsChange]);
|
|
3856
|
-
const handleDragOver = (0,
|
|
4181
|
+
const handleDragOver = (0, import_react6.useCallback)((e) => {
|
|
3857
4182
|
e.preventDefault();
|
|
3858
4183
|
}, []);
|
|
3859
4184
|
const startRecording = async () => {
|
|
@@ -3923,7 +4248,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
3923
4248
|
}
|
|
3924
4249
|
}
|
|
3925
4250
|
};
|
|
3926
|
-
const resetVoiceComposerState = (0,
|
|
4251
|
+
const resetVoiceComposerState = (0, import_react6.useCallback)((nextState = "idle") => {
|
|
3927
4252
|
setVoiceState(nextState);
|
|
3928
4253
|
setVoiceDraft(null);
|
|
3929
4254
|
voiceDraftRef.current = null;
|
|
@@ -3936,11 +4261,11 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
3936
4261
|
setIsVoiceAutoSendActive(false);
|
|
3937
4262
|
setVoiceError(null);
|
|
3938
4263
|
}, []);
|
|
3939
|
-
const armVoiceDraftForAppend = (0,
|
|
4264
|
+
const armVoiceDraftForAppend = (0, import_react6.useCallback)((segment) => {
|
|
3940
4265
|
voiceAppendBaseRef.current = segment;
|
|
3941
4266
|
voiceAppendBaseDurationRef.current = segment ? resolveVoiceSegmentDuration(segment) : 0;
|
|
3942
4267
|
}, []);
|
|
3943
|
-
const handleVoiceProviderStateChange = (0,
|
|
4268
|
+
const handleVoiceProviderStateChange = (0, import_react6.useCallback)((nextState) => {
|
|
3944
4269
|
if (voiceReviewMode === "armed" && (nextState === "waiting_for_speech" || nextState === "listening")) {
|
|
3945
4270
|
const currentDraft = voiceDraftRef.current;
|
|
3946
4271
|
if (currentDraft) {
|
|
@@ -3953,7 +4278,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
3953
4278
|
}
|
|
3954
4279
|
setVoiceState(nextState);
|
|
3955
4280
|
}, [armVoiceDraftForAppend, voiceAutoSendDelayMs, voiceReviewMode]);
|
|
3956
|
-
const ensureVoiceProvider = (0,
|
|
4281
|
+
const ensureVoiceProvider = (0, import_react6.useCallback)(async () => {
|
|
3957
4282
|
if (voiceProviderRef.current) {
|
|
3958
4283
|
return voiceProviderRef.current;
|
|
3959
4284
|
}
|
|
@@ -4040,7 +4365,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4040
4365
|
voiceProviderRef.current = provider;
|
|
4041
4366
|
return provider;
|
|
4042
4367
|
}, [armVoiceDraftForAppend, config, handleVoiceProviderStateChange, voiceAutoSendDelayMs, voiceMaxRecordingMs, voiceReviewMode]);
|
|
4043
|
-
const closeVoiceComposer = (0,
|
|
4368
|
+
const closeVoiceComposer = (0, import_react6.useCallback)(async () => {
|
|
4044
4369
|
voiceAppendBaseRef.current = null;
|
|
4045
4370
|
voiceAppendBaseDurationRef.current = 0;
|
|
4046
4371
|
setIsVoiceComposerOpen(false);
|
|
@@ -4056,7 +4381,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4056
4381
|
await voiceProviderRef.current.cancel();
|
|
4057
4382
|
}
|
|
4058
4383
|
}, []);
|
|
4059
|
-
const startVoiceCapture = (0,
|
|
4384
|
+
const startVoiceCapture = (0, import_react6.useCallback)(async (appendToDraft = false) => {
|
|
4060
4385
|
if (disabled || isGenerating) {
|
|
4061
4386
|
return;
|
|
4062
4387
|
}
|
|
@@ -4105,7 +4430,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4105
4430
|
setVoiceState("error");
|
|
4106
4431
|
}
|
|
4107
4432
|
}, [disabled, isGenerating, ensureVoiceProvider, config]);
|
|
4108
|
-
const stopVoiceCapture = (0,
|
|
4433
|
+
const stopVoiceCapture = (0, import_react6.useCallback)(async () => {
|
|
4109
4434
|
if (!voiceProviderRef.current) return;
|
|
4110
4435
|
try {
|
|
4111
4436
|
await voiceProviderRef.current.stop();
|
|
@@ -4114,7 +4439,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4114
4439
|
setVoiceState("error");
|
|
4115
4440
|
}
|
|
4116
4441
|
}, [config]);
|
|
4117
|
-
const cancelVoiceCapture = (0,
|
|
4442
|
+
const cancelVoiceCapture = (0, import_react6.useCallback)(async () => {
|
|
4118
4443
|
voiceAppendBaseRef.current = null;
|
|
4119
4444
|
voiceAppendBaseDurationRef.current = 0;
|
|
4120
4445
|
if (voiceProviderRef.current) {
|
|
@@ -4122,7 +4447,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4122
4447
|
}
|
|
4123
4448
|
resetVoiceComposerState("idle");
|
|
4124
4449
|
}, [resetVoiceComposerState]);
|
|
4125
|
-
const finalizeVoiceComposerAfterSend = (0,
|
|
4450
|
+
const finalizeVoiceComposerAfterSend = (0, import_react6.useCallback)(() => {
|
|
4126
4451
|
if (voicePersistComposer) {
|
|
4127
4452
|
resetVoiceComposerState("idle");
|
|
4128
4453
|
setIsVoiceComposerOpen(true);
|
|
@@ -4130,7 +4455,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4130
4455
|
}
|
|
4131
4456
|
void closeVoiceComposer();
|
|
4132
4457
|
}, [voicePersistComposer, resetVoiceComposerState, closeVoiceComposer]);
|
|
4133
|
-
const sendVoiceDraft = (0,
|
|
4458
|
+
const sendVoiceDraft = (0, import_react6.useCallback)(() => {
|
|
4134
4459
|
void (async () => {
|
|
4135
4460
|
if (!voiceDraft || disabled || isGenerating) {
|
|
4136
4461
|
return;
|
|
@@ -4156,7 +4481,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4156
4481
|
onAttachmentsChange,
|
|
4157
4482
|
finalizeVoiceComposerAfterSend
|
|
4158
4483
|
]);
|
|
4159
|
-
const cancelVoiceAutoSend = (0,
|
|
4484
|
+
const cancelVoiceAutoSend = (0, import_react6.useCallback)(() => {
|
|
4160
4485
|
void (async () => {
|
|
4161
4486
|
if (voiceReviewMode === "armed" && voiceProviderRef.current) {
|
|
4162
4487
|
await voiceProviderRef.current.cancel();
|
|
@@ -4168,7 +4493,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4168
4493
|
setVoiceCountdownMs(0);
|
|
4169
4494
|
setIsVoiceAutoSendActive(false);
|
|
4170
4495
|
}, [armVoiceDraftForAppend, voiceReviewMode]);
|
|
4171
|
-
const pauseVoiceReview = (0,
|
|
4496
|
+
const pauseVoiceReview = (0, import_react6.useCallback)(async () => {
|
|
4172
4497
|
if (voiceState === "listening") {
|
|
4173
4498
|
await stopVoiceCapture();
|
|
4174
4499
|
return;
|
|
@@ -4180,7 +4505,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4180
4505
|
setVoiceAudioLevel(0);
|
|
4181
4506
|
setVoiceState("review");
|
|
4182
4507
|
}, [armVoiceDraftForAppend, stopVoiceCapture, voiceReviewMode, voiceState]);
|
|
4183
|
-
(0,
|
|
4508
|
+
(0, import_react6.useEffect)(() => {
|
|
4184
4509
|
if (!voiceDraft || voiceAutoSendDelayMs <= 0 || !isVoiceAutoSendActive) {
|
|
4185
4510
|
return;
|
|
4186
4511
|
}
|
|
@@ -4208,8 +4533,8 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4208
4533
|
};
|
|
4209
4534
|
const canAddMoreAttachments = attachments.length < maxAttachments;
|
|
4210
4535
|
const showVoiceComposer = voiceComposeEnabled && isVoiceComposerOpen;
|
|
4211
|
-
return /* @__PURE__ */ (0,
|
|
4212
|
-
uploadProgress.size > 0 && /* @__PURE__ */ (0,
|
|
4536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: `border-t py-0 bg-transparent ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "px-0 md:p-2 pb-1 space-y-4 bg-transparent", children: [
|
|
4537
|
+
uploadProgress.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "space-y-2", children: Array.from(uploadProgress.entries()).map(([id, progress]) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4213
4538
|
FileUploadItem,
|
|
4214
4539
|
{
|
|
4215
4540
|
file: { name: progress.fileName },
|
|
@@ -4224,7 +4549,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4224
4549
|
},
|
|
4225
4550
|
id
|
|
4226
4551
|
)) }),
|
|
4227
|
-
isRecording && /* @__PURE__ */ (0,
|
|
4552
|
+
isRecording && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4228
4553
|
AudioRecorder,
|
|
4229
4554
|
{
|
|
4230
4555
|
isRecording,
|
|
@@ -4235,7 +4560,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4235
4560
|
config
|
|
4236
4561
|
}
|
|
4237
4562
|
),
|
|
4238
|
-
attachments.length > 0 && /* @__PURE__ */ (0,
|
|
4563
|
+
attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "grid grid-cols-4 gap-2", children: attachments.map((attachment, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4239
4564
|
AttachmentPreview,
|
|
4240
4565
|
{
|
|
4241
4566
|
attachment,
|
|
@@ -4243,7 +4568,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4243
4568
|
},
|
|
4244
4569
|
index
|
|
4245
4570
|
)) }),
|
|
4246
|
-
showVoiceComposer ? /* @__PURE__ */ (0,
|
|
4571
|
+
showVoiceComposer ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mb-1 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4247
4572
|
VoiceComposer,
|
|
4248
4573
|
{
|
|
4249
4574
|
state: voiceState,
|
|
@@ -4283,15 +4608,15 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4283
4608
|
void closeVoiceComposer();
|
|
4284
4609
|
}
|
|
4285
4610
|
}
|
|
4286
|
-
) }) : /* @__PURE__ */ (0,
|
|
4611
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("form", { onSubmit: handleSubmit, className: "mb-1 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
4287
4612
|
"div",
|
|
4288
4613
|
{
|
|
4289
4614
|
className: "flex items-end gap-2 p-3 border rounded-lg bg-background w-full md:min-w-3xl max-w-3xl",
|
|
4290
4615
|
onDrop: handleDrop,
|
|
4291
4616
|
onDragOver: handleDragOver,
|
|
4292
4617
|
children: [
|
|
4293
|
-
enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ (0,
|
|
4294
|
-
/* @__PURE__ */ (0,
|
|
4618
|
+
enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4619
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4295
4620
|
"input",
|
|
4296
4621
|
{
|
|
4297
4622
|
ref: fileInputRef,
|
|
@@ -4302,8 +4627,8 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4302
4627
|
className: "hidden"
|
|
4303
4628
|
}
|
|
4304
4629
|
),
|
|
4305
|
-
/* @__PURE__ */ (0,
|
|
4306
|
-
/* @__PURE__ */ (0,
|
|
4630
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Tooltip, { children: [
|
|
4631
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4307
4632
|
Button,
|
|
4308
4633
|
{
|
|
4309
4634
|
type: "button",
|
|
@@ -4316,27 +4641,56 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4316
4641
|
fileInputRef.current?.click();
|
|
4317
4642
|
},
|
|
4318
4643
|
disabled,
|
|
4319
|
-
children: /* @__PURE__ */ (0,
|
|
4644
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Paperclip, { className: "h-4 w-4" })
|
|
4320
4645
|
}
|
|
4321
4646
|
) }),
|
|
4322
|
-
/* @__PURE__ */ (0,
|
|
4647
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipContent, { children: config?.labels?.attachFileTooltip })
|
|
4323
4648
|
] })
|
|
4324
4649
|
] }),
|
|
4325
|
-
/* @__PURE__ */ (0,
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4650
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "relative flex-1", children: [
|
|
4651
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4652
|
+
Textarea,
|
|
4653
|
+
{
|
|
4654
|
+
ref: textareaRef,
|
|
4655
|
+
value,
|
|
4656
|
+
onChange: (e) => {
|
|
4657
|
+
onChange(e.target.value);
|
|
4658
|
+
syncMentionState(e.target.value, e.target.selectionStart ?? e.target.value.length);
|
|
4659
|
+
},
|
|
4660
|
+
onSelect: (e) => {
|
|
4661
|
+
const target = e.target;
|
|
4662
|
+
syncMentionState(target.value, target.selectionStart ?? target.value.length);
|
|
4663
|
+
},
|
|
4664
|
+
onClick: (e) => {
|
|
4665
|
+
const target = e.target;
|
|
4666
|
+
syncMentionState(target.value, target.selectionStart ?? target.value.length);
|
|
4667
|
+
},
|
|
4668
|
+
onKeyDown: handleKeyDown,
|
|
4669
|
+
placeholder,
|
|
4670
|
+
disabled,
|
|
4671
|
+
className: "max-h-[120px] resize-none border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0",
|
|
4672
|
+
rows: 1
|
|
4673
|
+
}
|
|
4674
|
+
),
|
|
4675
|
+
isMentionMenuOpen && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute bottom-full left-0 right-0 mb-2 overflow-hidden rounded-md border bg-popover shadow-md", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "p-1", children: filteredMentionAgents.map((agent, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
4676
|
+
"button",
|
|
4677
|
+
{
|
|
4678
|
+
type: "button",
|
|
4679
|
+
className: `flex w-full items-center gap-2 rounded-sm px-3 py-2 text-left text-sm ${index === activeMentionIndex ? "bg-accent text-accent-foreground" : "hover:bg-accent/60"}`,
|
|
4680
|
+
onMouseDown: (mouseEvent) => {
|
|
4681
|
+
mouseEvent.preventDefault();
|
|
4682
|
+
selectMentionAgent(agent);
|
|
4683
|
+
},
|
|
4684
|
+
children: [
|
|
4685
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "font-medium", children: agent.name }),
|
|
4686
|
+
agent.description && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: agent.description })
|
|
4687
|
+
]
|
|
4688
|
+
},
|
|
4689
|
+
agent.id
|
|
4690
|
+
)) }) })
|
|
4691
|
+
] }),
|
|
4692
|
+
enableAudioRecording && !isRecording && canAddMoreAttachments && !value.trim() && (voiceComposeEnabled ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Tooltip, { children: [
|
|
4693
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4340
4694
|
Button,
|
|
4341
4695
|
{
|
|
4342
4696
|
type: "button",
|
|
@@ -4347,11 +4701,11 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4347
4701
|
void startVoiceCapture();
|
|
4348
4702
|
},
|
|
4349
4703
|
disabled: disabled || isGenerating,
|
|
4350
|
-
children: /* @__PURE__ */ (0,
|
|
4704
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Mic, { className: "h-4 w-4" })
|
|
4351
4705
|
}
|
|
4352
4706
|
) }),
|
|
4353
|
-
/* @__PURE__ */ (0,
|
|
4354
|
-
] }) : /* @__PURE__ */ (0,
|
|
4707
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipContent, { children: config?.labels?.voiceEnter || config?.labels?.recordAudioTooltip })
|
|
4708
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4355
4709
|
AudioRecorder,
|
|
4356
4710
|
{
|
|
4357
4711
|
isRecording,
|
|
@@ -4362,8 +4716,8 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4362
4716
|
config
|
|
4363
4717
|
}
|
|
4364
4718
|
)),
|
|
4365
|
-
isGenerating ? /* @__PURE__ */ (0,
|
|
4366
|
-
/* @__PURE__ */ (0,
|
|
4719
|
+
isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Tooltip, { children: [
|
|
4720
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4367
4721
|
Button,
|
|
4368
4722
|
{
|
|
4369
4723
|
type: "button",
|
|
@@ -4371,36 +4725,36 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4371
4725
|
size: "icon",
|
|
4372
4726
|
className: "h-10 w-10",
|
|
4373
4727
|
onClick: onStopGeneration,
|
|
4374
|
-
children: /* @__PURE__ */ (0,
|
|
4728
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Square, { className: "h-4 w-4" })
|
|
4375
4729
|
}
|
|
4376
4730
|
) }),
|
|
4377
|
-
/* @__PURE__ */ (0,
|
|
4378
|
-
] }) : /* @__PURE__ */ (0,
|
|
4379
|
-
/* @__PURE__ */ (0,
|
|
4731
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
|
|
4732
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Tooltip, { children: [
|
|
4733
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4380
4734
|
Button,
|
|
4381
4735
|
{
|
|
4382
4736
|
type: "submit",
|
|
4383
4737
|
size: "icon",
|
|
4384
4738
|
className: "h-10 w-10",
|
|
4385
4739
|
disabled: disabled || !value.trim() && attachments.length === 0,
|
|
4386
|
-
children: disabled ? /* @__PURE__ */ (0,
|
|
4740
|
+
children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Send, { className: "h-4 w-4" })
|
|
4387
4741
|
}
|
|
4388
4742
|
) }),
|
|
4389
|
-
/* @__PURE__ */ (0,
|
|
4743
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipContent, { children: config?.labels?.sendMessageTooltip })
|
|
4390
4744
|
] })
|
|
4391
4745
|
]
|
|
4392
4746
|
}
|
|
4393
4747
|
) }),
|
|
4394
|
-
/* @__PURE__ */ (0,
|
|
4748
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "text-[10px] text-muted-foreground text-center", children: [
|
|
4395
4749
|
window.innerWidth > 768 ? config?.labels?.inputHelpText : "",
|
|
4396
|
-
attachments.length > 0 && /* @__PURE__ */ (0,
|
|
4750
|
+
attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4397
4751
|
" \u2022 ",
|
|
4398
4752
|
attachments.length,
|
|
4399
4753
|
"/",
|
|
4400
4754
|
maxAttachments,
|
|
4401
4755
|
" anexos"
|
|
4402
4756
|
] }),
|
|
4403
|
-
config?.labels?.footerLabel && /* @__PURE__ */ (0,
|
|
4757
|
+
config?.labels?.footerLabel && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4404
4758
|
" \u2022 ",
|
|
4405
4759
|
config.labels.footerLabel
|
|
4406
4760
|
] })
|
|
@@ -4409,21 +4763,21 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
|
|
|
4409
4763
|
});
|
|
4410
4764
|
|
|
4411
4765
|
// src/components/chat/UserProfile.tsx
|
|
4412
|
-
var
|
|
4766
|
+
var import_react7 = require("react");
|
|
4413
4767
|
|
|
4414
4768
|
// src/components/ui/scroll-area.tsx
|
|
4415
|
-
var
|
|
4769
|
+
var React12 = __toESM(require("react"), 1);
|
|
4416
4770
|
var ScrollAreaPrimitive = __toESM(require("@radix-ui/react-scroll-area"), 1);
|
|
4417
|
-
var
|
|
4418
|
-
var ScrollArea =
|
|
4419
|
-
return /* @__PURE__ */ (0,
|
|
4771
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
4772
|
+
var ScrollArea = React12.forwardRef(({ className, children, viewportClassName, onScroll, onScrollCapture, ...props }, ref) => {
|
|
4773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
4420
4774
|
ScrollAreaPrimitive.Root,
|
|
4421
4775
|
{
|
|
4422
4776
|
"data-slot": "scroll-area",
|
|
4423
4777
|
className: cn("relative", className),
|
|
4424
4778
|
...props,
|
|
4425
4779
|
children: [
|
|
4426
|
-
/* @__PURE__ */ (0,
|
|
4780
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4427
4781
|
ScrollAreaPrimitive.Viewport,
|
|
4428
4782
|
{
|
|
4429
4783
|
ref,
|
|
@@ -4437,8 +4791,8 @@ var ScrollArea = React11.forwardRef(({ className, children, viewportClassName, o
|
|
|
4437
4791
|
children
|
|
4438
4792
|
}
|
|
4439
4793
|
),
|
|
4440
|
-
/* @__PURE__ */ (0,
|
|
4441
|
-
/* @__PURE__ */ (0,
|
|
4794
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ScrollBar, {}),
|
|
4795
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ScrollAreaPrimitive.Corner, {})
|
|
4442
4796
|
]
|
|
4443
4797
|
}
|
|
4444
4798
|
);
|
|
@@ -4449,7 +4803,7 @@ function ScrollBar({
|
|
|
4449
4803
|
orientation = "vertical",
|
|
4450
4804
|
...props
|
|
4451
4805
|
}) {
|
|
4452
|
-
return /* @__PURE__ */ (0,
|
|
4806
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4453
4807
|
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
4454
4808
|
{
|
|
4455
4809
|
"data-slot": "scroll-area-scrollbar",
|
|
@@ -4461,7 +4815,7 @@ function ScrollBar({
|
|
|
4461
4815
|
className
|
|
4462
4816
|
),
|
|
4463
4817
|
...props,
|
|
4464
|
-
children: /* @__PURE__ */ (0,
|
|
4818
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4465
4819
|
ScrollAreaPrimitive.ScrollAreaThumb,
|
|
4466
4820
|
{
|
|
4467
4821
|
"data-slot": "scroll-area-thumb",
|
|
@@ -4473,8 +4827,8 @@ function ScrollBar({
|
|
|
4473
4827
|
}
|
|
4474
4828
|
|
|
4475
4829
|
// src/components/chat/UserProfile.tsx
|
|
4476
|
-
var
|
|
4477
|
-
var
|
|
4830
|
+
var import_lucide_react12 = require("lucide-react");
|
|
4831
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4478
4832
|
var getInitials2 = (name, email) => {
|
|
4479
4833
|
if (name) {
|
|
4480
4834
|
return name.split(" ").map((n) => n[0]).slice(0, 2).join("").toUpperCase();
|
|
@@ -4488,29 +4842,29 @@ var getFieldIcon = (type, key) => {
|
|
|
4488
4842
|
const iconClass = "h-4 w-4 text-muted-foreground";
|
|
4489
4843
|
switch (type) {
|
|
4490
4844
|
case "email":
|
|
4491
|
-
return /* @__PURE__ */ (0,
|
|
4845
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Mail, { className: iconClass });
|
|
4492
4846
|
case "phone":
|
|
4493
|
-
return /* @__PURE__ */ (0,
|
|
4847
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Phone, { className: iconClass });
|
|
4494
4848
|
case "url":
|
|
4495
|
-
return /* @__PURE__ */ (0,
|
|
4849
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Globe, { className: iconClass });
|
|
4496
4850
|
case "date":
|
|
4497
|
-
return /* @__PURE__ */ (0,
|
|
4851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Calendar, { className: iconClass });
|
|
4498
4852
|
}
|
|
4499
4853
|
const lowerKey = key?.toLowerCase() || "";
|
|
4500
|
-
if (lowerKey.includes("follower")) return /* @__PURE__ */ (0,
|
|
4501
|
-
if (lowerKey.includes("following")) return /* @__PURE__ */ (0,
|
|
4502
|
-
if (lowerKey.includes("post") || lowerKey.includes("publication")) return /* @__PURE__ */ (0,
|
|
4503
|
-
if (lowerKey.includes("verified") || lowerKey.includes("badge")) return /* @__PURE__ */ (0,
|
|
4504
|
-
if (lowerKey.includes("bio")) return /* @__PURE__ */ (0,
|
|
4505
|
-
if (lowerKey.includes("email")) return /* @__PURE__ */ (0,
|
|
4506
|
-
if (lowerKey.includes("phone") || lowerKey.includes("tel")) return /* @__PURE__ */ (0,
|
|
4507
|
-
if (lowerKey.includes("location") || lowerKey.includes("address") || lowerKey.includes("city")) return /* @__PURE__ */ (0,
|
|
4508
|
-
if (lowerKey.includes("company") || lowerKey.includes("org")) return /* @__PURE__ */ (0,
|
|
4509
|
-
if (lowerKey.includes("job") || lowerKey.includes("role") || lowerKey.includes("title") || lowerKey.includes("position")) return /* @__PURE__ */ (0,
|
|
4510
|
-
if (lowerKey.includes("website") || lowerKey.includes("url") || lowerKey.includes("link")) return /* @__PURE__ */ (0,
|
|
4511
|
-
if (lowerKey.includes("username") || lowerKey.includes("handle")) return /* @__PURE__ */ (0,
|
|
4512
|
-
if (lowerKey.includes("date") || lowerKey.includes("birthday") || lowerKey.includes("joined")) return /* @__PURE__ */ (0,
|
|
4513
|
-
return /* @__PURE__ */ (0,
|
|
4854
|
+
if (lowerKey.includes("follower")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Users, { className: iconClass });
|
|
4855
|
+
if (lowerKey.includes("following")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.UserPlus, { className: iconClass });
|
|
4856
|
+
if (lowerKey.includes("post") || lowerKey.includes("publication")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Image, { className: iconClass });
|
|
4857
|
+
if (lowerKey.includes("verified") || lowerKey.includes("badge")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.BadgeCheck, { className: iconClass });
|
|
4858
|
+
if (lowerKey.includes("bio")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.FileText, { className: iconClass });
|
|
4859
|
+
if (lowerKey.includes("email")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Mail, { className: iconClass });
|
|
4860
|
+
if (lowerKey.includes("phone") || lowerKey.includes("tel")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Phone, { className: iconClass });
|
|
4861
|
+
if (lowerKey.includes("location") || lowerKey.includes("address") || lowerKey.includes("city")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.MapPin, { className: iconClass });
|
|
4862
|
+
if (lowerKey.includes("company") || lowerKey.includes("org")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Building, { className: iconClass });
|
|
4863
|
+
if (lowerKey.includes("job") || lowerKey.includes("role") || lowerKey.includes("title") || lowerKey.includes("position")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Briefcase, { className: iconClass });
|
|
4864
|
+
if (lowerKey.includes("website") || lowerKey.includes("url") || lowerKey.includes("link")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Globe, { className: iconClass });
|
|
4865
|
+
if (lowerKey.includes("username") || lowerKey.includes("handle")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.AtSign, { className: iconClass });
|
|
4866
|
+
if (lowerKey.includes("date") || lowerKey.includes("birthday") || lowerKey.includes("joined")) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Calendar, { className: iconClass });
|
|
4867
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.User, { className: iconClass });
|
|
4514
4868
|
};
|
|
4515
4869
|
var formatValue = (value, type, key) => {
|
|
4516
4870
|
if (value === null || value === void 0) return "-";
|
|
@@ -4544,15 +4898,15 @@ var getMemoryCategoryIcon = (category) => {
|
|
|
4544
4898
|
const iconClass = "h-4 w-4 text-muted-foreground";
|
|
4545
4899
|
switch (category) {
|
|
4546
4900
|
case "preference":
|
|
4547
|
-
return /* @__PURE__ */ (0,
|
|
4901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Heart, { className: iconClass });
|
|
4548
4902
|
case "fact":
|
|
4549
|
-
return /* @__PURE__ */ (0,
|
|
4903
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Info, { className: iconClass });
|
|
4550
4904
|
case "goal":
|
|
4551
|
-
return /* @__PURE__ */ (0,
|
|
4905
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Target, { className: iconClass });
|
|
4552
4906
|
case "context":
|
|
4553
|
-
return /* @__PURE__ */ (0,
|
|
4907
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Lightbulb, { className: iconClass });
|
|
4554
4908
|
default:
|
|
4555
|
-
return /* @__PURE__ */ (0,
|
|
4909
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Brain, { className: iconClass });
|
|
4556
4910
|
}
|
|
4557
4911
|
};
|
|
4558
4912
|
var getMemoryCategoryLabel = (category) => {
|
|
@@ -4583,10 +4937,10 @@ var UserProfile = ({
|
|
|
4583
4937
|
onDeleteMemory,
|
|
4584
4938
|
className
|
|
4585
4939
|
}) => {
|
|
4586
|
-
const [newMemoryContent, setNewMemoryContent] = (0,
|
|
4587
|
-
const [isAddingMemory, setIsAddingMemory] = (0,
|
|
4588
|
-
const [editingMemoryId, setEditingMemoryId] = (0,
|
|
4589
|
-
const [editingMemoryContent, setEditingMemoryContent] = (0,
|
|
4940
|
+
const [newMemoryContent, setNewMemoryContent] = (0, import_react7.useState)("");
|
|
4941
|
+
const [isAddingMemory, setIsAddingMemory] = (0, import_react7.useState)(false);
|
|
4942
|
+
const [editingMemoryId, setEditingMemoryId] = (0, import_react7.useState)(null);
|
|
4943
|
+
const [editingMemoryContent, setEditingMemoryContent] = (0, import_react7.useState)("");
|
|
4590
4944
|
const handleAddMemory = () => {
|
|
4591
4945
|
if (newMemoryContent.trim() && onAddMemory) {
|
|
4592
4946
|
onAddMemory(newMemoryContent.trim(), "other");
|
|
@@ -4622,66 +4976,66 @@ var UserProfile = ({
|
|
|
4622
4976
|
const displayName = user?.name || user?.email?.split("@")[0] || "User";
|
|
4623
4977
|
const initials = getInitials2(user?.name, user?.email);
|
|
4624
4978
|
const normalizedFields = normalizeCustomFields(customFields);
|
|
4625
|
-
return /* @__PURE__ */ (0,
|
|
4979
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Sheet, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
4626
4980
|
SheetContent,
|
|
4627
4981
|
{
|
|
4628
4982
|
side: "right",
|
|
4629
4983
|
className: cn("w-full sm:max-w-md p-0 flex flex-col h-full overflow-hidden", className),
|
|
4630
4984
|
children: [
|
|
4631
|
-
/* @__PURE__ */ (0,
|
|
4632
|
-
/* @__PURE__ */ (0,
|
|
4633
|
-
/* @__PURE__ */ (0,
|
|
4634
|
-
/* @__PURE__ */ (0,
|
|
4635
|
-
user?.avatar && /* @__PURE__ */ (0,
|
|
4636
|
-
/* @__PURE__ */ (0,
|
|
4985
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SheetHeader, { className: "px-6 py-4 border-b shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SheetTitle, { children: labels.title }) }) }),
|
|
4986
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "p-6 space-y-6", children: [
|
|
4987
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center text-center space-y-4", children: [
|
|
4988
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Avatar, { className: "h-24 w-24 shrink-0", children: [
|
|
4989
|
+
user?.avatar && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AvatarImage, { src: user.avatar, alt: displayName }),
|
|
4990
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AvatarFallback, { className: "text-2xl bg-primary/10 text-primary", children: initials })
|
|
4637
4991
|
] }),
|
|
4638
|
-
/* @__PURE__ */ (0,
|
|
4639
|
-
/* @__PURE__ */ (0,
|
|
4640
|
-
user?.email && /* @__PURE__ */ (0,
|
|
4992
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "w-full px-2", children: [
|
|
4993
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { className: "text-xl font-semibold break-words", children: displayName }),
|
|
4994
|
+
user?.email && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm text-muted-foreground break-words", children: user.email })
|
|
4641
4995
|
] })
|
|
4642
4996
|
] }),
|
|
4643
|
-
/* @__PURE__ */ (0,
|
|
4644
|
-
/* @__PURE__ */ (0,
|
|
4645
|
-
/* @__PURE__ */ (0,
|
|
4646
|
-
/* @__PURE__ */ (0,
|
|
4647
|
-
/* @__PURE__ */ (0,
|
|
4648
|
-
/* @__PURE__ */ (0,
|
|
4649
|
-
/* @__PURE__ */ (0,
|
|
4650
|
-
/* @__PURE__ */ (0,
|
|
4651
|
-
/* @__PURE__ */ (0,
|
|
4997
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Separator, {}),
|
|
4998
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-3", children: [
|
|
4999
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.basicInfo }),
|
|
5000
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-2", children: [
|
|
5001
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
|
|
5002
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.User, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
|
|
5003
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
5004
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs text-muted-foreground", children: "Name" }),
|
|
5005
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm font-medium break-words", children: displayName })
|
|
4652
5006
|
] })
|
|
4653
5007
|
] }),
|
|
4654
|
-
user?.email && /* @__PURE__ */ (0,
|
|
4655
|
-
/* @__PURE__ */ (0,
|
|
4656
|
-
/* @__PURE__ */ (0,
|
|
4657
|
-
/* @__PURE__ */ (0,
|
|
4658
|
-
/* @__PURE__ */ (0,
|
|
5008
|
+
user?.email && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
|
|
5009
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.AtSign, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
|
|
5010
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
5011
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs text-muted-foreground", children: "Handle" }),
|
|
5012
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm font-medium break-words", children: user.email })
|
|
4659
5013
|
] })
|
|
4660
5014
|
] }),
|
|
4661
|
-
user?.id && user.id !== user?.name && user.id !== user?.email && /* @__PURE__ */ (0,
|
|
4662
|
-
/* @__PURE__ */ (0,
|
|
4663
|
-
/* @__PURE__ */ (0,
|
|
4664
|
-
/* @__PURE__ */ (0,
|
|
4665
|
-
/* @__PURE__ */ (0,
|
|
5015
|
+
user?.id && user.id !== user?.name && user.id !== user?.email && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
|
|
5016
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.User, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
|
|
5017
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
5018
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs text-muted-foreground", children: "ID" }),
|
|
5019
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm font-medium break-words", children: user.id })
|
|
4666
5020
|
] })
|
|
4667
5021
|
] })
|
|
4668
5022
|
] })
|
|
4669
5023
|
] }),
|
|
4670
|
-
normalizedFields.length > 0 && /* @__PURE__ */ (0,
|
|
4671
|
-
/* @__PURE__ */ (0,
|
|
4672
|
-
/* @__PURE__ */ (0,
|
|
4673
|
-
/* @__PURE__ */ (0,
|
|
4674
|
-
/* @__PURE__ */ (0,
|
|
5024
|
+
normalizedFields.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
5025
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Separator, {}),
|
|
5026
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-3", children: [
|
|
5027
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.customFields }),
|
|
5028
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "space-y-2", children: normalizedFields.map((field) => {
|
|
4675
5029
|
const isBioField = field.key.toLowerCase().includes("bio");
|
|
4676
|
-
return /* @__PURE__ */ (0,
|
|
5030
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
4677
5031
|
"div",
|
|
4678
5032
|
{
|
|
4679
5033
|
className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50",
|
|
4680
5034
|
children: [
|
|
4681
|
-
/* @__PURE__ */ (0,
|
|
4682
|
-
/* @__PURE__ */ (0,
|
|
4683
|
-
/* @__PURE__ */ (0,
|
|
4684
|
-
/* @__PURE__ */ (0,
|
|
5035
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mt-0.5 shrink-0", children: field.icon || getFieldIcon(field.type, field.key) }),
|
|
5036
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
5037
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs text-muted-foreground", children: field.label }),
|
|
5038
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: cn(
|
|
4685
5039
|
"text-sm font-medium",
|
|
4686
5040
|
isBioField ? "whitespace-pre-wrap break-words" : "break-words"
|
|
4687
5041
|
), children: formatValue(field.value, field.type, field.key) })
|
|
@@ -4693,26 +5047,26 @@ var UserProfile = ({
|
|
|
4693
5047
|
}) })
|
|
4694
5048
|
] })
|
|
4695
5049
|
] }),
|
|
4696
|
-
/* @__PURE__ */ (0,
|
|
4697
|
-
/* @__PURE__ */ (0,
|
|
4698
|
-
/* @__PURE__ */ (0,
|
|
4699
|
-
/* @__PURE__ */ (0,
|
|
4700
|
-
/* @__PURE__ */ (0,
|
|
5050
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Separator, {}),
|
|
5051
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-3", children: [
|
|
5052
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
5053
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
|
|
5054
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Brain, { className: "h-4 w-4" }),
|
|
4701
5055
|
labels.memories
|
|
4702
5056
|
] }),
|
|
4703
|
-
onAddMemory && /* @__PURE__ */ (0,
|
|
5057
|
+
onAddMemory && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4704
5058
|
Button,
|
|
4705
5059
|
{
|
|
4706
5060
|
variant: "ghost",
|
|
4707
5061
|
size: "sm",
|
|
4708
5062
|
className: "h-7 px-2",
|
|
4709
5063
|
onClick: () => setIsAddingMemory(true),
|
|
4710
|
-
children: /* @__PURE__ */ (0,
|
|
5064
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Plus, { className: "h-4 w-4" })
|
|
4711
5065
|
}
|
|
4712
5066
|
)
|
|
4713
5067
|
] }),
|
|
4714
|
-
isAddingMemory && onAddMemory && /* @__PURE__ */ (0,
|
|
4715
|
-
/* @__PURE__ */ (0,
|
|
5068
|
+
isAddingMemory && onAddMemory && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex gap-2", children: [
|
|
5069
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4716
5070
|
Input,
|
|
4717
5071
|
{
|
|
4718
5072
|
value: newMemoryContent,
|
|
@@ -4729,24 +5083,24 @@ var UserProfile = ({
|
|
|
4729
5083
|
autoFocus: true
|
|
4730
5084
|
}
|
|
4731
5085
|
),
|
|
4732
|
-
/* @__PURE__ */ (0,
|
|
5086
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { size: "sm", onClick: handleAddMemory, disabled: !newMemoryContent.trim(), children: "Salvar" })
|
|
4733
5087
|
] }),
|
|
4734
|
-
/* @__PURE__ */ (0,
|
|
5088
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "space-y-2", children: memories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm text-muted-foreground text-center py-4", children: labels.noMemories }) : memories.map((memory) => {
|
|
4735
5089
|
const isEditing = editingMemoryId === memory.id;
|
|
4736
|
-
return /* @__PURE__ */ (0,
|
|
5090
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
4737
5091
|
"div",
|
|
4738
5092
|
{
|
|
4739
5093
|
className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50 group",
|
|
4740
5094
|
children: [
|
|
4741
|
-
/* @__PURE__ */ (0,
|
|
4742
|
-
/* @__PURE__ */ (0,
|
|
4743
|
-
/* @__PURE__ */ (0,
|
|
4744
|
-
/* @__PURE__ */ (0,
|
|
4745
|
-
/* @__PURE__ */ (0,
|
|
4746
|
-
/* @__PURE__ */ (0,
|
|
5095
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mt-0.5 shrink-0", children: memory.source === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Bot, { className: "h-4 w-4 text-primary" }) : getMemoryCategoryIcon(memory.category) }),
|
|
5096
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
5097
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-2 mb-0.5", children: [
|
|
5098
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-xs text-muted-foreground", children: getMemoryCategoryLabel(memory.category) }),
|
|
5099
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-xs text-muted-foreground", children: "\u2022" }),
|
|
5100
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-xs text-muted-foreground", children: memory.source === "agent" ? "IA" : "Voc\xEA" })
|
|
4747
5101
|
] }),
|
|
4748
|
-
isEditing ? /* @__PURE__ */ (0,
|
|
4749
|
-
/* @__PURE__ */ (0,
|
|
5102
|
+
isEditing ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-2", children: [
|
|
5103
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4750
5104
|
Textarea,
|
|
4751
5105
|
{
|
|
4752
5106
|
value: editingMemoryContent,
|
|
@@ -4763,8 +5117,8 @@ var UserProfile = ({
|
|
|
4763
5117
|
}
|
|
4764
5118
|
}
|
|
4765
5119
|
),
|
|
4766
|
-
/* @__PURE__ */ (0,
|
|
4767
|
-
/* @__PURE__ */ (0,
|
|
5120
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex gap-1 justify-end", children: [
|
|
5121
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
4768
5122
|
Button,
|
|
4769
5123
|
{
|
|
4770
5124
|
variant: "ghost",
|
|
@@ -4772,12 +5126,12 @@ var UserProfile = ({
|
|
|
4772
5126
|
className: "h-7 px-2",
|
|
4773
5127
|
onClick: handleCancelEdit,
|
|
4774
5128
|
children: [
|
|
4775
|
-
/* @__PURE__ */ (0,
|
|
5129
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.X, { className: "h-3.5 w-3.5 mr-1" }),
|
|
4776
5130
|
"Cancelar"
|
|
4777
5131
|
]
|
|
4778
5132
|
}
|
|
4779
5133
|
),
|
|
4780
|
-
/* @__PURE__ */ (0,
|
|
5134
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
4781
5135
|
Button,
|
|
4782
5136
|
{
|
|
4783
5137
|
size: "sm",
|
|
@@ -4785,33 +5139,33 @@ var UserProfile = ({
|
|
|
4785
5139
|
onClick: handleSaveEdit,
|
|
4786
5140
|
disabled: !editingMemoryContent.trim(),
|
|
4787
5141
|
children: [
|
|
4788
|
-
/* @__PURE__ */ (0,
|
|
5142
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Check, { className: "h-3.5 w-3.5 mr-1" }),
|
|
4789
5143
|
"Salvar"
|
|
4790
5144
|
]
|
|
4791
5145
|
}
|
|
4792
5146
|
)
|
|
4793
5147
|
] })
|
|
4794
|
-
] }) : /* @__PURE__ */ (0,
|
|
5148
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm break-words", children: memory.content })
|
|
4795
5149
|
] }),
|
|
4796
|
-
!isEditing && (onUpdateMemory || onDeleteMemory) && /* @__PURE__ */ (0,
|
|
4797
|
-
onUpdateMemory && /* @__PURE__ */ (0,
|
|
5150
|
+
!isEditing && (onUpdateMemory || onDeleteMemory) && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0", children: [
|
|
5151
|
+
onUpdateMemory && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4798
5152
|
Button,
|
|
4799
5153
|
{
|
|
4800
5154
|
variant: "ghost",
|
|
4801
5155
|
size: "icon",
|
|
4802
5156
|
className: "h-7 w-7",
|
|
4803
5157
|
onClick: () => handleStartEdit(memory),
|
|
4804
|
-
children: /* @__PURE__ */ (0,
|
|
5158
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Pencil, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
4805
5159
|
}
|
|
4806
5160
|
),
|
|
4807
|
-
onDeleteMemory && /* @__PURE__ */ (0,
|
|
5161
|
+
onDeleteMemory && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4808
5162
|
Button,
|
|
4809
5163
|
{
|
|
4810
5164
|
variant: "ghost",
|
|
4811
5165
|
size: "icon",
|
|
4812
5166
|
className: "h-7 w-7",
|
|
4813
5167
|
onClick: () => onDeleteMemory(memory.id),
|
|
4814
|
-
children: /* @__PURE__ */ (0,
|
|
5168
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Trash2, { className: "h-3.5 w-3.5 text-destructive" })
|
|
4815
5169
|
}
|
|
4816
5170
|
)
|
|
4817
5171
|
] })
|
|
@@ -4822,8 +5176,8 @@ var UserProfile = ({
|
|
|
4822
5176
|
}) })
|
|
4823
5177
|
] })
|
|
4824
5178
|
] }) }),
|
|
4825
|
-
/* @__PURE__ */ (0,
|
|
4826
|
-
onEditProfile && /* @__PURE__ */ (0,
|
|
5179
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "p-4 border-t space-y-2 shrink-0", children: [
|
|
5180
|
+
onEditProfile && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4827
5181
|
Button,
|
|
4828
5182
|
{
|
|
4829
5183
|
variant: "outline",
|
|
@@ -4832,7 +5186,7 @@ var UserProfile = ({
|
|
|
4832
5186
|
children: "Edit Profile"
|
|
4833
5187
|
}
|
|
4834
5188
|
),
|
|
4835
|
-
onLogout && /* @__PURE__ */ (0,
|
|
5189
|
+
onLogout && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4836
5190
|
Button,
|
|
4837
5191
|
{
|
|
4838
5192
|
variant: "destructive",
|
|
@@ -4848,8 +5202,8 @@ var UserProfile = ({
|
|
|
4848
5202
|
};
|
|
4849
5203
|
|
|
4850
5204
|
// src/components/chat/ChatUI.tsx
|
|
4851
|
-
var
|
|
4852
|
-
var
|
|
5205
|
+
var import_lucide_react13 = require("lucide-react");
|
|
5206
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
4853
5207
|
var ChatUI = ({
|
|
4854
5208
|
messages = [],
|
|
4855
5209
|
threads = [],
|
|
@@ -4866,6 +5220,10 @@ var ChatUI = ({
|
|
|
4866
5220
|
agentOptions = [],
|
|
4867
5221
|
selectedAgentId = null,
|
|
4868
5222
|
onSelectAgent,
|
|
5223
|
+
participantIds,
|
|
5224
|
+
onParticipantsChange,
|
|
5225
|
+
targetAgentId = null,
|
|
5226
|
+
onTargetAgentChange,
|
|
4869
5227
|
className = "",
|
|
4870
5228
|
onAddMemory,
|
|
4871
5229
|
onUpdateMemory,
|
|
@@ -4873,12 +5231,12 @@ var ChatUI = ({
|
|
|
4873
5231
|
initialInput,
|
|
4874
5232
|
onInitialInputConsumed
|
|
4875
5233
|
}) => {
|
|
4876
|
-
const config = (0,
|
|
5234
|
+
const config = (0, import_react8.useMemo)(
|
|
4877
5235
|
() => mergeConfig(defaultChatConfig, userConfig),
|
|
4878
5236
|
[userConfig]
|
|
4879
5237
|
);
|
|
4880
|
-
const [isMobile, setIsMobile] = (0,
|
|
4881
|
-
const [isUserProfileOpen, setIsUserProfileOpen] = (0,
|
|
5238
|
+
const [isMobile, setIsMobile] = (0, import_react8.useState)(false);
|
|
5239
|
+
const [isUserProfileOpen, setIsUserProfileOpen] = (0, import_react8.useState)(false);
|
|
4882
5240
|
let userContext;
|
|
4883
5241
|
try {
|
|
4884
5242
|
const contextValue = useChatUserContext();
|
|
@@ -4892,10 +5250,10 @@ var ChatUI = ({
|
|
|
4892
5250
|
}
|
|
4893
5251
|
return false;
|
|
4894
5252
|
};
|
|
4895
|
-
const [inputValue, setInputValue] = (0,
|
|
4896
|
-
const [attachments, setAttachments] = (0,
|
|
4897
|
-
const [expandedMessageIds, setExpandedMessageIds] = (0,
|
|
4898
|
-
const [state, setState] = (0,
|
|
5253
|
+
const [inputValue, setInputValue] = (0, import_react8.useState)("");
|
|
5254
|
+
const [attachments, setAttachments] = (0, import_react8.useState)([]);
|
|
5255
|
+
const [expandedMessageIds, setExpandedMessageIds] = (0, import_react8.useState)({});
|
|
5256
|
+
const [state, setState] = (0, import_react8.useState)({
|
|
4899
5257
|
isRecording: false,
|
|
4900
5258
|
selectedThreadId: currentThreadId,
|
|
4901
5259
|
isAtBottom: true,
|
|
@@ -4907,41 +5265,41 @@ var ChatUI = ({
|
|
|
4907
5265
|
isSidebarCollapsed: false
|
|
4908
5266
|
// No longer used for main sidebar
|
|
4909
5267
|
});
|
|
4910
|
-
(0,
|
|
5268
|
+
(0, import_react8.useEffect)(() => {
|
|
4911
5269
|
if (currentThreadId !== state.selectedThreadId) {
|
|
4912
5270
|
setState((prev) => ({ ...prev, selectedThreadId: currentThreadId }));
|
|
4913
5271
|
}
|
|
4914
5272
|
}, [currentThreadId]);
|
|
4915
|
-
const initialInputApplied = (0,
|
|
4916
|
-
const initialInputConsumedRef = (0,
|
|
4917
|
-
(0,
|
|
5273
|
+
const initialInputApplied = (0, import_react8.useRef)(false);
|
|
5274
|
+
const initialInputConsumedRef = (0, import_react8.useRef)(false);
|
|
5275
|
+
(0, import_react8.useEffect)(() => {
|
|
4918
5276
|
if (initialInput && !initialInputApplied.current) {
|
|
4919
5277
|
setInputValue(initialInput);
|
|
4920
5278
|
initialInputApplied.current = true;
|
|
4921
5279
|
}
|
|
4922
5280
|
}, [initialInput]);
|
|
4923
|
-
const scrollAreaRef = (0,
|
|
4924
|
-
const stateRef = (0,
|
|
4925
|
-
const inputValueRef = (0,
|
|
4926
|
-
const attachmentsRef = (0,
|
|
4927
|
-
(0,
|
|
5281
|
+
const scrollAreaRef = (0, import_react8.useRef)(null);
|
|
5282
|
+
const stateRef = (0, import_react8.useRef)(state);
|
|
5283
|
+
const inputValueRef = (0, import_react8.useRef)(inputValue);
|
|
5284
|
+
const attachmentsRef = (0, import_react8.useRef)(attachments);
|
|
5285
|
+
(0, import_react8.useEffect)(() => {
|
|
4928
5286
|
stateRef.current = state;
|
|
4929
5287
|
}, [state]);
|
|
4930
|
-
(0,
|
|
5288
|
+
(0, import_react8.useEffect)(() => {
|
|
4931
5289
|
inputValueRef.current = inputValue;
|
|
4932
5290
|
}, [inputValue]);
|
|
4933
|
-
(0,
|
|
5291
|
+
(0, import_react8.useEffect)(() => {
|
|
4934
5292
|
attachmentsRef.current = attachments;
|
|
4935
5293
|
}, [attachments]);
|
|
4936
|
-
const [isCustomMounted, setIsCustomMounted] = (0,
|
|
4937
|
-
const [isCustomVisible, setIsCustomVisible] = (0,
|
|
5294
|
+
const [isCustomMounted, setIsCustomMounted] = (0, import_react8.useState)(false);
|
|
5295
|
+
const [isCustomVisible, setIsCustomVisible] = (0, import_react8.useState)(false);
|
|
4938
5296
|
const virtualizer = (0, import_react_virtual.useVirtualizer)({
|
|
4939
5297
|
count: messages.length,
|
|
4940
5298
|
getScrollElement: () => scrollAreaRef.current,
|
|
4941
5299
|
estimateSize: () => 100,
|
|
4942
5300
|
overscan: 5
|
|
4943
5301
|
});
|
|
4944
|
-
const createStateCallback = (0,
|
|
5302
|
+
const createStateCallback = (0, import_react8.useCallback)(
|
|
4945
5303
|
(setter) => ({
|
|
4946
5304
|
setState: (newState) => setter?.(newState),
|
|
4947
5305
|
getState: () => ({
|
|
@@ -4953,7 +5311,7 @@ var ChatUI = ({
|
|
|
4953
5311
|
[]
|
|
4954
5312
|
// No dependencies - uses refs for latest state
|
|
4955
5313
|
);
|
|
4956
|
-
(0,
|
|
5314
|
+
(0, import_react8.useEffect)(() => {
|
|
4957
5315
|
const checkMobile = () => {
|
|
4958
5316
|
setIsMobile(globalThis.innerWidth < 1024);
|
|
4959
5317
|
};
|
|
@@ -4961,7 +5319,7 @@ var ChatUI = ({
|
|
|
4961
5319
|
globalThis.addEventListener("resize", checkMobile);
|
|
4962
5320
|
return () => globalThis.removeEventListener("resize", checkMobile);
|
|
4963
5321
|
}, []);
|
|
4964
|
-
(0,
|
|
5322
|
+
(0, import_react8.useEffect)(() => {
|
|
4965
5323
|
if (!isMobile || !config.customComponent?.component) return;
|
|
4966
5324
|
if (state.showSidebar) {
|
|
4967
5325
|
setIsCustomMounted(true);
|
|
@@ -4972,8 +5330,8 @@ var ChatUI = ({
|
|
|
4972
5330
|
return () => clearTimeout(t);
|
|
4973
5331
|
}
|
|
4974
5332
|
}, [state.showSidebar, isMobile, config.customComponent]);
|
|
4975
|
-
const prevMessageCountRef = (0,
|
|
4976
|
-
(0,
|
|
5333
|
+
const prevMessageCountRef = (0, import_react8.useRef)(0);
|
|
5334
|
+
(0, import_react8.useEffect)(() => {
|
|
4977
5335
|
if (messages.length === 0) {
|
|
4978
5336
|
prevMessageCountRef.current = 0;
|
|
4979
5337
|
return;
|
|
@@ -4999,10 +5357,10 @@ var ChatUI = ({
|
|
|
4999
5357
|
}
|
|
5000
5358
|
});
|
|
5001
5359
|
}, [messages, state.isAtBottom, virtualizer]);
|
|
5002
|
-
(0,
|
|
5360
|
+
(0, import_react8.useEffect)(() => {
|
|
5003
5361
|
virtualizer.measure();
|
|
5004
5362
|
}, [expandedMessageIds, virtualizer]);
|
|
5005
|
-
(0,
|
|
5363
|
+
(0, import_react8.useEffect)(() => {
|
|
5006
5364
|
const validMessageIds = new Set(messages.map((message) => message.id));
|
|
5007
5365
|
setExpandedMessageIds((prev) => {
|
|
5008
5366
|
const activeIds = Object.keys(prev);
|
|
@@ -5017,7 +5375,7 @@ var ChatUI = ({
|
|
|
5017
5375
|
return next;
|
|
5018
5376
|
});
|
|
5019
5377
|
}, [messages]);
|
|
5020
|
-
const handleScroll = (0,
|
|
5378
|
+
const handleScroll = (0, import_react8.useCallback)((e) => {
|
|
5021
5379
|
const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
|
|
5022
5380
|
const isAtBottom = scrollHeight - scrollTop - clientHeight < 50;
|
|
5023
5381
|
setState((prev) => {
|
|
@@ -5025,7 +5383,7 @@ var ChatUI = ({
|
|
|
5025
5383
|
return { ...prev, isAtBottom };
|
|
5026
5384
|
});
|
|
5027
5385
|
}, []);
|
|
5028
|
-
const handleSendMessage = (0,
|
|
5386
|
+
const handleSendMessage = (0, import_react8.useCallback)((content, messageAttachments = []) => {
|
|
5029
5387
|
if (!content.trim() && messageAttachments.length === 0) return;
|
|
5030
5388
|
callbacks.onSendMessage?.(content, messageAttachments, createStateCallback());
|
|
5031
5389
|
if (initialInputApplied.current && !initialInputConsumedRef.current) {
|
|
@@ -5035,7 +5393,7 @@ var ChatUI = ({
|
|
|
5035
5393
|
setInputValue("");
|
|
5036
5394
|
setAttachments([]);
|
|
5037
5395
|
}, [callbacks, createStateCallback, onInitialInputConsumed]);
|
|
5038
|
-
const handleMessageAction = (0,
|
|
5396
|
+
const handleMessageAction = (0, import_react8.useCallback)((event) => {
|
|
5039
5397
|
const { action, messageId, content } = event;
|
|
5040
5398
|
switch (action) {
|
|
5041
5399
|
case "copy":
|
|
@@ -5054,7 +5412,7 @@ var ChatUI = ({
|
|
|
5054
5412
|
break;
|
|
5055
5413
|
}
|
|
5056
5414
|
}, [callbacks, createStateCallback]);
|
|
5057
|
-
const handleToggleMessageExpansion = (0,
|
|
5415
|
+
const handleToggleMessageExpansion = (0, import_react8.useCallback)((messageId) => {
|
|
5058
5416
|
setExpandedMessageIds((prev) => {
|
|
5059
5417
|
if (prev[messageId]) {
|
|
5060
5418
|
const next = { ...prev };
|
|
@@ -5067,44 +5425,44 @@ var ChatUI = ({
|
|
|
5067
5425
|
};
|
|
5068
5426
|
});
|
|
5069
5427
|
}, []);
|
|
5070
|
-
const handleCreateThread = (0,
|
|
5428
|
+
const handleCreateThread = (0, import_react8.useCallback)((title) => {
|
|
5071
5429
|
callbacks.onCreateThread?.(title, createStateCallback());
|
|
5072
5430
|
}, [callbacks, createStateCallback]);
|
|
5073
|
-
const handleSelectThread = (0,
|
|
5431
|
+
const handleSelectThread = (0, import_react8.useCallback)((threadId) => {
|
|
5074
5432
|
callbacks.onSelectThread?.(threadId, createStateCallback());
|
|
5075
5433
|
}, [callbacks, createStateCallback]);
|
|
5076
|
-
const handleRenameThread = (0,
|
|
5434
|
+
const handleRenameThread = (0, import_react8.useCallback)((threadId, newTitle) => {
|
|
5077
5435
|
callbacks.onRenameThread?.(threadId, newTitle, createStateCallback());
|
|
5078
5436
|
}, [callbacks, createStateCallback]);
|
|
5079
|
-
const handleDeleteThread = (0,
|
|
5437
|
+
const handleDeleteThread = (0, import_react8.useCallback)((threadId) => {
|
|
5080
5438
|
callbacks.onDeleteThread?.(threadId, createStateCallback());
|
|
5081
5439
|
}, [callbacks, createStateCallback]);
|
|
5082
|
-
const handleArchiveThread = (0,
|
|
5440
|
+
const handleArchiveThread = (0, import_react8.useCallback)((threadId) => {
|
|
5083
5441
|
callbacks.onArchiveThread?.(threadId, createStateCallback());
|
|
5084
5442
|
}, [callbacks, createStateCallback]);
|
|
5085
|
-
const closeSidebar = (0,
|
|
5443
|
+
const closeSidebar = (0, import_react8.useCallback)(() => {
|
|
5086
5444
|
setState((prev) => ({ ...prev, showSidebar: false }));
|
|
5087
5445
|
}, []);
|
|
5088
|
-
const handleCustomComponentToggle = (0,
|
|
5446
|
+
const handleCustomComponentToggle = (0, import_react8.useCallback)(() => {
|
|
5089
5447
|
setState((prev) => ({ ...prev, showSidebar: !prev.showSidebar }));
|
|
5090
5448
|
}, []);
|
|
5091
|
-
const sidebarUser = (0,
|
|
5449
|
+
const sidebarUser = (0, import_react8.useMemo)(() => user ? {
|
|
5092
5450
|
id: user.id,
|
|
5093
5451
|
name: user.name,
|
|
5094
5452
|
email: user.email,
|
|
5095
5453
|
avatar: user.avatar
|
|
5096
5454
|
} : null, [user?.id, user?.name, user?.email, user?.avatar]);
|
|
5097
|
-
const handleViewProfile = (0,
|
|
5455
|
+
const handleViewProfile = (0, import_react8.useCallback)(() => {
|
|
5098
5456
|
setIsUserProfileOpen(true);
|
|
5099
5457
|
callbacks.onViewProfile?.();
|
|
5100
5458
|
}, [callbacks.onViewProfile]);
|
|
5101
|
-
const sidebarUserMenuCallbacks = (0,
|
|
5459
|
+
const sidebarUserMenuCallbacks = (0, import_react8.useMemo)(() => ({
|
|
5102
5460
|
onViewProfile: handleViewProfile,
|
|
5103
5461
|
onOpenSettings: callbacks.onOpenSettings,
|
|
5104
5462
|
onThemeChange: callbacks.onThemeChange,
|
|
5105
5463
|
onLogout: callbacks.onLogout
|
|
5106
5464
|
}), [handleViewProfile, callbacks.onOpenSettings, callbacks.onThemeChange, callbacks.onLogout]);
|
|
5107
|
-
const renderCustomComponent = (0,
|
|
5465
|
+
const renderCustomComponent = (0, import_react8.useCallback)(() => {
|
|
5108
5466
|
const component = config?.customComponent?.component;
|
|
5109
5467
|
if (!component) return null;
|
|
5110
5468
|
if (typeof component === "function") {
|
|
@@ -5112,16 +5470,16 @@ var ChatUI = ({
|
|
|
5112
5470
|
}
|
|
5113
5471
|
return component;
|
|
5114
5472
|
}, [config?.customComponent?.component, closeSidebar, isMobile]);
|
|
5115
|
-
const SuggestionIconComponents = [
|
|
5473
|
+
const SuggestionIconComponents = [import_lucide_react13.MessageSquare, import_lucide_react13.Lightbulb, import_lucide_react13.Zap, import_lucide_react13.HelpCircle];
|
|
5116
5474
|
const renderSuggestions = () => {
|
|
5117
5475
|
if (messages.length > 0 || !suggestions.length) return null;
|
|
5118
|
-
return /* @__PURE__ */ (0,
|
|
5119
|
-
/* @__PURE__ */ (0,
|
|
5120
|
-
/* @__PURE__ */ (0,
|
|
5121
|
-
/* @__PURE__ */ (0,
|
|
5122
|
-
/* @__PURE__ */ (0,
|
|
5476
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col items-center justify-center min-h-[60vh] py-8 px-4", children: [
|
|
5477
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "text-center mb-8", children: [
|
|
5478
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "inline-flex items-center justify-center w-14 h-14 rounded-2xl bg-gradient-to-br from-primary/20 to-primary/5 mb-4 shadow-sm", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Sparkles, { className: "w-7 h-7 text-primary" }) }),
|
|
5479
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h2", { className: "text-xl font-semibold mb-2", children: config.branding.title }),
|
|
5480
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-muted-foreground text-sm max-w-md", children: config.branding.subtitle })
|
|
5123
5481
|
] }),
|
|
5124
|
-
/* @__PURE__ */ (0,
|
|
5482
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 w-full max-w-2xl", children: suggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5125
5483
|
"button",
|
|
5126
5484
|
{
|
|
5127
5485
|
type: "button",
|
|
@@ -5130,10 +5488,10 @@ var ChatUI = ({
|
|
|
5130
5488
|
children: [
|
|
5131
5489
|
(() => {
|
|
5132
5490
|
const IconComponent = SuggestionIconComponents[index % SuggestionIconComponents.length];
|
|
5133
|
-
return /* @__PURE__ */ (0,
|
|
5491
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex items-center justify-center w-8 h-8 rounded-lg bg-primary/10 text-primary shrink-0 group-hover:bg-primary/15 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(IconComponent, { className: "h-4 w-4" }) });
|
|
5134
5492
|
})(),
|
|
5135
|
-
/* @__PURE__ */ (0,
|
|
5136
|
-
/* @__PURE__ */ (0,
|
|
5493
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex-1 min-w-0 pr-6", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-sm font-medium leading-snug line-clamp-2", children: suggestion }) }),
|
|
5494
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.ArrowRight, { className: "absolute right-4 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" })
|
|
5137
5495
|
]
|
|
5138
5496
|
},
|
|
5139
5497
|
index
|
|
@@ -5144,40 +5502,41 @@ var ChatUI = ({
|
|
|
5144
5502
|
const items = messageSuggestions?.[messageId];
|
|
5145
5503
|
if (!items || items.length === 0) return null;
|
|
5146
5504
|
const inlineSuggestionOffsetClass = config.ui.showAvatars ? config.ui.compactMode ? "ml-9" : "ml-11" : "";
|
|
5147
|
-
return /* @__PURE__ */ (0,
|
|
5505
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: `flex flex-wrap gap-2 mt-2 ${inlineSuggestionOffsetClass}`, children: items.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5148
5506
|
"button",
|
|
5149
5507
|
{
|
|
5150
5508
|
type: "button",
|
|
5151
5509
|
onClick: () => handleSendMessage(suggestion),
|
|
5152
5510
|
className: "group inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border border-border bg-background hover:bg-accent hover:border-accent-foreground/20 transition-all duration-150 text-foreground/80 hover:text-foreground",
|
|
5153
5511
|
children: [
|
|
5154
|
-
/* @__PURE__ */ (0,
|
|
5155
|
-
/* @__PURE__ */ (0,
|
|
5512
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Sparkles, { className: "h-3 w-3 text-primary opacity-70 group-hover:opacity-100" }),
|
|
5513
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "max-w-[200px] truncate", children: suggestion })
|
|
5156
5514
|
]
|
|
5157
5515
|
},
|
|
5158
5516
|
`${messageId}-suggestion-${index}`
|
|
5159
5517
|
)) });
|
|
5160
5518
|
};
|
|
5161
|
-
const renderMessageLoadingSkeleton = () => /* @__PURE__ */ (0,
|
|
5519
|
+
const renderMessageLoadingSkeleton = () => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "space-y-6 py-2", children: [0, 1, 2, 3].map((index) => {
|
|
5162
5520
|
const isUserRow = index % 2 === 1;
|
|
5163
|
-
return /* @__PURE__ */ (0,
|
|
5521
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5164
5522
|
"div",
|
|
5165
5523
|
{
|
|
5166
5524
|
className: `flex gap-3 ${isUserRow ? "justify-end" : "justify-start"}`,
|
|
5167
5525
|
children: [
|
|
5168
|
-
!isUserRow && /* @__PURE__ */ (0,
|
|
5169
|
-
/* @__PURE__ */ (0,
|
|
5170
|
-
/* @__PURE__ */ (0,
|
|
5171
|
-
/* @__PURE__ */ (0,
|
|
5172
|
-
/* @__PURE__ */ (0,
|
|
5526
|
+
!isUserRow && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" }),
|
|
5527
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: `space-y-2 ${isUserRow ? "w-[70%]" : "w-[75%]"}`, children: [
|
|
5528
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Skeleton, { className: "h-4 w-24" }),
|
|
5529
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Skeleton, { className: "h-4 w-full" }),
|
|
5530
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Skeleton, { className: "h-4 w-[85%]" })
|
|
5173
5531
|
] }),
|
|
5174
|
-
isUserRow && /* @__PURE__ */ (0,
|
|
5532
|
+
isUserRow && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" })
|
|
5175
5533
|
]
|
|
5176
5534
|
},
|
|
5177
5535
|
`message-skeleton-${index}`
|
|
5178
5536
|
);
|
|
5179
5537
|
}) });
|
|
5180
|
-
const
|
|
5538
|
+
const isMultiAgentMode = config.agentSelector?.mode === "multi";
|
|
5539
|
+
const messageProps = (0, import_react8.useMemo)(() => ({
|
|
5181
5540
|
userAvatar: user?.avatar,
|
|
5182
5541
|
userName: user?.name,
|
|
5183
5542
|
assistantAvatar: assistant?.avatar,
|
|
@@ -5200,12 +5559,15 @@ var ChatUI = ({
|
|
|
5200
5559
|
longMessageChunkChars: config.ui.longMessageChunkChars,
|
|
5201
5560
|
renderUserMarkdown: config.ui.renderUserMarkdown,
|
|
5202
5561
|
markdown: config.markdown,
|
|
5203
|
-
onToggleExpanded: handleToggleMessageExpansion
|
|
5562
|
+
onToggleExpanded: handleToggleMessageExpansion,
|
|
5563
|
+
agentOptions: isMultiAgentMode ? agentOptions : void 0
|
|
5204
5564
|
}), [
|
|
5205
5565
|
user?.avatar,
|
|
5206
5566
|
user?.name,
|
|
5207
5567
|
assistant?.avatar,
|
|
5208
5568
|
assistant?.name,
|
|
5569
|
+
isMultiAgentMode,
|
|
5570
|
+
agentOptions,
|
|
5209
5571
|
config.ui.showTimestamps,
|
|
5210
5572
|
config.ui.showAvatars,
|
|
5211
5573
|
config.ui.compactMode,
|
|
@@ -5227,10 +5589,10 @@ var ChatUI = ({
|
|
|
5227
5589
|
handleToggleMessageExpansion
|
|
5228
5590
|
]);
|
|
5229
5591
|
const shouldShowAgentSelector = Boolean(
|
|
5230
|
-
config.agentSelector?.enabled &&
|
|
5592
|
+
config.agentSelector?.enabled && agentOptions.length > 0 && (!config.agentSelector?.hideIfSingle || agentOptions.length > 1) && (isMultiAgentMode ? onParticipantsChange : onSelectAgent)
|
|
5231
5593
|
);
|
|
5232
|
-
return /* @__PURE__ */ (0,
|
|
5233
|
-
/* @__PURE__ */ (0,
|
|
5594
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SidebarProvider, { defaultOpen: true, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: `flex h-[100svh] md:h-screen bg-background w-full overflow-hidden ${className}`, children: [
|
|
5595
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5234
5596
|
Sidebar2,
|
|
5235
5597
|
{
|
|
5236
5598
|
threads,
|
|
@@ -5247,8 +5609,8 @@ var ChatUI = ({
|
|
|
5247
5609
|
showThemeOptions: !!callbacks.onThemeChange
|
|
5248
5610
|
}
|
|
5249
5611
|
),
|
|
5250
|
-
/* @__PURE__ */ (0,
|
|
5251
|
-
/* @__PURE__ */ (0,
|
|
5612
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SidebarInset, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col h-full min-h-0", children: [
|
|
5613
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5252
5614
|
ChatHeader,
|
|
5253
5615
|
{
|
|
5254
5616
|
config,
|
|
@@ -5258,14 +5620,17 @@ var ChatUI = ({
|
|
|
5258
5620
|
onNewThread: handleCreateThread,
|
|
5259
5621
|
showCustomComponentButton: !!config?.customComponent?.component,
|
|
5260
5622
|
showAgentSelector: shouldShowAgentSelector,
|
|
5623
|
+
isMultiAgentMode,
|
|
5261
5624
|
agentOptions,
|
|
5262
5625
|
selectedAgentId,
|
|
5263
|
-
onSelectAgent
|
|
5626
|
+
onSelectAgent,
|
|
5627
|
+
participantIds,
|
|
5628
|
+
onParticipantsChange
|
|
5264
5629
|
}
|
|
5265
5630
|
),
|
|
5266
|
-
/* @__PURE__ */ (0,
|
|
5267
|
-
/* @__PURE__ */ (0,
|
|
5268
|
-
/* @__PURE__ */ (0,
|
|
5631
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-1 flex-row min-h-0 overflow-hidden", children: [
|
|
5632
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex-1 flex flex-col min-h-0", children: [
|
|
5633
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5269
5634
|
ScrollArea,
|
|
5270
5635
|
{
|
|
5271
5636
|
ref: scrollAreaRef,
|
|
@@ -5273,7 +5638,7 @@ var ChatUI = ({
|
|
|
5273
5638
|
viewportClassName: "p-4 overscroll-contain",
|
|
5274
5639
|
onScrollCapture: handleScroll,
|
|
5275
5640
|
style: { contain: "strict" },
|
|
5276
|
-
children: /* @__PURE__ */ (0,
|
|
5641
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "max-w-4xl mx-auto pb-4", children: isMessagesLoading ? renderMessageLoadingSkeleton() : messages.length === 0 ? renderSuggestions() : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5277
5642
|
"div",
|
|
5278
5643
|
{
|
|
5279
5644
|
style: {
|
|
@@ -5285,7 +5650,7 @@ var ChatUI = ({
|
|
|
5285
5650
|
const message = messages[virtualRow.index];
|
|
5286
5651
|
const prevMessage = virtualRow.index > 0 ? messages[virtualRow.index - 1] : null;
|
|
5287
5652
|
const isGrouped = prevMessage !== null && prevMessage.role === message.role;
|
|
5288
|
-
return /* @__PURE__ */ (0,
|
|
5653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5289
5654
|
"div",
|
|
5290
5655
|
{
|
|
5291
5656
|
"data-index": virtualRow.index,
|
|
@@ -5297,8 +5662,8 @@ var ChatUI = ({
|
|
|
5297
5662
|
width: "100%",
|
|
5298
5663
|
transform: `translateY(${virtualRow.start}px)`
|
|
5299
5664
|
},
|
|
5300
|
-
children: /* @__PURE__ */ (0,
|
|
5301
|
-
/* @__PURE__ */ (0,
|
|
5665
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: virtualRow.index === 0 ? "" : isGrouped ? "pt-2" : "pt-4", children: [
|
|
5666
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5302
5667
|
Message,
|
|
5303
5668
|
{
|
|
5304
5669
|
message,
|
|
@@ -5317,38 +5682,52 @@ var ChatUI = ({
|
|
|
5317
5682
|
) })
|
|
5318
5683
|
}
|
|
5319
5684
|
),
|
|
5320
|
-
/* @__PURE__ */ (0,
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5685
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "bg-background pb-[env(safe-area-inset-bottom)]", children: [
|
|
5686
|
+
isMultiAgentMode && shouldShowAgentSelector && onTargetAgentChange && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "px-4 pt-1", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5687
|
+
TargetAgentSelector,
|
|
5688
|
+
{
|
|
5689
|
+
agents: participantIds && participantIds.length > 0 ? agentOptions.filter((a) => participantIds.includes(a.id)) : agentOptions,
|
|
5690
|
+
targetAgentId,
|
|
5691
|
+
onTargetChange: onTargetAgentChange,
|
|
5692
|
+
placeholder: config.agentSelector?.label || "Select agent",
|
|
5693
|
+
disabled: isGenerating
|
|
5694
|
+
}
|
|
5695
|
+
) }),
|
|
5696
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5697
|
+
ChatInput,
|
|
5698
|
+
{
|
|
5699
|
+
value: inputValue,
|
|
5700
|
+
onChange: (value) => {
|
|
5701
|
+
setInputValue(value);
|
|
5702
|
+
if (initialInputApplied.current && !initialInputConsumedRef.current) {
|
|
5703
|
+
initialInputConsumedRef.current = true;
|
|
5704
|
+
onInitialInputConsumed?.();
|
|
5705
|
+
}
|
|
5706
|
+
},
|
|
5707
|
+
onSubmit: handleSendMessage,
|
|
5708
|
+
attachments,
|
|
5709
|
+
onAttachmentsChange: setAttachments,
|
|
5710
|
+
placeholder: config.labels.inputPlaceholder,
|
|
5711
|
+
disabled: false,
|
|
5712
|
+
isGenerating,
|
|
5713
|
+
onStopGeneration: callbacks.onStopGeneration,
|
|
5714
|
+
enableFileUpload: config.features.enableFileUpload,
|
|
5715
|
+
enableAudioRecording: config.features.enableAudioRecording,
|
|
5716
|
+
maxAttachments: config.features.maxAttachments,
|
|
5717
|
+
maxFileSize: config.features.maxFileSize,
|
|
5718
|
+
config,
|
|
5719
|
+
mentionAgents: participantIds && participantIds.length > 0 ? agentOptions.filter((a) => participantIds.includes(a.id)) : agentOptions,
|
|
5720
|
+
onTargetAgentChange
|
|
5721
|
+
}
|
|
5722
|
+
)
|
|
5723
|
+
] })
|
|
5345
5724
|
] }),
|
|
5346
|
-
config?.customComponent?.component && !isMobile && /* @__PURE__ */ (0,
|
|
5725
|
+
config?.customComponent?.component && !isMobile && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5347
5726
|
"div",
|
|
5348
5727
|
{
|
|
5349
5728
|
className: "h-full transition-all duration-300 ease-in-out overflow-hidden",
|
|
5350
5729
|
style: { width: state.showSidebar ? config.customComponent.panelWidth ?? 320 : 0 },
|
|
5351
|
-
children: state.showSidebar && /* @__PURE__ */ (0,
|
|
5730
|
+
children: state.showSidebar && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5352
5731
|
"div",
|
|
5353
5732
|
{
|
|
5354
5733
|
className: "h-full overflow-hidden border-l bg-background animate-in slide-in-from-right-4 duration-300",
|
|
@@ -5360,8 +5739,8 @@ var ChatUI = ({
|
|
|
5360
5739
|
)
|
|
5361
5740
|
] })
|
|
5362
5741
|
] }) }),
|
|
5363
|
-
isCustomMounted && config.customComponent?.component && isMobile && /* @__PURE__ */ (0,
|
|
5364
|
-
/* @__PURE__ */ (0,
|
|
5742
|
+
isCustomMounted && config.customComponent?.component && isMobile && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "fixed inset-0 z-50", children: [
|
|
5743
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5365
5744
|
"div",
|
|
5366
5745
|
{
|
|
5367
5746
|
className: `absolute inset-0 bg-background/80 backdrop-blur-sm transition-opacity duration-200 ease-out ${isCustomVisible ? "opacity-100" : "opacity-0"}`,
|
|
@@ -5369,16 +5748,16 @@ var ChatUI = ({
|
|
|
5369
5748
|
onClick: closeSidebar
|
|
5370
5749
|
}
|
|
5371
5750
|
),
|
|
5372
|
-
/* @__PURE__ */ (0,
|
|
5751
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5373
5752
|
"div",
|
|
5374
5753
|
{
|
|
5375
5754
|
className: `absolute top-0 right-0 h-full w-full bg-background transform-gpu transition-transform duration-200 ease-out ${isCustomVisible ? "translate-x-0" : "translate-x-full"}`,
|
|
5376
5755
|
style: { willChange: "transform" },
|
|
5377
|
-
children: /* @__PURE__ */ (0,
|
|
5756
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "h-full overflow-hidden", children: renderCustomComponent() })
|
|
5378
5757
|
}
|
|
5379
5758
|
)
|
|
5380
5759
|
] }),
|
|
5381
|
-
isUserProfileOpen && /* @__PURE__ */ (0,
|
|
5760
|
+
isUserProfileOpen && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5382
5761
|
UserProfile,
|
|
5383
5762
|
{
|
|
5384
5763
|
isOpen: isUserProfileOpen,
|
|
@@ -5401,14 +5780,14 @@ var ChatUI = ({
|
|
|
5401
5780
|
};
|
|
5402
5781
|
|
|
5403
5782
|
// src/components/chat/ThreadManager.tsx
|
|
5404
|
-
var
|
|
5405
|
-
var
|
|
5406
|
-
var
|
|
5783
|
+
var import_react9 = require("react");
|
|
5784
|
+
var import_lucide_react14 = require("lucide-react");
|
|
5785
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
5407
5786
|
var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onArchive }) => {
|
|
5408
|
-
const [isEditing, setIsEditing] = (0,
|
|
5409
|
-
const [editTitle, setEditTitle] = (0,
|
|
5410
|
-
const inputRef = (0,
|
|
5411
|
-
(0,
|
|
5787
|
+
const [isEditing, setIsEditing] = (0, import_react9.useState)(false);
|
|
5788
|
+
const [editTitle, setEditTitle] = (0, import_react9.useState)(thread.title);
|
|
5789
|
+
const inputRef = (0, import_react9.useRef)(null);
|
|
5790
|
+
(0, import_react9.useEffect)(() => {
|
|
5412
5791
|
if (isEditing && inputRef.current) {
|
|
5413
5792
|
inputRef.current.focus();
|
|
5414
5793
|
inputRef.current.select();
|
|
@@ -5432,9 +5811,9 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
|
|
|
5432
5811
|
handleCancelEdit();
|
|
5433
5812
|
}
|
|
5434
5813
|
};
|
|
5435
|
-
return /* @__PURE__ */ (0,
|
|
5436
|
-
/* @__PURE__ */ (0,
|
|
5437
|
-
/* @__PURE__ */ (0,
|
|
5814
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Card, { className: `cursor-pointer transition-all duration-200 hover:shadow-md py-0 ${isActive ? "ring-2 ring-primary bg-primary/5" : "hover:bg-muted/50"}`, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CardContent, { className: "p-3 max-w-sm", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
|
|
5815
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex-1 min-w-0", onClick: onSelect, children: isEditing ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5816
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5438
5817
|
Input,
|
|
5439
5818
|
{
|
|
5440
5819
|
ref: inputRef,
|
|
@@ -5446,44 +5825,44 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
|
|
|
5446
5825
|
placeholder: config?.labels?.threadNamePlaceholder || "Conversation name"
|
|
5447
5826
|
}
|
|
5448
5827
|
),
|
|
5449
|
-
/* @__PURE__ */ (0,
|
|
5450
|
-
/* @__PURE__ */ (0,
|
|
5451
|
-
] }) : /* @__PURE__ */ (0,
|
|
5452
|
-
/* @__PURE__ */ (0,
|
|
5453
|
-
/* @__PURE__ */ (0,
|
|
5454
|
-
/* @__PURE__ */ (0,
|
|
5455
|
-
/* @__PURE__ */ (0,
|
|
5828
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Button, { size: "sm", variant: "ghost", onClick: handleSaveEdit, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Check, { className: "h-3 w-3" }) }),
|
|
5829
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Button, { size: "sm", variant: "ghost", onClick: handleCancelEdit, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.X, { className: "h-3 w-3" }) })
|
|
5830
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
5831
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h4", { className: "font-medium text-sm truncate mb-1", children: thread.title }),
|
|
5832
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
5833
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
5834
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Hash, { className: "h-3 w-3" }),
|
|
5456
5835
|
thread.messageCount,
|
|
5457
5836
|
" msgs"
|
|
5458
5837
|
] }),
|
|
5459
|
-
/* @__PURE__ */ (0,
|
|
5460
|
-
/* @__PURE__ */ (0,
|
|
5461
|
-
/* @__PURE__ */ (0,
|
|
5838
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Separator, { orientation: "vertical", className: "h-3" }),
|
|
5839
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
5840
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Calendar, { className: "h-3 w-3" }),
|
|
5462
5841
|
formatDate(thread.updatedAt, config?.labels)
|
|
5463
5842
|
] }),
|
|
5464
|
-
thread.isArchived && /* @__PURE__ */ (0,
|
|
5465
|
-
/* @__PURE__ */ (0,
|
|
5466
|
-
/* @__PURE__ */ (0,
|
|
5467
|
-
/* @__PURE__ */ (0,
|
|
5843
|
+
thread.isArchived && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
5844
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Separator, { orientation: "vertical", className: "h-3" }),
|
|
5845
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Badge, { variant: "secondary", className: "text-xs", children: [
|
|
5846
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Archive, { className: "h-2 w-2 mr-1" }),
|
|
5468
5847
|
config?.labels?.archiveThread || "Archived"
|
|
5469
5848
|
] })
|
|
5470
5849
|
] })
|
|
5471
5850
|
] })
|
|
5472
5851
|
] }) }),
|
|
5473
|
-
!isEditing && /* @__PURE__ */ (0,
|
|
5474
|
-
/* @__PURE__ */ (0,
|
|
5475
|
-
/* @__PURE__ */ (0,
|
|
5476
|
-
/* @__PURE__ */ (0,
|
|
5477
|
-
/* @__PURE__ */ (0,
|
|
5852
|
+
!isEditing && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DropdownMenu, { children: [
|
|
5853
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Button, { variant: "ghost", size: "icon", className: "h-6 w-6 m-auto", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.MoreVertical, { className: "h-3 w-3" }) }) }),
|
|
5854
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DropdownMenuContent, { align: "end", children: [
|
|
5855
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DropdownMenuItem, { onClick: () => setIsEditing(true), children: [
|
|
5856
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Edit2, { className: "h-4 w-4 mr-2" }),
|
|
5478
5857
|
config?.labels?.renameThread || "Rename"
|
|
5479
5858
|
] }),
|
|
5480
|
-
/* @__PURE__ */ (0,
|
|
5481
|
-
/* @__PURE__ */ (0,
|
|
5859
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DropdownMenuItem, { onClick: onArchive, children: [
|
|
5860
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Archive, { className: "h-4 w-4 mr-2" }),
|
|
5482
5861
|
thread.isArchived ? config?.labels?.unarchiveThread || "Unarchive" : config?.labels?.archiveThread || "Archive"
|
|
5483
5862
|
] }),
|
|
5484
|
-
/* @__PURE__ */ (0,
|
|
5485
|
-
/* @__PURE__ */ (0,
|
|
5486
|
-
/* @__PURE__ */ (0,
|
|
5863
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(DropdownMenuSeparator, {}),
|
|
5864
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DropdownMenuItem, { onClick: onDelete, className: "text-destructive", children: [
|
|
5865
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Trash2, { className: "h-4 w-4 mr-2" }),
|
|
5487
5866
|
config?.labels?.deleteThread || "Delete"
|
|
5488
5867
|
] })
|
|
5489
5868
|
] })
|
|
@@ -5491,24 +5870,24 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
|
|
|
5491
5870
|
] }) }) });
|
|
5492
5871
|
};
|
|
5493
5872
|
var CreateThreadDialog2 = ({ onCreateThread, config }) => {
|
|
5494
|
-
const [title, setTitle] = (0,
|
|
5495
|
-
const [isOpen, setIsOpen] = (0,
|
|
5873
|
+
const [title, setTitle] = (0, import_react9.useState)("");
|
|
5874
|
+
const [isOpen, setIsOpen] = (0, import_react9.useState)(false);
|
|
5496
5875
|
const handleCreate = () => {
|
|
5497
5876
|
onCreateThread(title.trim() || void 0);
|
|
5498
5877
|
setTitle("");
|
|
5499
5878
|
setIsOpen(false);
|
|
5500
5879
|
};
|
|
5501
|
-
return /* @__PURE__ */ (0,
|
|
5502
|
-
/* @__PURE__ */ (0,
|
|
5503
|
-
/* @__PURE__ */ (0,
|
|
5880
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [
|
|
5881
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(DialogTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Button, { variant: "outline", className: "w-full", children: [
|
|
5882
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Plus, { className: "h-4 w-4 mr-2" }),
|
|
5504
5883
|
config?.labels?.createNewThread || "New Conversation"
|
|
5505
5884
|
] }) }),
|
|
5506
|
-
/* @__PURE__ */ (0,
|
|
5507
|
-
/* @__PURE__ */ (0,
|
|
5508
|
-
/* @__PURE__ */ (0,
|
|
5509
|
-
/* @__PURE__ */ (0,
|
|
5885
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DialogContent, { children: [
|
|
5886
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DialogHeader, { children: [
|
|
5887
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(DialogTitle, { children: config?.labels?.createNewThread || "Create New Conversation" }),
|
|
5888
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(DialogDescription, { children: "Give your new conversation a name or leave blank to auto-generate one." })
|
|
5510
5889
|
] }),
|
|
5511
|
-
/* @__PURE__ */ (0,
|
|
5890
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5512
5891
|
Input,
|
|
5513
5892
|
{
|
|
5514
5893
|
value: title,
|
|
@@ -5518,9 +5897,9 @@ var CreateThreadDialog2 = ({ onCreateThread, config }) => {
|
|
|
5518
5897
|
autoFocus: true
|
|
5519
5898
|
}
|
|
5520
5899
|
),
|
|
5521
|
-
/* @__PURE__ */ (0,
|
|
5522
|
-
/* @__PURE__ */ (0,
|
|
5523
|
-
/* @__PURE__ */ (0,
|
|
5900
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DialogFooter, { children: [
|
|
5901
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Button, { variant: "outline", onClick: () => setIsOpen(false), children: config?.labels?.cancel || "Cancel" }),
|
|
5902
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Button, { onClick: handleCreate, children: config?.labels?.create || "Create" })
|
|
5524
5903
|
] })
|
|
5525
5904
|
] })
|
|
5526
5905
|
] });
|
|
@@ -5538,9 +5917,9 @@ var ThreadManager = ({
|
|
|
5538
5917
|
onClose,
|
|
5539
5918
|
className = ""
|
|
5540
5919
|
}) => {
|
|
5541
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
5542
|
-
const [showArchived, setShowArchived] = (0,
|
|
5543
|
-
const [deleteThreadId, setDeleteThreadId] = (0,
|
|
5920
|
+
const [searchQuery, setSearchQuery] = (0, import_react9.useState)("");
|
|
5921
|
+
const [showArchived, setShowArchived] = (0, import_react9.useState)(false);
|
|
5922
|
+
const [deleteThreadId, setDeleteThreadId] = (0, import_react9.useState)(null);
|
|
5544
5923
|
const filteredThreads = threads.filter((thread) => {
|
|
5545
5924
|
const title = (thread.title ?? "").toString();
|
|
5546
5925
|
const matchesSearch = title.toLowerCase().includes(searchQuery.toLowerCase());
|
|
@@ -5574,20 +5953,20 @@ var ThreadManager = ({
|
|
|
5574
5953
|
setDeleteThreadId(null);
|
|
5575
5954
|
};
|
|
5576
5955
|
if (!isOpen) return null;
|
|
5577
|
-
return /* @__PURE__ */ (0,
|
|
5578
|
-
/* @__PURE__ */ (0,
|
|
5579
|
-
/* @__PURE__ */ (0,
|
|
5580
|
-
/* @__PURE__ */ (0,
|
|
5581
|
-
/* @__PURE__ */ (0,
|
|
5582
|
-
/* @__PURE__ */ (0,
|
|
5956
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: `fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ${className}`, children: [
|
|
5957
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "fixed left-0 top-0 h-full w-full max-w-md border-r bg-background shadow-lg", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Card, { className: "h-full border-0 rounded-none", children: [
|
|
5958
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(CardHeader, { className: "border-b", children: [
|
|
5959
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
5960
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(CardTitle, { className: "flex items-center gap-2", children: [
|
|
5961
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.MessageSquare, { className: "h-5 w-5" }),
|
|
5583
5962
|
config?.labels?.newChat || "Conversations"
|
|
5584
5963
|
] }),
|
|
5585
|
-
/* @__PURE__ */ (0,
|
|
5964
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.X, { className: "h-4 w-4" }) })
|
|
5586
5965
|
] }),
|
|
5587
|
-
/* @__PURE__ */ (0,
|
|
5588
|
-
/* @__PURE__ */ (0,
|
|
5589
|
-
/* @__PURE__ */ (0,
|
|
5590
|
-
/* @__PURE__ */ (0,
|
|
5966
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "space-y-3", children: [
|
|
5967
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "relative", children: [
|
|
5968
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
5969
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5591
5970
|
Input,
|
|
5592
5971
|
{
|
|
5593
5972
|
placeholder: config?.labels?.search || "Search conversations...",
|
|
@@ -5597,8 +5976,8 @@ var ThreadManager = ({
|
|
|
5597
5976
|
}
|
|
5598
5977
|
)
|
|
5599
5978
|
] }),
|
|
5600
|
-
/* @__PURE__ */ (0,
|
|
5601
|
-
/* @__PURE__ */ (0,
|
|
5979
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
5980
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
5602
5981
|
Button,
|
|
5603
5982
|
{
|
|
5604
5983
|
variant: "outline",
|
|
@@ -5606,12 +5985,12 @@ var ThreadManager = ({
|
|
|
5606
5985
|
onClick: () => setShowArchived(!showArchived),
|
|
5607
5986
|
className: "text-xs",
|
|
5608
5987
|
children: [
|
|
5609
|
-
/* @__PURE__ */ (0,
|
|
5988
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Filter, { className: "h-3 w-3 mr-1" }),
|
|
5610
5989
|
showArchived ? config?.labels?.hideArchived || "Hide Archived" : config?.labels?.showArchived || "Show Archived"
|
|
5611
5990
|
]
|
|
5612
5991
|
}
|
|
5613
5992
|
),
|
|
5614
|
-
/* @__PURE__ */ (0,
|
|
5993
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Badge, { variant: "secondary", className: "text-xs", children: [
|
|
5615
5994
|
filteredThreads.length,
|
|
5616
5995
|
" / ",
|
|
5617
5996
|
threads.length
|
|
@@ -5619,14 +5998,14 @@ var ThreadManager = ({
|
|
|
5619
5998
|
] })
|
|
5620
5999
|
] })
|
|
5621
6000
|
] }),
|
|
5622
|
-
/* @__PURE__ */ (0,
|
|
5623
|
-
/* @__PURE__ */ (0,
|
|
5624
|
-
/* @__PURE__ */ (0,
|
|
5625
|
-
/* @__PURE__ */ (0,
|
|
5626
|
-
/* @__PURE__ */ (0,
|
|
5627
|
-
] }) : Object.entries(groupedThreads).map(([group, groupThreads]) => /* @__PURE__ */ (0,
|
|
5628
|
-
/* @__PURE__ */ (0,
|
|
5629
|
-
/* @__PURE__ */ (0,
|
|
6001
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(CardContent, { className: "p-0 flex-1", children: [
|
|
6002
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "p-4", children: onCreateThread && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CreateThreadDialog2, { onCreateThread, config }) }),
|
|
6003
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ScrollArea, { className: "h-[calc(100vh-280px)]", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "px-4 pb-4 space-y-4", children: Object.keys(groupedThreads).length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
6004
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.MessageSquare, { className: "h-12 w-12 mx-auto mb-3 opacity-50" }),
|
|
6005
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-sm", children: searchQuery ? config?.labels?.noThreadsFound || "No conversations found" : config?.labels?.noThreadsYet || "No conversations yet" })
|
|
6006
|
+
] }) : Object.entries(groupedThreads).map(([group, groupThreads]) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { children: [
|
|
6007
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h3", { className: "text-sm font-medium text-muted-foreground mb-2 px-2", children: group }),
|
|
6008
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "space-y-2", children: groupThreads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5630
6009
|
ThreadItem,
|
|
5631
6010
|
{
|
|
5632
6011
|
thread,
|
|
@@ -5642,14 +6021,14 @@ var ThreadManager = ({
|
|
|
5642
6021
|
] }, group)) }) })
|
|
5643
6022
|
] })
|
|
5644
6023
|
] }) }),
|
|
5645
|
-
deleteThreadId && /* @__PURE__ */ (0,
|
|
5646
|
-
/* @__PURE__ */ (0,
|
|
5647
|
-
/* @__PURE__ */ (0,
|
|
5648
|
-
/* @__PURE__ */ (0,
|
|
6024
|
+
deleteThreadId && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(AlertDialogContent, { children: [
|
|
6025
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(AlertDialogHeader, { children: [
|
|
6026
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(AlertDialogTitle, { children: config?.labels?.deleteConfirmTitle || "Delete Conversation" }),
|
|
6027
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(AlertDialogDescription, { children: config?.labels?.deleteConfirmDescription || "Are you sure you want to delete this conversation? This action cannot be undone." })
|
|
5649
6028
|
] }),
|
|
5650
|
-
/* @__PURE__ */ (0,
|
|
5651
|
-
/* @__PURE__ */ (0,
|
|
5652
|
-
/* @__PURE__ */ (0,
|
|
6029
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(AlertDialogFooter, { children: [
|
|
6030
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(AlertDialogCancel, { children: config?.labels?.cancel || "Cancel" }),
|
|
6031
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5653
6032
|
AlertDialogAction,
|
|
5654
6033
|
{
|
|
5655
6034
|
onClick: () => deleteThreadId && handleDeleteThread(deleteThreadId),
|
|
@@ -5661,55 +6040,29 @@ var ThreadManager = ({
|
|
|
5661
6040
|
] }) })
|
|
5662
6041
|
] }) });
|
|
5663
6042
|
};
|
|
5664
|
-
|
|
5665
|
-
// src/lib/chatUtils.ts
|
|
5666
|
-
var chatUtils = {
|
|
5667
|
-
generateId: () => globalThis.crypto?.randomUUID?.() ?? `id-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,
|
|
5668
|
-
generateMessageId: () => chatUtils.generateId(),
|
|
5669
|
-
generateThreadId: () => chatUtils.generateId(),
|
|
5670
|
-
createMessage: (role, content, attachments) => ({
|
|
5671
|
-
id: chatUtils.generateMessageId(),
|
|
5672
|
-
role,
|
|
5673
|
-
content,
|
|
5674
|
-
timestamp: Date.now(),
|
|
5675
|
-
attachments,
|
|
5676
|
-
isComplete: true
|
|
5677
|
-
}),
|
|
5678
|
-
createThread: (title) => ({
|
|
5679
|
-
id: chatUtils.generateThreadId(),
|
|
5680
|
-
title,
|
|
5681
|
-
createdAt: Date.now(),
|
|
5682
|
-
updatedAt: Date.now(),
|
|
5683
|
-
messageCount: 0
|
|
5684
|
-
}),
|
|
5685
|
-
generateThreadTitle: (firstMessage) => {
|
|
5686
|
-
const cleaned = firstMessage.replace(/[^\w\s]/g, "").trim();
|
|
5687
|
-
const words = cleaned.split(/\s+/).slice(0, 6);
|
|
5688
|
-
return words.join(" ") || "Nova Conversa";
|
|
5689
|
-
}
|
|
5690
|
-
};
|
|
5691
6043
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5692
6044
|
0 && (module.exports = {
|
|
6045
|
+
AgentBadge,
|
|
5693
6046
|
ChatHeader,
|
|
5694
6047
|
ChatInput,
|
|
5695
6048
|
ChatUI,
|
|
5696
6049
|
ChatUserContextProvider,
|
|
5697
6050
|
Message,
|
|
6051
|
+
ParticipantsSelector,
|
|
5698
6052
|
Sidebar,
|
|
6053
|
+
TargetAgentSelector,
|
|
5699
6054
|
ThreadManager,
|
|
5700
6055
|
UserMenu,
|
|
5701
6056
|
UserProfile,
|
|
5702
|
-
|
|
6057
|
+
assignAgentColors,
|
|
5703
6058
|
chatUtils,
|
|
5704
6059
|
cn,
|
|
5705
|
-
configUtils,
|
|
5706
6060
|
createObjectUrlFromDataUrl,
|
|
5707
6061
|
defaultChatConfig,
|
|
5708
|
-
featureFlags,
|
|
5709
6062
|
formatDate,
|
|
6063
|
+
getAgentColor,
|
|
6064
|
+
getAgentInitials,
|
|
5710
6065
|
mergeConfig,
|
|
5711
|
-
|
|
5712
|
-
useChatUserContext,
|
|
5713
|
-
validateConfig
|
|
6066
|
+
useChatUserContext
|
|
5714
6067
|
});
|
|
5715
6068
|
//# sourceMappingURL=index.cjs.map
|