@elevasis/ui 2.66.0 → 2.68.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/api/index.d.ts +1 -1
  2. package/dist/api/index.js +3 -3
  3. package/dist/app/index.d.ts +16 -15
  4. package/dist/app/index.js +31 -21
  5. package/dist/auth/index.js +10 -12
  6. package/dist/charts/index.js +10 -12
  7. package/dist/chunk-2MTP3H3A.js +425 -0
  8. package/dist/chunk-3KMDHCAR.js +52 -0
  9. package/dist/chunk-3MEXPLWT.js +265 -0
  10. package/dist/{chunk-XNW3O6QW.js → chunk-5NRJ2BLQ.js} +1 -1
  11. package/dist/chunk-75NOC536.js +2162 -0
  12. package/dist/chunk-76IVMVI3.js +1764 -0
  13. package/dist/chunk-AH52XQB7.js +1 -0
  14. package/dist/chunk-BZZCNLT6.js +12 -0
  15. package/dist/chunk-DLR4SDZW.js +51 -0
  16. package/dist/chunk-FK3K2VK2.js +2103 -0
  17. package/dist/chunk-GBXTRSAU.js +37 -0
  18. package/dist/chunk-HJVPVS57.js +1934 -0
  19. package/dist/{chunk-M535KHLW.js → chunk-JC5W55J3.js} +1 -1
  20. package/dist/{chunk-I7BZVVVU.js → chunk-L3HFJFYF.js} +89 -382
  21. package/dist/chunk-LGKLC5MG.js +44 -0
  22. package/dist/{chunk-4DV4ECMG.js → chunk-N7U24M2J.js} +4 -0
  23. package/dist/chunk-NDHMZT2G.js +383 -0
  24. package/dist/chunk-OOACTYRA.js +10 -0
  25. package/dist/chunk-PDHTXPSF.js +12 -0
  26. package/dist/chunk-QYI5BZKM.js +85 -0
  27. package/dist/{chunk-4OEVLV66.js → chunk-R6NMRXNO.js} +112 -147
  28. package/dist/chunk-SIVUCZXQ.js +1194 -0
  29. package/dist/{chunk-JFBZ6XDW.js → chunk-SNZDFCOQ.js} +3 -49
  30. package/dist/chunk-TGPJNKDU.js +1595 -0
  31. package/dist/chunk-TUMSNGTX.js +35 -0
  32. package/dist/chunk-TYKAKJGW.js +67 -0
  33. package/dist/chunk-UD657ICS.js +589 -0
  34. package/dist/chunk-WPIASV3H.js +194 -0
  35. package/dist/chunk-ZFISGKYW.js +39 -0
  36. package/dist/chunk-ZGCWTWBD.js +16127 -0
  37. package/dist/chunk-ZNKZMK2E.js +4528 -0
  38. package/dist/chunk-ZWS3TCQR.js +11032 -0
  39. package/dist/components/chat/index.js +2 -1
  40. package/dist/components/index.d.ts +23 -11
  41. package/dist/components/index.js +2773 -14
  42. package/dist/components/navigation/index.js +11 -12
  43. package/dist/features/auth/index.d.ts +0 -4
  44. package/dist/features/auth/index.js +12 -13
  45. package/dist/features/clients/index.js +14 -12
  46. package/dist/features/crm/index.d.ts +1371 -15
  47. package/dist/features/crm/index.js +15 -12
  48. package/dist/features/dashboard/index.d.ts +1 -2
  49. package/dist/features/dashboard/index.js +15 -12
  50. package/dist/features/delivery/index.d.ts +0 -4
  51. package/dist/features/delivery/index.js +15 -12
  52. package/dist/features/knowledge/index.js +10 -12
  53. package/dist/features/lead-gen/index.d.ts +35 -15
  54. package/dist/features/lead-gen/index.js +16 -12
  55. package/dist/features/monitoring/index.js +15 -12
  56. package/dist/features/monitoring/requests/index.js +13 -13
  57. package/dist/features/operations/index.d.ts +1 -2
  58. package/dist/features/operations/index.js +21 -12
  59. package/dist/features/public-agent-chat/index.js +2 -1
  60. package/dist/features/seo/index.js +2 -1
  61. package/dist/features/settings/index.d.ts +0 -4
  62. package/dist/features/settings/index.js +14 -12
  63. package/dist/hooks/access/index.js +10 -12
  64. package/dist/hooks/delivery/index.d.ts +0 -4
  65. package/dist/hooks/delivery/index.js +2 -23
  66. package/dist/hooks/index.d.ts +13 -7
  67. package/dist/hooks/index.js +10 -12
  68. package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +1 -2
  69. package/dist/hooks/published.d.ts +13 -7
  70. package/dist/hooks/published.js +10 -12
  71. package/dist/initialization/index.d.ts +1 -5
  72. package/dist/knowledge/index.d.ts +1 -2
  73. package/dist/knowledge/index.js +15 -13
  74. package/dist/layout/index.js +14 -12
  75. package/dist/organization/index.d.ts +3 -3
  76. package/dist/organization/index.js +1 -21
  77. package/dist/profile/index.d.ts +0 -4
  78. package/dist/provider/index.d.ts +2 -7
  79. package/dist/provider/index.js +10 -12
  80. package/dist/provider/published.d.ts +2 -7
  81. package/dist/provider/published.js +10 -12
  82. package/dist/supabase/index.d.ts +0 -8
  83. package/dist/test-utils/index.d.ts +5 -0
  84. package/dist/test-utils/index.js +5 -5
  85. package/dist/test-utils/setup-integration.js +1 -1
  86. package/dist/test-utils/setup.js +1 -1
  87. package/dist/theme/index.js +2 -1
  88. package/dist/typeform/index.js +2049 -1
  89. package/dist/types/index.d.ts +13 -7
  90. package/dist/utils/index.d.ts +1 -2
  91. package/dist/utils/index.js +1 -1
  92. package/package.json +5 -5
  93. package/dist/chunk-ANNM5R7S.js +0 -51404
  94. package/dist/chunk-AUDNF2Q7.js +0 -2050
  95. package/dist/index.css +0 -659
  96. package/dist/index.d.ts +0 -17888
  97. package/dist/index.js +0 -30
  98. package/dist/{chunk-GMXGDO3I.js → chunk-MISHPEJX.js} +1 -1
