@optifye/dashboard-core 6.10.17 → 6.10.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -58070,6 +58070,2056 @@ var ImprovementCenterView = () => {
58070
58070
  ] });
58071
58071
  };
58072
58072
  var ImprovementCenterView_default = ImprovementCenterView;
58073
+ var ThreadSidebar = ({
58074
+ activeThreadId,
58075
+ onSelectThread,
58076
+ onNewThread,
58077
+ className = ""
58078
+ }) => {
58079
+ const { threads, isLoading, error, deleteThread: deleteThread2 } = useThreads();
58080
+ const [deletingId, setDeletingId] = React24.useState(null);
58081
+ const handleDelete = async (e, threadId) => {
58082
+ e.stopPropagation();
58083
+ if (confirm("Are you sure you want to delete this conversation?")) {
58084
+ setDeletingId(threadId);
58085
+ try {
58086
+ await deleteThread2(threadId);
58087
+ if (activeThreadId === threadId) {
58088
+ onNewThread();
58089
+ }
58090
+ } catch (error2) {
58091
+ console.error("Error deleting thread:", error2);
58092
+ alert("Failed to delete conversation. Please try again.");
58093
+ } finally {
58094
+ setDeletingId(null);
58095
+ }
58096
+ }
58097
+ };
58098
+ const formatDate2 = (dateString) => {
58099
+ const date = new Date(dateString);
58100
+ const now2 = /* @__PURE__ */ new Date();
58101
+ const diffMs = now2.getTime() - date.getTime();
58102
+ const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
58103
+ if (diffDays === 0) {
58104
+ return "Today";
58105
+ } else if (diffDays === 1) {
58106
+ return "Yesterday";
58107
+ } else if (diffDays < 7) {
58108
+ return date.toLocaleDateString("en-US", { weekday: "short" });
58109
+ } else {
58110
+ return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
58111
+ }
58112
+ };
58113
+ if (error) {
58114
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `p-4 text-red-600 text-sm ${className}`, children: "Failed to load conversations" });
58115
+ }
58116
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col h-screen bg-gray-50 border-r border-gray-200 ${className}`, children: [
58117
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-shrink-0 p-4 border-b border-gray-200", children: [
58118
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Chat History" }),
58119
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 mt-1", children: "Your previous conversations" })
58120
+ ] }),
58121
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto min-h-0", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center p-8", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "sm" }) }) : threads.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center text-gray-500 text-sm", children: "No conversations yet" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2", children: threads.map((thread) => /* @__PURE__ */ jsxRuntime.jsxs(
58122
+ "div",
58123
+ {
58124
+ onClick: () => onSelectThread(thread.id),
58125
+ className: `group relative flex items-start gap-3 px-4 py-3 cursor-pointer transition-all ${activeThreadId === thread.id ? "bg-blue-50 border-l-4 border-blue-600 hover:bg-blue-100" : "hover:bg-gray-100 border-l-4 border-transparent"}`,
58126
+ children: [
58127
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: `w-4 h-4 mt-0.5 flex-shrink-0 ${activeThreadId === thread.id ? "text-blue-600" : "text-gray-400"}` }),
58128
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
58129
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: `text-sm font-medium truncate ${activeThreadId === thread.id ? "text-blue-900" : "text-gray-900"}`, children: thread.title || "Untitled Chat" }),
58130
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-xs mt-0.5 ${activeThreadId === thread.id ? "text-blue-700" : "text-gray-500"}`, children: formatDate2(thread.created_at) })
58131
+ ] }),
58132
+ deletingId === thread.id ? /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(
58133
+ "button",
58134
+ {
58135
+ onClick: (e) => handleDelete(e, thread.id),
58136
+ className: "flex-shrink-0 opacity-0 group-hover:opacity-100 p-1 hover:bg-gray-200 rounded transition-all",
58137
+ title: "Delete conversation",
58138
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "w-3.5 h-3.5 text-gray-500" })
58139
+ }
58140
+ )
58141
+ ]
58142
+ },
58143
+ thread.id
58144
+ )) }) }),
58145
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 p-4 border-t border-gray-200", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 text-center", children: [
58146
+ threads.length,
58147
+ " conversation",
58148
+ threads.length !== 1 ? "s" : ""
58149
+ ] }) })
58150
+ ] });
58151
+ };
58152
+ var ProfilePicture = React24__namespace.default.memo(({
58153
+ alt = "Axel",
58154
+ className = "",
58155
+ size = "md",
58156
+ animate = false
58157
+ }) => {
58158
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(AxelOrb, { size, animate }) });
58159
+ });
58160
+ ProfilePicture.displayName = "ProfilePicture";
58161
+ var GREETING_MESSAGES = [
58162
+ "How can I help you today?",
58163
+ "What would you like to know?",
58164
+ "Ready to optimize your operations?",
58165
+ "How can I assist you today?"
58166
+ ];
58167
+ var getDailyGreeting = () => {
58168
+ const now2 = /* @__PURE__ */ new Date();
58169
+ const startOfYear = new Date(now2.getFullYear(), 0, 0);
58170
+ const diff = now2.getTime() - startOfYear.getTime();
58171
+ const oneDay = 1e3 * 60 * 60 * 24;
58172
+ const dayOfYear = Math.floor(diff / oneDay);
58173
+ const index = dayOfYear % GREETING_MESSAGES.length;
58174
+ return GREETING_MESSAGES[index];
58175
+ };
58176
+ var AIAgentView = () => {
58177
+ const { navigate, pathname } = useNavigation();
58178
+ const config = useDashboardConfig();
58179
+ const entityConfig = useEntityConfig();
58180
+ const dateTimeConfig = useDateTimeConfig();
58181
+ const shiftConfig = useShiftConfig();
58182
+ const { formatNumber } = useFormatNumber();
58183
+ const [inputValue, setInputValue] = React24.useState("");
58184
+ const [loadingThreads, setLoadingThreads] = React24.useState(/* @__PURE__ */ new Set());
58185
+ const [lastError, setLastError] = React24.useState(null);
58186
+ const [copiedMessageId, setCopiedMessageId] = React24.useState(null);
58187
+ const [activeThreadId, setActiveThreadId] = React24.useState(void 0);
58188
+ const [isSidebarOpen, setIsSidebarOpen] = React24.useState(false);
58189
+ const [streamingStates, setStreamingStates] = React24.useState(/* @__PURE__ */ new Map());
58190
+ const [userId, setUserId] = React24.useState(null);
58191
+ const [pendingThreadId, setPendingThreadId] = React24.useState(null);
58192
+ const [isTransitioning, setIsTransitioning] = React24.useState(false);
58193
+ const [typedText, setTypedText] = React24.useState("");
58194
+ const [newChatCount, setNewChatCount] = React24.useState(0);
58195
+ const [greetingReset, setGreetingReset] = React24.useState(0);
58196
+ const [hasStartedTyping, setHasStartedTyping] = React24.useState(false);
58197
+ const [typingStartTime, setTypingStartTime] = React24.useState(null);
58198
+ const [lastTypingTime, setLastTypingTime] = React24.useState(null);
58199
+ const [characterCount, setCharacterCount] = React24.useState(0);
58200
+ const typingTimeoutRef = React24.useRef(null);
58201
+ const currentGreeting = React24.useMemo(() => getDailyGreeting(), [greetingReset]);
58202
+ const isThreadLoading = (threadId) => {
58203
+ return threadId ? loadingThreads.has(threadId) : false;
58204
+ };
58205
+ const getStreamingState = (threadId) => {
58206
+ return threadId ? streamingStates.get(threadId) || { message: "", reasoning: "" } : { message: "", reasoning: "" };
58207
+ };
58208
+ const trackTypingStart = () => {
58209
+ if (!hasStartedTyping) {
58210
+ const now2 = Date.now();
58211
+ setHasStartedTyping(true);
58212
+ setTypingStartTime(now2);
58213
+ setLastTypingTime(now2);
58214
+ trackCoreEvent("AI Agent Input Started", {
58215
+ line_id: lineId,
58216
+ company_id: companyId,
58217
+ shift_id: shiftId,
58218
+ active_thread_id: activeThreadId,
58219
+ has_existing_messages: messages.length > 0,
58220
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
58221
+ });
58222
+ }
58223
+ };
58224
+ const trackTypingProgress = (newValue) => {
58225
+ const now2 = Date.now();
58226
+ setLastTypingTime(now2);
58227
+ setCharacterCount(newValue.length);
58228
+ if (typingTimeoutRef.current) {
58229
+ clearTimeout(typingTimeoutRef.current);
58230
+ }
58231
+ typingTimeoutRef.current = setTimeout(() => {
58232
+ if (hasStartedTyping && typingStartTime && newValue.length > 0) {
58233
+ const typingDuration = now2 - typingStartTime;
58234
+ trackCoreEvent("AI Agent Input Typing Progress", {
58235
+ line_id: lineId,
58236
+ company_id: companyId,
58237
+ shift_id: shiftId,
58238
+ active_thread_id: activeThreadId,
58239
+ character_count: newValue.length,
58240
+ typing_duration_ms: typingDuration,
58241
+ has_existing_messages: messages.length > 0,
58242
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
58243
+ });
58244
+ }
58245
+ }, 2e3);
58246
+ };
58247
+ const trackMessageSent = (messageContent) => {
58248
+ if (hasStartedTyping && typingStartTime) {
58249
+ const now2 = Date.now();
58250
+ const totalTypingDuration = now2 - typingStartTime;
58251
+ trackCoreEvent("AI Agent Message Sent", {
58252
+ line_id: lineId,
58253
+ company_id: companyId,
58254
+ shift_id: shiftId,
58255
+ active_thread_id: activeThreadId,
58256
+ message_length: messageContent.length,
58257
+ character_count: messageContent.length,
58258
+ typing_duration_ms: totalTypingDuration,
58259
+ has_existing_messages: messages.length > 0,
58260
+ is_new_conversation: !activeThreadId,
58261
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
58262
+ });
58263
+ }
58264
+ resetTypingState();
58265
+ };
58266
+ const resetTypingState = () => {
58267
+ setHasStartedTyping(false);
58268
+ setTypingStartTime(null);
58269
+ setLastTypingTime(null);
58270
+ setCharacterCount(0);
58271
+ if (typingTimeoutRef.current) {
58272
+ clearTimeout(typingTimeoutRef.current);
58273
+ typingTimeoutRef.current = null;
58274
+ }
58275
+ };
58276
+ const textareaRef = React24.useRef(null);
58277
+ const messagesEndRef = React24.useRef(null);
58278
+ const containerRef = React24.useRef(null);
58279
+ const renderedContentCache = React24.useRef(/* @__PURE__ */ new Map());
58280
+ const { createThread, mutate: mutateThreads } = useThreads();
58281
+ const { messages, addMessage, setMessages } = useMessages(activeThreadId);
58282
+ const agnoApiUrl = config.endpoints?.agnoApiUrl || "https://fastapi-production-111f9.up.railway.app";
58283
+ const sseClient = React24.useMemo(() => {
58284
+ console.log("[AIAgentView] Using AGNO API URL:", agnoApiUrl);
58285
+ return new SSEChatClient(agnoApiUrl);
58286
+ }, [agnoApiUrl]);
58287
+ const getLineIdFromPath = () => {
58288
+ const pathParts = pathname.split("/");
58289
+ const lineIdIndex = pathParts.findIndex((part) => part === "ai-agent") + 1;
58290
+ if (lineIdIndex > 0 && lineIdIndex < pathParts.length) {
58291
+ return pathParts[lineIdIndex];
58292
+ }
58293
+ return entityConfig.defaultLineId || LINE_1_UUID;
58294
+ };
58295
+ const lineId = getLineIdFromPath();
58296
+ const { shiftId } = getCurrentShift(dateTimeConfig.defaultTimezone || "Asia/Kolkata", shiftConfig);
58297
+ const companyId = entityConfig.companyId || "default-company-id";
58298
+ const configuredLineIds = getConfiguredLineIds(entityConfig);
58299
+ const lineDisplayNames = getAllLineDisplayNames(entityConfig);
58300
+ const allLines = configuredLineIds.map((id3) => ({
58301
+ id: id3,
58302
+ name: lineDisplayNames[id3] || `Line ${id3.substring(0, 8)}`
58303
+ }));
58304
+ const ACTIVE_THREAD_STORAGE_KEY = `ai-agent-active-thread-${lineId}`;
58305
+ React24.useLayoutEffect(() => {
58306
+ const savedThreadId = localStorage.getItem(ACTIVE_THREAD_STORAGE_KEY);
58307
+ if (savedThreadId && savedThreadId !== "undefined") {
58308
+ setActiveThreadId(savedThreadId);
58309
+ }
58310
+ }, [ACTIVE_THREAD_STORAGE_KEY]);
58311
+ React24.useEffect(() => {
58312
+ if (activeThreadId) {
58313
+ localStorage.setItem(ACTIVE_THREAD_STORAGE_KEY, activeThreadId);
58314
+ } else {
58315
+ localStorage.removeItem(ACTIVE_THREAD_STORAGE_KEY);
58316
+ }
58317
+ }, [activeThreadId, ACTIVE_THREAD_STORAGE_KEY]);
58318
+ React24.useEffect(() => {
58319
+ const handleVisibilityChange = () => {
58320
+ if (document.visibilityState === "hidden" && activeThreadId) {
58321
+ localStorage.setItem(ACTIVE_THREAD_STORAGE_KEY, activeThreadId);
58322
+ }
58323
+ };
58324
+ const handleBeforeUnload = () => {
58325
+ if (activeThreadId) {
58326
+ localStorage.setItem(ACTIVE_THREAD_STORAGE_KEY, activeThreadId);
58327
+ }
58328
+ };
58329
+ document.addEventListener("visibilitychange", handleVisibilityChange);
58330
+ window.addEventListener("beforeunload", handleBeforeUnload);
58331
+ return () => {
58332
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
58333
+ window.removeEventListener("beforeunload", handleBeforeUnload);
58334
+ if (activeThreadId) {
58335
+ localStorage.setItem(ACTIVE_THREAD_STORAGE_KEY, activeThreadId);
58336
+ }
58337
+ };
58338
+ }, [activeThreadId, ACTIVE_THREAD_STORAGE_KEY]);
58339
+ React24.useEffect(() => {
58340
+ if (textareaRef.current) {
58341
+ textareaRef.current.style.height = "auto";
58342
+ textareaRef.current.style.height = `${Math.min(textareaRef.current.scrollHeight, 120)}px`;
58343
+ }
58344
+ }, [inputValue]);
58345
+ const scrollToBottom = () => {
58346
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
58347
+ };
58348
+ React24.useEffect(() => {
58349
+ if (activeThreadId && messages.length > 0) {
58350
+ setTimeout(scrollToBottom, 100);
58351
+ }
58352
+ }, [activeThreadId]);
58353
+ React24.useEffect(() => {
58354
+ if (messages.length === 0 && !isTransitioning) {
58355
+ let index = 0;
58356
+ setTypedText("");
58357
+ const typeInterval = setInterval(() => {
58358
+ if (index < currentGreeting.length) {
58359
+ setTypedText(currentGreeting.substring(0, index + 1));
58360
+ index++;
58361
+ } else {
58362
+ clearInterval(typeInterval);
58363
+ }
58364
+ }, 50);
58365
+ return () => clearInterval(typeInterval);
58366
+ }
58367
+ }, [messages.length, isTransitioning, greetingReset, currentGreeting]);
58368
+ React24.useEffect(() => {
58369
+ if (isSidebarOpen) {
58370
+ setNewChatCount(0);
58371
+ }
58372
+ }, [isSidebarOpen]);
58373
+ const copyToClipboard = async (text, messageId) => {
58374
+ try {
58375
+ await navigator.clipboard.writeText(text);
58376
+ setCopiedMessageId(messageId);
58377
+ setTimeout(() => setCopiedMessageId(null), 2e3);
58378
+ } catch (err) {
58379
+ console.error("Failed to copy text: ", err);
58380
+ }
58381
+ };
58382
+ const handleNewThread = () => {
58383
+ setActiveThreadId(void 0);
58384
+ setMessages([]);
58385
+ setInputValue("");
58386
+ setPendingThreadId(null);
58387
+ setTypedText("");
58388
+ setGreetingReset((prev) => prev + 1);
58389
+ resetTypingState();
58390
+ localStorage.removeItem(ACTIVE_THREAD_STORAGE_KEY);
58391
+ textareaRef.current?.focus();
58392
+ };
58393
+ React24.useEffect(() => {
58394
+ return () => {
58395
+ if (typingTimeoutRef.current) {
58396
+ clearTimeout(typingTimeoutRef.current);
58397
+ }
58398
+ };
58399
+ }, []);
58400
+ React24.useEffect(() => {
58401
+ const checkAuth = async () => {
58402
+ const supabase2 = _getSupabaseInstance();
58403
+ const { data: { session } } = await supabase2.auth.getSession();
58404
+ if (session?.user) {
58405
+ setUserId(session.user.id);
58406
+ console.log("[AIAgentView] User authenticated:", session.user.id);
58407
+ } else {
58408
+ console.log("[AIAgentView] No authenticated session found");
58409
+ }
58410
+ };
58411
+ checkAuth();
58412
+ const supabase = _getSupabaseInstance();
58413
+ const { data: { subscription } } = supabase.auth.onAuthStateChange((event, session) => {
58414
+ if (session?.user) {
58415
+ setUserId(session.user.id);
58416
+ } else {
58417
+ setUserId(null);
58418
+ }
58419
+ });
58420
+ return () => {
58421
+ subscription.unsubscribe();
58422
+ };
58423
+ }, []);
58424
+ const handleSubmit = async (e) => {
58425
+ e.preventDefault();
58426
+ if (!inputValue.trim() || !userId) return;
58427
+ let currentThreadId = activeThreadId || `temp-${Date.now()}`;
58428
+ if (isThreadLoading(currentThreadId)) return;
58429
+ const userMessage = inputValue.trim();
58430
+ trackMessageSent(userMessage);
58431
+ if (displayMessages.length === 0) {
58432
+ setIsTransitioning(true);
58433
+ setTimeout(() => {
58434
+ setIsTransitioning(false);
58435
+ }, 800);
58436
+ }
58437
+ setInputValue("");
58438
+ setLoadingThreads((prev) => new Set(prev).add(currentThreadId));
58439
+ setLastError(null);
58440
+ if (!activeThreadId) {
58441
+ setPendingThreadId(currentThreadId);
58442
+ }
58443
+ setStreamingStates((prev) => {
58444
+ const newMap = new Map(prev);
58445
+ newMap.set(currentThreadId, { message: "", reasoning: "" });
58446
+ return newMap;
58447
+ });
58448
+ const tempUserMessage = {
58449
+ id: Date.now(),
58450
+ // Temporary ID
58451
+ thread_id: activeThreadId || "",
58452
+ role: "user",
58453
+ content: userMessage,
58454
+ reasoning: null,
58455
+ model_id: null,
58456
+ token_usage: null,
58457
+ metadata: null,
58458
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
58459
+ position: messages.length
58460
+ };
58461
+ setMessages((prev) => [...prev, tempUserMessage]);
58462
+ setTimeout(scrollToBottom, 100);
58463
+ try {
58464
+ await sseClient.sendMessage(
58465
+ userMessage,
58466
+ userId,
58467
+ activeThreadId || null,
58468
+ {
58469
+ companyId,
58470
+ lineId,
58471
+ shiftId,
58472
+ allLines
58473
+ },
58474
+ {
58475
+ onThreadCreated: (threadId) => {
58476
+ if (!activeThreadId) {
58477
+ const oldThreadId = currentThreadId;
58478
+ currentThreadId = threadId;
58479
+ setActiveThreadId(threadId);
58480
+ setPendingThreadId(null);
58481
+ if (!isSidebarOpen) {
58482
+ setNewChatCount((prev) => prev + 1);
58483
+ }
58484
+ setLoadingThreads((prev) => {
58485
+ const newSet = new Set(prev);
58486
+ if (newSet.has(oldThreadId)) {
58487
+ newSet.delete(oldThreadId);
58488
+ newSet.add(threadId);
58489
+ }
58490
+ return newSet;
58491
+ });
58492
+ setStreamingStates((prev) => {
58493
+ const newMap = new Map(prev);
58494
+ const streamingState = newMap.get(oldThreadId);
58495
+ if (streamingState) {
58496
+ newMap.delete(oldThreadId);
58497
+ newMap.set(threadId, streamingState);
58498
+ }
58499
+ return newMap;
58500
+ });
58501
+ mutateThreads();
58502
+ }
58503
+ },
58504
+ onMessage: (text) => {
58505
+ setStreamingStates((prev) => {
58506
+ const newMap = new Map(prev);
58507
+ const current = newMap.get(currentThreadId) || { message: "", reasoning: "" };
58508
+ newMap.set(currentThreadId, { ...current, message: current.message + text });
58509
+ return newMap;
58510
+ });
58511
+ },
58512
+ onComplete: async (messageId) => {
58513
+ if (currentThreadId && !currentThreadId.startsWith("temp-")) {
58514
+ const updatedMessages = await getAllThreadMessages(currentThreadId);
58515
+ setMessages(updatedMessages);
58516
+ }
58517
+ setStreamingStates((prev) => {
58518
+ const newMap = new Map(prev);
58519
+ newMap.delete(currentThreadId);
58520
+ return newMap;
58521
+ });
58522
+ setLoadingThreads((prev) => {
58523
+ const newSet = new Set(prev);
58524
+ newSet.delete(currentThreadId);
58525
+ return newSet;
58526
+ });
58527
+ if (!activeThreadId) {
58528
+ setPendingThreadId(null);
58529
+ }
58530
+ },
58531
+ onError: (error) => {
58532
+ console.error("Chat error:", error);
58533
+ setLastError(error);
58534
+ setLoadingThreads((prev) => {
58535
+ const newSet = new Set(prev);
58536
+ newSet.delete(currentThreadId);
58537
+ return newSet;
58538
+ });
58539
+ setStreamingStates((prev) => {
58540
+ const newMap = new Map(prev);
58541
+ newMap.delete(currentThreadId);
58542
+ return newMap;
58543
+ });
58544
+ if (!activeThreadId) {
58545
+ setPendingThreadId(null);
58546
+ }
58547
+ setMessages((prev) => prev.slice(0, -1));
58548
+ }
58549
+ }
58550
+ );
58551
+ } catch (error) {
58552
+ console.error("[AIAgentView] Error in chat:", error);
58553
+ const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
58554
+ setLastError(errorMessage);
58555
+ setLoadingThreads((prev) => {
58556
+ const newSet = new Set(prev);
58557
+ newSet.delete(currentThreadId);
58558
+ return newSet;
58559
+ });
58560
+ setStreamingStates((prev) => {
58561
+ const newMap = new Map(prev);
58562
+ newMap.delete(currentThreadId);
58563
+ return newMap;
58564
+ });
58565
+ if (!activeThreadId) {
58566
+ setPendingThreadId(null);
58567
+ }
58568
+ setMessages((prev) => prev.slice(0, -1));
58569
+ }
58570
+ };
58571
+ const handleKeyDown = (e) => {
58572
+ if (e.key === "Enter" && !e.shiftKey) {
58573
+ e.preventDefault();
58574
+ if (!isCurrentThreadLoading) {
58575
+ handleSubmit(e);
58576
+ }
58577
+ }
58578
+ };
58579
+ const formatMessage = (content) => {
58580
+ const processInlineFormatting = (text) => {
58581
+ text = text.replace(/\*\*(.*?)\*\*/g, '<strong class="font-semibold text-gray-900">$1</strong>');
58582
+ text = text.replace(/`([^`]+)`/g, '<code class="bg-gray-100 px-1.5 py-0.5 rounded text-sm font-mono text-gray-800">$1</code>');
58583
+ return text;
58584
+ };
58585
+ const parseTableFromText = (lines2, startIndex) => {
58586
+ const tableLines = [];
58587
+ let i = startIndex;
58588
+ while (i < lines2.length) {
58589
+ const line = lines2[i].trim();
58590
+ if (!line) {
58591
+ i++;
58592
+ break;
58593
+ }
58594
+ if (line.includes("|") || line.match(/^[-|=\s]+$/)) {
58595
+ tableLines.push(line);
58596
+ i++;
58597
+ } else {
58598
+ break;
58599
+ }
58600
+ }
58601
+ if (tableLines.length === 0) return { html: "", endIndex: startIndex };
58602
+ const dataLines = tableLines.filter((line) => !line.match(/^[-|=\s]+$/));
58603
+ if (dataLines.length === 0) return { html: "", endIndex: i };
58604
+ let headerRow = [];
58605
+ let dataRows = [];
58606
+ const firstLine = dataLines[0];
58607
+ if (firstLine.includes("|")) {
58608
+ const cells = firstLine.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
58609
+ if (cells.length >= 2) {
58610
+ headerRow = cells;
58611
+ for (let j = 1; j < dataLines.length; j++) {
58612
+ const row = dataLines[j];
58613
+ if (row.includes("|")) {
58614
+ const rowCells = row.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
58615
+ while (rowCells.length < headerRow.length) rowCells.push("");
58616
+ if (rowCells.length > headerRow.length) rowCells.splice(headerRow.length);
58617
+ dataRows.push(rowCells);
58618
+ }
58619
+ }
58620
+ }
58621
+ }
58622
+ if (headerRow.length === 0) {
58623
+ for (const line of dataLines) {
58624
+ if (line.includes("|")) {
58625
+ const rowCells = line.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
58626
+ if (rowCells.length >= 2) {
58627
+ dataRows.push(rowCells);
58628
+ }
58629
+ }
58630
+ }
58631
+ if (dataRows.length > 0 && dataRows[0].length > 0) {
58632
+ headerRow = dataRows[0].map((_, index) => `Column ${index + 1}`);
58633
+ }
58634
+ }
58635
+ if (headerRow.length > 0 && dataRows.length > 0) {
58636
+ let tableHtml = '<div class="overflow-x-auto my-4"><table class="min-w-full border-collapse border border-gray-300 rounded-lg shadow-sm">';
58637
+ tableHtml += '<thead class="bg-gray-50">';
58638
+ tableHtml += "<tr>";
58639
+ headerRow.forEach((header) => {
58640
+ tableHtml += `<th class="border border-gray-300 px-4 py-2 text-left font-semibold text-gray-900">${processInlineFormatting(header)}</th>`;
58641
+ });
58642
+ tableHtml += "</tr>";
58643
+ tableHtml += "</thead>";
58644
+ tableHtml += '<tbody class="bg-white divide-y divide-gray-200">';
58645
+ dataRows.forEach((row, rowIndex) => {
58646
+ tableHtml += `<tr class="${rowIndex % 2 === 0 ? "bg-white" : "bg-gray-50"}">`;
58647
+ row.forEach((cell) => {
58648
+ tableHtml += `<td class="border border-gray-300 px-4 py-2 text-gray-800">${processInlineFormatting(cell)}</td>`;
58649
+ });
58650
+ tableHtml += "</tr>";
58651
+ });
58652
+ tableHtml += "</tbody>";
58653
+ tableHtml += "</table></div>";
58654
+ return { html: tableHtml, endIndex: i };
58655
+ }
58656
+ return { html: "", endIndex: startIndex };
58657
+ };
58658
+ const processedContent = content;
58659
+ const lines = processedContent.split("\n");
58660
+ const formattedLines = [];
58661
+ let inList = false;
58662
+ for (let i = 0; i < lines.length; i++) {
58663
+ let line = lines[i];
58664
+ const trimmedLine = line.trim();
58665
+ if (!trimmedLine) {
58666
+ if (inList) {
58667
+ formattedLines.push("</ul>");
58668
+ inList = false;
58669
+ }
58670
+ formattedLines.push("<br/>");
58671
+ continue;
58672
+ }
58673
+ if (trimmedLine.includes("|") && (trimmedLine.match(/\|/g) || []).length >= 1) {
58674
+ if (inList) {
58675
+ formattedLines.push("</ul>");
58676
+ inList = false;
58677
+ }
58678
+ const tableResult = parseTableFromText(lines, i);
58679
+ if (tableResult.html) {
58680
+ formattedLines.push(tableResult.html);
58681
+ i = tableResult.endIndex - 1;
58682
+ continue;
58683
+ }
58684
+ }
58685
+ if (trimmedLine.startsWith("###")) {
58686
+ if (inList) {
58687
+ formattedLines.push("</ul>");
58688
+ inList = false;
58689
+ }
58690
+ const headerText = processInlineFormatting(trimmedLine.replace(/^###\s*/, ""));
58691
+ formattedLines.push(`<h3 class="text-lg font-semibold text-gray-900 mt-4 mb-2">${headerText}</h3>`);
58692
+ continue;
58693
+ } else if (trimmedLine.startsWith("##")) {
58694
+ if (inList) {
58695
+ formattedLines.push("</ul>");
58696
+ inList = false;
58697
+ }
58698
+ const headerText = processInlineFormatting(trimmedLine.replace(/^##\s*/, ""));
58699
+ formattedLines.push(`<h2 class="text-xl font-semibold text-gray-900 mt-4 mb-2">${headerText}</h2>`);
58700
+ continue;
58701
+ } else if (trimmedLine.startsWith("#")) {
58702
+ if (inList) {
58703
+ formattedLines.push("</ul>");
58704
+ inList = false;
58705
+ }
58706
+ const headerText = processInlineFormatting(trimmedLine.replace(/^#\s*/, ""));
58707
+ formattedLines.push(`<h1 class="text-3xl font-semibold text-gray-900 mt-4 mb-3">${headerText}</h1>`);
58708
+ continue;
58709
+ }
58710
+ const listMatch = trimmedLine.match(/^([-*•]\s+|\d+\.\s+|^\s*[-*•]\s+)/);
58711
+ if (listMatch) {
58712
+ if (!inList) {
58713
+ formattedLines.push('<ul class="space-y-1 mt-2 mb-2">');
58714
+ inList = true;
58715
+ }
58716
+ const listContent = processInlineFormatting(trimmedLine.replace(/^([-*•]\s+|\d+\.\s+|\s*[-*•]\s+)/, ""));
58717
+ formattedLines.push(`<li class="ml-4 text-gray-700 flex items-start"><span class="mr-2 text-gray-500">\u2022</span><span>${listContent}</span></li>`);
58718
+ continue;
58719
+ } else if (inList) {
58720
+ formattedLines.push("</ul>");
58721
+ inList = false;
58722
+ }
58723
+ if (trimmedLine.match(/^---+$/)) {
58724
+ formattedLines.push('<hr class="my-4 border-gray-200"/>');
58725
+ continue;
58726
+ }
58727
+ if (trimmedLine) {
58728
+ const processedLine = processInlineFormatting(line);
58729
+ if (trimmedLine.endsWith(":") && trimmedLine.length < 50 && !trimmedLine.includes("**")) {
58730
+ formattedLines.push(`<h3 class="text-lg font-semibold text-gray-900 mt-4 mb-2">${processedLine}</h3>`);
58731
+ } else {
58732
+ formattedLines.push(`<p class="text-gray-800 leading-relaxed mb-2">${processedLine}</p>`);
58733
+ }
58734
+ }
58735
+ }
58736
+ if (inList) {
58737
+ formattedLines.push("</ul>");
58738
+ }
58739
+ return formattedLines.join("");
58740
+ };
58741
+ const formatTime5 = (timestamp) => {
58742
+ const date = new Date(timestamp);
58743
+ return date.toLocaleTimeString([], {
58744
+ hour: "2-digit",
58745
+ minute: "2-digit",
58746
+ hour12: false
58747
+ });
58748
+ };
58749
+ const displayMessages = [...messages];
58750
+ const effectiveThreadId = activeThreadId || pendingThreadId || void 0;
58751
+ const currentStreaming = getStreamingState(effectiveThreadId);
58752
+ const isCurrentThreadLoading = isThreadLoading(effectiveThreadId);
58753
+ if (isCurrentThreadLoading && currentStreaming.message) {
58754
+ displayMessages.push({
58755
+ id: -1,
58756
+ // Use -1 for streaming message to identify it
58757
+ thread_id: activeThreadId || "",
58758
+ role: "assistant",
58759
+ content: currentStreaming.message,
58760
+ reasoning: currentStreaming.reasoning || null,
58761
+ model_id: "gpt-4o-mini",
58762
+ token_usage: null,
58763
+ metadata: null,
58764
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
58765
+ position: messages.length
58766
+ });
58767
+ }
58768
+ const renderAssistantContent = (content) => {
58769
+ const cached = renderedContentCache.current.get(content);
58770
+ if (cached) {
58771
+ return cached;
58772
+ }
58773
+ const parseChartPatterns = (text) => {
58774
+ const chartElements = [];
58775
+ let lastIndex = 0;
58776
+ console.log("[DEBUG] Parsing chart patterns from text:", text);
58777
+ const chartRegex = /\[\s*(?:Calling\s+|CALL\s+)?(create_[a-z_]+)\s*\(([\s\S]*?)\)\s*\]/g;
58778
+ let match;
58779
+ const processedIndices = /* @__PURE__ */ new Set();
58780
+ let matchCount = 0;
58781
+ while ((match = chartRegex.exec(text)) !== null) {
58782
+ matchCount++;
58783
+ const startIndex = match.index;
58784
+ const endIndex = startIndex + match[0].length;
58785
+ console.log(`[DEBUG] Found chart pattern #${matchCount}:`, {
58786
+ fullMatch: match[0],
58787
+ chartType: match[1],
58788
+ argsString: match[2],
58789
+ startIndex,
58790
+ endIndex
58791
+ });
58792
+ if (!processedIndices.has(startIndex)) {
58793
+ processedIndices.add(startIndex);
58794
+ if (startIndex > lastIndex) {
58795
+ const beforeText = text.substring(lastIndex, startIndex);
58796
+ chartElements.push(
58797
+ /* @__PURE__ */ jsxRuntime.jsx(
58798
+ "div",
58799
+ {
58800
+ dangerouslySetInnerHTML: { __html: formatMessage(beforeText) }
58801
+ },
58802
+ `text-${lastIndex}`
58803
+ )
58804
+ );
58805
+ }
58806
+ const chartType = match[1];
58807
+ const argsString = match[2];
58808
+ try {
58809
+ const args = parseChartArguments(argsString);
58810
+ const chartElement = renderChart(chartType, args, startIndex);
58811
+ if (chartElement) {
58812
+ console.log(`[DEBUG] Successfully rendered chart: ${chartType}`);
58813
+ chartElements.push(chartElement);
58814
+ } else {
58815
+ console.warn(`[DEBUG] Chart element was null for type: ${chartType}`);
58816
+ console.warn(`[DEBUG] Args were:`, args);
58817
+ chartElements.push(
58818
+ /* @__PURE__ */ jsxRuntime.jsxs(
58819
+ "div",
58820
+ {
58821
+ className: "text-red-500 text-sm border border-red-300 bg-red-50 p-3 rounded",
58822
+ children: [
58823
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Chart Rendering Error:" }),
58824
+ " Failed to render ",
58825
+ chartType,
58826
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
58827
+ /* @__PURE__ */ jsxRuntime.jsxs("small", { children: [
58828
+ "Check console for details. Args: ",
58829
+ JSON.stringify(args, null, 2)
58830
+ ] })
58831
+ ]
58832
+ },
58833
+ `error-${startIndex}`
58834
+ )
58835
+ );
58836
+ }
58837
+ } catch (error) {
58838
+ console.error(`Failed to parse chart ${chartType}:`, error);
58839
+ console.error(`Args string was:`, argsString);
58840
+ chartElements.push(
58841
+ /* @__PURE__ */ jsxRuntime.jsxs(
58842
+ "div",
58843
+ {
58844
+ className: "text-red-500 text-sm border border-red-300 bg-red-50 p-3 rounded",
58845
+ children: [
58846
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Chart Parsing Error:" }),
58847
+ " Failed to parse ",
58848
+ chartType,
58849
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
58850
+ /* @__PURE__ */ jsxRuntime.jsxs("small", { children: [
58851
+ "Error: ",
58852
+ error instanceof Error ? error.message : String(error)
58853
+ ] }),
58854
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
58855
+ /* @__PURE__ */ jsxRuntime.jsxs("small", { children: [
58856
+ "Original: ",
58857
+ match[0]
58858
+ ] })
58859
+ ]
58860
+ },
58861
+ `error-${startIndex}`
58862
+ )
58863
+ );
58864
+ }
58865
+ lastIndex = endIndex;
58866
+ }
58867
+ }
58868
+ console.log(`[DEBUG] Total chart patterns found: ${matchCount}`);
58869
+ if (lastIndex < text.length) {
58870
+ const remainingText = text.substring(lastIndex);
58871
+ chartElements.push(
58872
+ /* @__PURE__ */ jsxRuntime.jsx(
58873
+ "div",
58874
+ {
58875
+ dangerouslySetInnerHTML: { __html: formatMessage(remainingText) }
58876
+ },
58877
+ `text-${lastIndex}`
58878
+ )
58879
+ );
58880
+ }
58881
+ if (chartElements.length === 1 && lastIndex === 0) {
58882
+ console.log("[DEBUG] No charts found in text, returning null");
58883
+ return null;
58884
+ }
58885
+ console.log(`[DEBUG] Returning ${chartElements.length} chart elements`);
58886
+ return chartElements;
58887
+ };
58888
+ const parseChartArguments = (argsString) => {
58889
+ console.log("[DEBUG] Parsing chart arguments:", argsString);
58890
+ const extractParameters = (str) => {
58891
+ const params = {};
58892
+ let currentPos = 0;
58893
+ while (currentPos < str.length) {
58894
+ while (currentPos < str.length && /\s|,/.test(str[currentPos])) {
58895
+ currentPos++;
58896
+ }
58897
+ if (currentPos >= str.length) break;
58898
+ const paramMatch = str.substring(currentPos).match(/^(\w+)\s*=/);
58899
+ if (!paramMatch) {
58900
+ console.warn("[DEBUG] No parameter name found at position", currentPos);
58901
+ break;
58902
+ }
58903
+ const paramName = paramMatch[1];
58904
+ currentPos += paramMatch[0].length;
58905
+ while (currentPos < str.length && /\s/.test(str[currentPos])) {
58906
+ currentPos++;
58907
+ }
58908
+ if (currentPos >= str.length) break;
58909
+ let value;
58910
+ let valueEnd;
58911
+ if (str[currentPos] === "[") {
58912
+ let bracketCount = 0;
58913
+ let arrayStart = currentPos;
58914
+ valueEnd = str.length;
58915
+ for (let i = currentPos; i < str.length; i++) {
58916
+ if (str[i] === "[") bracketCount++;
58917
+ else if (str[i] === "]") bracketCount--;
58918
+ if (bracketCount === 0) {
58919
+ valueEnd = i + 1;
58920
+ break;
58921
+ }
58922
+ }
58923
+ if (bracketCount !== 0) {
58924
+ console.error("[DEBUG] Unmatched brackets in array value");
58925
+ break;
58926
+ }
58927
+ const arrayStr = str.substring(arrayStart, valueEnd);
58928
+ console.log(`[DEBUG] Found array parameter: ${paramName} = ${arrayStr}`);
58929
+ try {
58930
+ value = JSON.parse(arrayStr);
58931
+ console.log(`[DEBUG] Successfully parsed array ${paramName}:`, value);
58932
+ } catch (e) {
58933
+ console.error(`[DEBUG] Failed to parse array ${paramName}:`, e);
58934
+ console.error(`Array value that failed:`, arrayStr);
58935
+ value = arrayStr;
58936
+ }
58937
+ } else if (str[currentPos] === "{") {
58938
+ let braceCount = 0;
58939
+ let objectStart = currentPos;
58940
+ valueEnd = str.length;
58941
+ for (let i = currentPos; i < str.length; i++) {
58942
+ if (str[i] === "{") braceCount++;
58943
+ else if (str[i] === "}") braceCount--;
58944
+ if (braceCount === 0) {
58945
+ valueEnd = i + 1;
58946
+ break;
58947
+ }
58948
+ }
58949
+ if (braceCount !== 0) {
58950
+ console.error("[DEBUG] Unmatched braces in object value");
58951
+ break;
58952
+ }
58953
+ const objectStr = str.substring(objectStart, valueEnd);
58954
+ console.log(`[DEBUG] Found object parameter: ${paramName} = ${objectStr}`);
58955
+ try {
58956
+ value = JSON.parse(objectStr);
58957
+ console.log(`[DEBUG] Successfully parsed object ${paramName}:`, value);
58958
+ } catch (e) {
58959
+ console.error(`[DEBUG] Failed to parse object ${paramName}:`, e);
58960
+ console.error(`Object value that failed:`, objectStr);
58961
+ value = objectStr;
58962
+ }
58963
+ } else if (str[currentPos] === '"') {
58964
+ let stringStart = currentPos + 1;
58965
+ let stringEnd = stringStart;
58966
+ while (stringEnd < str.length) {
58967
+ if (str[stringEnd] === '"' && str[stringEnd - 1] !== "\\") {
58968
+ break;
58969
+ }
58970
+ stringEnd++;
58971
+ }
58972
+ if (stringEnd >= str.length) {
58973
+ console.error("[DEBUG] Unterminated string value");
58974
+ valueEnd = str.length;
58975
+ break;
58976
+ }
58977
+ value = str.substring(stringStart, stringEnd);
58978
+ valueEnd = stringEnd + 1;
58979
+ console.log(`[DEBUG] Found string parameter: ${paramName} = "${value}"`);
58980
+ } else {
58981
+ let valueStart = currentPos;
58982
+ let valueEndPos = valueStart;
58983
+ while (valueEndPos < str.length && str[valueEndPos] !== ",") {
58984
+ valueEndPos++;
58985
+ }
58986
+ const rawValue = str.substring(valueStart, valueEndPos).trim();
58987
+ valueEnd = valueEndPos;
58988
+ if (rawValue === "true" || rawValue === "True") {
58989
+ value = true;
58990
+ } else if (rawValue === "false" || rawValue === "False") {
58991
+ value = false;
58992
+ } else if (rawValue === "null" || rawValue === "None") {
58993
+ value = null;
58994
+ } else if (!isNaN(Number(rawValue)) && rawValue !== "") {
58995
+ value = Number(rawValue);
58996
+ } else {
58997
+ value = rawValue;
58998
+ }
58999
+ console.log(`[DEBUG] Found unquoted parameter: ${paramName} = ${rawValue} (parsed as ${typeof value})`);
59000
+ }
59001
+ params[paramName] = value;
59002
+ currentPos = valueEnd;
59003
+ }
59004
+ return params;
59005
+ };
59006
+ const result = extractParameters(argsString);
59007
+ console.log("[DEBUG] Final parsed arguments:", result);
59008
+ return result;
59009
+ };
59010
+ const renderChart = (chartType, args, key) => {
59011
+ console.log(`[DEBUG] Attempting to render chart type: ${chartType}`, args);
59012
+ const CHART_COLORS = {
59013
+ primary: "#3b82f6",
59014
+ // blue-500
59015
+ secondary: "#10b981",
59016
+ // green-500
59017
+ accent: "#f59e0b",
59018
+ // amber-500
59019
+ danger: "#ef4444",
59020
+ // red-500
59021
+ violet: "#8b5cf6",
59022
+ // violet-500
59023
+ cyan: "#06b6d4",
59024
+ // cyan-500
59025
+ orange: "#f97316",
59026
+ // orange-500
59027
+ indigo: "#6366f1"
59028
+ // indigo-500
59029
+ };
59030
+ const CHART_COLOR_PALETTE = Object.values(CHART_COLORS);
59031
+ const CHART_STYLES = {
59032
+ grid: {
59033
+ strokeDasharray: "3 3",
59034
+ stroke: "#e5e7eb"
59035
+ // gray-300
59036
+ },
59037
+ axis: {
59038
+ tick: { fontSize: 12, fill: "#4b5563" },
59039
+ // gray-600
59040
+ stroke: "#9ca3af"
59041
+ // gray-400
59042
+ },
59043
+ margin: { top: 10, right: 30, left: 20, bottom: 40 },
59044
+ barRadius: [4, 4, 0, 0]
59045
+ // Top corners rounded
59046
+ };
59047
+ const CustomTooltip4 = ({ active, payload, label }) => {
59048
+ if (active && payload && payload.length) {
59049
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white px-4 py-3 shadow-lg rounded-lg border border-gray-200", children: [
59050
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-900 mb-1", children: label }),
59051
+ payload.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-gray-600", style: { color: entry.color }, children: [
59052
+ entry.name,
59053
+ ": ",
59054
+ typeof entry.value === "number" ? formatNumber(entry.value) : entry.value,
59055
+ args.unit || ""
59056
+ ] }, index))
59057
+ ] });
59058
+ }
59059
+ return null;
59060
+ };
59061
+ const DualAxisTooltip = ({ active, payload, label }) => {
59062
+ if (active && payload && payload.length) {
59063
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white px-4 py-3 shadow-lg rounded-lg border border-gray-200", children: [
59064
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-900 mb-2", children: label }),
59065
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: payload.map((entry, index) => {
59066
+ const value = typeof entry.value === "number" ? formatNumber(entry.value) : entry.value;
59067
+ const unit = entry.dataKey === args.left_y_field ? args.left_unit || "" : entry.dataKey === args.right_y_field ? args.right_unit || "" : "";
59068
+ return /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm", style: { color: entry.color }, children: [
59069
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
59070
+ entry.name,
59071
+ ":"
59072
+ ] }),
59073
+ " ",
59074
+ value,
59075
+ unit
59076
+ ] }, index);
59077
+ }) })
59078
+ ] });
59079
+ }
59080
+ return null;
59081
+ };
59082
+ const formatXAxisTick = (value) => {
59083
+ if (typeof value === "string") {
59084
+ if (value.match(/^\d{2}\/\d{2}\s/)) {
59085
+ return value;
59086
+ }
59087
+ if (value.length > 15) {
59088
+ return value.substring(0, 12) + "...";
59089
+ }
59090
+ }
59091
+ return value;
59092
+ };
59093
+ const ChartWrapper = ({ children, title }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 bg-white rounded-xl shadow-sm border border-gray-200 p-6", children: [
59094
+ title && /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold text-gray-900 mb-4", children: title }),
59095
+ children
59096
+ ] });
59097
+ switch (chartType) {
59098
+ case "create_gauge_chart":
59099
+ console.log("[DEBUG] Rendering gauge chart");
59100
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-64 w-full flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
59101
+ GaugeChart,
59102
+ {
59103
+ value: args.value || 0,
59104
+ min: args.min_value || 0,
59105
+ max: args.max_value || 100,
59106
+ target: args.target,
59107
+ label: args.label || "",
59108
+ unit: args.unit || "",
59109
+ thresholds: args.thresholds,
59110
+ className: "w-full max-w-sm"
59111
+ }
59112
+ ) }) }, `gauge-${key}`);
59113
+ case "create_bar_chart":
59114
+ console.log("[DEBUG] Rendering bar chart");
59115
+ if (!args.data || !args.x_field || !args.y_field) {
59116
+ console.error("Bar chart missing required parameters:", { data: !!args.data, x_field: !!args.x_field, y_field: !!args.y_field });
59117
+ return null;
59118
+ }
59119
+ if (!Array.isArray(args.data)) {
59120
+ console.error("Bar chart data must be an array, got:", typeof args.data, args.data);
59121
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
59122
+ "Error: Chart data must be an array. Received: ",
59123
+ typeof args.data
59124
+ ] }) }, `bar-error-${key}`);
59125
+ }
59126
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-64", style: { minHeight: "200px", minWidth: "300px" }, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.BarChart, { data: args.data, margin: CHART_STYLES.margin, children: [
59127
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
59128
+ /* @__PURE__ */ jsxRuntime.jsx(
59129
+ recharts.XAxis,
59130
+ {
59131
+ dataKey: args.x_field,
59132
+ ...CHART_STYLES.axis,
59133
+ angle: -45,
59134
+ textAnchor: "end",
59135
+ height: 60,
59136
+ interval: 0,
59137
+ tickFormatter: formatXAxisTick
59138
+ }
59139
+ ),
59140
+ /* @__PURE__ */ jsxRuntime.jsx(
59141
+ recharts.YAxis,
59142
+ {
59143
+ ...CHART_STYLES.axis,
59144
+ tickFormatter: (value) => formatNumber(value)
59145
+ }
59146
+ ),
59147
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip4, {}), cursor: { fill: "rgba(0, 0, 0, 0.05)" } }),
59148
+ /* @__PURE__ */ jsxRuntime.jsx(
59149
+ recharts.Bar,
59150
+ {
59151
+ dataKey: args.y_field,
59152
+ fill: args.color || CHART_COLORS.primary,
59153
+ radius: CHART_STYLES.barRadius
59154
+ }
59155
+ )
59156
+ ] }) }) }) }, `bar-${key}`);
59157
+ case "create_line_chart":
59158
+ console.log("[DEBUG] Rendering line chart");
59159
+ if (!args.data || !args.x_field || !args.y_field) {
59160
+ console.error("Line chart missing required parameters:", { data: !!args.data, x_field: !!args.x_field, y_field: !!args.y_field });
59161
+ return null;
59162
+ }
59163
+ if (!Array.isArray(args.data)) {
59164
+ console.error("Line chart data must be an array, got:", typeof args.data, args.data);
59165
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
59166
+ "Error: Chart data must be an array. Received: ",
59167
+ typeof args.data
59168
+ ] }) }, `line-error-${key}`);
59169
+ }
59170
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-64", style: { minHeight: "200px", minWidth: "300px" }, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.LineChart, { data: args.data, margin: CHART_STYLES.margin, children: [
59171
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
59172
+ /* @__PURE__ */ jsxRuntime.jsx(
59173
+ recharts.XAxis,
59174
+ {
59175
+ dataKey: args.x_field,
59176
+ ...CHART_STYLES.axis,
59177
+ angle: -45,
59178
+ textAnchor: "end",
59179
+ height: 60,
59180
+ interval: 0,
59181
+ tickFormatter: formatXAxisTick
59182
+ }
59183
+ ),
59184
+ /* @__PURE__ */ jsxRuntime.jsx(
59185
+ recharts.YAxis,
59186
+ {
59187
+ ...CHART_STYLES.axis,
59188
+ tickFormatter: (value) => formatNumber(value)
59189
+ }
59190
+ ),
59191
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip4, {}), cursor: { strokeDasharray: "3 3" } }),
59192
+ /* @__PURE__ */ jsxRuntime.jsx(
59193
+ recharts.Line,
59194
+ {
59195
+ type: "monotone",
59196
+ dataKey: args.y_field,
59197
+ stroke: CHART_COLORS.primary,
59198
+ strokeWidth: 2,
59199
+ dot: { r: 4, fill: CHART_COLORS.primary },
59200
+ activeDot: { r: 6 }
59201
+ }
59202
+ )
59203
+ ] }) }) }) }, `line-${key}`);
59204
+ case "create_pie_chart":
59205
+ console.log("[DEBUG] Rendering pie chart");
59206
+ if (!args.data || !args.label_field || !args.value_field) {
59207
+ console.error("Pie chart missing required parameters:", { data: !!args.data, label_field: !!args.label_field, value_field: !!args.value_field });
59208
+ console.error("Available args:", Object.keys(args));
59209
+ return null;
59210
+ }
59211
+ if (!Array.isArray(args.data)) {
59212
+ console.error("Pie chart data must be an array, got:", typeof args.data, args.data);
59213
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
59214
+ "Error: Chart data must be an array. Received: ",
59215
+ typeof args.data
59216
+ ] }) }, `pie-error-${key}`);
59217
+ }
59218
+ const pieData = args.data.map((item) => ({
59219
+ name: item[args.label_field],
59220
+ value: item[args.value_field]
59221
+ }));
59222
+ console.log("[DEBUG] Pie chart data transformed:", pieData);
59223
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-64 w-full max-w-md mx-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
59224
+ PieChart4,
59225
+ {
59226
+ data: pieData,
59227
+ showPercentages: args.show_percentages || false,
59228
+ colors: CHART_COLOR_PALETTE
59229
+ }
59230
+ ) }) }, `pie-${key}`);
59231
+ case "create_comparison_table":
59232
+ console.log("[DEBUG] Rendering comparison table");
59233
+ if (!args.data) {
59234
+ console.error("Comparison table missing required data");
59235
+ return null;
59236
+ }
59237
+ if (!Array.isArray(args.data)) {
59238
+ console.error("Comparison table data must be an array, got:", typeof args.data, args.data);
59239
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
59240
+ "Error: Table data must be an array. Received: ",
59241
+ typeof args.data
59242
+ ] }) }, `table-error-${key}`);
59243
+ }
59244
+ const columns = args.columns || Object.keys(args.data[0] || {});
59245
+ let sortedData = [...args.data];
59246
+ if (args.sort_by && columns.includes(args.sort_by)) {
59247
+ sortedData.sort((a, b) => {
59248
+ const aVal = a[args.sort_by];
59249
+ const bVal = b[args.sort_by];
59250
+ const comparison = aVal > bVal ? 1 : aVal < bVal ? -1 : 0;
59251
+ return args.sort_descending === false ? comparison : -comparison;
59252
+ });
59253
+ }
59254
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto rounded-lg border border-gray-200", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-gray-200", children: [
59255
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
59256
+ "th",
59257
+ {
59258
+ className: `px-6 py-3 text-left text-xs font-medium text-gray-600 uppercase tracking-wider ${col === args.highlight_column ? "bg-blue-50" : ""}`,
59259
+ children: col
59260
+ },
59261
+ col
59262
+ )) }) }),
59263
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-white divide-y divide-gray-200", children: sortedData.map((row, rowIdx) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: rowIdx % 2 === 0 ? "bg-white" : "bg-gray-50", children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
59264
+ "td",
59265
+ {
59266
+ className: `px-6 py-4 whitespace-nowrap text-sm ${col === args.highlight_column ? "font-medium text-blue-600 bg-blue-50" : "text-gray-900"}`,
59267
+ children: typeof row[col] === "number" ? formatNumber(row[col]) : row[col]
59268
+ },
59269
+ col
59270
+ )) }, rowIdx)) })
59271
+ ] }) }) }, `table-${key}`);
59272
+ case "create_multi_line_chart":
59273
+ console.log("[DEBUG] Rendering multi-line chart");
59274
+ if (!args.data || !args.x_field || !args.y_fields || !args.legend) {
59275
+ console.error("Multi-line chart missing required parameters:", {
59276
+ data: !!args.data,
59277
+ x_field: !!args.x_field,
59278
+ y_fields: !!args.y_fields,
59279
+ legend: !!args.legend
59280
+ });
59281
+ return null;
59282
+ }
59283
+ if (!Array.isArray(args.data)) {
59284
+ console.error("Multi-line chart data must be an array, got:", typeof args.data, args.data);
59285
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
59286
+ "Error: Chart data must be an array. Received: ",
59287
+ typeof args.data
59288
+ ] }) }, `multi-line-error-${key}`);
59289
+ }
59290
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", style: { minHeight: "250px", minWidth: "300px" }, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.LineChart, { data: args.data, margin: CHART_STYLES.margin, children: [
59291
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
59292
+ /* @__PURE__ */ jsxRuntime.jsx(
59293
+ recharts.XAxis,
59294
+ {
59295
+ dataKey: args.x_field,
59296
+ ...CHART_STYLES.axis,
59297
+ angle: -45,
59298
+ textAnchor: "end",
59299
+ height: 60,
59300
+ interval: 0,
59301
+ tickFormatter: formatXAxisTick
59302
+ }
59303
+ ),
59304
+ /* @__PURE__ */ jsxRuntime.jsx(
59305
+ recharts.YAxis,
59306
+ {
59307
+ ...CHART_STYLES.axis,
59308
+ tickFormatter: (value) => formatNumber(value)
59309
+ }
59310
+ ),
59311
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip4, {}), cursor: { strokeDasharray: "3 3" } }),
59312
+ /* @__PURE__ */ jsxRuntime.jsx(
59313
+ recharts.Legend,
59314
+ {
59315
+ wrapperStyle: { paddingTop: "20px" },
59316
+ formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
59317
+ }
59318
+ ),
59319
+ args.y_fields.map((field, index) => /* @__PURE__ */ jsxRuntime.jsx(
59320
+ recharts.Line,
59321
+ {
59322
+ type: "monotone",
59323
+ dataKey: field,
59324
+ stroke: CHART_COLOR_PALETTE[index % CHART_COLOR_PALETTE.length],
59325
+ strokeWidth: 2,
59326
+ name: args.legend[index] || field,
59327
+ dot: { r: 4 },
59328
+ activeDot: { r: 6 }
59329
+ },
59330
+ field
59331
+ ))
59332
+ ] }) }) }) }, `multi-line-${key}`);
59333
+ case "create_stacked_bar_chart":
59334
+ console.log("[DEBUG] Rendering stacked bar chart");
59335
+ if (!args.data || !args.x_field || !args.stack_fields) {
59336
+ console.error("Stacked bar chart missing required parameters:", {
59337
+ data: !!args.data,
59338
+ x_field: !!args.x_field,
59339
+ stack_fields: !!args.stack_fields
59340
+ });
59341
+ return null;
59342
+ }
59343
+ if (!Array.isArray(args.data)) {
59344
+ console.error("Stacked bar chart data must be an array, got:", typeof args.data, args.data);
59345
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
59346
+ "Error: Chart data must be an array. Received: ",
59347
+ typeof args.data
59348
+ ] }) }, `stacked-bar-error-${key}`);
59349
+ }
59350
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", style: { minHeight: "250px", minWidth: "300px" }, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.BarChart, { data: args.data, margin: CHART_STYLES.margin, children: [
59351
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
59352
+ /* @__PURE__ */ jsxRuntime.jsx(
59353
+ recharts.XAxis,
59354
+ {
59355
+ dataKey: args.x_field,
59356
+ ...CHART_STYLES.axis,
59357
+ angle: -45,
59358
+ textAnchor: "end",
59359
+ height: 60,
59360
+ interval: 0,
59361
+ tickFormatter: formatXAxisTick
59362
+ }
59363
+ ),
59364
+ /* @__PURE__ */ jsxRuntime.jsx(
59365
+ recharts.YAxis,
59366
+ {
59367
+ ...CHART_STYLES.axis,
59368
+ tickFormatter: (value) => formatNumber(value)
59369
+ }
59370
+ ),
59371
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip4, {}), cursor: { fill: "rgba(0, 0, 0, 0.05)" } }),
59372
+ /* @__PURE__ */ jsxRuntime.jsx(
59373
+ recharts.Legend,
59374
+ {
59375
+ wrapperStyle: { paddingTop: "20px" },
59376
+ formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
59377
+ }
59378
+ ),
59379
+ args.stack_fields.map((field, index) => /* @__PURE__ */ jsxRuntime.jsx(
59380
+ recharts.Bar,
59381
+ {
59382
+ dataKey: field,
59383
+ stackId: "stack",
59384
+ fill: CHART_COLOR_PALETTE[index % CHART_COLOR_PALETTE.length],
59385
+ name: field,
59386
+ radius: index === args.stack_fields.length - 1 ? CHART_STYLES.barRadius : void 0
59387
+ },
59388
+ field
59389
+ ))
59390
+ ] }) }) }) }, `stacked-bar-${key}`);
59391
+ case "create_dual_axis_chart":
59392
+ console.log("[DEBUG] Rendering dual-axis chart");
59393
+ if (!args.data || !args.x_field || !args.left_y_field || !args.right_y_field) {
59394
+ console.error("Dual-axis chart missing required parameters:", {
59395
+ data: !!args.data,
59396
+ x_field: !!args.x_field,
59397
+ left_y_field: !!args.left_y_field,
59398
+ right_y_field: !!args.right_y_field
59399
+ });
59400
+ return null;
59401
+ }
59402
+ if (!Array.isArray(args.data)) {
59403
+ console.error("Dual-axis chart data must be an array, got:", typeof args.data, args.data);
59404
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
59405
+ "Error: Chart data must be an array. Received: ",
59406
+ typeof args.data
59407
+ ] }) }, `dual-axis-error-${key}`);
59408
+ }
59409
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", style: { minHeight: "250px", minWidth: "300px" }, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ComposedChart, { data: args.data, margin: { ...CHART_STYLES.margin, bottom: 80 }, children: [
59410
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
59411
+ /* @__PURE__ */ jsxRuntime.jsx(
59412
+ recharts.XAxis,
59413
+ {
59414
+ dataKey: args.x_field,
59415
+ ...CHART_STYLES.axis,
59416
+ angle: -45,
59417
+ textAnchor: "end",
59418
+ height: 100,
59419
+ interval: 0,
59420
+ tickFormatter: formatXAxisTick
59421
+ }
59422
+ ),
59423
+ /* @__PURE__ */ jsxRuntime.jsx(
59424
+ recharts.YAxis,
59425
+ {
59426
+ yAxisId: "left",
59427
+ orientation: "left",
59428
+ label: {
59429
+ value: args.left_label || args.left_y_field,
59430
+ angle: -90,
59431
+ position: "insideLeft",
59432
+ style: { textAnchor: "middle", fill: "#4b5563" }
59433
+ },
59434
+ ...CHART_STYLES.axis,
59435
+ tickFormatter: (value) => `${formatNumber(value)}${args.left_unit || ""}`
59436
+ }
59437
+ ),
59438
+ /* @__PURE__ */ jsxRuntime.jsx(
59439
+ recharts.YAxis,
59440
+ {
59441
+ yAxisId: "right",
59442
+ orientation: "right",
59443
+ label: {
59444
+ value: args.right_label || args.right_y_field,
59445
+ angle: 90,
59446
+ position: "insideRight",
59447
+ style: { textAnchor: "middle", fill: "#4b5563" }
59448
+ },
59449
+ ...CHART_STYLES.axis,
59450
+ tickFormatter: (value) => `${formatNumber(value)}${args.right_unit || ""}`
59451
+ }
59452
+ ),
59453
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(DualAxisTooltip, {}), cursor: { fill: "rgba(0, 0, 0, 0.05)" } }),
59454
+ /* @__PURE__ */ jsxRuntime.jsx(
59455
+ recharts.Legend,
59456
+ {
59457
+ wrapperStyle: { paddingTop: "20px" },
59458
+ formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
59459
+ }
59460
+ ),
59461
+ /* @__PURE__ */ jsxRuntime.jsx(
59462
+ recharts.Bar,
59463
+ {
59464
+ yAxisId: "left",
59465
+ dataKey: args.left_y_field,
59466
+ fill: CHART_COLORS.primary,
59467
+ name: args.left_label || args.left_y_field,
59468
+ radius: CHART_STYLES.barRadius
59469
+ }
59470
+ ),
59471
+ /* @__PURE__ */ jsxRuntime.jsx(
59472
+ recharts.Line,
59473
+ {
59474
+ yAxisId: "right",
59475
+ type: "monotone",
59476
+ dataKey: args.right_y_field,
59477
+ stroke: CHART_COLORS.danger,
59478
+ strokeWidth: 3,
59479
+ name: args.right_label || args.right_y_field,
59480
+ dot: { r: 5, fill: CHART_COLORS.danger },
59481
+ activeDot: { r: 7 }
59482
+ }
59483
+ )
59484
+ ] }) }) }) }, `dual-axis-${key}`);
59485
+ case "create_scatter_plot":
59486
+ console.log("[DEBUG] Rendering scatter plot");
59487
+ if (!args.data || !args.x_field || !args.y_field || !args.group_field) {
59488
+ console.error("Scatter plot missing required parameters:", {
59489
+ data: !!args.data,
59490
+ x_field: !!args.x_field,
59491
+ y_field: !!args.y_field,
59492
+ group_field: !!args.group_field
59493
+ });
59494
+ return null;
59495
+ }
59496
+ if (!Array.isArray(args.data)) {
59497
+ console.error("Scatter plot data must be an array, got:", typeof args.data, args.data);
59498
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
59499
+ "Error: Chart data must be an array. Received: ",
59500
+ typeof args.data
59501
+ ] }) }, `scatter-error-${key}`);
59502
+ }
59503
+ const groupedData = args.data.reduce((acc, item) => {
59504
+ const group = item[args.group_field];
59505
+ if (!acc[group]) {
59506
+ acc[group] = [];
59507
+ }
59508
+ acc[group].push(item);
59509
+ return acc;
59510
+ }, {});
59511
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", style: { minHeight: "250px", minWidth: "300px" }, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ScatterChart, { margin: CHART_STYLES.margin, children: [
59512
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
59513
+ /* @__PURE__ */ jsxRuntime.jsx(
59514
+ recharts.XAxis,
59515
+ {
59516
+ dataKey: args.x_field,
59517
+ type: "number",
59518
+ name: args.x_field,
59519
+ ...CHART_STYLES.axis
59520
+ }
59521
+ ),
59522
+ /* @__PURE__ */ jsxRuntime.jsx(
59523
+ recharts.YAxis,
59524
+ {
59525
+ dataKey: args.y_field,
59526
+ type: "number",
59527
+ name: args.y_field,
59528
+ ...CHART_STYLES.axis
59529
+ }
59530
+ ),
59531
+ /* @__PURE__ */ jsxRuntime.jsx(
59532
+ recharts.Tooltip,
59533
+ {
59534
+ cursor: { strokeDasharray: "3 3" },
59535
+ content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip4, {})
59536
+ }
59537
+ ),
59538
+ /* @__PURE__ */ jsxRuntime.jsx(
59539
+ recharts.Legend,
59540
+ {
59541
+ wrapperStyle: { paddingTop: "20px" },
59542
+ formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
59543
+ }
59544
+ ),
59545
+ Object.entries(groupedData).map(([group, data], index) => /* @__PURE__ */ jsxRuntime.jsx(
59546
+ recharts.Scatter,
59547
+ {
59548
+ name: group,
59549
+ data,
59550
+ fill: CHART_COLOR_PALETTE[index % CHART_COLOR_PALETTE.length]
59551
+ },
59552
+ group
59553
+ ))
59554
+ ] }) }) }) }, `scatter-${key}`);
59555
+ case "create_combo_chart":
59556
+ console.log("[DEBUG] Rendering combo chart");
59557
+ if (!args.data || !args.x_field || !args.bar_field || !args.line_field) {
59558
+ console.error("Combo chart missing required parameters:", {
59559
+ data: !!args.data,
59560
+ x_field: !!args.x_field,
59561
+ bar_field: !!args.bar_field,
59562
+ line_field: !!args.line_field
59563
+ });
59564
+ return null;
59565
+ }
59566
+ if (!Array.isArray(args.data)) {
59567
+ console.error("Combo chart data must be an array, got:", typeof args.data, args.data);
59568
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
59569
+ "Error: Chart data must be an array. Received: ",
59570
+ typeof args.data
59571
+ ] }) }, `combo-error-${key}`);
59572
+ }
59573
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", style: { minHeight: "250px", minWidth: "300px" }, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ComposedChart, { data: args.data, margin: { ...CHART_STYLES.margin, bottom: 80 }, children: [
59574
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
59575
+ /* @__PURE__ */ jsxRuntime.jsx(
59576
+ recharts.XAxis,
59577
+ {
59578
+ dataKey: args.x_field,
59579
+ ...CHART_STYLES.axis,
59580
+ angle: -45,
59581
+ textAnchor: "end",
59582
+ height: 100,
59583
+ interval: 0,
59584
+ tickFormatter: formatXAxisTick
59585
+ }
59586
+ ),
59587
+ /* @__PURE__ */ jsxRuntime.jsx(
59588
+ recharts.YAxis,
59589
+ {
59590
+ yAxisId: "left",
59591
+ orientation: "left",
59592
+ ...CHART_STYLES.axis,
59593
+ tickFormatter: (value) => formatNumber(value)
59594
+ }
59595
+ ),
59596
+ /* @__PURE__ */ jsxRuntime.jsx(
59597
+ recharts.YAxis,
59598
+ {
59599
+ yAxisId: "right",
59600
+ orientation: "right",
59601
+ ...CHART_STYLES.axis,
59602
+ tickFormatter: (value) => formatNumber(value)
59603
+ }
59604
+ ),
59605
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip4, {}), cursor: { fill: "rgba(0, 0, 0, 0.05)" } }),
59606
+ /* @__PURE__ */ jsxRuntime.jsx(
59607
+ recharts.Legend,
59608
+ {
59609
+ wrapperStyle: { paddingTop: "20px" },
59610
+ formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
59611
+ }
59612
+ ),
59613
+ /* @__PURE__ */ jsxRuntime.jsx(
59614
+ recharts.Bar,
59615
+ {
59616
+ yAxisId: "left",
59617
+ dataKey: args.bar_field,
59618
+ fill: CHART_COLORS.primary,
59619
+ name: args.bar_field,
59620
+ radius: CHART_STYLES.barRadius
59621
+ }
59622
+ ),
59623
+ /* @__PURE__ */ jsxRuntime.jsx(
59624
+ recharts.Line,
59625
+ {
59626
+ yAxisId: "right",
59627
+ type: "monotone",
59628
+ dataKey: args.line_field,
59629
+ stroke: CHART_COLORS.danger,
59630
+ strokeWidth: 3,
59631
+ name: args.line_field,
59632
+ dot: { r: 5 },
59633
+ activeDot: { r: 7 }
59634
+ }
59635
+ )
59636
+ ] }) }) }) }, `combo-${key}`);
59637
+ case "create_area_chart":
59638
+ console.log("[DEBUG] Rendering area chart");
59639
+ if (!args.data || !args.x_field || !args.y_field) {
59640
+ console.error("Area chart missing required parameters:", {
59641
+ data: !!args.data,
59642
+ x_field: !!args.x_field,
59643
+ y_field: !!args.y_field
59644
+ });
59645
+ return null;
59646
+ }
59647
+ if (!Array.isArray(args.data)) {
59648
+ console.error("Area chart data must be an array, got:", typeof args.data, args.data);
59649
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500 text-sm", children: [
59650
+ "Error: Chart data must be an array. Received: ",
59651
+ typeof args.data
59652
+ ] }) }, `area-error-${key}`);
59653
+ }
59654
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", style: { minHeight: "250px", minWidth: "300px" }, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ComposedChart, { data: args.data, margin: { ...CHART_STYLES.margin, bottom: 80 }, children: [
59655
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: "colorGradient", x1: "0", y1: "0", x2: "0", y2: "1", children: [
59656
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "5%", stopColor: CHART_COLORS.primary, stopOpacity: 0.8 }),
59657
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "95%", stopColor: CHART_COLORS.primary, stopOpacity: 0.1 })
59658
+ ] }) }),
59659
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
59660
+ /* @__PURE__ */ jsxRuntime.jsx(
59661
+ recharts.XAxis,
59662
+ {
59663
+ dataKey: args.x_field,
59664
+ ...CHART_STYLES.axis,
59665
+ angle: -45,
59666
+ textAnchor: "end",
59667
+ height: 100,
59668
+ interval: 0,
59669
+ tickFormatter: formatXAxisTick
59670
+ }
59671
+ ),
59672
+ /* @__PURE__ */ jsxRuntime.jsx(
59673
+ recharts.YAxis,
59674
+ {
59675
+ ...CHART_STYLES.axis,
59676
+ tickFormatter: (value) => formatNumber(value)
59677
+ }
59678
+ ),
59679
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip4, {}), cursor: { strokeDasharray: "3 3" } }),
59680
+ /* @__PURE__ */ jsxRuntime.jsx(
59681
+ recharts.Legend,
59682
+ {
59683
+ wrapperStyle: { paddingTop: "20px" },
59684
+ formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
59685
+ }
59686
+ ),
59687
+ /* @__PURE__ */ jsxRuntime.jsx(
59688
+ recharts.Area,
59689
+ {
59690
+ type: "monotone",
59691
+ dataKey: args.y_field,
59692
+ stroke: CHART_COLORS.primary,
59693
+ strokeWidth: 2,
59694
+ fill: args.fill !== false ? "url(#colorGradient)" : "none",
59695
+ name: args.y_field,
59696
+ dot: { r: 4, fill: CHART_COLORS.primary },
59697
+ activeDot: { r: 6 }
59698
+ }
59699
+ )
59700
+ ] }) }) }) }, `area-${key}`);
59701
+ default:
59702
+ console.warn(`Unknown chart type: ${chartType}`);
59703
+ return null;
59704
+ }
59705
+ };
59706
+ const chartContent = parseChartPatterns(content);
59707
+ let finalNode;
59708
+ if (chartContent) {
59709
+ finalNode = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "formatted-content", children: chartContent });
59710
+ } else {
59711
+ finalNode = /* @__PURE__ */ jsxRuntime.jsx(
59712
+ "div",
59713
+ {
59714
+ className: "formatted-content",
59715
+ dangerouslySetInnerHTML: { __html: formatMessage(content) }
59716
+ }
59717
+ );
59718
+ }
59719
+ renderedContentCache.current.set(content, finalNode);
59720
+ return finalNode;
59721
+ };
59722
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-screen bg-white", children: [
59723
+ /* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: {
59724
+ __html: `
59725
+ @keyframes slideDown {
59726
+ 0% {
59727
+ transform: translateY(-40vh);
59728
+ opacity: 1;
59729
+ }
59730
+ 100% {
59731
+ transform: translateY(0);
59732
+ opacity: 1;
59733
+ }
59734
+ }
59735
+
59736
+ @keyframes waveLoad {
59737
+ 0% {
59738
+ background-position: -200% 0;
59739
+ }
59740
+ 100% {
59741
+ background-position: 200% 0;
59742
+ }
59743
+ }
59744
+
59745
+ .thinking-wave {
59746
+ background: linear-gradient(
59747
+ 90deg,
59748
+ #6b7280 0%,
59749
+ #6b7280 40%,
59750
+ #3b82f6 50%,
59751
+ #6b7280 60%,
59752
+ #6b7280 100%
59753
+ );
59754
+ background-size: 200% 100%;
59755
+ -webkit-background-clip: text;
59756
+ background-clip: text;
59757
+ -webkit-text-fill-color: transparent;
59758
+ animation: waveLoad 3s ease-in-out infinite;
59759
+ }
59760
+ `
59761
+ } }),
59762
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex-1 flex flex-col h-screen transition-all duration-300 ${isSidebarOpen ? "lg:mr-80 mr-0" : "mr-0"}`, children: [
59763
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex-shrink-0 bg-white px-3 sm:px-6 md:px-8 py-2 sm:py-5 md:py-6 shadow-sm border-b border-gray-200/80 sticky top-0 z-10", children: [
59764
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
59765
+ /* @__PURE__ */ jsxRuntime.jsx(
59766
+ "button",
59767
+ {
59768
+ onClick: () => navigate("/"),
59769
+ className: "p-2 -ml-2 rounded-full active:bg-gray-100 transition-colors",
59770
+ "aria-label": "Navigate back",
59771
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-5 h-5 text-gray-700", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
59772
+ }
59773
+ ),
59774
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col items-center justify-center", children: [
59775
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
59776
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-base font-semibold text-gray-900", children: "Chat with Axel" }),
59777
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex h-2 w-2", children: [
59778
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" }),
59779
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-green-500" })
59780
+ ] })
59781
+ ] }),
59782
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-gray-500", children: /* @__PURE__ */ jsxRuntime.jsx(ISTTimer_default, {}) })
59783
+ ] }),
59784
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
59785
+ /* @__PURE__ */ jsxRuntime.jsx(
59786
+ "button",
59787
+ {
59788
+ onClick: handleNewThread,
59789
+ className: "p-2 rounded-full active:bg-gray-100 transition-colors",
59790
+ "aria-label": "New chat",
59791
+ title: "New chat",
59792
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "w-5 h-5 text-gray-700" })
59793
+ }
59794
+ ),
59795
+ /* @__PURE__ */ jsxRuntime.jsx(
59796
+ "button",
59797
+ {
59798
+ onClick: () => setIsSidebarOpen(!isSidebarOpen),
59799
+ className: "relative p-2 -mr-2 rounded-full active:bg-gray-100 transition-colors",
59800
+ "aria-label": "Toggle chat history",
59801
+ title: isSidebarOpen ? "Hide history" : "Show history",
59802
+ children: isSidebarOpen ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-5 h-5 text-gray-700" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
59803
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "w-5 h-5 text-gray-700" }),
59804
+ newChatCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-1 right-1 bg-red-500 text-white text-[9px] rounded-full w-4 h-4 flex items-center justify-center font-medium", children: newChatCount })
59805
+ ] })
59806
+ }
59807
+ )
59808
+ ] })
59809
+ ] }) }),
59810
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden sm:flex items-center justify-between relative", children: [
59811
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsxRuntime.jsx(
59812
+ BackButtonMinimal,
59813
+ {
59814
+ onClick: () => navigate("/"),
59815
+ text: "Back",
59816
+ size: "default",
59817
+ "aria-label": "Navigate back to dashboard"
59818
+ }
59819
+ ) }),
59820
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 text-center mx-auto", children: [
59821
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-3 mb-1", children: [
59822
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl md:text-2xl lg:text-3xl font-semibold text-gray-900", children: "Chat with Axel" }),
59823
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 w-1.5 md:h-2 md:w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
59824
+ ] }),
59825
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-500", children: /* @__PURE__ */ jsxRuntime.jsx(ISTTimer_default, {}) }) })
59826
+ ] }),
59827
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute right-0 flex items-center gap-2", children: [
59828
+ /* @__PURE__ */ jsxRuntime.jsxs(
59829
+ "button",
59830
+ {
59831
+ onClick: handleNewThread,
59832
+ className: "flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm font-medium",
59833
+ children: [
59834
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "w-4 h-4" }),
59835
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "New Chat" })
59836
+ ]
59837
+ }
59838
+ ),
59839
+ /* @__PURE__ */ jsxRuntime.jsx(
59840
+ "button",
59841
+ {
59842
+ onClick: () => setIsSidebarOpen(!isSidebarOpen),
59843
+ className: "relative flex items-center gap-2 px-4 py-2 text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors text-sm font-medium",
59844
+ "aria-label": "Toggle chat history",
59845
+ children: isSidebarOpen ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
59846
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4" }),
59847
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Hide History" })
59848
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
59849
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "w-4 h-4" }),
59850
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Chat History" }),
59851
+ newChatCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 bg-red-500 text-white text-xs rounded-full px-2 py-0.5 font-medium", children: newChatCount })
59852
+ ] })
59853
+ }
59854
+ )
59855
+ ] })
59856
+ ] })
59857
+ ] }),
59858
+ /* @__PURE__ */ jsxRuntime.jsx(
59859
+ "main",
59860
+ {
59861
+ ref: containerRef,
59862
+ className: `flex-1 bg-gray-50/50 min-h-0 ${displayMessages.length === 0 && !isTransitioning ? "flex items-center justify-center" : "overflow-y-auto"}`,
59863
+ children: !activeThreadId && displayMessages.length === 0 && !isTransitioning ? (
59864
+ /* Centered welcome and input for new chat */
59865
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full max-w-3xl mx-auto px-3 sm:px-4 md:px-6 flex flex-col items-center justify-center space-y-8 sm:space-y-12 -mt-8 sm:-mt-16", children: [
59866
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
59867
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center mb-4 sm:mb-6 md:mb-8", children: /* @__PURE__ */ jsxRuntime.jsx(ProfilePicture, { alt: "Axel - AI Manufacturing Expert", size: "2xl", animate: true }) }),
59868
+ /* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-lg sm:text-xl md:text-2xl lg:text-3xl font-semibold text-gray-900 px-2 sm:px-4", children: [
59869
+ typedText,
59870
+ typedText.length < currentGreeting.length && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "animate-pulse", children: "|" })
59871
+ ] })
59872
+ ] }),
59873
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, children: [
59874
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative bg-white rounded-2xl sm:rounded-3xl shadow-lg border border-gray-200 focus-within:border-gray-300 transition-all duration-200", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-end gap-2 p-3 sm:p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 relative", children: [
59875
+ /* @__PURE__ */ jsxRuntime.jsx(
59876
+ "textarea",
59877
+ {
59878
+ ref: textareaRef,
59879
+ value: inputValue,
59880
+ onChange: (e) => {
59881
+ const newValue = e.target.value;
59882
+ setInputValue(newValue);
59883
+ if (newValue.length > 0 && !hasStartedTyping) {
59884
+ trackTypingStart();
59885
+ }
59886
+ if (newValue.length > 0) {
59887
+ trackTypingProgress(newValue);
59888
+ }
59889
+ if (newValue.length === 0) {
59890
+ resetTypingState();
59891
+ }
59892
+ },
59893
+ onKeyDown: handleKeyDown,
59894
+ onFocus: () => {
59895
+ trackCoreEvent("AI Agent Input Focused", {
59896
+ line_id: lineId,
59897
+ company_id: companyId,
59898
+ shift_id: shiftId,
59899
+ active_thread_id: activeThreadId,
59900
+ has_existing_messages: messages.length > 0,
59901
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
59902
+ });
59903
+ },
59904
+ placeholder: "Ask me anything about your shop-floor",
59905
+ className: "w-full resize-none bg-transparent px-3 sm:px-4 py-3 sm:py-2 pr-12 sm:pr-14 focus:outline-none placeholder-gray-500 text-gray-900 text-sm sm:text-base leading-relaxed",
59906
+ rows: 1,
59907
+ style: { minHeight: "40px", maxHeight: "120px" }
59908
+ }
59909
+ ),
59910
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 sm:right-3 bottom-2 sm:bottom-2 flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
59911
+ "button",
59912
+ {
59913
+ type: "submit",
59914
+ disabled: !inputValue.trim() || isCurrentThreadLoading,
59915
+ className: "inline-flex items-center justify-center w-8 h-8 sm:w-9 sm:h-9 bg-gray-900 text-white rounded-full hover:bg-gray-800 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-gray-500/20",
59916
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "w-4 h-4" })
59917
+ }
59918
+ ) })
59919
+ ] }) }) }),
59920
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-center justify-center gap-2 sm:gap-4 mt-2 text-xs text-gray-400", children: [
59921
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-center", children: isCurrentThreadLoading ? "You can type your next message while Axel responds" : "Press Enter to send \u2022 Shift+Enter for new line" }),
59922
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
59923
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-1.5 h-1.5 rounded-full ${isCurrentThreadLoading ? "bg-orange-500" : "bg-green-500"}` }),
59924
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: isCurrentThreadLoading ? "Responding..." : "Connected" })
59925
+ ] })
59926
+ ] })
59927
+ ] }) })
59928
+ ] })
59929
+ ) : isTransitioning ? (
59930
+ /* Transition state - show user message first, then thinking */
59931
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-4xl mx-auto px-3 sm:px-4 md:px-6 py-4 sm:py-6 pb-24 sm:pb-32", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 sm:space-y-6", children: [
59932
+ displayMessages.map((message, index) => /* @__PURE__ */ jsxRuntime.jsxs(
59933
+ "div",
59934
+ {
59935
+ className: `flex gap-2 sm:gap-3 md:gap-4 ${message.role === "user" ? "justify-end" : "justify-start"}`,
59936
+ children: [
59937
+ message.role === "assistant" && /* @__PURE__ */ jsxRuntime.jsx(ProfilePicture, {}),
59938
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `max-w-none w-full group ${message.role === "user" ? "order-1" : ""}`, children: /* @__PURE__ */ jsxRuntime.jsx(
59939
+ "div",
59940
+ {
59941
+ className: `relative px-3 sm:px-4 md:px-5 py-3 sm:py-4 rounded-xl sm:rounded-2xl shadow-sm ${message.role === "user" ? "bg-blue-600 text-white max-w-[90%] sm:max-w-[85%] ml-auto" : "bg-white border border-gray-200/80 max-w-full"}`,
59942
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${message.role === "user" ? "text-white" : "text-gray-800"}`, children: [
59943
+ message.role === "assistant" ? message.id === -1 ? /* @__PURE__ */ jsxRuntime.jsx(
59944
+ "div",
59945
+ {
59946
+ className: "formatted-content",
59947
+ dangerouslySetInnerHTML: { __html: formatMessage(message.content) }
59948
+ }
59949
+ ) : renderAssistantContent(message.content) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap leading-relaxed", children: message.content }),
59950
+ message.id === -1 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block w-0.5 h-4 bg-gray-400 animate-pulse ml-0.5" })
59951
+ ] })
59952
+ }
59953
+ ) })
59954
+ ]
59955
+ },
59956
+ message.id === -1 ? "streaming-message" : `${message.id}-${index}`
59957
+ )),
59958
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4 justify-start", children: [
59959
+ /* @__PURE__ */ jsxRuntime.jsx(ProfilePicture, {}),
59960
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white border border-gray-200/80 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium thinking-wave", children: "Thinking" }) }) })
59961
+ ] })
59962
+ ] }) })
59963
+ ) : (
59964
+ /* Regular chat view with messages */
59965
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-4xl mx-auto px-3 sm:px-4 md:px-6 py-3 sm:py-6 pb-20 sm:pb-32", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3 sm:space-y-6", children: [
59966
+ displayMessages.map((message, index) => /* @__PURE__ */ jsxRuntime.jsxs(
59967
+ "div",
59968
+ {
59969
+ className: `flex gap-2 sm:gap-3 md:gap-4 ${message.role === "user" ? "justify-end" : "justify-start"}`,
59970
+ children: [
59971
+ message.role === "assistant" && /* @__PURE__ */ jsxRuntime.jsx(ProfilePicture, {}),
59972
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `max-w-none w-full group ${message.role === "user" ? "order-1" : ""}`, children: [
59973
+ /* @__PURE__ */ jsxRuntime.jsxs(
59974
+ "div",
59975
+ {
59976
+ className: `relative px-3 sm:px-4 md:px-5 py-2.5 sm:py-4 rounded-2xl sm:rounded-2xl shadow-sm ${message.role === "user" ? "bg-blue-500 sm:bg-blue-600 text-white max-w-[85%] sm:max-w-[85%] ml-auto" : "bg-gray-100 sm:bg-white sm:border sm:border-gray-200/80 max-w-full"}`,
59977
+ children: [
59978
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${message.role === "user" ? "text-white" : "text-gray-800"}`, children: [
59979
+ message.role === "assistant" ? message.id === -1 ? /* @__PURE__ */ jsxRuntime.jsx(
59980
+ "div",
59981
+ {
59982
+ className: "formatted-content",
59983
+ dangerouslySetInnerHTML: { __html: formatMessage(message.content) }
59984
+ }
59985
+ ) : renderAssistantContent(message.content) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap leading-relaxed", children: message.content }),
59986
+ message.id === -1 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block w-0.5 h-4 bg-gray-400 animate-pulse ml-0.5" })
59987
+ ] }),
59988
+ message.role === "assistant" && message.id !== -1 && /* @__PURE__ */ jsxRuntime.jsx(
59989
+ "button",
59990
+ {
59991
+ onClick: () => copyToClipboard(message.content, message.id.toString()),
59992
+ className: "absolute top-2 sm:top-3 right-2 sm:right-3 opacity-100 sm:opacity-0 group-hover:opacity-100 transition-opacity duration-200 p-1 sm:p-1.5 hover:bg-gray-100 rounded-lg",
59993
+ title: "Copy message",
59994
+ children: copiedMessageId === message.id.toString() ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "w-3.5 h-3.5 sm:w-4 sm:h-4 text-green-600" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "w-3.5 h-3.5 sm:w-4 sm:h-4 text-gray-500" })
59995
+ }
59996
+ ),
59997
+ message.reasoning && /* @__PURE__ */ jsxRuntime.jsxs("details", { className: "mt-3 pt-3 border-t border-gray-200", children: [
59998
+ /* @__PURE__ */ jsxRuntime.jsx("summary", { className: "cursor-pointer text-sm text-gray-600 hover:text-gray-800", children: "View reasoning" }),
59999
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 text-sm text-gray-600", children: message.reasoning })
60000
+ ] })
60001
+ ]
60002
+ }
60003
+ ),
60004
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `mt-1.5 sm:mt-2 flex items-center gap-2 text-xs text-gray-400 ${message.role === "user" ? "justify-end" : "justify-start"}`, children: [
60005
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatTime5(message.created_at) }),
60006
+ message.role === "assistant" && message.id !== -1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
60007
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-1 h-1 bg-gray-300 rounded-full" }),
60008
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Axel" })
60009
+ ] })
60010
+ ] })
60011
+ ] })
60012
+ ]
60013
+ },
60014
+ message.id === -1 ? "streaming-message" : `${message.id}-${index}`
60015
+ )),
60016
+ lastError && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4 justify-start", children: [
60017
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-xl bg-red-100 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "w-6 h-6 text-red-600" }) }) }),
60018
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-red-50 border border-red-200 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: [
60019
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-red-800 text-sm", children: lastError }),
60020
+ /* @__PURE__ */ jsxRuntime.jsx(
60021
+ "button",
60022
+ {
60023
+ onClick: () => setLastError(null),
60024
+ className: "mt-2 text-xs text-red-600 hover:text-red-800 underline",
60025
+ children: "Dismiss"
60026
+ }
60027
+ )
60028
+ ] })
60029
+ ] }),
60030
+ isCurrentThreadLoading && !currentStreaming.message && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4 justify-start", children: [
60031
+ /* @__PURE__ */ jsxRuntime.jsx(ProfilePicture, {}),
60032
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white border border-gray-200/80 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium thinking-wave", children: "Thinking" }) }) })
60033
+ ] }),
60034
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
60035
+ ] }) })
60036
+ )
60037
+ }
60038
+ ),
60039
+ (displayMessages.length > 0 || isTransitioning) && /* @__PURE__ */ jsxRuntime.jsx("footer", { className: `fixed bottom-0 left-0 right-0 bg-gradient-to-t from-white via-white/95 to-transparent sm:from-gray-50/50 sm:to-transparent pointer-events-none ${isSidebarOpen ? "lg:right-80" : "right-0"}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-4xl mx-auto p-2 sm:p-4 md:p-6 pointer-events-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, children: [
60040
+ /* @__PURE__ */ jsxRuntime.jsx(
60041
+ "div",
60042
+ {
60043
+ className: `relative bg-white rounded-xl sm:rounded-3xl shadow-md sm:shadow-lg border border-gray-200 focus-within:border-blue-400 sm:focus-within:border-gray-300 transition-all duration-200 ${isTransitioning ? "animate-slide-down" : ""}`,
60044
+ style: isTransitioning ? {
60045
+ animation: "slideDown 0.8s cubic-bezier(0.4, 0, 0.2, 1) forwards"
60046
+ } : {},
60047
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-end gap-1 sm:gap-2 p-2 sm:p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 relative", children: [
60048
+ /* @__PURE__ */ jsxRuntime.jsx(
60049
+ "textarea",
60050
+ {
60051
+ ref: textareaRef,
60052
+ value: inputValue,
60053
+ onChange: (e) => {
60054
+ const newValue = e.target.value;
60055
+ setInputValue(newValue);
60056
+ if (newValue.length > 0 && !hasStartedTyping) {
60057
+ trackTypingStart();
60058
+ }
60059
+ if (newValue.length > 0) {
60060
+ trackTypingProgress(newValue);
60061
+ }
60062
+ if (newValue.length === 0) {
60063
+ resetTypingState();
60064
+ }
60065
+ },
60066
+ onKeyDown: handleKeyDown,
60067
+ onFocus: () => {
60068
+ trackCoreEvent("AI Agent Input Focused", {
60069
+ line_id: lineId,
60070
+ company_id: companyId,
60071
+ shift_id: shiftId,
60072
+ active_thread_id: activeThreadId,
60073
+ has_existing_messages: messages.length > 0,
60074
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
60075
+ });
60076
+ },
60077
+ placeholder: "Message Axel...",
60078
+ className: "w-full resize-none bg-transparent px-2 sm:px-4 py-2 sm:py-2 pr-10 sm:pr-14 focus:outline-none placeholder-gray-400 sm:placeholder-gray-500 text-gray-900 text-sm sm:text-base leading-relaxed",
60079
+ rows: 1,
60080
+ style: { minHeight: "36px", maxHeight: "120px" }
60081
+ }
60082
+ ),
60083
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-1 sm:right-3 bottom-1 sm:bottom-2 flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
60084
+ "button",
60085
+ {
60086
+ type: "submit",
60087
+ disabled: !inputValue.trim() || isCurrentThreadLoading,
60088
+ className: "inline-flex items-center justify-center w-7 h-7 sm:w-9 sm:h-9 bg-blue-500 sm:bg-gray-900 text-white rounded-full active:scale-95 sm:hover:bg-gray-800 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-blue-400/20 sm:focus:ring-gray-500/20",
60089
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "w-3.5 h-3.5 sm:w-4 sm:h-4" })
60090
+ }
60091
+ ) })
60092
+ ] }) })
60093
+ }
60094
+ ),
60095
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden sm:flex flex-col sm:flex-row items-center justify-center gap-2 sm:gap-4 mt-2 text-xs text-gray-400", children: [
60096
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-center", children: isCurrentThreadLoading ? "You can type your next message while Axel responds" : "Press Enter to send \u2022 Shift+Enter for new line" }),
60097
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
60098
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-1.5 h-1.5 rounded-full ${isCurrentThreadLoading ? "bg-orange-500" : "bg-green-500"}` }),
60099
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: isCurrentThreadLoading ? "Responding..." : "Connected" })
60100
+ ] })
60101
+ ] })
60102
+ ] }) }) })
60103
+ ] }),
60104
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `fixed inset-0 sm:inset-auto sm:right-0 sm:top-0 z-20 h-screen transition-transform duration-300 ease-in-out ${isSidebarOpen ? "translate-x-0" : "translate-x-full"}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full sm:w-96 lg:w-80 h-full bg-white sm:border-l sm:border-gray-200 shadow-lg", children: /* @__PURE__ */ jsxRuntime.jsx(
60105
+ ThreadSidebar,
60106
+ {
60107
+ activeThreadId,
60108
+ onSelectThread: setActiveThreadId,
60109
+ onNewThread: handleNewThread,
60110
+ className: "h-full"
60111
+ }
60112
+ ) }) }),
60113
+ isSidebarOpen && /* @__PURE__ */ jsxRuntime.jsx(
60114
+ "div",
60115
+ {
60116
+ className: "fixed inset-0 bg-black bg-opacity-30 z-10 lg:hidden",
60117
+ onClick: () => setIsSidebarOpen(false)
60118
+ }
60119
+ )
60120
+ ] });
60121
+ };
60122
+ var AIAgentView_default = AIAgentView;
58073
60123
  var S3Service = class {
58074
60124
  constructor(config) {
58075
60125
  this.s3Client = null;
@@ -58524,87 +60574,9 @@ var streamProxyConfig = {
58524
60574
  responseLimit: false
58525
60575
  }
58526
60576
  };
58527
- var ThreadSidebar = ({
58528
- activeThreadId,
58529
- onSelectThread,
58530
- onNewThread,
58531
- className = ""
58532
- }) => {
58533
- const { threads, isLoading, error, deleteThread: deleteThread2 } = useThreads();
58534
- const [deletingId, setDeletingId] = React24.useState(null);
58535
- const handleDelete = async (e, threadId) => {
58536
- e.stopPropagation();
58537
- if (confirm("Are you sure you want to delete this conversation?")) {
58538
- setDeletingId(threadId);
58539
- try {
58540
- await deleteThread2(threadId);
58541
- if (activeThreadId === threadId) {
58542
- onNewThread();
58543
- }
58544
- } catch (error2) {
58545
- console.error("Error deleting thread:", error2);
58546
- alert("Failed to delete conversation. Please try again.");
58547
- } finally {
58548
- setDeletingId(null);
58549
- }
58550
- }
58551
- };
58552
- const formatDate2 = (dateString) => {
58553
- const date = new Date(dateString);
58554
- const now2 = /* @__PURE__ */ new Date();
58555
- const diffMs = now2.getTime() - date.getTime();
58556
- const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
58557
- if (diffDays === 0) {
58558
- return "Today";
58559
- } else if (diffDays === 1) {
58560
- return "Yesterday";
58561
- } else if (diffDays < 7) {
58562
- return date.toLocaleDateString("en-US", { weekday: "short" });
58563
- } else {
58564
- return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
58565
- }
58566
- };
58567
- if (error) {
58568
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `p-4 text-red-600 text-sm ${className}`, children: "Failed to load conversations" });
58569
- }
58570
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col h-screen bg-gray-50 border-r border-gray-200 ${className}`, children: [
58571
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-shrink-0 p-4 border-b border-gray-200", children: [
58572
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Chat History" }),
58573
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 mt-1", children: "Your previous conversations" })
58574
- ] }),
58575
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto min-h-0", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center p-8", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "sm" }) }) : threads.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center text-gray-500 text-sm", children: "No conversations yet" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2", children: threads.map((thread) => /* @__PURE__ */ jsxRuntime.jsxs(
58576
- "div",
58577
- {
58578
- onClick: () => onSelectThread(thread.id),
58579
- className: `group relative flex items-start gap-3 px-4 py-3 cursor-pointer transition-all ${activeThreadId === thread.id ? "bg-blue-50 border-l-4 border-blue-600 hover:bg-blue-100" : "hover:bg-gray-100 border-l-4 border-transparent"}`,
58580
- children: [
58581
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: `w-4 h-4 mt-0.5 flex-shrink-0 ${activeThreadId === thread.id ? "text-blue-600" : "text-gray-400"}` }),
58582
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
58583
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: `text-sm font-medium truncate ${activeThreadId === thread.id ? "text-blue-900" : "text-gray-900"}`, children: thread.title || "Untitled Chat" }),
58584
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-xs mt-0.5 ${activeThreadId === thread.id ? "text-blue-700" : "text-gray-500"}`, children: formatDate2(thread.created_at) })
58585
- ] }),
58586
- deletingId === thread.id ? /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(
58587
- "button",
58588
- {
58589
- onClick: (e) => handleDelete(e, thread.id),
58590
- className: "flex-shrink-0 opacity-0 group-hover:opacity-100 p-1 hover:bg-gray-200 rounded transition-all",
58591
- title: "Delete conversation",
58592
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "w-3.5 h-3.5 text-gray-500" })
58593
- }
58594
- )
58595
- ]
58596
- },
58597
- thread.id
58598
- )) }) }),
58599
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 p-4 border-t border-gray-200", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 text-center", children: [
58600
- threads.length,
58601
- " conversation",
58602
- threads.length !== 1 ? "s" : ""
58603
- ] }) })
58604
- ] });
58605
- };
58606
60577
 
58607
60578
  exports.ACTION_NAMES = ACTION_NAMES;
60579
+ exports.AIAgentView = AIAgentView_default;
58608
60580
  exports.AcceptInvite = AcceptInvite;
58609
60581
  exports.AcceptInviteView = AcceptInviteView_default;
58610
60582
  exports.AdvancedFilterDialog = AdvancedFilterDialog;