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