@@ -0,0 +1,2103 @@
1
+ import { ZodFormRenderer } from './chunk-3MEXPLWT.js';
2
+ import { ResourceHealthChart } from './chunk-LGKLC5MG.js';
3
+ import { Graph_module_css_default, useDirectedChainHighlighting, useNodeSelection, useFitViewTrigger } from './chunk-HENXLGVD.js';
4
+ import { AppShellCenteredContainer, AppShellLoader } from './chunk-GBXTRSAU.js';
5
+ import { useCyberColors, GlowDot, JsonViewer, useExecuteResource, EmptyState, useDashboardMetrics, useResources, useTimeRangeDates, useUnresolvedErrors, useRecentExecutionsByResource, PageTitleCaption, HeroStatsRow, useCommandQueue, useScheduledTasks, TabCountBadge, useResourcesHealth } from './chunk-ZGCWTWBD.js';
6
+ import { glassBase } from './chunk-R6NMRXNO.js';
7
+ import { CardHeader } from './chunk-62GVNH5U.js';
8
+ import { useInitialization } from './chunk-P45GQ3ZW.js';
9
+ import { STATUS_COLORS, getStatusIcon, formatDuration, getStatusColors, AGENT_CONSTANTS, shouldAnimateEdge, TIMELINE_CONSTANTS, calculateBarPosition, CONTAINER_CONSTANTS, useExecutionPath, useUnifiedWorkflowLayout, WORKFLOW_CONSTANTS, useReactFlowAgent } from './chunk-BLXJEIQS.js';
10
+ import { formatTimeAgo, formatRelativeTime } from './chunk-L3HFJFYF.js';
11
+ import { getTimeRangeDates } from './chunk-Y6I3IC45.js';
12
+ import { ResourceStatusColors } from './chunk-6SSQGWK7.js';
13
+ import { memo, useMemo, useEffect, useState, useCallback, Fragment } from 'react';
14
+ import { Paper, Stack, Text, Group, Badge, Box, useComputedColorScheme, Card, ActionIcon, Loader, SegmentedControl, Collapse, Button, Modal, Center, SimpleGrid, Title, Tabs, Grid, ThemeIcon } from '@mantine/core';
15
+ import { jsxs, jsx, Fragment as Fragment$1 } from 'react/jsx-runtime';
16
+ import { Position, Handle, getSmoothStepPath, BaseEdge as BaseEdge$1, EdgeLabelRenderer, Panel, useReactFlow, Controls, ReactFlowProvider, ReactFlow } from '@xyflow/react';
17
+ import { IconPlayerPlay, IconPlayerStop, IconArrowsSplit, IconSquare, IconFocus2, IconChevronRight, IconArrowUpRight, IconLayoutDashboard, IconActivity, IconAlertTriangle, IconHandStop, IconCalendarEvent, IconCircleCheck, IconBrain, IconGitBranch, IconTool, IconWand, IconCheck, IconAlertCircle } from '@tabler/icons-react';
18
+ import '@xyflow/react/dist/style.css';
19
+ import { z } from 'zod';
20
+ import { notifications } from '@mantine/notifications';
21
+ import '@mantine/charts/styles.css';
22
+
23
+ var DOMAIN_COLORS = {
24
+ primary: "var(--color-primary)",
25
+ agent: "#8b5cf6",
26
+ workflow: "#3b82f6",
27
+ trigger: "#f97316",
28
+ integration: "#14b8a6",
29
+ approval: "#f59e0b"
30
+ };
31
+ function fill(color, isDark) {
32
+ return isDark ? `color-mix(in srgb, ${color} 80%, black)` : `color-mix(in srgb, ${color} 60%, white)`;
33
+ }
34
+ function glow(color) {
35
+ return `color-mix(in srgb, ${color} 40%, transparent)`;
36
+ }
37
+ function useGraphTheme() {
38
+ const isDark = useComputedColorScheme("dark") === "dark";
39
+ return useMemo(
40
+ () => ({
41
+ primary: fill(DOMAIN_COLORS.primary, isDark),
42
+ primaryGlow: glow(DOMAIN_COLORS.primary),
43
+ agent: fill(DOMAIN_COLORS.agent, isDark),
44
+ workflow: fill(DOMAIN_COLORS.workflow, isDark),
45
+ trigger: fill(DOMAIN_COLORS.trigger, isDark),
46
+ integration: fill(DOMAIN_COLORS.integration, isDark),
47
+ approval: fill(DOMAIN_COLORS.approval, isDark),
48
+ agentGlow: glow(DOMAIN_COLORS.agent),
49
+ workflowGlow: glow(DOMAIN_COLORS.workflow),
50
+ triggerGlow: glow(DOMAIN_COLORS.trigger),
51
+ integrationGlow: glow(DOMAIN_COLORS.integration),
52
+ approvalGlow: glow(DOMAIN_COLORS.approval),
53
+ edgeTriggers: fill(DOMAIN_COLORS.workflow, isDark),
54
+ edgeUses: fill(DOMAIN_COLORS.integration, isDark),
55
+ edgeApproval: fill(DOMAIN_COLORS.approval, isDark),
56
+ edgeTriggersGlow: glow(DOMAIN_COLORS.workflow),
57
+ edgeUsesGlow: glow(DOMAIN_COLORS.integration),
58
+ edgeApprovalGlow: glow(DOMAIN_COLORS.approval)
59
+ }),
60
+ [isDark]
61
+ );
62
+ }
63
+ function getGraphBackgroundStyles(isDark) {
64
+ const pct = isDark ? 5 : 3;
65
+ const glowPct = isDark ? 8 : 5;
66
+ const mix = (percent) => `color-mix(in srgb, var(--color-primary) ${percent}%, transparent)`;
67
+ return {
68
+ backgroundImage: `
69
+ linear-gradient(${mix(pct)} 1px, transparent 1px),
70
+ linear-gradient(90deg, ${mix(pct)} 1px, transparent 1px),
71
+ radial-gradient(ellipse at 50% 50%, ${mix(glowPct)} 0%, transparent 70%)
72
+ `,
73
+ backgroundColor: "color-mix(in srgb, var(--color-background) 50%, var(--glass-background))",
74
+ backdropFilter: "var(--glass-blur)",
75
+ backgroundSize: "40px 40px, 40px 40px, 100% 100%"
76
+ };
77
+ }
78
+ function useGraphBackgroundStyles() {
79
+ const isDark = useComputedColorScheme("dark") === "dark";
80
+ return useMemo(() => getGraphBackgroundStyles(isDark), [isDark]);
81
+ }
82
+ function GraphContainer({ children, height = 600 }) {
83
+ const backgroundStyles = useGraphBackgroundStyles();
84
+ return /* @__PURE__ */ jsx(
85
+ Box,
86
+ {
87
+ style: {
88
+ width: "100%",
89
+ height,
90
+ border: "1px solid var(--color-border)",
91
+ borderRadius: "var(--mantine-radius-md)",
92
+ overflow: "hidden",
93
+ position: "relative",
94
+ ...backgroundStyles
95
+ },
96
+ children
97
+ }
98
+ );
99
+ }
100
+ function GraphBackground() {
101
+ return null;
102
+ }
103
+ function LegendDot({ color }) {
104
+ return /* @__PURE__ */ jsx(
105
+ Box,
106
+ {
107
+ style: {
108
+ width: 10,
109
+ height: 10,
110
+ borderRadius: "50%",
111
+ backgroundColor: `var(--mantine-color-${color}-5)`
112
+ }
113
+ }
114
+ );
115
+ }
116
+ function LegendLine({ color }) {
117
+ return /* @__PURE__ */ jsx(
118
+ Box,
119
+ {
120
+ style: {
121
+ width: 20,
122
+ height: 3,
123
+ borderRadius: 2,
124
+ background: `linear-gradient(90deg, var(--mantine-color-${color}-5), var(--mantine-color-${color}-6))`
125
+ }
126
+ }
127
+ );
128
+ }
129
+ function GraphLegend({ title = "Legend", items, position = "bottom-right" }) {
130
+ const margins = {
131
+ marginBottom: position.includes("bottom") ? 12 : void 0,
132
+ marginTop: position.includes("top") ? 12 : void 0,
133
+ marginRight: position.includes("right") ? 60 : 12,
134
+ marginLeft: position.includes("left") ? 12 : void 0
135
+ };
136
+ return /* @__PURE__ */ jsx(Panel, { position, style: margins, children: /* @__PURE__ */ jsx(Card, { p: "xs", className: Graph_module_css_default.legend, children: /* @__PURE__ */ jsxs(Group, { children: [
137
+ /* @__PURE__ */ jsx(
138
+ Text,
139
+ {
140
+ size: "xs",
141
+ fw: 600,
142
+ style: {
143
+ letterSpacing: "0.5px",
144
+ textTransform: "uppercase",
145
+ fontFamily: "var(--mantine-font-family-headings)"
146
+ },
147
+ children: title
148
+ }
149
+ ),
150
+ items.map((item) => /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
151
+ item.type === "line" ? /* @__PURE__ */ jsx(LegendLine, { color: item.color }) : /* @__PURE__ */ jsx(LegendDot, { color: item.color }),
152
+ /* @__PURE__ */ jsx(Text, { size: "xs", children: item.label })
153
+ ] }, item.label))
154
+ ] }) }) });
155
+ }
156
+ function GraphFitViewButton({ padding = 0.2, variant = "reactflow", duration = 300 }) {
157
+ const { fitView } = useReactFlow();
158
+ const handleFitView = () => {
159
+ fitView({ padding, duration });
160
+ };
161
+ if (variant === "mantine") {
162
+ return /* @__PURE__ */ jsx(
163
+ ActionIcon,
164
+ {
165
+ onClick: handleFitView,
166
+ variant: "default",
167
+ size: "lg",
168
+ title: "Fit view",
169
+ style: {
170
+ position: "absolute",
171
+ bottom: 12,
172
+ right: 12,
173
+ zIndex: 5,
174
+ background: "var(--color-surface)",
175
+ border: "1px solid var(--color-border)"
176
+ },
177
+ children: /* @__PURE__ */ jsx(IconFocus2, { size: 18 })
178
+ }
179
+ );
180
+ }
181
+ return /* @__PURE__ */ jsx(Controls, { position: "bottom-right", showZoom: false, showFitView: false, showInteractive: false, children: /* @__PURE__ */ jsx(
182
+ "button",
183
+ {
184
+ className: "react-flow__controls-button react-flow__controls-fitview",
185
+ onClick: handleFitView,
186
+ title: "Fit view",
187
+ children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { d: "M8 3H5C3.89 3 3 3.89 3 5V8H5V5H8V3M19 3H16V5H19V8H21V5C21 3.89 20.11 3 19 3M19 19H16V21H19C20.11 21 21 20.11 21 19V16H19V19M5 19H8V21H5C3.89 21 3 20.11 3 19V16H5V19Z" }) })
188
+ }
189
+ ) });
190
+ }
191
+ function GraphFitViewHandler({
192
+ trigger,
193
+ padding = 0.15,
194
+ duration = 300,
195
+ delay = 250
196
+ }) {
197
+ const { fitView } = useReactFlow();
198
+ useEffect(() => {
199
+ if (trigger && trigger > 0) {
200
+ const timeout = setTimeout(() => {
201
+ fitView({ padding, duration });
202
+ }, delay);
203
+ return () => clearTimeout(timeout);
204
+ }
205
+ return void 0;
206
+ }, [trigger, fitView, padding, duration, delay]);
207
+ return null;
208
+ }
209
+ var colorClassMap = {
210
+ violet: Graph_module_css_default.nodeAgent,
211
+ blue: Graph_module_css_default.nodeWorkflow,
212
+ orange: Graph_module_css_default.nodeTrigger,
213
+ teal: Graph_module_css_default.nodeIntegration,
214
+ gray: Graph_module_css_default.nodeExternal,
215
+ yellow: Graph_module_css_default.nodeHuman
216
+ };
217
+ var BaseNode = memo(function BaseNode2({
218
+ children,
219
+ color,
220
+ selected = false,
221
+ highlighted = false,
222
+ width = 220,
223
+ className = "",
224
+ handleDirection = "horizontal",
225
+ showSourceHandle = true,
226
+ showTargetHandle = true
227
+ }) {
228
+ const typeClass = colorClassMap[color] || Graph_module_css_default.nodeAgent;
229
+ const highlightClass = highlighted ? Graph_module_css_default.nodeHighlighted : "";
230
+ const targetPosition = handleDirection === "horizontal" ? Position.Left : Position.Top;
231
+ const sourcePosition = handleDirection === "horizontal" ? Position.Right : Position.Bottom;
232
+ return /* @__PURE__ */ jsxs("div", { className: `${Graph_module_css_default.node} ${typeClass} ${highlightClass} ${className}`, children: [
233
+ showTargetHandle && /* @__PURE__ */ jsx(Handle, { type: "target", position: targetPosition, style: { opacity: 0, pointerEvents: "none" } }),
234
+ showSourceHandle && /* @__PURE__ */ jsx(Handle, { type: "source", position: sourcePosition, style: { opacity: 0, pointerEvents: "none" } }),
235
+ /* @__PURE__ */ jsx(
236
+ Paper,
237
+ {
238
+ p: "sm",
239
+ className: `${Graph_module_css_default.nodeCard} ${selected ? Graph_module_css_default.nodeCardSelected : ""}`,
240
+ style: {
241
+ width,
242
+ ...glassBase,
243
+ border: `1px solid ${selected ? `var(--mantine-color-${color}-5)` : "var(--color-border)"}`,
244
+ backgroundColor: "var(--color-surface)",
245
+ cursor: "pointer",
246
+ boxShadow: selected ? `0 0 15px var(--mantine-color-${color}-5), var(--standard-box-shadow)` : "var(--standard-box-shadow)"
247
+ },
248
+ children
249
+ }
250
+ )
251
+ ] });
252
+ });
253
+ var BaseEdge = memo(function BaseEdge2({
254
+ id,
255
+ sourceX,
256
+ sourceY,
257
+ targetX,
258
+ targetY,
259
+ sourcePosition,
260
+ targetPosition,
261
+ color,
262
+ glowColor,
263
+ label,
264
+ selected,
265
+ animated = true,
266
+ dimmed = false,
267
+ edgeIndex = 0,
268
+ totalEdges = 1
269
+ }) {
270
+ const edgeSpacing = 10;
271
+ const baseOffset = 15;
272
+ const offsetAmount = totalEdges > 1 ? (edgeIndex - (totalEdges - 1) / 2) * edgeSpacing : 0;
273
+ const [edgePath, labelX, labelY] = getSmoothStepPath({
274
+ sourceX,
275
+ sourceY: sourceY + offsetAmount,
276
+ sourcePosition,
277
+ targetX,
278
+ targetY: targetY + offsetAmount,
279
+ targetPosition,
280
+ borderRadius: 8,
281
+ offset: baseOffset + Math.abs(offsetAmount)
282
+ // Stagger the turn points horizontally
283
+ });
284
+ const edgeOpacity = dimmed ? 0.25 : 1;
285
+ return /* @__PURE__ */ jsxs("g", { style: { opacity: edgeOpacity }, children: [
286
+ /* @__PURE__ */ jsx(
287
+ "path",
288
+ {
289
+ d: edgePath,
290
+ fill: "none",
291
+ stroke: color,
292
+ strokeWidth: selected ? 8 : 6,
293
+ strokeOpacity: 0.2,
294
+ style: { filter: "blur(4px)" }
295
+ }
296
+ ),
297
+ animated && !dimmed && /* @__PURE__ */ jsx(
298
+ "path",
299
+ {
300
+ d: edgePath,
301
+ fill: "none",
302
+ stroke: color,
303
+ strokeWidth: selected ? 4 : 3,
304
+ strokeOpacity: 0.3,
305
+ strokeDasharray: "12 6",
306
+ className: Graph_module_css_default.edgeAnimated,
307
+ style: { filter: `drop-shadow(0 0 3px ${glowColor})` }
308
+ }
309
+ ),
310
+ /* @__PURE__ */ jsx(
311
+ BaseEdge$1,
312
+ {
313
+ id,
314
+ path: edgePath,
315
+ style: {
316
+ stroke: color,
317
+ strokeWidth: selected ? 3 : 2,
318
+ filter: dimmed ? "none" : selected ? `drop-shadow(0 0 6px ${glowColor})` : `drop-shadow(0 0 2px ${glowColor})`
319
+ }
320
+ }
321
+ ),
322
+ animated && !dimmed && /* @__PURE__ */ jsx(
323
+ "path",
324
+ {
325
+ d: edgePath,
326
+ fill: "none",
327
+ stroke: "white",
328
+ strokeWidth: 2,
329
+ strokeOpacity: 0.6,
330
+ strokeDasharray: "4 20",
331
+ className: Graph_module_css_default.edgeAnimated,
332
+ style: { filter: "drop-shadow(0 0 2px white)" }
333
+ }
334
+ ),
335
+ label && /* @__PURE__ */ jsx(EdgeLabelRenderer, { children: /* @__PURE__ */ jsx(
336
+ "div",
337
+ {
338
+ className: `${Graph_module_css_default.edgeLabel} ${dimmed ? Graph_module_css_default.edgeLabelDimmed : ""}`,
339
+ style: {
340
+ position: "absolute",
341
+ transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)`,
342
+ pointerEvents: "all",
343
+ fontSize: 10,
344
+ fontWeight: 600,
345
+ textTransform: "uppercase",
346
+ letterSpacing: "0.5px",
347
+ padding: "3px 8px",
348
+ borderRadius: 6,
349
+ background: `linear-gradient(135deg, ${color}, ${color}dd)`,
350
+ color: "var(--color-text)",
351
+ boxShadow: "0 2px 8px rgba(0,0,0,0.2)",
352
+ opacity: dimmed ? 0.25 : 1
353
+ },
354
+ children: label
355
+ }
356
+ ) })
357
+ ] });
358
+ });
359
+ function ExecutionStatusBadge({
360
+ status,
361
+ size = "sm",
362
+ variant = "light",
363
+ showLoader = true
364
+ }) {
365
+ const statusColors = STATUS_COLORS[status];
366
+ const isRunning = status === "running" && showLoader;
367
+ return /* @__PURE__ */ jsx(
368
+ Badge,
369
+ {
370
+ color: statusColors.badge,
371
+ size,
372
+ variant,
373
+ leftSection: isRunning ? /* @__PURE__ */ jsx(Loader, { size: 10, color: statusColors.badge }) : void 0,
374
+ children: status.charAt(0).toUpperCase() + status.slice(1)
375
+ }
376
+ );
377
+ }
378
+ function getRateColor(rate) {
379
+ if (rate >= 95) return "var(--color-success)";
380
+ if (rate >= 80) return "var(--color-warning)";
381
+ return "var(--color-error)";
382
+ }
383
+ function getMantineRateColor(rate) {
384
+ if (rate >= 95) return "green";
385
+ if (rate >= 80) return "yellow";
386
+ return "red";
387
+ }
388
+ function ExecutionStats({
389
+ totalExecutions,
390
+ successCount,
391
+ failureCount,
392
+ warningCount,
393
+ successRate,
394
+ align = "flex-end",
395
+ compact = false
396
+ }) {
397
+ const cyberColors = useCyberColors();
398
+ if (totalExecutions === 0 && !compact) {
399
+ return null;
400
+ }
401
+ if (compact && totalExecutions === 0) {
402
+ return /* @__PURE__ */ jsxs(Group, { gap: 10, wrap: "nowrap", style: { width: "100%" }, children: [
403
+ /* @__PURE__ */ jsx(Text, { size: "md", fw: 700, ff: "monospace", c: "dimmed", style: { minWidth: 42 }, children: "\u2014" }),
404
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", style: { whiteSpace: "nowrap" }, children: "No recent executions" })
405
+ ] });
406
+ }
407
+ if (compact) {
408
+ return /* @__PURE__ */ jsxs(Group, { gap: 10, wrap: "nowrap", style: { width: "100%" }, children: [
409
+ /* @__PURE__ */ jsxs(Group, { gap: 8, wrap: "nowrap", children: [
410
+ /* @__PURE__ */ jsxs(Text, { size: "md", fw: 700, ff: "monospace", style: { color: getRateColor(successRate), minWidth: 42 }, children: [
411
+ successRate,
412
+ "%"
413
+ ] }),
414
+ /* @__PURE__ */ jsxs(Group, { gap: 5, wrap: "nowrap", children: [
415
+ /* @__PURE__ */ jsx(GlowDot, { size: "sm", color: cyberColors.green }),
416
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, c: "green", children: successCount })
417
+ ] }),
418
+ failureCount > 0 && /* @__PURE__ */ jsxs(Group, { gap: 5, wrap: "nowrap", children: [
419
+ /* @__PURE__ */ jsx(GlowDot, { size: "sm", color: cyberColors.red }),
420
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, c: "red", children: failureCount })
421
+ ] })
422
+ ] }),
423
+ /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", style: { whiteSpace: "nowrap" }, children: [
424
+ totalExecutions,
425
+ " ",
426
+ totalExecutions === 1 ? "run" : "runs"
427
+ ] })
428
+ ] });
429
+ }
430
+ return /* @__PURE__ */ jsxs(Stack, { gap: 2, align, style: { whiteSpace: "nowrap" }, children: [
431
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "blue", children: [
432
+ totalExecutions,
433
+ " ",
434
+ totalExecutions === 1 ? "execution" : "executions"
435
+ ] }),
436
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "green", children: [
437
+ successCount,
438
+ " success"
439
+ ] }),
440
+ warningCount != null && warningCount > 0 && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "yellow", children: [
441
+ warningCount,
442
+ " warning"
443
+ ] }),
444
+ failureCount > 0 && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "red", children: [
445
+ failureCount,
446
+ " failed"
447
+ ] }),
448
+ /* @__PURE__ */ jsxs(Text, { size: "xs", fw: 600, c: getMantineRateColor(successRate), children: [
449
+ successRate,
450
+ "% Success Rate"
451
+ ] })
452
+ ] });
453
+ }
454
+ function TimelineAxis({ totalDuration }) {
455
+ const markers = [
456
+ { position: 0, time: 0 },
457
+ { position: 25, time: totalDuration * 0.25 },
458
+ { position: 50, time: totalDuration * 0.5 },
459
+ { position: 75, time: totalDuration * 0.75 },
460
+ { position: 100, time: totalDuration }
461
+ ];
462
+ return /* @__PURE__ */ jsx(
463
+ Box,
464
+ {
465
+ style: {
466
+ position: "relative",
467
+ height: 20
468
+ },
469
+ children: markers.map((marker, idx) => /* @__PURE__ */ jsx(
470
+ Box,
471
+ {
472
+ style: {
473
+ position: "absolute",
474
+ left: `${marker.position}%`,
475
+ transform: marker.position === 100 ? "translateX(-100%)" : marker.position === 0 ? "none" : "translateX(-50%)",
476
+ top: 4
477
+ },
478
+ children: /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatDuration(marker.time) })
479
+ },
480
+ idx
481
+ ))
482
+ }
483
+ );
484
+ }
485
+ function TimelineContainer({ executionStart, executionEnd, children }) {
486
+ const totalDuration = executionEnd - executionStart;
487
+ return /* @__PURE__ */ jsxs(
488
+ Box,
489
+ {
490
+ style: {
491
+ borderBottom: "1px solid var(--color-border)",
492
+ backgroundColor: "var(--color-background)",
493
+ padding: "var(--mantine-spacing-xs)"
494
+ },
495
+ children: [
496
+ /* @__PURE__ */ jsx(
497
+ Box,
498
+ {
499
+ style: {
500
+ position: "relative"
501
+ },
502
+ children: /* @__PURE__ */ jsx(Box, { style: { position: "relative", zIndex: 1 }, children })
503
+ }
504
+ ),
505
+ /* @__PURE__ */ jsx(Box, { style: { paddingLeft: TIMELINE_CONSTANTS.LABEL_WIDTH + 12, paddingRight: 16 }, children: /* @__PURE__ */ jsx(TimelineAxis, { totalDuration }) })
506
+ ]
507
+ }
508
+ );
509
+ }
510
+ function TimelineBar({
511
+ startTime,
512
+ endTime,
513
+ executionStart,
514
+ executionEnd,
515
+ status,
516
+ label,
517
+ onClick,
518
+ isSelected = false,
519
+ hasSelection = false
520
+ }) {
521
+ const colors = getStatusColors(status);
522
+ const { left, width } = calculateBarPosition(startTime, endTime, executionStart, executionEnd);
523
+ const opacity = hasSelection && !isSelected ? 0.5 : 1;
524
+ return /* @__PURE__ */ jsx(
525
+ Box,
526
+ {
527
+ style: {
528
+ position: "absolute",
529
+ left: `${left}%`,
530
+ width: `${width}%`,
531
+ top: 4,
532
+ height: TIMELINE_CONSTANTS.BAR_HEIGHT / 2,
533
+ backgroundColor: colors.color,
534
+ opacity,
535
+ borderRadius: 4,
536
+ cursor: onClick ? "pointer" : "default",
537
+ display: "flex",
538
+ alignItems: "center",
539
+ justifyContent: "center",
540
+ overflow: "hidden"
541
+ },
542
+ onClick,
543
+ children: label && /* @__PURE__ */ jsx(Text, { size: "xs", c: "white", style: { whiteSpace: "nowrap" }, children: label })
544
+ }
545
+ );
546
+ }
547
+ function TimelineRow({
548
+ label,
549
+ bars,
550
+ executionStart,
551
+ executionEnd,
552
+ indent = 0,
553
+ selectedNodeId
554
+ }) {
555
+ const labelMatch = label.match(/^(.+?)\s*\((.+?)\)$/);
556
+ const labelName = labelMatch ? labelMatch[1] : label;
557
+ const labelDuration = labelMatch ? labelMatch[2] : null;
558
+ const statusColor = bars.length > 0 ? getStatusColors(bars[0].status).color : "var(--color-text-dimmed)";
559
+ const hasSelection = selectedNodeId !== null && selectedNodeId !== void 0;
560
+ return /* @__PURE__ */ jsxs(
561
+ Box,
562
+ {
563
+ style: {
564
+ display: "flex",
565
+ gap: 0,
566
+ height: TIMELINE_CONSTANTS.BAR_HEIGHT
567
+ // paddingLeft: indent * TIMELINE_CONSTANTS.INDENT_SIZE
568
+ },
569
+ children: [
570
+ /* @__PURE__ */ jsxs(
571
+ Box,
572
+ {
573
+ style: {
574
+ height: TIMELINE_CONSTANTS.BAR_HEIGHT,
575
+ width: TIMELINE_CONSTANTS.LABEL_WIDTH,
576
+ flexShrink: 0,
577
+ display: "flex",
578
+ alignItems: "center",
579
+ gap: 6,
580
+ paddingRight: 12,
581
+ paddingLeft: 8 + indent * TIMELINE_CONSTANTS.INDENT_SIZE,
582
+ // Indent only the label, not the timeline bars
583
+ overflow: "hidden"
584
+ },
585
+ children: [
586
+ /* @__PURE__ */ jsx(
587
+ Box,
588
+ {
589
+ style: {
590
+ width: 6,
591
+ height: 6,
592
+ borderRadius: "50%",
593
+ backgroundColor: statusColor,
594
+ flexShrink: 0
595
+ }
596
+ }
597
+ ),
598
+ /* @__PURE__ */ jsx(Text, { size: "sm", truncate: true, style: { flexShrink: 1, minWidth: 0 }, children: labelName }),
599
+ labelDuration && /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", ff: "monospace", style: { flexShrink: 0 }, children: [
600
+ "(",
601
+ labelDuration,
602
+ ")"
603
+ ] })
604
+ ]
605
+ }
606
+ ),
607
+ /* @__PURE__ */ jsx(
608
+ Box,
609
+ {
610
+ style: {
611
+ position: "relative",
612
+ flex: 1,
613
+ height: TIMELINE_CONSTANTS.BAR_HEIGHT,
614
+ marginLeft: 12,
615
+ marginRight: 16
616
+ // Right margin to match grid padding
617
+ },
618
+ children: bars.map((bar, idx) => {
619
+ const isSelected = bar.nodeId !== void 0 && bar.nodeId === selectedNodeId;
620
+ return /* @__PURE__ */ jsx(
621
+ TimelineBar,
622
+ {
623
+ ...bar,
624
+ executionStart,
625
+ executionEnd,
626
+ isSelected,
627
+ hasSelection
628
+ },
629
+ idx
630
+ );
631
+ })
632
+ }
633
+ )
634
+ ]
635
+ }
636
+ );
637
+ }
638
+ var VisualizerContainer = ({ children, handleContainerClick, height }) => {
639
+ const containerHeight = height ?? CONTAINER_CONSTANTS.CONTAINER_HEIGHT;
640
+ return /* @__PURE__ */ jsx(Box, { onClick: handleContainerClick, children: /* @__PURE__ */ jsx(
641
+ "div",
642
+ {
643
+ className: `elevasis-graph-root ${Graph_module_css_default.graphContainer}`,
644
+ style: {
645
+ width: "100%",
646
+ height: `${containerHeight}px`,
647
+ overflow: "hidden"
648
+ },
649
+ children
650
+ }
651
+ ) });
652
+ };
653
+ var EmptyVisualizer = ({ message = "Select an execution to view timeline" }) => {
654
+ return /* @__PURE__ */ jsx(
655
+ Box,
656
+ {
657
+ h: CONTAINER_CONSTANTS.CONTAINER_HEIGHT,
658
+ bg: "var(--color-background)",
659
+ style: {
660
+ borderBottom: "1px solid var(--color-border)",
661
+ borderRadius: "var(--mantine-radius-default)",
662
+ display: "flex",
663
+ alignItems: "center",
664
+ justifyContent: "center"
665
+ },
666
+ children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: message })
667
+ }
668
+ );
669
+ };
670
+ var UnifiedWorkflowNode = memo(function UnifiedWorkflowNode2({ data }) {
671
+ const selected = data.isSelected ?? false;
672
+ const primaryColor = data.isEntryPoint ? "teal" : data.isEndNode ? "violet" : data.isConditional ? "orange" : "blue";
673
+ const statusColors = data.executionStatus ? STATUS_COLORS[data.executionStatus] : void 0;
674
+ const showExecutionStatus = data.isExecuted && data.executionStatus;
675
+ return /* @__PURE__ */ jsx(
676
+ BaseNode,
677
+ {
678
+ color: primaryColor,
679
+ selected,
680
+ highlighted: Boolean(data.highlighted),
681
+ width: 220,
682
+ className: data.isDimmed ? "dimmed-node" : "",
683
+ showSourceHandle: !data.isEndNode,
684
+ children: /* @__PURE__ */ jsx("div", { style: { opacity: data.isDimmed ? 0.3 : 1 }, children: /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
685
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, lineClamp: 1, style: { fontFamily: "var(--mantine-font-family-headings)" }, children: data.name }),
686
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
687
+ data.isEntryPoint && /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "teal", leftSection: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 10 }), children: "Entry" }),
688
+ data.isEndNode && /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "violet", leftSection: /* @__PURE__ */ jsx(IconPlayerStop, { size: 10 }), children: "End" }),
689
+ data.isConditional && /* @__PURE__ */ jsxs(Badge, { size: "xs", variant: "light", color: "orange", leftSection: /* @__PURE__ */ jsx(IconArrowsSplit, { size: 10 }), children: [
690
+ data.routeCount,
691
+ " routes"
692
+ ] }),
693
+ !data.isEntryPoint && !data.isEndNode && !data.isConditional && /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", leftSection: /* @__PURE__ */ jsx(IconSquare, { size: 10 }), children: "Step" }),
694
+ /* @__PURE__ */ jsx(Text, { size: "xs", ff: "monospace", c: "dimmed", truncate: true, children: data.id })
695
+ ] }),
696
+ !data.isDimmed && data.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 2, children: data.description }),
697
+ showExecutionStatus && statusColors && /* @__PURE__ */ jsx(Box, { mt: 4, children: /* @__PURE__ */ jsxs(Group, { gap: 8, align: "center", children: [
698
+ /* @__PURE__ */ jsx(Box, { children: getStatusIcon({
699
+ status: data.executionStatus,
700
+ colors: { icon: statusColors.color },
701
+ iconSize: 16,
702
+ spinDuration: "1s"
703
+ }) }),
704
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: statusColors.badge, children: data.executionStatus }),
705
+ data.duration !== void 0 && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatDuration(data.duration) })
706
+ ] }) })
707
+ ] }) })
708
+ }
709
+ );
710
+ });
711
+ var UnifiedWorkflowEdge = memo(function UnifiedWorkflowEdge2({
712
+ id,
713
+ sourceX,
714
+ sourceY,
715
+ targetX,
716
+ targetY,
717
+ selected,
718
+ data
719
+ }) {
720
+ const colors = useGraphTheme();
721
+ const edgeType = data?.edgeType || "linear";
722
+ const isDimmed = data?.isDimmed ?? false;
723
+ const isAnimated = data?.isAnimated ?? false;
724
+ let edgeColor;
725
+ let glowColor;
726
+ let label;
727
+ switch (edgeType) {
728
+ case "conditional":
729
+ edgeColor = colors.trigger;
730
+ glowColor = colors.triggerGlow;
731
+ label = data?.label || "route";
732
+ break;
733
+ case "default":
734
+ edgeColor = colors.integration;
735
+ glowColor = colors.integrationGlow;
736
+ label = data?.label || "default";
737
+ break;
738
+ case "linear":
739
+ default:
740
+ edgeColor = colors.workflow;
741
+ glowColor = colors.workflowGlow;
742
+ label = void 0;
743
+ break;
744
+ }
745
+ return /* @__PURE__ */ jsx(
746
+ BaseEdge,
747
+ {
748
+ id,
749
+ sourceX,
750
+ sourceY,
751
+ targetX,
752
+ targetY,
753
+ sourcePosition: Position.Right,
754
+ targetPosition: Position.Left,
755
+ color: edgeColor,
756
+ glowColor,
757
+ label,
758
+ selected,
759
+ animated: isAnimated,
760
+ dimmed: isDimmed
761
+ }
762
+ );
763
+ });
764
+ var nodeTypes = {
765
+ unifiedWorkflowNode: UnifiedWorkflowNode
766
+ };
767
+ var edgeTypes = {
768
+ unifiedWorkflowEdge: UnifiedWorkflowEdge
769
+ };
770
+ var NODE_LEGEND_ITEMS = [
771
+ { color: "teal", label: "Entry" },
772
+ { color: "blue", label: "Step" },
773
+ { color: "orange", label: "Conditional" },
774
+ { color: "violet", label: "End" }
775
+ ];
776
+ var EDGE_LEGEND_ITEMS = [
777
+ { color: "blue", label: "Next", type: "line" },
778
+ { color: "orange", label: "Route", type: "line" },
779
+ { color: "teal", label: "Default", type: "line" }
780
+ ];
781
+ function UnifiedWorkflowGraph({
782
+ resourceDefinition,
783
+ executionLogs,
784
+ selectedStepId,
785
+ onStepSelect,
786
+ fitViewTrigger: externalFitViewTrigger
787
+ }) {
788
+ const hasExecutionData = executionLogs && executionLogs.length > 0;
789
+ const [mode, setMode] = useState(hasExecutionData ? "execution" : "definition");
790
+ useEffect(() => {
791
+ setMode(hasExecutionData ? "execution" : "definition");
792
+ }, [hasExecutionData]);
793
+ const isDefinitionMode = mode === "definition";
794
+ const executionPath = useExecutionPath(
795
+ isDefinitionMode ? void 0 : executionLogs,
796
+ isDefinitionMode ? void 0 : resourceDefinition
797
+ );
798
+ const workflowInput = useMemo(
799
+ () => resourceDefinition ? { entryPoint: resourceDefinition.entryPoint, steps: resourceDefinition.steps } : void 0,
800
+ [resourceDefinition]
801
+ );
802
+ const {
803
+ nodes: layoutNodes,
804
+ edges: layoutEdges,
805
+ graphHeight
806
+ } = useUnifiedWorkflowLayout(workflowInput, executionPath, isDefinitionMode ? null : selectedStepId, mode);
807
+ const {
808
+ nodes: highlightedNodes,
809
+ edges: highlightedEdges,
810
+ handleNodeMouseEnter,
811
+ handleNodeMouseLeave
812
+ } = useDirectedChainHighlighting(layoutNodes, layoutEdges);
813
+ const nodes = isDefinitionMode ? highlightedNodes : layoutNodes;
814
+ const edges = isDefinitionMode ? highlightedEdges : layoutEdges;
815
+ const [internalFitViewTrigger, setInternalFitViewTrigger] = useState(0);
816
+ const executedStepsCount = executionPath?.executedSteps.size ?? 0;
817
+ const nodesCount = nodes.length;
818
+ useEffect(() => {
819
+ if (nodesCount > 0) {
820
+ setInternalFitViewTrigger((prev) => prev + 1);
821
+ }
822
+ }, [nodesCount, executedStepsCount]);
823
+ const fitViewTrigger = (externalFitViewTrigger ?? 0) + internalFitViewTrigger;
824
+ const { handleNodeClick, handlePaneClick, handleContainerClick } = useNodeSelection(
825
+ selectedStepId || null,
826
+ onStepSelect || (() => {
827
+ })
828
+ );
829
+ if (!resourceDefinition || !resourceDefinition.steps.length) {
830
+ return /* @__PURE__ */ jsx(EmptyVisualizer, {});
831
+ }
832
+ return /* @__PURE__ */ jsx(
833
+ VisualizerContainer,
834
+ {
835
+ handleContainerClick: isDefinitionMode ? void 0 : handleContainerClick,
836
+ height: graphHeight,
837
+ children: /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsxs(
838
+ ReactFlow,
839
+ {
840
+ nodes,
841
+ edges,
842
+ nodeTypes,
843
+ edgeTypes,
844
+ onNodeClick: isDefinitionMode ? void 0 : handleNodeClick,
845
+ onPaneClick: isDefinitionMode ? void 0 : handlePaneClick,
846
+ onNodeMouseEnter: isDefinitionMode ? handleNodeMouseEnter : void 0,
847
+ onNodeMouseLeave: isDefinitionMode ? handleNodeMouseLeave : void 0,
848
+ fitView: true,
849
+ fitViewOptions: {
850
+ padding: WORKFLOW_CONSTANTS.FIT_VIEW_PADDING
851
+ },
852
+ proOptions: { hideAttribution: true },
853
+ minZoom: WORKFLOW_CONSTANTS.MIN_ZOOM,
854
+ maxZoom: WORKFLOW_CONSTANTS.MAX_ZOOM,
855
+ defaultViewport: { x: 0, y: 0, zoom: 1 },
856
+ nodesDraggable: false,
857
+ nodesConnectable: false,
858
+ elementsSelectable: !isDefinitionMode,
859
+ selectNodesOnDrag: false,
860
+ zoomOnScroll: true,
861
+ panOnDrag: true,
862
+ children: [
863
+ /* @__PURE__ */ jsx(GraphBackground, {}),
864
+ /* @__PURE__ */ jsx(Panel, { position: "top-right", style: { marginTop: 12, marginRight: 12 }, children: /* @__PURE__ */ jsx(
865
+ SegmentedControl,
866
+ {
867
+ size: "xs",
868
+ value: mode,
869
+ onChange: (value) => setMode(value),
870
+ data: [
871
+ { label: "Definition", value: "definition" },
872
+ { label: "Execution", value: "execution" }
873
+ ],
874
+ styles: {
875
+ root: {
876
+ backgroundColor: "var(--color-surface)",
877
+ border: "1px solid var(--color-border)"
878
+ }
879
+ }
880
+ }
881
+ ) }),
882
+ /* @__PURE__ */ jsx(GraphLegend, { title: "Legend", items: NODE_LEGEND_ITEMS, position: "bottom-right" }),
883
+ /* @__PURE__ */ jsx(GraphLegend, { title: "Flow", items: EDGE_LEGEND_ITEMS, position: "bottom-left" }),
884
+ /* @__PURE__ */ jsx(GraphFitViewButton, { padding: WORKFLOW_CONSTANTS.FIT_VIEW_PADDING, variant: "mantine" }),
885
+ /* @__PURE__ */ jsx(GraphFitViewHandler, { trigger: fitViewTrigger, padding: WORKFLOW_CONSTANTS.FIT_VIEW_PADDING })
886
+ ]
887
+ }
888
+ ) })
889
+ }
890
+ );
891
+ }
892
+ function WorkflowExecutionTimeline({ timelineData, selectedStepId }) {
893
+ const { steps } = timelineData;
894
+ const executionStart = steps[0]?.startTime || 0;
895
+ const executionEnd = steps[steps.length - 1]?.endTime || executionStart;
896
+ return /* @__PURE__ */ jsx(TimelineContainer, { executionStart, executionEnd, children: steps.map(
897
+ (step) => step.startTime && step.endTime && /* @__PURE__ */ jsx(
898
+ TimelineRow,
899
+ {
900
+ label: step.stepName,
901
+ bars: [
902
+ {
903
+ startTime: step.startTime,
904
+ endTime: step.endTime,
905
+ status: step.status,
906
+ nodeId: step.stepId
907
+ }
908
+ ],
909
+ executionStart,
910
+ executionEnd,
911
+ selectedNodeId: selectedStepId
912
+ },
913
+ step.stepId
914
+ )
915
+ ) });
916
+ }
917
+ var statusColorMap = {
918
+ running: "blue",
919
+ completed: "teal",
920
+ failed: "orange",
921
+ pending: "violet",
922
+ warning: "yellow"
923
+ };
924
+ var AgentIterationNode = memo(function AgentIterationNode2({ data, selected }) {
925
+ const {
926
+ nodeType,
927
+ label,
928
+ iterationNumber,
929
+ status,
930
+ reasoningCount,
931
+ actionCount,
932
+ toolCallCount,
933
+ failedToolCallCount,
934
+ duration,
935
+ isLive
936
+ } = data;
937
+ const colors = getStatusColors(status);
938
+ const nodeColor = statusColorMap[status];
939
+ const hasToolCalls = nodeType === "iteration" && toolCallCount !== void 0 && toolCallCount > 0;
940
+ const hasFailedToolCalls = failedToolCallCount !== void 0 && failedToolCallCount > 0;
941
+ return /* @__PURE__ */ jsxs(BaseNode, { color: nodeColor, selected, width: AGENT_CONSTANTS.NODE_WIDTH, children: [
942
+ /* @__PURE__ */ jsxs(Box, { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
943
+ /* @__PURE__ */ jsx(
944
+ Box,
945
+ {
946
+ style: {
947
+ width: AGENT_CONSTANTS.CIRCLE_SIZE,
948
+ height: AGENT_CONSTANTS.CIRCLE_SIZE,
949
+ borderRadius: "50%",
950
+ border: `2px solid ${colors.color}`,
951
+ display: "flex",
952
+ alignItems: "center",
953
+ justifyContent: "center"
954
+ },
955
+ children: getStatusIcon({
956
+ status,
957
+ colors: { icon: colors.color },
958
+ iconSize: AGENT_CONSTANTS.STATUS_ICON_SIZE,
959
+ spinDuration: "1s"
960
+ })
961
+ }
962
+ ),
963
+ /* @__PURE__ */ jsx(
964
+ Text,
965
+ {
966
+ size: "sm",
967
+ fw: status === "running" ? 500 : 400,
968
+ ta: "center",
969
+ mt: 4,
970
+ style: { maxWidth: 150, fontFamily: "var(--mantine-font-family-headings)" },
971
+ children: nodeType === "iteration" ? `Iteration ${iterationNumber}` : label
972
+ }
973
+ ),
974
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: colors.badge, mt: 4, children: status.toUpperCase() }),
975
+ /* @__PURE__ */ jsxs(Stack, { gap: 2, mt: 2, align: "center", children: [
976
+ nodeType === "iteration" && reasoningCount !== void 0 && reasoningCount > 0 && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
977
+ reasoningCount,
978
+ " reasoning"
979
+ ] }),
980
+ nodeType === "iteration" && actionCount !== void 0 && actionCount > 0 && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
981
+ actionCount,
982
+ " ",
983
+ actionCount === 1 ? "action" : "actions"
984
+ ] }),
985
+ hasToolCalls && /* @__PURE__ */ jsxs(Group, { gap: 4, align: "center", wrap: "nowrap", children: [
986
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", style: { whiteSpace: "nowrap" }, children: [
987
+ toolCallCount,
988
+ " ",
989
+ toolCallCount === 1 ? "tool" : "tools"
990
+ ] }),
991
+ hasFailedToolCalls && /* @__PURE__ */ jsxs(Badge, { size: "xs", variant: "light", color: "red", px: 4, children: [
992
+ failedToolCallCount,
993
+ " failed"
994
+ ] })
995
+ ] }),
996
+ duration !== void 0 && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatDuration(duration) })
997
+ ] })
998
+ ] }),
999
+ isLive && /* @__PURE__ */ jsx(
1000
+ Badge,
1001
+ {
1002
+ size: "xs",
1003
+ variant: "filled",
1004
+ style: {
1005
+ position: "absolute",
1006
+ top: 4,
1007
+ right: 4
1008
+ },
1009
+ children: /* @__PURE__ */ jsx("span", { className: Graph_module_css_default.livePulse, children: "LIVE" })
1010
+ }
1011
+ )
1012
+ ] });
1013
+ });
1014
+ var statusEdgeColors = {
1015
+ running: {
1016
+ color: "var(--mantine-color-blue-5)",
1017
+ glow: "rgba(59, 130, 246, 0.5)"
1018
+ },
1019
+ completed: {
1020
+ color: "var(--mantine-color-teal-5)",
1021
+ glow: "rgba(20, 184, 166, 0.5)"
1022
+ },
1023
+ failed: {
1024
+ color: "var(--mantine-color-orange-5)",
1025
+ glow: "rgba(249, 115, 22, 0.5)"
1026
+ },
1027
+ pending: {
1028
+ color: "var(--mantine-color-gray-5)",
1029
+ glow: "rgba(156, 163, 175, 0.3)"
1030
+ },
1031
+ warning: {
1032
+ color: "var(--mantine-color-yellow-5)",
1033
+ glow: "rgba(234, 179, 8, 0.5)"
1034
+ }
1035
+ };
1036
+ var AgentIterationEdge = memo(function AgentIterationEdge2({
1037
+ id,
1038
+ sourceX,
1039
+ sourceY,
1040
+ targetX,
1041
+ targetY,
1042
+ data,
1043
+ selected
1044
+ }) {
1045
+ const edgeData = data;
1046
+ const sourceStatus = edgeData?.sourceStatus || "pending";
1047
+ const targetStatus = edgeData?.targetStatus || "pending";
1048
+ const edgeColors = statusEdgeColors[sourceStatus];
1049
+ const isAnimated = shouldAnimateEdge(sourceStatus, targetStatus);
1050
+ return /* @__PURE__ */ jsx(
1051
+ BaseEdge,
1052
+ {
1053
+ id,
1054
+ sourceX,
1055
+ sourceY,
1056
+ targetX,
1057
+ targetY,
1058
+ sourcePosition: Position.Right,
1059
+ targetPosition: Position.Left,
1060
+ color: edgeColors.color,
1061
+ glowColor: edgeColors.glow,
1062
+ animated: isAnimated,
1063
+ selected
1064
+ }
1065
+ );
1066
+ });
1067
+ var nodeTypes2 = {
1068
+ agentIteration: AgentIterationNode
1069
+ };
1070
+ var edgeTypes2 = {
1071
+ agentIteration: AgentIterationEdge
1072
+ };
1073
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "warning"]);
1074
+ function hasAgentLifecycleLogs(execution) {
1075
+ return Boolean(
1076
+ execution?.executionLogs?.some((log) => {
1077
+ const context = log.context;
1078
+ return context?.type === "agent" && "lifecycle" in context;
1079
+ })
1080
+ );
1081
+ }
1082
+ function getUnavailableTraceMessage(execution, selectedExecutionId) {
1083
+ if (!selectedExecutionId) {
1084
+ return null;
1085
+ }
1086
+ if (execution?.isArchived) {
1087
+ return "Detailed trace unavailable for archived execution. Raw logs can be loaded below, but graph and detail rendering do not hydrate archived logs yet.";
1088
+ }
1089
+ if (execution && execution.executionLogs.length === 0 && TERMINAL_STATUSES.has(execution.status)) {
1090
+ return "Detailed trace unavailable. This terminal execution has no lifecycle logs available for graph rendering.";
1091
+ }
1092
+ if (execution && TERMINAL_STATUSES.has(execution.status) && !hasAgentLifecycleLogs(execution)) {
1093
+ return "Detailed trace unavailable. This run has no agent lifecycle context, so raw logs are shown below instead.";
1094
+ }
1095
+ return null;
1096
+ }
1097
+ function AgentExecutionVisualizer({
1098
+ resourceDefinition,
1099
+ iterationData,
1100
+ execution,
1101
+ selectedExecutionId,
1102
+ liveExecutions,
1103
+ selectedIterationId,
1104
+ onIterationSelect
1105
+ }) {
1106
+ const { nodes, edges } = useReactFlowAgent(
1107
+ iterationData,
1108
+ resourceDefinition,
1109
+ selectedIterationId,
1110
+ liveExecutions,
1111
+ selectedExecutionId
1112
+ );
1113
+ const fitViewTrigger = useFitViewTrigger(iterationData, nodes);
1114
+ const handleIterationSelect = useCallback(
1115
+ (id) => {
1116
+ onIterationSelect(id);
1117
+ },
1118
+ [onIterationSelect]
1119
+ );
1120
+ const { handlePaneClick, handleContainerClick } = useNodeSelection(selectedIterationId, handleIterationSelect);
1121
+ const handleNodeClick = useCallback(
1122
+ (_event, node) => {
1123
+ if (node.id === "initialization" || node.id === "completion") {
1124
+ handleIterationSelect(selectedIterationId === node.id ? null : node.id);
1125
+ return;
1126
+ }
1127
+ const iterationNumber = Number.parseInt(node.id.replace("iteration-", ""), 10);
1128
+ if (!Number.isNaN(iterationNumber)) {
1129
+ handleIterationSelect(iterationNumber === selectedIterationId ? null : iterationNumber);
1130
+ }
1131
+ },
1132
+ [selectedIterationId, handleIterationSelect]
1133
+ );
1134
+ const unavailableTraceMessage = getUnavailableTraceMessage(execution, selectedExecutionId);
1135
+ if (unavailableTraceMessage) {
1136
+ return /* @__PURE__ */ jsx(EmptyVisualizer, { message: unavailableTraceMessage });
1137
+ }
1138
+ if (!iterationData || nodes.length === 0) {
1139
+ return /* @__PURE__ */ jsx(EmptyVisualizer, {});
1140
+ }
1141
+ return /* @__PURE__ */ jsx(VisualizerContainer, { handleContainerClick, children: /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsxs(
1142
+ ReactFlow,
1143
+ {
1144
+ nodes,
1145
+ edges,
1146
+ nodeTypes: nodeTypes2,
1147
+ edgeTypes: edgeTypes2,
1148
+ onNodeClick: handleNodeClick,
1149
+ onPaneClick: handlePaneClick,
1150
+ fitView: true,
1151
+ fitViewOptions: {
1152
+ padding: AGENT_CONSTANTS.FIT_VIEW_PADDING
1153
+ },
1154
+ proOptions: { hideAttribution: true },
1155
+ minZoom: AGENT_CONSTANTS.MIN_ZOOM,
1156
+ maxZoom: AGENT_CONSTANTS.MAX_ZOOM,
1157
+ nodesDraggable: false,
1158
+ nodesConnectable: false,
1159
+ elementsSelectable: true,
1160
+ selectNodesOnDrag: false,
1161
+ zoomOnScroll: false,
1162
+ panOnDrag: false,
1163
+ children: [
1164
+ /* @__PURE__ */ jsx(GraphBackground, {}),
1165
+ /* @__PURE__ */ jsx(GraphFitViewButton, { padding: AGENT_CONSTANTS.FIT_VIEW_PADDING, variant: "mantine", duration: 300 }),
1166
+ /* @__PURE__ */ jsx(GraphFitViewHandler, { trigger: fitViewTrigger, padding: AGENT_CONSTANTS.FIT_VIEW_PADDING })
1167
+ ]
1168
+ }
1169
+ ) }) });
1170
+ }
1171
+ function getSubActivityLabel(activity) {
1172
+ if (activity.type === "tool-call") {
1173
+ return "toolName" in activity.details && activity.details.toolName ? activity.details.toolName : activity.type;
1174
+ }
1175
+ if (activity.type === "action") {
1176
+ return "actionType" in activity.details && activity.details.actionType ? activity.details.actionType : activity.type;
1177
+ }
1178
+ return activity.type;
1179
+ }
1180
+ function getSubActivityStatus(activity) {
1181
+ if (activity.type === "tool-call" && "success" in activity.details) {
1182
+ return activity.details.success ? "completed" : "failed";
1183
+ }
1184
+ return "completed";
1185
+ }
1186
+ function AgentExecutionTimeline({ iterationData, selectedIterationId }) {
1187
+ const { initialization, iterations, completion } = iterationData;
1188
+ const executionStart = initialization.startTime;
1189
+ const executionEnd = completion.endTime;
1190
+ return /* @__PURE__ */ jsxs(TimelineContainer, { executionStart, executionEnd, children: [
1191
+ initialization.startTime && initialization.endTime && /* @__PURE__ */ jsx(
1192
+ TimelineRow,
1193
+ {
1194
+ label: `Initialization (${formatDuration(initialization.duration || 0)})`,
1195
+ bars: [
1196
+ {
1197
+ startTime: initialization.startTime,
1198
+ endTime: initialization.endTime,
1199
+ status: initialization.status,
1200
+ nodeId: "initialization"
1201
+ }
1202
+ ],
1203
+ executionStart,
1204
+ executionEnd,
1205
+ selectedNodeId: selectedIterationId
1206
+ }
1207
+ ),
1208
+ iterations.map((iteration) => /* @__PURE__ */ jsxs(Fragment, { children: [
1209
+ iteration.startTime && iteration.endTime && /* @__PURE__ */ jsx(
1210
+ TimelineRow,
1211
+ {
1212
+ label: `Iteration ${iteration.iterationNumber} (${formatDuration(iteration.duration || 0)})`,
1213
+ bars: [
1214
+ {
1215
+ startTime: iteration.startTime,
1216
+ endTime: iteration.endTime,
1217
+ status: iteration.status,
1218
+ nodeId: iteration.iterationNumber
1219
+ }
1220
+ ],
1221
+ executionStart,
1222
+ executionEnd,
1223
+ selectedNodeId: selectedIterationId
1224
+ }
1225
+ ),
1226
+ iteration.subActivities.map((activity, activityIndex) => {
1227
+ const activityLabel = getSubActivityLabel(activity);
1228
+ const activityStatus = getSubActivityStatus(activity);
1229
+ return /* @__PURE__ */ jsx(
1230
+ TimelineRow,
1231
+ {
1232
+ label: `${activityLabel} (${formatDuration(activity.duration)})`,
1233
+ bars: [
1234
+ {
1235
+ startTime: activity.startTime,
1236
+ endTime: activity.endTime,
1237
+ status: activityStatus,
1238
+ nodeId: iteration.iterationNumber
1239
+ }
1240
+ ],
1241
+ executionStart,
1242
+ executionEnd,
1243
+ indent: 1,
1244
+ selectedNodeId: selectedIterationId
1245
+ },
1246
+ `${iteration.iterationNumber}-${activity.type}-${activity.startTime}-${activityIndex}`
1247
+ );
1248
+ })
1249
+ ] }, iteration.iterationNumber)),
1250
+ completion.startTime && completion.endTime && /* @__PURE__ */ jsx(
1251
+ TimelineRow,
1252
+ {
1253
+ label: `Completion (${formatDuration(completion.duration || 0)})`,
1254
+ bars: [
1255
+ {
1256
+ startTime: completion.startTime,
1257
+ endTime: completion.endTime,
1258
+ status: completion.status,
1259
+ nodeId: "completion"
1260
+ }
1261
+ ],
1262
+ executionStart,
1263
+ executionEnd,
1264
+ selectedNodeId: selectedIterationId
1265
+ }
1266
+ )
1267
+ ] });
1268
+ }
1269
+ function CollapsibleJsonSection({ title, data, defaultExpanded = false }) {
1270
+ const [isExpanded, setIsExpanded] = useState(defaultExpanded);
1271
+ const [isHovered, setIsHovered] = useState(false);
1272
+ return /* @__PURE__ */ jsxs(
1273
+ "div",
1274
+ {
1275
+ style: {
1276
+ borderRadius: "var(--mantine-radius-default)",
1277
+ backgroundColor: isHovered ? "var(--color-surface-hover, rgba(0,0,0,0.02))" : "transparent",
1278
+ transition: "background-color var(--duration-fast) var(--easing)"
1279
+ },
1280
+ children: [
1281
+ /* @__PURE__ */ jsxs(
1282
+ Group,
1283
+ {
1284
+ gap: 4,
1285
+ onClick: () => setIsExpanded(!isExpanded),
1286
+ onMouseEnter: () => setIsHovered(true),
1287
+ onMouseLeave: () => setIsHovered(false),
1288
+ style: {
1289
+ cursor: "pointer",
1290
+ padding: "0.375rem 0.5rem",
1291
+ userSelect: "none"
1292
+ },
1293
+ wrap: "nowrap",
1294
+ children: [
1295
+ /* @__PURE__ */ jsx(
1296
+ ActionIcon,
1297
+ {
1298
+ variant: "transparent",
1299
+ size: "xs",
1300
+ style: {
1301
+ transition: "transform var(--duration-fast) var(--easing)",
1302
+ transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
1303
+ },
1304
+ children: /* @__PURE__ */ jsx(IconChevronRight, { size: 14 })
1305
+ }
1306
+ ),
1307
+ title
1308
+ ]
1309
+ }
1310
+ ),
1311
+ /* @__PURE__ */ jsx(Collapse, { in: isExpanded, children: /* @__PURE__ */ jsx(JsonViewer, { data }) })
1312
+ ]
1313
+ }
1314
+ );
1315
+ }
1316
+ function CollapsibleTextSection({ title, text }) {
1317
+ return /* @__PURE__ */ jsx(
1318
+ CollapsibleJsonSection,
1319
+ {
1320
+ title: /* @__PURE__ */ jsx(Text, { size: "xs", fw: 500, children: title }),
1321
+ data: text
1322
+ }
1323
+ );
1324
+ }
1325
+ function ActivityIcon({ activity }) {
1326
+ if (activity.type === "tool-call") {
1327
+ return /* @__PURE__ */ jsx(IconTool, { size: 16 });
1328
+ }
1329
+ if (activity.type === "action") {
1330
+ return /* @__PURE__ */ jsx(IconWand, { size: 16 });
1331
+ }
1332
+ return /* @__PURE__ */ jsx(IconBrain, { size: 16 });
1333
+ }
1334
+ function getActivityTitle(activity) {
1335
+ if (activity.type === "tool-call") {
1336
+ return "toolName" in activity.details && activity.details.toolName ? activity.details.toolName : "Tool call";
1337
+ }
1338
+ if (activity.type === "action") {
1339
+ return "actionType" in activity.details && activity.details.actionType ? activity.details.actionType : "Action";
1340
+ }
1341
+ return "Reasoning";
1342
+ }
1343
+ function ActivityBadge({ activity }) {
1344
+ if (activity.type !== "tool-call" || !("success" in activity.details)) {
1345
+ return /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "gray", children: activity.type });
1346
+ }
1347
+ return activity.details.success ? /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "green", leftSection: /* @__PURE__ */ jsx(IconCheck, { size: 12 }), children: "Success" }) : /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "red", leftSection: /* @__PURE__ */ jsx(IconAlertCircle, { size: 12 }), children: "Error" });
1348
+ }
1349
+ function ActivityDetails({ activity }) {
1350
+ if (activity.type === "reasoning" && "output" in activity.details && typeof activity.details.output === "string" && activity.details.output) {
1351
+ return /* @__PURE__ */ jsx(CollapsibleTextSection, { title: "Reasoning", text: activity.details.output });
1352
+ }
1353
+ if (activity.type === "action" && "data" in activity.details && activity.details.data) {
1354
+ return /* @__PURE__ */ jsx(
1355
+ CollapsibleJsonSection,
1356
+ {
1357
+ title: /* @__PURE__ */ jsx(Text, { size: "xs", fw: 500, children: "Data" }),
1358
+ data: activity.details.data
1359
+ }
1360
+ );
1361
+ }
1362
+ if (activity.type !== "tool-call") {
1363
+ return null;
1364
+ }
1365
+ return /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
1366
+ "error" in activity.details && activity.details.error && /* @__PURE__ */ jsx(Text, { size: "xs", c: "var(--color-error)", children: activity.details.error }),
1367
+ "input" in activity.details && activity.details.input !== void 0 && /* @__PURE__ */ jsx(
1368
+ CollapsibleJsonSection,
1369
+ {
1370
+ title: /* @__PURE__ */ jsx(Text, { size: "xs", fw: 500, children: "Input" }),
1371
+ data: activity.details.input
1372
+ }
1373
+ ),
1374
+ "output" in activity.details && activity.details.output !== void 0 && /* @__PURE__ */ jsx(
1375
+ CollapsibleJsonSection,
1376
+ {
1377
+ title: /* @__PURE__ */ jsx(Text, { size: "xs", fw: 500, children: "Output" }),
1378
+ data: activity.details.output
1379
+ }
1380
+ )
1381
+ ] });
1382
+ }
1383
+ function ActivityRow({ activity }) {
1384
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "xs", bg: "none", children: /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
1385
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", wrap: "nowrap", children: [
1386
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 0 }, children: [
1387
+ /* @__PURE__ */ jsx(ActivityIcon, { activity }),
1388
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, truncate: true, children: getActivityTitle(activity) })
1389
+ ] }),
1390
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", children: [
1391
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatDuration(activity.duration) }),
1392
+ /* @__PURE__ */ jsx(ActivityBadge, { activity })
1393
+ ] })
1394
+ ] }),
1395
+ /* @__PURE__ */ jsx(ActivityDetails, { activity })
1396
+ ] }) });
1397
+ }
1398
+ function AgentIterationDetailPanel({ iteration, totals }) {
1399
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, bg: "none", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
1400
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", gap: "sm", children: [
1401
+ /* @__PURE__ */ jsxs("div", { children: [
1402
+ /* @__PURE__ */ jsx(Text, { fw: 600, children: iteration ? `Iteration ${iteration.iterationNumber} activity` : "Iteration activity" }),
1403
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: iteration ? `${iteration.subActivities.length} ordered sub-activities` : "Select an iteration to inspect activity" })
1404
+ ] }),
1405
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1406
+ /* @__PURE__ */ jsxs(Badge, { variant: "light", color: "blue", children: [
1407
+ totals.totalToolCalls,
1408
+ " tools"
1409
+ ] }),
1410
+ /* @__PURE__ */ jsxs(Badge, { variant: "light", color: totals.toolErrorCount > 0 ? "red" : "green", children: [
1411
+ totals.toolErrorCount,
1412
+ " errors"
1413
+ ] }),
1414
+ totals.totalDuration !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "light", color: "gray", children: formatDuration(totals.totalDuration) })
1415
+ ] })
1416
+ ] }),
1417
+ iteration ? iteration.subActivities.length > 0 ? /* @__PURE__ */ jsx(Stack, { gap: "xs", children: iteration.subActivities.map((activity, index) => /* @__PURE__ */ jsx(
1418
+ ActivityRow,
1419
+ {
1420
+ activity
1421
+ },
1422
+ `${activity.type}-${activity.startTime}-${activity.endTime}-${index}`
1423
+ )) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No reasoning, actions, or tool calls were captured for this iteration." }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Select an iteration node to view reasoning, actions, and tool calls." })
1424
+ ] }) });
1425
+ }
1426
+ var isZodSchema = (value) => value instanceof z.ZodType;
1427
+ function RunResourceButton({
1428
+ resourceId,
1429
+ resourceType,
1430
+ getInput,
1431
+ label,
1432
+ icon,
1433
+ color,
1434
+ onSuccess,
1435
+ onError
1436
+ }) {
1437
+ const [modalState, setModalState] = useState(null);
1438
+ const { execute, isPending } = useExecuteResource({ resourceId, resourceType });
1439
+ const resolvedLabel = label ?? "Run";
1440
+ const resolvedColor = color ?? void 0;
1441
+ const handleExecute = useCallback(
1442
+ async (input) => {
1443
+ try {
1444
+ const result = await execute(input);
1445
+ setModalState(null);
1446
+ notifications.show({
1447
+ title: "Execution started",
1448
+ message: `Execution ${result.executionId} started`,
1449
+ color: "green"
1450
+ });
1451
+ onSuccess?.(result);
1452
+ } catch (err) {
1453
+ const error = err instanceof Error ? err : new Error(String(err));
1454
+ notifications.show({
1455
+ title: "Execution failed",
1456
+ message: error.message,
1457
+ color: "red"
1458
+ });
1459
+ onError?.(error);
1460
+ }
1461
+ },
1462
+ [execute, onSuccess, onError]
1463
+ );
1464
+ const handleClick = useCallback(() => {
1465
+ const result = getInput();
1466
+ const maybeSchema = result.schema;
1467
+ if (isZodSchema(maybeSchema)) {
1468
+ const defaults = result.defaults;
1469
+ setModalState({ schema: maybeSchema, defaults });
1470
+ } else {
1471
+ void handleExecute(result);
1472
+ }
1473
+ }, [getInput, handleExecute]);
1474
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1475
+ /* @__PURE__ */ jsx(Button, { leftSection: icon, color: resolvedColor, loading: isPending, onClick: handleClick, children: resolvedLabel }),
1476
+ /* @__PURE__ */ jsx(Modal, { opened: modalState !== null, onClose: () => setModalState(null), children: modalState !== null && /* @__PURE__ */ jsx(
1477
+ ZodFormRenderer,
1478
+ {
1479
+ schema: modalState.schema,
1480
+ defaults: modalState.defaults,
1481
+ isPending,
1482
+ submitLabel: resolvedLabel,
1483
+ onSubmit: (data) => handleExecute(data)
1484
+ }
1485
+ ) })
1486
+ ] });
1487
+ }
1488
+ var DEFAULT_LIMIT = 6;
1489
+ var typeIcons = {
1490
+ workflow: IconGitBranch,
1491
+ agent: IconBrain
1492
+ };
1493
+ function ResourceCard({ resource, onClick }) {
1494
+ const [hovered, setHovered] = useState(false);
1495
+ const Icon = typeIcons[resource.type] ?? IconActivity;
1496
+ const cyberColors = useCyberColors();
1497
+ return /* @__PURE__ */ jsxs(
1498
+ Card,
1499
+ {
1500
+ withBorder: true,
1501
+ style: {
1502
+ cursor: "pointer",
1503
+ transition: "all 150ms ease",
1504
+ borderColor: hovered ? "var(--border-primary-strong)" : "var(--color-border)",
1505
+ boxShadow: hovered ? "var(--card-shadow), 0 0 12px color-mix(in srgb, var(--color-primary) 25%, transparent)" : "var(--card-shadow)",
1506
+ transform: hovered ? "translateY(-1px)" : "none"
1507
+ },
1508
+ onMouseEnter: () => setHovered(true),
1509
+ onMouseLeave: () => setHovered(false),
1510
+ onClick,
1511
+ children: [
1512
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: "sm", wrap: "nowrap", align: "flex-start", children: [
1513
+ /* @__PURE__ */ jsxs(Group, { gap: "sm", wrap: "nowrap", style: { minWidth: 0 }, children: [
1514
+ /* @__PURE__ */ jsx(ThemeIcon, { size: 32, radius: "md", variant: "light", children: /* @__PURE__ */ jsx(Icon, { size: 18 }) }),
1515
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, truncate: true, children: resource.name })
1516
+ ] }),
1517
+ resource.active && resource.execution ? (() => {
1518
+ const rate = resource.execution.successRate;
1519
+ const color = rate >= 95 ? cyberColors.green : rate >= 80 ? cyberColors.yellow : cyberColors.red;
1520
+ return /* @__PURE__ */ jsxs(Group, { gap: 8, wrap: "nowrap", style: { flexShrink: 0 }, children: [
1521
+ /* @__PURE__ */ jsxs(Text, { size: "xs", fw: 500, style: { color, letterSpacing: "0.03em" }, children: [
1522
+ rate.toFixed(0),
1523
+ "%"
1524
+ ] }),
1525
+ /* @__PURE__ */ jsx(GlowDot, { size: "md", color })
1526
+ ] });
1527
+ })() : null
1528
+ ] }),
1529
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1530
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1531
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: resource.type }),
1532
+ /* @__PURE__ */ jsx(
1533
+ Badge,
1534
+ {
1535
+ size: "xs",
1536
+ variant: "light",
1537
+ color: ResourceStatusColors[resource.status],
1538
+ children: resource.status
1539
+ }
1540
+ )
1541
+ ] }),
1542
+ resource.active && resource.execution ? /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
1543
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
1544
+ resource.execution.totalExecutions,
1545
+ " runs"
1546
+ ] }),
1547
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "\xB7" }),
1548
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
1549
+ "Last run ",
1550
+ formatTimeAgo(resource.execution.lastExecution)
1551
+ ] })
1552
+ ] }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No recent activity" })
1553
+ ] })
1554
+ ]
1555
+ }
1556
+ );
1557
+ }
1558
+ function ResourceOverview({
1559
+ recentExecutions,
1560
+ allResources,
1561
+ isLoading,
1562
+ limit = DEFAULT_LIMIT,
1563
+ onResourceClick
1564
+ }) {
1565
+ const { displayResources, totalCount } = useMemo(() => {
1566
+ const items = [];
1567
+ const seenIds = /* @__PURE__ */ new Set();
1568
+ const resourceLookup = /* @__PURE__ */ new Map();
1569
+ if (allResources) {
1570
+ for (const r of [...allResources.workflows, ...allResources.agents]) {
1571
+ resourceLookup.set(r.resourceId, r);
1572
+ }
1573
+ }
1574
+ if (recentExecutions) {
1575
+ for (const exec of recentExecutions) {
1576
+ const def = resourceLookup.get(exec.resourceId);
1577
+ items.push({
1578
+ resourceId: exec.resourceId,
1579
+ name: def?.name ?? exec.resourceName ?? exec.resourceId,
1580
+ type: def?.type ?? exec.resourceType ?? "",
1581
+ status: def?.status ?? "dev",
1582
+ active: true,
1583
+ execution: exec
1584
+ });
1585
+ seenIds.add(exec.resourceId);
1586
+ }
1587
+ }
1588
+ if (allResources) {
1589
+ for (const r of [...allResources.workflows, ...allResources.agents]) {
1590
+ if (!seenIds.has(r.resourceId)) {
1591
+ items.push({
1592
+ resourceId: r.resourceId,
1593
+ name: r.name,
1594
+ type: r.type,
1595
+ status: r.status,
1596
+ active: false
1597
+ });
1598
+ seenIds.add(r.resourceId);
1599
+ }
1600
+ }
1601
+ }
1602
+ return { displayResources: items.slice(0, limit), totalCount: items.length };
1603
+ }, [recentExecutions, allResources, limit]);
1604
+ const handleClick = (resource) => {
1605
+ onResourceClick?.(resource);
1606
+ };
1607
+ return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
1608
+ /* @__PURE__ */ jsx(
1609
+ CardHeader,
1610
+ {
1611
+ icon: /* @__PURE__ */ jsx(IconLayoutDashboard, { size: 18 }),
1612
+ title: "Resources",
1613
+ subtitle: totalCount > limit ? `Showing ${limit} of ${totalCount}` : void 0,
1614
+ rightSection: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1615
+ totalCount > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "light", size: "sm", children: [
1616
+ totalCount,
1617
+ " total"
1618
+ ] }),
1619
+ /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: () => onResourceClick?.(displayResources[0]), children: /* @__PURE__ */ jsx(IconArrowUpRight, { size: 16 }) })
1620
+ ] })
1621
+ }
1622
+ ),
1623
+ isLoading ? /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) : displayResources.length === 0 ? /* @__PURE__ */ jsx(EmptyState, { icon: IconLayoutDashboard, title: "No resources registered" }) : /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2, lg: 3 }, children: displayResources.map((resource) => /* @__PURE__ */ jsx(ResourceCard, { resource, onClick: () => handleClick(resource) }, resource.resourceId)) })
1624
+ ] });
1625
+ }
1626
+ var severityColor = {
1627
+ critical: "red",
1628
+ warning: "yellow",
1629
+ info: "blue"
1630
+ };
1631
+ function OperationsOverview({
1632
+ timeRange,
1633
+ onResourceClick,
1634
+ onErrorsNavigate,
1635
+ onCommandQueueNavigate,
1636
+ onScheduledTasksNavigate,
1637
+ renderTrendChart,
1638
+ renderOperationalOverview
1639
+ }) {
1640
+ const { organizationReady, error: initError } = useInitialization();
1641
+ const { data: dashboardDataRaw, isLoading, error } = useDashboardMetrics(timeRange);
1642
+ const dashboardData = dashboardDataRaw;
1643
+ const { data: resourcesData, isLoading: resourcesLoading } = useResources();
1644
+ const { startDate, endDate } = useTimeRangeDates(timeRange);
1645
+ const { data: errorData, isLoading: errorsLoading } = useUnresolvedErrors({ startDate, endDate });
1646
+ const { data: recentExecData, isLoading: recentExecLoading } = useRecentExecutionsByResource({
1647
+ timeRange,
1648
+ limit: 6
1649
+ });
1650
+ if (initError?.layer === "organization") {
1651
+ return /* @__PURE__ */ jsx(AppShellCenteredContainer, { children: /* @__PURE__ */ jsxs(Stack, { align: "center", justify: "center", children: [
1652
+ /* @__PURE__ */ jsx(Title, { order: 3, c: "dimmed", children: "No organization detected" }),
1653
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: initError?.message })
1654
+ ] }) });
1655
+ }
1656
+ if (!organizationReady || isLoading || resourcesLoading) return /* @__PURE__ */ jsx(AppShellLoader, {});
1657
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1658
+ /* @__PURE__ */ jsx(PageTitleCaption, { title: "Overview", caption: "AI Operations Health & Performance" }),
1659
+ /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
1660
+ /* @__PURE__ */ jsx(
1661
+ HeroStatsRow,
1662
+ {
1663
+ resourcesData,
1664
+ resourcesLoading,
1665
+ dashboardData,
1666
+ dashboardLoading: isLoading,
1667
+ unresolvedErrorCount: errorData?.total ?? null,
1668
+ errorsLoading
1669
+ }
1670
+ ),
1671
+ renderTrendChart?.(dashboardData?.executionHealth, isLoading, error ?? void 0)
1672
+ ] }),
1673
+ /* @__PURE__ */ jsx(
1674
+ ResourceOverview,
1675
+ {
1676
+ recentExecutions: recentExecData?.resources,
1677
+ allResources: resourcesData,
1678
+ isLoading: resourcesLoading || recentExecLoading,
1679
+ limit: 6,
1680
+ onResourceClick: onResourceClick ? (resource) => onResourceClick({
1681
+ resourceId: resource.resourceId,
1682
+ resourceType: resource.type
1683
+ }) : void 0
1684
+ }
1685
+ ),
1686
+ renderOperationalOverview ? renderOperationalOverview({
1687
+ timeRange,
1688
+ onErrorsNavigate,
1689
+ onCommandQueueNavigate,
1690
+ onScheduledTasksNavigate
1691
+ }) : /* @__PURE__ */ jsx(
1692
+ DashboardOperationsOverview,
1693
+ {
1694
+ timeRange,
1695
+ onErrorsNavigate,
1696
+ onCommandQueueNavigate,
1697
+ onScheduledTasksNavigate
1698
+ }
1699
+ )
1700
+ ] });
1701
+ }
1702
+ var Dashboard = OperationsOverview;
1703
+ function DashboardOperationsOverview({
1704
+ timeRange,
1705
+ onErrorsNavigate,
1706
+ onCommandQueueNavigate,
1707
+ onScheduledTasksNavigate
1708
+ }) {
1709
+ const { startDate, endDate } = useTimeRangeDates(timeRange);
1710
+ const { data: errorData, isLoading: errorsLoading } = useUnresolvedErrors({ startDate, endDate });
1711
+ const errors = errorData?.errors ?? [];
1712
+ const errorCount = errorData?.total ?? 0;
1713
+ const { data: allCommands } = useCommandQueue({ status: "pending", limit: 100 });
1714
+ const commands = allCommands?.tasks ?? [];
1715
+ const commandCount = commands.length;
1716
+ const { data: allTasks, isLoading: tasksLoading } = useScheduledTasks();
1717
+ const tasks = allTasks ?? [];
1718
+ const now = /* @__PURE__ */ new Date();
1719
+ const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
1720
+ const { totalScheduled, upcomingTasks } = useMemo(() => {
1721
+ const totalScheduled2 = tasks.filter((t) => t.status === "active").length;
1722
+ const upcomingTasks2 = tasks.filter((t) => t.status === "active" && t.nextRunAt).sort((a, b) => new Date(a.nextRunAt).getTime() - new Date(b.nextRunAt).getTime()).slice(0, 5);
1723
+ return { totalScheduled: totalScheduled2, upcomingTasks: upcomingTasks2 };
1724
+ }, [tasks]);
1725
+ const defaultTab = useMemo(() => {
1726
+ if (errorCount > 0) return "errors";
1727
+ if (commandCount > 0) return "commands";
1728
+ if (totalScheduled > 0) return "scheduled";
1729
+ return "errors";
1730
+ }, [errorCount, commandCount, totalScheduled]);
1731
+ const [activeTab, setActiveTab] = useState(null);
1732
+ const effectiveTab = activeTab ?? defaultTab;
1733
+ const formatDaysUntil = (runAt) => {
1734
+ const diffMs = runAt.getTime() - now.getTime();
1735
+ const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
1736
+ const diffHours = Math.floor(diffMs / (1e3 * 60 * 60));
1737
+ if (diffHours < 0) return "Overdue";
1738
+ if (diffHours < 1) return "Soon";
1739
+ if (diffDays === 0) return "Today";
1740
+ if (diffDays === 1) return "Tomorrow";
1741
+ if (diffDays <= 7) return `In ${diffDays}d`;
1742
+ return `In ${Math.floor(diffDays / 7)}w`;
1743
+ };
1744
+ return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
1745
+ /* @__PURE__ */ jsx(CardHeader, { icon: /* @__PURE__ */ jsx(IconActivity, { size: 18 }), title: "Operational Overview" }),
1746
+ /* @__PURE__ */ jsxs(Tabs, { value: effectiveTab, onChange: setActiveTab, variant: "default", children: [
1747
+ /* @__PURE__ */ jsxs(Tabs.List, { children: [
1748
+ /* @__PURE__ */ jsx(
1749
+ Tabs.Tab,
1750
+ {
1751
+ value: "errors",
1752
+ leftSection: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 16 }),
1753
+ rightSection: /* @__PURE__ */ jsx(TabCountBadge, { count: errorCount, isLoading: errorsLoading }),
1754
+ children: "Unresolved Errors"
1755
+ }
1756
+ ),
1757
+ /* @__PURE__ */ jsx(
1758
+ Tabs.Tab,
1759
+ {
1760
+ value: "commands",
1761
+ leftSection: /* @__PURE__ */ jsx(IconHandStop, { size: 16 }),
1762
+ rightSection: /* @__PURE__ */ jsx(TabCountBadge, { count: commandCount }),
1763
+ children: "Command Queue"
1764
+ }
1765
+ ),
1766
+ /* @__PURE__ */ jsx(
1767
+ Tabs.Tab,
1768
+ {
1769
+ value: "scheduled",
1770
+ leftSection: /* @__PURE__ */ jsx(IconCalendarEvent, { size: 16 }),
1771
+ rightSection: /* @__PURE__ */ jsx(TabCountBadge, { count: totalScheduled, isLoading: tasksLoading }),
1772
+ children: "Scheduled Tasks"
1773
+ }
1774
+ )
1775
+ ] }),
1776
+ /* @__PURE__ */ jsx(Tabs.Panel, { value: "errors", pt: "sm", children: errorsLoading ? /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) : errors.length === 0 ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No unresolved errors" }) : /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
1777
+ errors.map((error) => /* @__PURE__ */ jsx(
1778
+ Box,
1779
+ {
1780
+ px: "sm",
1781
+ py: 6,
1782
+ onClick: onErrorsNavigate,
1783
+ style: {
1784
+ borderRadius: 4,
1785
+ cursor: onErrorsNavigate ? "pointer" : "default"
1786
+ },
1787
+ children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1788
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 200, width: 200, flexShrink: 0 }, children: [
1789
+ /* @__PURE__ */ jsx(
1790
+ Box,
1791
+ {
1792
+ style: {
1793
+ width: 8,
1794
+ height: 8,
1795
+ borderRadius: "50%",
1796
+ backgroundColor: `var(--mantine-color-${severityColor[error.severity]}-6)`,
1797
+ flexShrink: 0
1798
+ }
1799
+ }
1800
+ ),
1801
+ /* @__PURE__ */ jsxs(Stack, { gap: 0, style: { minWidth: 0 }, children: [
1802
+ /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 1, children: error.resourceName || error.resourceId }),
1803
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 1, children: error.errorType })
1804
+ ] })
1805
+ ] }),
1806
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 1, style: { flex: "1 1 auto", minWidth: 0 }, children: error.message }),
1807
+ /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
1808
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: severityColor[error.severity], children: error.severity }),
1809
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatTimeAgo(error.timestamp) })
1810
+ ] })
1811
+ ] })
1812
+ },
1813
+ error.id
1814
+ )),
1815
+ errorCount > 5 && /* @__PURE__ */ jsx(
1816
+ Group,
1817
+ {
1818
+ gap: 4,
1819
+ justify: "center",
1820
+ pt: 4,
1821
+ onClick: onErrorsNavigate,
1822
+ style: { cursor: onErrorsNavigate ? "pointer" : "default" },
1823
+ children: /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "See all errors" })
1824
+ }
1825
+ )
1826
+ ] }) }),
1827
+ /* @__PURE__ */ jsx(Tabs.Panel, { value: "commands", pt: "sm", children: commands.length === 0 ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No pending decisions" }) : /* @__PURE__ */ jsx(Stack, { gap: 4, children: commands.slice(0, 5).map((task) => /* @__PURE__ */ jsx(
1828
+ Box,
1829
+ {
1830
+ px: "sm",
1831
+ py: 6,
1832
+ onClick: onCommandQueueNavigate,
1833
+ style: {
1834
+ borderRadius: 4,
1835
+ cursor: onCommandQueueNavigate ? "pointer" : "default"
1836
+ },
1837
+ children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1838
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 0 }, children: [
1839
+ /* @__PURE__ */ jsx(
1840
+ Box,
1841
+ {
1842
+ style: {
1843
+ width: 8,
1844
+ height: 8,
1845
+ borderRadius: "50%",
1846
+ backgroundColor: `var(--mantine-color-${task.priority >= 8 ? "red" : task.priority >= 4 ? "yellow" : "blue"}-6)`,
1847
+ flexShrink: 0
1848
+ }
1849
+ }
1850
+ ),
1851
+ /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 1, children: task.description || "No description" })
1852
+ ] }),
1853
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: task.status })
1854
+ ] })
1855
+ },
1856
+ task.id
1857
+ )) }) }),
1858
+ /* @__PURE__ */ jsx(Tabs.Panel, { value: "scheduled", pt: "sm", children: tasksLoading ? /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) : upcomingTasks.length === 0 ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No scheduled tasks" }) : /* @__PURE__ */ jsx(Stack, { gap: 4, children: upcomingTasks.map((task) => {
1859
+ const runAt = new Date(task.nextRunAt);
1860
+ const daysUntilNum = Math.floor((runAt.getTime() - today.getTime()) / (1e3 * 60 * 60 * 24));
1861
+ return /* @__PURE__ */ jsx(
1862
+ Box,
1863
+ {
1864
+ px: "sm",
1865
+ py: 6,
1866
+ onClick: onScheduledTasksNavigate,
1867
+ style: {
1868
+ borderRadius: 4,
1869
+ cursor: onScheduledTasksNavigate ? "pointer" : "default"
1870
+ },
1871
+ children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1872
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 0 }, children: [
1873
+ /* @__PURE__ */ jsx(
1874
+ Box,
1875
+ {
1876
+ style: {
1877
+ width: 8,
1878
+ height: 8,
1879
+ borderRadius: "50%",
1880
+ backgroundColor: `var(--mantine-color-${daysUntilNum < 0 ? "red" : daysUntilNum <= 1 ? "yellow" : "blue"}-6)`,
1881
+ flexShrink: 0
1882
+ }
1883
+ }
1884
+ ),
1885
+ /* @__PURE__ */ jsx(Text, { size: "xs", truncate: true, children: task.name || task.target.resourceId })
1886
+ ] }),
1887
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: daysUntilNum <= 1 ? void 0 : "gray", children: formatDaysUntil(runAt) })
1888
+ ] })
1889
+ },
1890
+ task.id
1891
+ );
1892
+ }) }) })
1893
+ ] })
1894
+ ] });
1895
+ }
1896
+ var entityTypeConfig = {
1897
+ workflow: { icon: IconGitBranch, hasPath: true },
1898
+ agent: { icon: IconBrain, hasPath: true }
1899
+ };
1900
+ function getEntityConfig(entityType) {
1901
+ return entityTypeConfig[entityType] || { icon: IconActivity, hasPath: false };
1902
+ }
1903
+ function RecentExecutionsByResource({ timeRange, limit = 5, onResourceClick }) {
1904
+ const { data, isLoading, isFetching, error } = useRecentExecutionsByResource({
1905
+ timeRange,
1906
+ limit
1907
+ });
1908
+ const showLoading = (isLoading || isFetching) && !data;
1909
+ const { data: resourcesData } = useResources();
1910
+ const resourceDefLookup = useMemo(() => {
1911
+ if (!resourcesData) return /* @__PURE__ */ new Map();
1912
+ const allResources = [...resourcesData.workflows || [], ...resourcesData.agents || []];
1913
+ return new Map(allResources.map((r) => [r.resourceId, r]));
1914
+ }, [resourcesData]);
1915
+ const enrichedExecutions = useMemo(() => {
1916
+ if (!data?.resources) return [];
1917
+ return data.resources.map((exec) => {
1918
+ const resourceDef = resourceDefLookup.get(exec.resourceId);
1919
+ return {
1920
+ ...exec,
1921
+ resourceType: resourceDef?.type || "",
1922
+ resourceName: resourceDef?.name || exec.resourceId
1923
+ };
1924
+ });
1925
+ }, [data, resourceDefLookup]);
1926
+ const resourceIds = useMemo(
1927
+ () => enrichedExecutions.map((r) => ({
1928
+ entityType: r.resourceType,
1929
+ entityId: r.resourceId
1930
+ })),
1931
+ [enrichedExecutions]
1932
+ );
1933
+ const { startDate, endDate } = useMemo(() => getTimeRangeDates(timeRange), [timeRange]);
1934
+ const granularity = timeRange === "1h" || timeRange === "24h" ? "hour" : "day";
1935
+ const { data: healthData } = useResourcesHealth({
1936
+ resources: resourceIds,
1937
+ startDate,
1938
+ endDate,
1939
+ granularity
1940
+ });
1941
+ const healthLookup = useMemo(() => {
1942
+ if (!healthData?.resources) return /* @__PURE__ */ new Map();
1943
+ return new Map(healthData.resources.map((r) => [`${r.entityType}-${r.entityId}`, r]));
1944
+ }, [healthData]);
1945
+ const handleResourceClick = (resource) => {
1946
+ const config = getEntityConfig(resource.resourceType);
1947
+ if (config.hasPath) {
1948
+ onResourceClick?.({ resourceType: resource.resourceType, resourceId: resource.resourceId });
1949
+ }
1950
+ };
1951
+ if (showLoading) {
1952
+ return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) });
1953
+ }
1954
+ if (error) {
1955
+ return /* @__PURE__ */ jsx(Center, { py: "md", children: /* @__PURE__ */ jsxs(Text, { size: "sm", c: "red.6", children: [
1956
+ "Failed to load: ",
1957
+ error.message
1958
+ ] }) });
1959
+ }
1960
+ if (enrichedExecutions.length === 0) {
1961
+ return /* @__PURE__ */ jsx(EmptyState, { icon: IconPlayerPlay, title: "No executions in this time range" });
1962
+ }
1963
+ return /* @__PURE__ */ jsx(Stack, { gap: "sm", children: enrichedExecutions.map((resource) => {
1964
+ const config = getEntityConfig(resource.resourceType);
1965
+ const Icon = config.icon;
1966
+ const resourceKey = `${resource.resourceType}-${resource.resourceId}`;
1967
+ const resourceHealth = healthLookup.get(resourceKey);
1968
+ const resourceDef = resourceDefLookup.get(resource.resourceId);
1969
+ return /* @__PURE__ */ jsx(
1970
+ Card,
1971
+ {
1972
+ withBorder: true,
1973
+ style: {
1974
+ cursor: config.hasPath ? "pointer" : "default",
1975
+ transition: "box-shadow var(--duration-fast) var(--easing)"
1976
+ },
1977
+ onClick: () => handleResourceClick(resource),
1978
+ children: /* @__PURE__ */ jsxs(Grid, { gutter: "sm", align: "center", children: [
1979
+ /* @__PURE__ */ jsx(Grid.Col, { span: 8, children: /* @__PURE__ */ jsxs(Group, { gap: "sm", wrap: "nowrap", children: [
1980
+ /* @__PURE__ */ jsx(Icon, { size: 24, color: "var(--color-primary)" }),
1981
+ /* @__PURE__ */ jsxs(Stack, { gap: 4, style: { flex: 1, minWidth: 0 }, children: [
1982
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, truncate: true, children: resource.resourceName }),
1983
+ resourceDef?.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, children: resourceDef.description }),
1984
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1985
+ resourceDef?.version && /* @__PURE__ */ jsxs(Badge, { variant: "outline", size: "xs", children: [
1986
+ "v",
1987
+ resourceDef.version
1988
+ ] }),
1989
+ resourceDef?.status && /* @__PURE__ */ jsx(Badge, { color: ResourceStatusColors[resourceDef.status], variant: "outline", size: "xs", children: resourceDef.status.toUpperCase() })
1990
+ ] }),
1991
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
1992
+ "Last run ",
1993
+ formatRelativeTime(resource.lastExecution)
1994
+ ] })
1995
+ ] })
1996
+ ] }) }),
1997
+ /* @__PURE__ */ jsx(Grid.Col, { span: 4, children: /* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "md", wrap: "nowrap", children: [
1998
+ /* @__PURE__ */ jsx(
1999
+ ExecutionStats,
2000
+ {
2001
+ totalExecutions: resource.totalExecutions,
2002
+ successCount: resource.successCount,
2003
+ failureCount: resource.failureCount,
2004
+ warningCount: resource.warningCount,
2005
+ successRate: resource.successRate
2006
+ }
2007
+ ),
2008
+ /* @__PURE__ */ jsx(
2009
+ ResourceHealthChart,
2010
+ {
2011
+ healthData: resourceHealth,
2012
+ hasExecutions: resource.totalExecutions > 0,
2013
+ width: 300,
2014
+ height: 60
2015
+ }
2016
+ )
2017
+ ] }) })
2018
+ ] })
2019
+ },
2020
+ resource.resourceId
2021
+ );
2022
+ }) });
2023
+ }
2024
+ var severityColor2 = {
2025
+ critical: "red",
2026
+ warning: "yellow",
2027
+ info: "blue"
2028
+ };
2029
+ function UnresolvedErrorsTeaser({ timeRange, onNavigateToAllErrors }) {
2030
+ const { startDate, endDate } = useTimeRangeDates(timeRange);
2031
+ const { data, isLoading } = useUnresolvedErrors({ startDate, endDate });
2032
+ const errors = data?.errors ?? [];
2033
+ const total = data?.total ?? 0;
2034
+ if (isLoading) {
2035
+ return /* @__PURE__ */ jsx(
2036
+ Paper,
2037
+ {
2038
+ style: {
2039
+ background: "var(--glass-background)",
2040
+ backdropFilter: "var(--glass-blur)",
2041
+ border: "1px solid var(--color-border)",
2042
+ borderRadius: 8
2043
+ },
2044
+ children: /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) })
2045
+ }
2046
+ );
2047
+ }
2048
+ return /* @__PURE__ */ jsxs(
2049
+ Paper,
2050
+ {
2051
+ style: {
2052
+ background: "var(--glass-background)",
2053
+ backdropFilter: "var(--glass-blur)",
2054
+ border: "1px solid var(--color-border)",
2055
+ borderRadius: 8
2056
+ },
2057
+ children: [
2058
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: errors.length > 0 ? "sm" : 0, children: [
2059
+ /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
2060
+ /* @__PURE__ */ jsx(ThemeIcon, { size: 28, radius: "md", variant: "light", color: total > 0 ? "red" : "green", children: total > 0 ? /* @__PURE__ */ jsx(IconAlertTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconCircleCheck, { size: 16 }) }),
2061
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: "Unresolved Errors" })
2062
+ ] }),
2063
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
2064
+ total > 0 && /* @__PURE__ */ jsxs(Badge, { size: "xs", variant: "light", color: "red", children: [
2065
+ total,
2066
+ " unresolved"
2067
+ ] }),
2068
+ /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: onNavigateToAllErrors, children: /* @__PURE__ */ jsx(IconArrowUpRight, { size: 14 }) })
2069
+ ] })
2070
+ ] }),
2071
+ errors.length === 0 && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No unresolved errors" }),
2072
+ errors.length > 0 && /* @__PURE__ */ jsx(Stack, { gap: 4, children: errors.map((error) => /* @__PURE__ */ jsx(
2073
+ Box,
2074
+ {
2075
+ px: "sm",
2076
+ py: 6,
2077
+ onClick: onNavigateToAllErrors,
2078
+ style: {
2079
+ borderLeft: `2px solid var(--mantine-color-${severityColor2[error.severity]}-6)`,
2080
+ borderRadius: 4,
2081
+ cursor: onNavigateToAllErrors ? "pointer" : "default",
2082
+ textDecoration: "none",
2083
+ color: "inherit"
2084
+ },
2085
+ children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
2086
+ /* @__PURE__ */ jsxs(Stack, { gap: 0, style: { minWidth: 0 }, children: [
2087
+ /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 1, children: error.resourceName || error.resourceId }),
2088
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 1, children: error.errorType })
2089
+ ] }),
2090
+ /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
2091
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: severityColor2[error.severity], children: error.severity }),
2092
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatTimeAgo(error.timestamp) })
2093
+ ] })
2094
+ ] })
2095
+ },
2096
+ error.id
2097
+ )) })
2098
+ ]
2099
+ }
2100
+ );
2101
+ }
2102
+
2103
+ export { AgentExecutionTimeline, AgentExecutionVisualizer, AgentIterationDetailPanel, AgentIterationEdge, AgentIterationNode, BaseEdge, BaseNode, CollapsibleJsonSection, Dashboard, DashboardOperationsOverview, EmptyVisualizer, ExecutionStats, ExecutionStatusBadge, GraphBackground, GraphContainer, GraphFitViewButton, GraphFitViewHandler, GraphLegend, OperationsOverview, RecentExecutionsByResource, ResourceOverview, RunResourceButton, TimelineAxis, TimelineBar, TimelineContainer, TimelineRow, UnifiedWorkflowEdge, UnifiedWorkflowGraph, UnifiedWorkflowNode, UnresolvedErrorsTeaser, VisualizerContainer, WorkflowExecutionTimeline, getGraphBackgroundStyles, useGraphBackgroundStyles, useGraphTheme };