@workflow/web 5.0.0-beta.41 → 5.0.0-beta.42

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 (28) hide show
  1. package/build/client/assets/app-9JVnf-IU.css +1 -0
  2. package/build/client/assets/{arrow-up-right-jWH-UQH9.js → arrow-up-right-D39pnGsD.js} +1 -1
  3. package/build/client/assets/{highlighted-body-B3W2YXNL-DmmWu7VM.js → highlighted-body-B3W2YXNL-Dc1dLaUr.js} +1 -1
  4. package/build/client/assets/{home-BwYHJJJr.js → home-C6CuMqQu.js} +3 -3
  5. package/build/client/assets/{loader-circle-fFQM94Ej.js → loader-circle-BOxaTUjK.js} +1 -1
  6. package/build/client/assets/{manifest-f6a9dca2.js → manifest-cf88886b.js} +1 -1
  7. package/build/client/assets/{mermaid-3ZIDBTTL-DchhEfRL.js → mermaid-3ZIDBTTL-gEw-Ch1C.js} +308 -284
  8. package/build/client/assets/{root-D6p4Hb4F.js → root-BfhMCbkz.js} +3 -3
  9. package/build/client/assets/root-Bl5xphvU.css +1 -0
  10. package/build/client/assets/{run-detail-vPCbZIXx.js → run-detail-DKz7lp2q.js} +221 -105
  11. package/build/client/assets/{workflow-graph-viewer-t_fSwuwz.js → workflow-graph-viewer-CxrWityD.js} +3 -145
  12. package/build/client/assets/{zstd-browser-decoder-BTw1glGN.js → zstd-browser-decoder-CAEVa0bm.js} +1 -1
  13. package/build/server/assets/{app-D8GiFFR6.js → app-SrggQnfh.js} +739 -608
  14. package/build/server/assets/{highlighted-body-B3W2YXNL-BZVc2guG.js → highlighted-body-B3W2YXNL-DMhwZQgG.js} +1 -1
  15. package/build/server/assets/{index-DTci39F3.js → index-ByPjQpgH.js} +1 -1
  16. package/build/server/assets/index-DsnQrgwB.js +156 -0
  17. package/build/server/assets/{mermaid-3ZIDBTTL-DOefrphg.js → mermaid-3ZIDBTTL-CK9fLYE8.js} +1 -1
  18. package/build/server/assets/{token-c3byIJRC.js → token-sFDUVNm0.js} +1 -1
  19. package/build/server/assets/{token-util-C2yENsqE.js → token-util-CighjZkT.js} +1 -1
  20. package/build/server/assets/{websocket-server-DagS_hnJ.js → websocket-server-BADWB2u5.js} +1 -1
  21. package/build/server/assets/{wrapper-Cnumc4u1.js → wrapper-Bwi-W3ol.js} +3 -3
  22. package/build/server/assets/{ws-transport-2gJL6hC2.js → ws-transport-DaZsgQ2B.js} +41 -3
  23. package/build/server/assets/{zstd-browser-decoder-BCVvr1WT.js → zstd-browser-decoder-dRi0VqoM.js} +1 -1
  24. package/build/server/index.js +3 -3
  25. package/package.json +7 -7
  26. package/build/client/assets/app-BkGXg64e.css +0 -1
  27. package/build/client/assets/root-ZRjqDhEN.css +0 -1
  28. package/build/server/assets/index-BByEr1g6.js +0 -154
@@ -1,7 +1,7 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports, o as reactDomExports, D as ReactDOM, d as useNavigate, e as useSearchParams, c as Link, w as withComponentProps, G as useParams } from "./index-PFjW8YjQ.js";
2
- import { C as CircleAlert, O as parseStepName, B as parseWorkflowName, Q as ErrorCard, U as format, Z as Zap, S as Send, R as ResolveHookModal, q as ChevronUp, X, N as ErrorBoundary, V as Circle, u as unwrapOrThrow, W as WorkflowWebAPIError, I as unwrapServerActionResult, Y as useEscapeKeydown, t as composeEventHandlers, _ as useCallbackRef, $ as useLayoutEffect2, s as useControllableState, a0 as useId, a1 as createContext2, v as Presence, x as createContextScope, n as hideOthers, o as ReactRemoveScroll, a2 as useFocusGuards, a3 as LAYOUT, a4 as wakeUpRun, l as resumeHook, A as Alert, c as AlertTitle, g as getErrorTitle, d as AlertDescription, e as getErrorMessage, a as Skeleton$1, a5 as RunActionsButtons, F as StatusBadge, h as CopyableText, b as RelativeTime, T as Tabs, K as TabsList, L as TabsTrigger, M as TabsContent, a6 as cancelRun, a7 as recreateRun } from "./workflow-graph-viewer-t_fSwuwz.js";
3
- import { c as createLucideIcon, Y as cn, Z as CopyableDataBlock, $ as CollapsibleRoot, a0 as CollapsibleTrigger, a1 as CollapsibleContent, a2 as CopyButton, O as cva, a3 as RESERVED_ATTRIBUTE_KEY_PREFIX, a4 as Spinner, a5 as ContextCardProvider, h as useToast, a6 as Skeleton, a7 as DecryptClickContext, a8 as Yr, a9 as isEncryptedMarker, m as ChevronRight, aa as TimestampTooltip, ab as formatDuration, C as Check, l as Copy, ac as DataInspector, ad as _r, ae as isHookLifecycleEventType, af as isTerminalStepEventType, ag as isWaitEventType, ah as isStepEventType, ai as RunClickContext, aj as StreamClickContext, ak as Collapsible, al as isExpiredMarker, am as isDoStreamStep, an as extractConversation, ao as EncryptedDataBlock, ap as getEventDataRefFields, aq as hasEncryptedFields, ar as useSidebarDataOptional, as as isTerminalWorkflowRunStatus, at as clsx, au as useActiveSpan, av as useSidebarData, aw as Tooltip, ax as TooltipTrigger, ay as IconButton, az as TooltipContent, J as ChevronDown, aA as useRowWindow, aB as isSpanDimmedBySearch, aC as ROW_HEIGHT_PX, aD as getSpanDurationMs, aE as isSpanErrored, aF as formatDurationPrecise, aG as TooltipProvider, aH as ActiveSpanProvider, aI as useReducedMotion, aJ as searchSpans, aK as computeRootBounds, aL as computeTimeMarkers, aM as clampViewportToRoot, aN as getHighResInMs, aO as scrollRowIntoView, aP as TIMELINE_PADDING_PX, aQ as Minimap, aR as Timeline, aS as TimelineHeader, aT as wheelZoomScaleFactor, aU as wheelDeltaToPixels, aV as SidebarDataProvider, aW as fetchHook, n as fetchEvents, aX as hydrateResourceIOAsync, N as fetchRun, aY as fetchStep, aZ as hydrateResourceIO, a_ as fetchStreams, a$ as apiBase, b0 as Slot, L as useComposedRefs, b1 as Slottable, e as cn$1, b2 as buttonVariants, b3 as fetchEvent, b4 as fetchEventsByCorrelationId, b5 as isEncryptedData, b6 as hydrateData, b7 as decrypt, b8 as deriveRunPayloadKeys, b9 as getWebRevivers, T as Tooltip$1, a as TooltipTrigger$1, b as TooltipContent$1, ba as LIVE_UPDATE_INTERVAL_MS$1, u as useServerConfig, bb as getEncryptionKeyForRun, t as toast, bc as StreamViewerSkeleton, bd as Lock, be as StreamViewer } from "./mermaid-3ZIDBTTL-DchhEfRL.js";
4
- import { A as ArrowUpRight } from "./arrow-up-right-jWH-UQH9.js";
2
+ import { C as CircleAlert, O as parseStepName, B as parseWorkflowName, Q as ErrorCard, U as format, Z as Zap, S as Send, R as ResolveHookModal, q as ChevronUp, X, N as ErrorBoundary, V as Circle, u as unwrapOrThrow, W as WorkflowWebAPIError, I as unwrapServerActionResult, Y as useEscapeKeydown, t as composeEventHandlers, _ as useCallbackRef, $ as useLayoutEffect2, s as useControllableState, a0 as useId, a1 as createContext2, v as Presence, x as createContextScope, n as hideOthers, o as ReactRemoveScroll, a2 as useFocusGuards, a3 as LAYOUT, a4 as wakeUpRun, l as resumeHook, A as Alert, c as AlertTitle, g as getErrorTitle, d as AlertDescription, e as getErrorMessage, a as Skeleton$1, a5 as RunActionsButtons, F as StatusBadge, h as CopyableText, b as RelativeTime, T as Tabs, K as TabsList, L as TabsTrigger, M as TabsContent, a6 as cancelRun, a7 as recreateRun } from "./workflow-graph-viewer-CxrWityD.js";
3
+ import { c as createLucideIcon, Y as entityEventClass, Z as cn, $ as CopyableDataBlock, a0 as CollapsibleRoot, a1 as CollapsibleTrigger, a2 as CollapsibleContent, a3 as CopyButton, O as cva, a4 as RESERVED_ATTRIBUTE_KEY_PREFIX, a5 as Spinner, a6 as TooltipProvider, a7 as Tooltip, a8 as TooltipTrigger, a9 as TooltipContent, aa as ContextCardProvider, h as useToast, ab as Skeleton, ac as DecryptClickContext, ad as Yr, ae as isEncryptedMarker, m as ChevronRight, af as TimestampTooltip, ag as formatDuration, C as Check, l as Copy, ah as DataInspector, ai as _r, aj as isHookLifecycleEventType, ak as isTerminalStepEventType, al as isWaitEventType, am as isStepEventType, an as RunClickContext, ao as StreamClickContext, ap as Collapsible, aq as isExpiredMarker, ar as isDoStreamStep, as as extractConversation, at as EncryptedDataBlock, au as getEventDataRefFields, av as hasEncryptedFields, aw as useSidebarDataOptional, ax as isTerminalWorkflowRunStatus, ay as clsx, az as useActiveSpan, aA as useSidebarData, aB as IconButton, J as ChevronDown, aC as useRowWindow, aD as isSpanDimmedBySearch, aE as ROW_HEIGHT_PX, aF as getSpanDurationMs, aG as isSpanErrored, aH as formatDurationPrecise, aI as ActiveSpanProvider, aJ as useReducedMotion, aK as searchSpans, aL as computeRootBounds, aM as computeTimeMarkers, aN as clampViewportToRoot, aO as getHighResInMs, aP as scrollRowIntoView, aQ as TIMELINE_PADDING_PX, aR as Minimap, aS as Timeline, aT as TimelineHeader, aU as wheelZoomScaleFactor, aV as wheelDeltaToPixels, aW as SidebarDataProvider, aX as fetchHook, n as fetchEvents, aY as hydrateResourceIOAsync, N as fetchRun, aZ as fetchStep, a_ as hydrateResourceIO, a$ as fetchStreams, b0 as apiBase, b1 as Slot, L as useComposedRefs, b2 as Slottable, e as cn$1, b3 as buttonVariants, b4 as fetchEvent, b5 as fetchEventsByCorrelationId, b6 as isEncryptedData, b7 as hydrateData, b8 as decrypt, b9 as deriveRunPayloadKeys, ba as getWebRevivers, T as Tooltip$1, a as TooltipTrigger$1, b as TooltipContent$1, bb as LIVE_UPDATE_INTERVAL_MS$1, u as useServerConfig, bc as getEncryptionKeyForRun, t as toast, bd as StreamViewerSkeleton, be as Lock, bf as StreamViewer } from "./mermaid-3ZIDBTTL-gEw-Ch1C.js";
4
+ import { A as ArrowUpRight } from "./arrow-up-right-D39pnGsD.js";
5
5
  /**
6
6
  * @license lucide-react v0.575.0 - ISC
7
7
  *
@@ -76,6 +76,97 @@ const __iconNode = [
76
76
  ["line", { x1: "8", x2: "14", y1: "11", y2: "11", key: "durymu" }]
77
77
  ];
78
78
  const ZoomOut = createLucideIcon("zoom-out", __iconNode);
79
+ const EVENT_ID_BODY_LENGTH = 26;
80
+ const SLOT_LEADING_ZEROS = 10;
81
+ function isSlotBody(body) {
82
+ if (body.length !== EVENT_ID_BODY_LENGTH)
83
+ return false;
84
+ for (let i = 0; i < SLOT_LEADING_ZEROS; i++) {
85
+ if (body[i] !== "0")
86
+ return false;
87
+ }
88
+ for (let i = SLOT_LEADING_ZEROS; i < EVENT_ID_BODY_LENGTH; i++) {
89
+ const code = body.charCodeAt(i);
90
+ if (code < 48 || code > 57)
91
+ return false;
92
+ }
93
+ return true;
94
+ }
95
+ function stripEventIdPrefix(eventId) {
96
+ const underscore = eventId.indexOf("_");
97
+ return underscore === -1 ? eventId : eventId.slice(underscore + 1);
98
+ }
99
+ function isSlotEventId(eventId) {
100
+ return isSlotBody(stripEventIdPrefix(eventId));
101
+ }
102
+ const TERMINAL_EVENT_CLASSES = /* @__PURE__ */ new Set([
103
+ "step_terminal",
104
+ "wait_completed",
105
+ "hook_disposed"
106
+ ]);
107
+ const SINGLETON_EVENT_CLASSES = /* @__PURE__ */ new Set([
108
+ "run_started"
109
+ ]);
110
+ const RUN_ENTITY_KEY = "";
111
+ const DUPLICATE_EVENT_MESSAGE = "Written by a concurrent replay after an event of the same kind was already recorded and acted on. The run follows the earlier one.";
112
+ function compareEventId(a, b) {
113
+ if (a.eventId.length !== b.eventId.length) {
114
+ return a.eventId.length - b.eventId.length;
115
+ }
116
+ return a.eventId < b.eventId ? -1 : a.eventId > b.eventId ? 1 : 0;
117
+ }
118
+ function createdAtMs(event) {
119
+ const createdAt = event.createdAt;
120
+ return createdAt instanceof Date ? createdAt.getTime() : new Date(createdAt).getTime();
121
+ }
122
+ function hasKnowableLogOrder(orderedById) {
123
+ if (orderedById.every((event) => isSlotEventId(event.eventId)))
124
+ return true;
125
+ for (let index = 1; index < orderedById.length; index++) {
126
+ const previous = createdAtMs(orderedById[index - 1]);
127
+ const current = createdAtMs(orderedById[index]);
128
+ if (Number.isNaN(previous) || Number.isNaN(current))
129
+ return false;
130
+ if (current < previous)
131
+ return false;
132
+ }
133
+ return true;
134
+ }
135
+ function foldDuplicates(ordered) {
136
+ const duplicates = /* @__PURE__ */ new Set();
137
+ const seenClasses = /* @__PURE__ */ new Set();
138
+ const closedEntities = /* @__PURE__ */ new Set();
139
+ for (const event of ordered) {
140
+ const eventClass = entityEventClass(event.eventType);
141
+ if (eventClass === void 0)
142
+ continue;
143
+ const entity = event.correlationId ?? RUN_ENTITY_KEY;
144
+ const classKey = `${eventClass}:${entity}`;
145
+ const repeatsClass = seenClasses.has(classKey);
146
+ const entityWasClosed = closedEntities.has(entity);
147
+ if (TERMINAL_EVENT_CLASSES.has(eventClass)) {
148
+ closedEntities.add(entity);
149
+ }
150
+ if (!repeatsClass) {
151
+ if (entityWasClosed)
152
+ break;
153
+ seenClasses.add(classKey);
154
+ continue;
155
+ }
156
+ if (entityWasClosed || SINGLETON_EVENT_CLASSES.has(eventClass)) {
157
+ duplicates.add(event.eventId);
158
+ }
159
+ }
160
+ return duplicates;
161
+ }
162
+ function findDuplicateEventIds(events, { isCompleteHistory }) {
163
+ if (!isCompleteHistory || events.length < 2)
164
+ return /* @__PURE__ */ new Set();
165
+ const ordered = events.filter((event) => Boolean(event.eventId)).sort(compareEventId);
166
+ if (!hasKnowableLogOrder(ordered))
167
+ return /* @__PURE__ */ new Set();
168
+ return foldDuplicates(ordered);
169
+ }
79
170
  const WORKFLOW_ULID_BODY = "[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}";
80
171
  const STEP_ID_PATTERN = new RegExp(`^step_(${WORKFLOW_ULID_BODY})$`, "i");
81
172
  const WAIT_ID_PATTERN = new RegExp(`^wait_(${WORKFLOW_ULID_BODY})$`, "i");
@@ -410,7 +501,7 @@ const rowCopyValueVariants = cva("flex min-w-0 flex-1 items-center justify-end g
410
501
  });
411
502
  function DetailKeyValueRowBase({ label, value, copyText, href, removed = false, variant }) {
412
503
  const stringValue = typeof value === "string" ? value : void 0;
413
- return jsxRuntimeExports.jsxs("div", { className: "px-1.5 hover:bg-gray-100 flex justify-between gap-3 -mx-1.5 py-0.5 rounded items-center", children: [jsxRuntimeExports.jsx("span", { className: "flex min-w-0 items-center gap-1.5 truncate text-label-13 text-gray-900", children: label }), removed ? jsxRuntimeExports.jsx("span", { className: "shrink-0 text-copy-13 italic text-gray-700", children: "removed" }) : copyText ? jsxRuntimeExports.jsxs("div", { className: cn(rowCopyValueVariants({ variant })), title: copyText, children: [href ? jsxRuntimeExports.jsxs("a", { href, target: "_blank", rel: "noreferrer", className: cn(rowValueVariants({ variant }), "flex min-w-0 items-center gap-0.5 hover:underline"), children: [jsxRuntimeExports.jsx(MiddleTruncate, { value: copyText, className: "min-w-0 text-right", style: { gridTemplateColumns: "minmax(0, 1fr)" } }), jsxRuntimeExports.jsx(ArrowUpRight, { "aria-hidden": true, className: "h-3 w-3 shrink-0" })] }) : jsxRuntimeExports.jsx(MiddleTruncate, { value: copyText, className: cn(rowValueVariants({ variant, className: "text-right" })), style: { gridTemplateColumns: "minmax(0, 1fr)" } }), jsxRuntimeExports.jsx(CopyButton, { copyText, ariaLabel: `Copy ${label}`, className: "shrink-0 -mr-1" })] }) : jsxRuntimeExports.jsx("span", { className: cn(rowValueVariants({ variant })), title: stringValue, children: href ? jsxRuntimeExports.jsx("a", { href, target: "_blank", rel: "noreferrer", className: "hover:underline", children: value }) : value })] });
504
+ return jsxRuntimeExports.jsxs("div", { className: "px-1.5 hover:bg-gray-100 flex justify-between gap-3 -mx-1.5 py-0.5 rounded items-center", children: [jsxRuntimeExports.jsx("span", { className: "flex min-w-0 items-center gap-1.5 truncate text-label-13 text-gray-900", children: label }), removed ? jsxRuntimeExports.jsx("span", { className: "shrink-0 text-copy-13 italic text-gray-700", children: "removed" }) : copyText ? jsxRuntimeExports.jsxs("div", { className: cn(rowCopyValueVariants({ variant })), title: copyText, children: [href ? jsxRuntimeExports.jsxs("a", { href, target: "_blank", rel: "noreferrer", className: cn(rowValueVariants({ variant }), "flex min-w-0 items-center gap-0.5 hover:underline"), children: [jsxRuntimeExports.jsx(MiddleTruncate, { value: copyText, className: "min-w-0 grid-cols-[minmax(0,1fr)] text-right" }), jsxRuntimeExports.jsx(ArrowUpRight, { "aria-hidden": true, className: "h-3 w-3 shrink-0" })] }) : jsxRuntimeExports.jsx(MiddleTruncate, { value: copyText, className: cn(rowValueVariants({ variant, className: "text-right" }), "grid-cols-[minmax(0,1fr)]") }), jsxRuntimeExports.jsx(CopyButton, { copyText, ariaLabel: `Copy ${label}`, className: "shrink-0 -mr-1" })] }) : jsxRuntimeExports.jsx("span", { className: cn(rowValueVariants({ variant })), title: stringValue, children: href ? jsxRuntimeExports.jsx("a", { href, target: "_blank", rel: "noreferrer", className: "hover:underline", children: value }) : value })] });
414
505
  }
415
506
  function DetailKeyValueRow(props) {
416
507
  return jsxRuntimeExports.jsx(DetailKeyValueRowBase, { ...props });
@@ -485,15 +576,17 @@ function AttrSetEventBlock({ data }) {
485
576
  return jsxRuntimeExports.jsx(CopyableDataBlock, { data });
486
577
  }
487
578
  const writerLabel = describeWriter(data.writer);
488
- return jsxRuntimeExports.jsxs("div", { className: "flex flex-col px-3 py-1", children: [jsxRuntimeExports.jsx("div", { className: "flex flex-col", children: data.changes.map((change, index) => jsxRuntimeExports.jsx(AttributeRow, { attributeKey: change.key, removed: change.value === null, value: change.value ?? void 0 }, `${change.key}:${index}`)) }), writerLabel && jsxRuntimeExports.jsx("div", { className: "border-t py-1.5 text-label-12", style: {
489
- borderColor: "var(--ds-gray-alpha-400)",
490
- color: "var(--ds-gray-700)"
491
- }, children: writerLabel })] });
579
+ return jsxRuntimeExports.jsxs("div", { className: "flex flex-col px-3 py-1", children: [jsxRuntimeExports.jsx("div", { className: "flex flex-col", children: data.changes.map((change, index) => jsxRuntimeExports.jsx(AttributeRow, { attributeKey: change.key, removed: change.value === null, value: change.value ?? void 0 }, `${change.key}:${index}`)) }), writerLabel && jsxRuntimeExports.jsx("div", { className: "border-gray-alpha-400 border-t py-1.5 text-gray-700 text-label-12", children: writerLabel })] });
492
580
  }
493
581
  const STYLES$2 = `.wf-decrypt-btn{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 12px;border-radius:6px;font-size:14px;font-weight:500;line-height:20px;cursor:pointer;white-space:nowrap;gap:6px;transition:background 150ms}.wf-decrypt-idle{color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400)}.wf-decrypt-idle:hover{background:var(--ds-gray-alpha-200)}.wf-decrypt-done{color:var(--ds-green-900);background:var(--ds-green-100);box-shadow:0 0 0 1px var(--ds-green-400);cursor:default}`;
494
582
  function DecryptButton({ decrypted = false, loading = false, onClick }) {
495
583
  return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES$2 } }), jsxRuntimeExports.jsxs("button", { type: "button", onClick: decrypted ? void 0 : onClick, disabled: decrypted || loading, className: `wf-decrypt-btn ${decrypted ? "wf-decrypt-done" : "wf-decrypt-idle"}`, children: [loading ? jsxRuntimeExports.jsx(Spinner, { size: 14 }) : decrypted ? jsxRuntimeExports.jsxs("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), jsxRuntimeExports.jsx("path", { d: "M7 11V7a5 5 0 0 1 9.9-1" })] }) : jsxRuntimeExports.jsxs("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), jsxRuntimeExports.jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })] }), loading ? "Decrypting…" : decrypted ? "Decrypted" : "Decrypt"] })] });
496
584
  }
585
+ function DuplicateEventTooltip({ isDuplicate = false, children }) {
586
+ if (!isDuplicate)
587
+ return children;
588
+ return jsxRuntimeExports.jsx(TooltipProvider, { delayDuration: 300, children: jsxRuntimeExports.jsxs(Tooltip, { children: [jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children }), jsxRuntimeExports.jsx(TooltipContent, { className: "max-w-[264px] leading-snug", collisionPadding: 8, side: "top", children: DUPLICATE_EVENT_MESSAGE })] }) });
589
+ }
497
590
  function isStructuredError(value) {
498
591
  return value != null && typeof value === "object" && (typeof value.message === "string" || typeof value.stack === "string");
499
592
  }
@@ -549,24 +642,7 @@ function MenuDropdown({ options, value, onChange }) {
549
642
  document.addEventListener("mousedown", handleClickOutside);
550
643
  return () => document.removeEventListener("mousedown", handleClickOutside);
551
644
  }, [open]);
552
- return jsxRuntimeExports.jsxs("div", { ref, style: { position: "relative", flexShrink: 0 }, children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES } }), jsxRuntimeExports.jsxs("button", { type: "button", className: "wf-menu-btn", onClick: () => setOpen(!open), children: [jsxRuntimeExports.jsx("span", { children: label }), jsxRuntimeExports.jsx("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", style: {
553
- marginLeft: 16,
554
- marginRight: -4,
555
- color: "var(--ds-gray-900)"
556
- }, children: jsxRuntimeExports.jsx("path", { d: "M4.5 6L8 9.5L11.5 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })] }), open && jsxRuntimeExports.jsx("div", { style: {
557
- position: "absolute",
558
- right: 0,
559
- top: "100%",
560
- marginTop: 4,
561
- minWidth: 140,
562
- padding: 4,
563
- borderRadius: 12,
564
- background: "var(--ds-background-100)",
565
- boxShadow: "var(--ds-shadow-menu, var(--ds-shadow-medium))",
566
- zIndex: 2001
567
- }, role: "menu", children: options.map((option) => jsxRuntimeExports.jsx("button", { type: "button", role: "menuitem", className: "wf-menu-item", style: {
568
- fontWeight: option.value === value ? 500 : 400
569
- }, onClick: () => {
645
+ return jsxRuntimeExports.jsxs("div", { ref, className: "relative shrink-0", children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES } }), jsxRuntimeExports.jsxs("button", { type: "button", className: "wf-menu-btn", onClick: () => setOpen(!open), children: [jsxRuntimeExports.jsx("span", { children: label }), jsxRuntimeExports.jsx("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", className: "-mr-1 ml-4 text-gray-900", children: jsxRuntimeExports.jsx("path", { d: "M4.5 6L8 9.5L11.5 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })] }), open && jsxRuntimeExports.jsx("div", { className: "absolute top-full right-0 z-[2001] mt-1 min-w-[140px] bg-background-100 p-1 material-menu", role: "menu", children: options.map((option) => jsxRuntimeExports.jsx("button", { type: "button", role: "menuitem", className: cn("wf-menu-item", option.value === value ? "font-medium" : "font-normal"), onClick: () => {
570
646
  onChange(option.value);
571
647
  setOpen(false);
572
648
  }, children: option.label }, option.value)) })] });
@@ -643,8 +719,8 @@ function buildNameMaps(events, run) {
643
719
  const workflowName = (run == null ? void 0 : run.workflowName) ? ((_b = parseWorkflowName(run.workflowName)) == null ? void 0 : _b.shortName) ?? run.workflowName : null;
644
720
  return { correlationNameMap, workflowName };
645
721
  }
646
- function buildDurationMap(events) {
647
- const chronological = [...events].sort((a, b) => getEffectiveEventTime(a) - getEffectiveEventTime(b));
722
+ function buildDurationMap(events, duplicateEventIds = /* @__PURE__ */ new Set()) {
723
+ const chronological = [...events].filter((event) => !duplicateEventIds.has(event.eventId)).sort((a, b) => getEffectiveEventTime(a) - getEffectiveEventTime(b));
648
724
  const createdTimes = /* @__PURE__ */ new Map();
649
725
  const firstStartedTimes = /* @__PURE__ */ new Map();
650
726
  const startedTimes = /* @__PURE__ */ new Map();
@@ -893,7 +969,7 @@ function RowsSkeleton({ showSeparateEventOccurrenceTimestamps = false }) {
893
969
  marginLeft: i % 4 === 0 ? 5 : 6
894
970
  } })] }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0 flex items-center justify-center", children: jsxRuntimeExports.jsx(Skeleton, { className: "w-5 h-5", style: { borderRadius: 4 } }) }), showSeparateEventOccurrenceTimestamps && jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "70%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "70%" } }) }), jsxRuntimeExports.jsxs("div", { className: "min-w-0 px-4 flex items-center gap-1.5", style: { flex: "2 1 0%" }, children: [jsxRuntimeExports.jsx(Skeleton, { className: "flex-shrink-0", style: { width: 6, height: 6, borderRadius: "50%" } }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "60%" } })] }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "50%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "75%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "75%" } }) })] }, i)) });
895
971
  }
896
- function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected, suppressGroupDimming = false, showSeparateEventOccurrenceTimestamps = false }) {
972
+ function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected, suppressGroupDimming = false, showSeparateEventOccurrenceTimestamps = false, isDuplicate = false }) {
897
973
  const [isLoading, setIsLoading] = reactExports.useState(false);
898
974
  const [loadedEventData, setLoadedEventData] = reactExports.useState(cachedEventData);
899
975
  const [loadError, setLoadError] = reactExports.useState(null);
@@ -1011,7 +1087,9 @@ function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand,
1011
1087
  }, children: jsxRuntimeExports.jsx(ChevronRight, { className: "h-3 w-3 transition-transform", style: {
1012
1088
  color: "var(--ds-gray-900)",
1013
1089
  transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
1014
- } }) }), showSeparateEventOccurrenceTimestamps && jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: occurredAt ? jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(occurredAt) }) }) : "-" }), jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(TimestampTooltip, { date: displayedCreatedAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(displayedCreatedAt) }) }) }), jsxRuntimeExports.jsx("div", { className: "font-medium min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5", style: { color: "var(--ds-gray-900)" }, children: [jsxRuntimeExports.jsxs("span", { style: {
1090
+ } }) }), showSeparateEventOccurrenceTimestamps && jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: occurredAt ? jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(occurredAt) }) }) : "-" }), jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(TimestampTooltip, { date: displayedCreatedAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(displayedCreatedAt) }) }) }), jsxRuntimeExports.jsx("div", { className: "font-medium min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(DuplicateEventTooltip, { isDuplicate, children: jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5", style: {
1091
+ color: isDuplicate ? "var(--ds-gray-700)" : "var(--ds-gray-900)"
1092
+ }, children: [jsxRuntimeExports.jsxs("span", { style: {
1015
1093
  position: "relative",
1016
1094
  display: "inline-flex",
1017
1095
  width: 6,
@@ -1030,7 +1108,7 @@ function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand,
1030
1108
  height: 6,
1031
1109
  borderRadius: "50%",
1032
1110
  backgroundColor: statusDotColor
1033
- } })] }), formatEventType(event.eventType)] }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4 overflow-hidden text-ellipsis whitespace-nowrap", style: { flex: "2 1 0%" }, title: eventName !== "-" ? eventName : void 0, children: eventName }), jsxRuntimeExports.jsx(CopyableCell, { value: event.correlationId || "", className: "font-mono", style: { flex: "3 1 0%" } }), jsxRuntimeExports.jsx(CopyableCell, { value: event.eventId, className: "font-mono", style: { flex: "3 1 0%" } })] })] }), isExpanded && jsxRuntimeExports.jsxs("div", { className: "flex", children: [jsxRuntimeExports.jsx(TreeGutter, { isFirst: false, isLast, isRunLevel: isRun, hasSelection: hasActive, showBranch: false, showLaneLine: showLaneLine && !isLaneEnd, isLaneStart: false, isLaneEnd: false, continuationOnly: true }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0" }), jsxRuntimeExports.jsxs("div", { className: "flex-1 my-1.5 mr-3 ml-2 py-2 rounded-md border overflow-hidden", style: {
1111
+ } })] }), formatEventType(event.eventType)] }) }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4 overflow-hidden text-ellipsis whitespace-nowrap", style: { flex: "2 1 0%" }, title: eventName !== "-" ? eventName : void 0, children: eventName }), jsxRuntimeExports.jsx(CopyableCell, { value: event.correlationId || "", className: "font-mono", style: { flex: "3 1 0%" } }), jsxRuntimeExports.jsx(CopyableCell, { value: event.eventId, className: "font-mono", style: { flex: "3 1 0%" } })] })] }), isExpanded && jsxRuntimeExports.jsxs("div", { className: "flex", children: [jsxRuntimeExports.jsx(TreeGutter, { isFirst: false, isLast, isRunLevel: isRun, hasSelection: hasActive, showBranch: false, showLaneLine: showLaneLine && !isLaneEnd, isLaneStart: false, isLaneEnd: false, continuationOnly: true }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0" }), jsxRuntimeExports.jsxs("div", { className: "flex-1 my-1.5 mr-3 ml-2 py-2 rounded-md border overflow-hidden", style: {
1034
1112
  borderColor: "var(--ds-gray-alpha-200)",
1035
1113
  opacity: contentOpacity,
1036
1114
  transition: "opacity 150ms"
@@ -1068,6 +1146,9 @@ function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = fals
1068
1146
  const dir = effectiveSortOrder === "desc" ? -1 : 1;
1069
1147
  return [...sourceEvents].sort((a, b) => dir * (getEffectiveEventTime(a) - getEffectiveEventTime(b)));
1070
1148
  }, [events, effectiveSortOrder, isExactSearchActive, searchResults]);
1149
+ const duplicateEventIds = reactExports.useMemo(() => findDuplicateEventIds(events ?? [], {
1150
+ isCompleteHistory: !hasMoreEvents && !isExactSearchActive
1151
+ }), [events, hasMoreEvents, isExactSearchActive]);
1071
1152
  const hasEncryptedInlineData = reactExports.useMemo(() => {
1072
1153
  const sourceEvents = isExactSearchActive ? searchResults : events;
1073
1154
  if (!sourceEvents)
@@ -1085,7 +1166,7 @@ function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = fals
1085
1166
  }, []);
1086
1167
  const hasEncryptedData = hasEncryptedDataProp || hasEncryptedInlineData || foundEncryptedInLazyData;
1087
1168
  const { correlationNameMap, workflowName } = reactExports.useMemo(() => buildNameMaps(isExactSearchActive ? searchResults : events ?? null, run ?? null), [events, isExactSearchActive, run, searchResults]);
1088
- const durationMap = reactExports.useMemo(() => buildDurationMap(sortedEvents), [sortedEvents]);
1169
+ const durationMap = reactExports.useMemo(() => buildDurationMap(sortedEvents, duplicateEventIds), [sortedEvents, duplicateEventIds]);
1089
1170
  const [selectedGroupKey, setSelectedGroupKey] = reactExports.useState(void 0);
1090
1171
  const [hoveredGroupKey, setHoveredGroupKey] = reactExports.useState(void 0);
1091
1172
  const onSelectGroup = reactExports.useCallback((groupKey) => {
@@ -1301,7 +1382,7 @@ function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = fals
1301
1382
  void (onLoadMoreEvents == null ? void 0 : onLoadMoreEvents());
1302
1383
  }, itemContent: (index) => {
1303
1384
  const ev = sortedEvents[index];
1304
- return jsxRuntimeExports.jsx(EventRow$1, { event: ev, index, isFirst: index === 0, isLast: index === sortedEvents.length - 1, isExpanded: expandedEventIds.has(ev.eventId), onToggleExpand: toggleEventExpanded, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData: eventDataCacheRef.current.get(ev.eventId) ?? null, onCacheEventData: cacheEventData, encryptionKey, onEncryptedDataDetected: handleEncryptedDataDetected, suppressGroupDimming: isExactSearchActive, showSeparateEventOccurrenceTimestamps });
1385
+ return jsxRuntimeExports.jsx(EventRow$1, { event: ev, index, isFirst: index === 0, isLast: index === sortedEvents.length - 1, isExpanded: expandedEventIds.has(ev.eventId), onToggleExpand: toggleEventExpanded, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData: eventDataCacheRef.current.get(ev.eventId) ?? null, onCacheEventData: cacheEventData, encryptionKey, onEncryptedDataDetected: handleEncryptedDataDetected, suppressGroupDimming: isExactSearchActive, isDuplicate: duplicateEventIds.has(ev.eventId), showSeparateEventOccurrenceTimestamps });
1305
1386
  }, style: { flex: 1, minHeight: 0 } }), jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 flex items-center h-10 border-t px-4 text-label-12", style: {
1306
1387
  borderColor: "var(--ds-gray-alpha-200)",
1307
1388
  color: "var(--ds-gray-900)",
@@ -1313,76 +1394,59 @@ function EventListView(props) {
1313
1394
  }
1314
1395
  function ConversationView({ messages }) {
1315
1396
  if (messages.length === 0) {
1316
- return jsxRuntimeExports.jsx("div", { className: "text-center py-8 text-[11px]", style: { color: "var(--ds-gray-600)" }, children: "No messages" });
1397
+ return jsxRuntimeExports.jsx("div", { className: "py-8 text-center text-[11px] text-gray-600", children: "No messages" });
1317
1398
  }
1318
1399
  return jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-3 p-3", children: messages.map((message, index) => jsxRuntimeExports.jsx(MessageBubble, { message }, index)) });
1319
1400
  }
1320
1401
  function MessageBubble({ message }) {
1321
1402
  const role = message.role;
1322
1403
  const parts = parseContent(message.content);
1323
- const style = getRoleStyle(role);
1324
- return jsxRuntimeExports.jsxs("div", { className: "rounded-md border text-[11px]", style: {
1325
- backgroundColor: style.bg,
1326
- borderColor: style.border
1327
- }, children: [jsxRuntimeExports.jsx("div", { className: "px-2.5 py-1 border-b text-[10px] font-medium uppercase tracking-wide", style: {
1328
- borderColor: style.border,
1329
- color: style.label
1330
- }, children: role }), jsxRuntimeExports.jsx("div", { className: "px-2.5 py-2 space-y-2", children: parts.map((part, i) => jsxRuntimeExports.jsx(ContentPart, { part, role }, i)) })] });
1404
+ const roleClasses = getRoleClasses(role);
1405
+ return jsxRuntimeExports.jsxs("div", { className: `rounded-md border text-[11px] ${roleClasses.bubble}`, children: [jsxRuntimeExports.jsx("div", { className: `border-b px-2.5 py-1 font-medium text-[10px] uppercase tracking-wide ${roleClasses.label}`, children: role }), jsxRuntimeExports.jsx("div", { className: "px-2.5 py-2 space-y-2", children: parts.map((part, i) => jsxRuntimeExports.jsx(ContentPart, { part, role }, i)) })] });
1331
1406
  }
1332
1407
  function ContentPart({ part, role }) {
1333
1408
  if (part.type === "text") {
1334
1409
  if (!part.text)
1335
1410
  return null;
1336
1411
  if (role === "assistant") {
1337
- return jsxRuntimeExports.jsx("div", { className: "prose prose-sm max-w-none text-[11px] [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", style: { color: "var(--ds-gray-1000)" }, children: jsxRuntimeExports.jsx(_r, { children: part.text }) });
1412
+ return jsxRuntimeExports.jsx("div", { className: "prose prose-sm max-w-none text-[11px] text-gray-1000 [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", children: jsxRuntimeExports.jsx(_r, { children: part.text }) });
1338
1413
  }
1339
- return jsxRuntimeExports.jsx("div", { className: "whitespace-pre-wrap break-words", style: { color: "var(--ds-gray-1000)" }, children: part.text });
1414
+ return jsxRuntimeExports.jsx("div", { className: "whitespace-pre-wrap break-words text-gray-1000", children: part.text });
1340
1415
  }
1341
1416
  if (part.type === "tool-call") {
1342
- return jsxRuntimeExports.jsxs("div", { className: "rounded border px-2 py-1.5", style: {
1343
- backgroundColor: "var(--ds-purple-100)",
1344
- borderColor: "var(--ds-purple-300)"
1345
- }, children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-medium", children: [jsxRuntimeExports.jsx("span", { children: "🔧" }), jsxRuntimeExports.jsx("span", { style: { color: "var(--ds-purple-900)" }, children: part.toolName })] }), part.input != null && jsxRuntimeExports.jsx("div", { className: "mt-1.5 overflow-x-auto p-1.5 rounded", style: { backgroundColor: "var(--ds-gray-100)" }, children: typeof part.input === "string" ? jsxRuntimeExports.jsx("pre", { className: "text-[10px]", style: { color: "var(--ds-gray-800)" }, children: part.input }) : jsxRuntimeExports.jsx(DataInspector, { data: part.input }) })] });
1417
+ return jsxRuntimeExports.jsxs("div", { className: "rounded border border-purple-300 bg-purple-100 px-2 py-1.5", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-medium", children: [jsxRuntimeExports.jsx("span", { children: "🔧" }), jsxRuntimeExports.jsx("span", { className: "text-purple-900", children: part.toolName })] }), part.input != null && jsxRuntimeExports.jsx("div", { className: "mt-1.5 overflow-x-auto rounded bg-gray-100 p-1.5", children: typeof part.input === "string" ? jsxRuntimeExports.jsx("pre", { className: "text-[10px] text-gray-800", children: part.input }) : jsxRuntimeExports.jsx(DataInspector, { data: part.input }) })] });
1346
1418
  }
1347
1419
  if (part.type === "tool-result") {
1348
- return jsxRuntimeExports.jsxs("div", { className: "rounded border px-2 py-1.5", style: {
1349
- backgroundColor: "var(--ds-green-100)",
1350
- borderColor: "var(--ds-green-300)"
1351
- }, children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-medium", children: [jsxRuntimeExports.jsx("span", { children: "✓" }), jsxRuntimeExports.jsxs("span", { style: { color: "var(--ds-green-900)" }, children: [part.toolName, " result"] })] }), part.output != null && jsxRuntimeExports.jsx("div", { className: "mt-1.5 overflow-x-auto max-h-[200px] overflow-y-auto p-1.5 rounded", style: { backgroundColor: "var(--ds-gray-100)" }, children: typeof part.output === "string" ? jsxRuntimeExports.jsx("pre", { className: "text-[10px]", style: { color: "var(--ds-gray-800)" }, children: part.output }) : jsxRuntimeExports.jsx(DataInspector, { data: part.output, expandLevel: 1 }) })] });
1420
+ return jsxRuntimeExports.jsxs("div", { className: "rounded border border-green-300 bg-green-100 px-2 py-1.5", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-medium", children: [jsxRuntimeExports.jsx("span", { children: "✓" }), jsxRuntimeExports.jsxs("span", { className: "text-green-900", children: [part.toolName, " result"] })] }), part.output != null && jsxRuntimeExports.jsx("div", { className: "mt-1.5 max-h-[200px] overflow-x-auto overflow-y-auto rounded bg-gray-100 p-1.5", children: typeof part.output === "string" ? jsxRuntimeExports.jsx("pre", { className: "text-[10px] text-gray-800", children: part.output }) : jsxRuntimeExports.jsx(DataInspector, { data: part.output, expandLevel: 1 }) })] });
1352
1421
  }
1353
1422
  return null;
1354
1423
  }
1355
- function getRoleStyle(role) {
1424
+ function getRoleClasses(role) {
1356
1425
  switch (role) {
1357
1426
  case "user":
1358
1427
  return {
1359
- bg: "var(--ds-blue-100)",
1360
- border: "var(--ds-blue-300)",
1361
- label: "var(--ds-blue-700)"
1428
+ bubble: "border-blue-300 bg-blue-100",
1429
+ label: "border-blue-300 text-blue-700"
1362
1430
  };
1363
1431
  case "assistant":
1364
1432
  return {
1365
- bg: "var(--ds-gray-100)",
1366
- border: "var(--ds-gray-300)",
1367
- label: "var(--ds-gray-700)"
1433
+ bubble: "border-gray-300 bg-gray-100",
1434
+ label: "border-gray-300 text-gray-700"
1368
1435
  };
1369
1436
  case "system":
1370
1437
  return {
1371
- bg: "var(--ds-amber-100)",
1372
- border: "var(--ds-amber-300)",
1373
- label: "var(--ds-amber-700)"
1438
+ bubble: "border-amber-300 bg-amber-100",
1439
+ label: "border-amber-300 text-amber-700"
1374
1440
  };
1375
1441
  case "tool":
1376
1442
  return {
1377
- bg: "var(--ds-green-50)",
1378
- border: "var(--ds-green-300)",
1379
- label: "var(--ds-green-700)"
1443
+ bubble: "border-green-300 bg-green-100",
1444
+ label: "border-green-300 text-green-700"
1380
1445
  };
1381
1446
  default:
1382
1447
  return {
1383
- bg: "var(--ds-gray-100)",
1384
- border: "var(--ds-gray-300)",
1385
- label: "var(--ds-gray-700)"
1448
+ bubble: "border-gray-300 bg-gray-100",
1449
+ label: "border-gray-300 text-gray-700"
1386
1450
  };
1387
1451
  }
1388
1452
  }
@@ -1808,9 +1872,13 @@ function cascadeSpans(runSpan, spans) {
1808
1872
  };
1809
1873
  });
1810
1874
  }
1811
- function buildTrace(run, events, now) {
1812
- const groupedEvents = groupEventsByCorrelation(events);
1813
- const latestKnownTime = computeLatestKnownTime(events, run);
1875
+ function buildTrace(run, events, now, { isCompleteHistory = false } = {}) {
1876
+ const duplicateEventIds = findDuplicateEventIds(events, {
1877
+ isCompleteHistory
1878
+ });
1879
+ const actedOnEvents = duplicateEventIds.size === 0 ? events : events.filter((event) => !duplicateEventIds.has(event.eventId));
1880
+ const groupedEvents = groupEventsByCorrelation(actedOnEvents);
1881
+ const latestKnownTime = computeLatestKnownTime(actedOnEvents, run);
1814
1882
  const { runSpan, spans } = buildSpans(run, groupedEvents, now, latestKnownTime);
1815
1883
  const sortedCascadingSpans = cascadeSpans(runSpan, spans);
1816
1884
  const traceStartMs = otelTimeToMs(runSpan.startTime);
@@ -1827,34 +1895,72 @@ function buildTrace(run, events, now) {
1827
1895
  }
1828
1896
  }
1829
1897
  ],
1830
- knownDurationMs: Math.max(0, knownDurationMs)
1898
+ knownDurationMs: Math.max(0, knownDurationMs),
1899
+ duplicateEventIds
1831
1900
  };
1832
1901
  }
1833
- const GUTTER_PX = 1;
1834
- const MIN_PX = 50;
1835
- const DEFAULT_START_PX = 340;
1836
- function paneColTemplate(startPx) {
1837
- return `${startPx}px ${GUTTER_PX}px minmax(${MIN_PX}px, 1fr)`;
1838
- }
1839
- const COL_TEMPLATE = paneColTemplate(DEFAULT_START_PX);
1840
1902
  const ROWS = [
1841
- { id: "r0", name: 62, off: 0, bar: 72 },
1842
- { id: "r1", name: 78, off: 6, bar: 48 },
1843
- { id: "r2", name: 50, off: 10, bar: 55 },
1844
- { id: "r3", name: 84, off: 18, bar: 30 },
1845
- { id: "r4", name: 45, off: 18, bar: 42 },
1846
- { id: "r5", name: 66, off: 34, bar: 38 },
1847
- { id: "r6", name: 55, off: 41, bar: 25 },
1848
- { id: "r7", name: 40, off: 50, bar: 30 }
1903
+ {
1904
+ id: "r0",
1905
+ nameClassName: "w-[62%]",
1906
+ offsetClassName: "left-0",
1907
+ barClassName: "w-[72%]",
1908
+ topClassName: "top-0"
1909
+ },
1910
+ {
1911
+ id: "r1",
1912
+ nameClassName: "w-[78%]",
1913
+ offsetClassName: "left-[6%]",
1914
+ barClassName: "w-[48%]",
1915
+ topClassName: "top-[3.5px]"
1916
+ },
1917
+ {
1918
+ id: "r2",
1919
+ nameClassName: "w-1/2",
1920
+ offsetClassName: "left-[10%]",
1921
+ barClassName: "w-[55%]",
1922
+ topClassName: "top-[7px]"
1923
+ },
1924
+ {
1925
+ id: "r3",
1926
+ nameClassName: "w-[84%]",
1927
+ offsetClassName: "left-[18%]",
1928
+ barClassName: "w-[30%]",
1929
+ topClassName: "top-[10.5px]"
1930
+ },
1931
+ {
1932
+ id: "r4",
1933
+ nameClassName: "w-[45%]",
1934
+ offsetClassName: "left-[18%]",
1935
+ barClassName: "w-[42%]",
1936
+ topClassName: "top-[14px]"
1937
+ },
1938
+ {
1939
+ id: "r5",
1940
+ nameClassName: "w-[66%]",
1941
+ offsetClassName: "left-[34%]",
1942
+ barClassName: "w-[38%]",
1943
+ topClassName: "top-[17.5px]"
1944
+ },
1945
+ {
1946
+ id: "r6",
1947
+ nameClassName: "w-[55%]",
1948
+ offsetClassName: "left-[41%]",
1949
+ barClassName: "w-1/4",
1950
+ topClassName: "top-[21px]"
1951
+ },
1952
+ {
1953
+ id: "r7",
1954
+ nameClassName: "w-2/5",
1955
+ offsetClassName: "left-1/2",
1956
+ barClassName: "w-[30%]",
1957
+ topClassName: "top-[24.5px]"
1958
+ }
1849
1959
  ];
1850
1960
  const HEADER_MARKERS = ["m0", "m1", "m2", "m3"];
1851
1961
  const HeaderDivider = () => jsxRuntimeExports.jsx("div", { className: "flex justify-center", children: jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }) });
1852
1962
  function TraceViewerSkeleton() {
1853
- return jsxRuntimeExports.jsxs("output", { "aria-busy": "true", "aria-label": "Loading trace", className: "flex flex-col w-full h-full min-h-0 bg-background-100", children: [jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Loading trace…" }), jsxRuntimeExports.jsx("div", { className: "relative h-10 min-h-10 shrink-0 border-b border-gray-alpha-400", children: jsxRuntimeExports.jsx("div", { className: "absolute inset-x-4 top-[6px]", children: ROWS.map((row, index) => jsxRuntimeExports.jsx(Skeleton, { className: "absolute h-[3px] rounded-full", style: {
1854
- left: `${row.off}%`,
1855
- width: `${row.bar}%`,
1856
- top: index * 3.5
1857
- } }, row.id)) }) }), jsxRuntimeExports.jsxs("div", { className: "shrink-0 grid", style: { gridTemplateColumns: COL_TEMPLATE }, children: [jsxRuntimeExports.jsxs("div", { className: "h-10 min-h-10 flex items-center border-b border-gray-alpha-400 pl-4 pr-2 gap-1.5", children: [jsxRuntimeExports.jsx(Skeleton, { className: "w-3.5 h-3.5 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5 w-40" })] }), jsxRuntimeExports.jsx(HeaderDivider, {}), jsxRuntimeExports.jsx("div", { className: "h-10 min-h-10 flex items-end border-b border-gray-alpha-400 px-4 pb-1 gap-2", children: jsxRuntimeExports.jsx("div", { className: "relative flex-1 flex items-end justify-between", children: HEADER_MARKERS.map((id) => jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5 w-9" }, id)) }) })] }), jsxRuntimeExports.jsxs("div", { className: "grid flex-1 min-h-0 overflow-hidden", style: { gridTemplateColumns: COL_TEMPLATE }, children: [jsxRuntimeExports.jsx("div", { className: "block overflow-visible", children: jsxRuntimeExports.jsx("ul", { className: "block divide-y divide-gray-alpha-400 border-b border-gray-alpha-400", children: ROWS.map((row) => jsxRuntimeExports.jsxs("li", { className: "h-10 flex items-center pl-4 pr-2", children: [jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [jsxRuntimeExports.jsx(Skeleton, { className: "w-4 h-4 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5", style: { width: `${row.name}%` } })] }), jsxRuntimeExports.jsx(Skeleton, { className: "ml-2 h-3.5 w-10 shrink-0" })] }, row.id)) }) }), jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }), jsxRuntimeExports.jsx("div", { className: "relative min-h-0", children: ROWS.map((row) => jsxRuntimeExports.jsx("div", { className: "relative h-10", children: jsxRuntimeExports.jsx("div", { className: "absolute inset-x-4 inset-y-0", children: jsxRuntimeExports.jsx(Skeleton, { className: "absolute top-1/2 -translate-y-1/2 h-6 rounded-[0.25rem]", style: { left: `${row.off}%`, width: `${row.bar}%` } }) }) }, row.id)) })] })] });
1963
+ return jsxRuntimeExports.jsxs("output", { "aria-busy": "true", "aria-label": "Loading trace", className: "flex flex-col w-full h-full min-h-0 bg-background-100", children: [jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Loading trace…" }), jsxRuntimeExports.jsx("div", { className: "relative h-10 min-h-10 shrink-0 border-b border-gray-alpha-400", children: jsxRuntimeExports.jsx("div", { className: "absolute inset-x-4 top-[6px]", children: ROWS.map((row) => jsxRuntimeExports.jsx(Skeleton, { className: `absolute h-[3px] rounded-full ${row.offsetClassName} ${row.barClassName} ${row.topClassName}` }, row.id)) }) }), jsxRuntimeExports.jsxs("div", { className: "grid shrink-0 grid-cols-[340px_1px_minmax(50px,1fr)]", children: [jsxRuntimeExports.jsxs("div", { className: "h-10 min-h-10 flex items-center border-b border-gray-alpha-400 pl-4 pr-2 gap-1.5", children: [jsxRuntimeExports.jsx(Skeleton, { className: "w-3.5 h-3.5 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5 w-40" })] }), jsxRuntimeExports.jsx(HeaderDivider, {}), jsxRuntimeExports.jsx("div", { className: "h-10 min-h-10 flex items-end border-b border-gray-alpha-400 px-4 pb-1 gap-2", children: jsxRuntimeExports.jsx("div", { className: "relative flex-1 flex items-end justify-between", children: HEADER_MARKERS.map((id) => jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5 w-9" }, id)) }) })] }), jsxRuntimeExports.jsxs("div", { className: "grid min-h-0 flex-1 grid-cols-[340px_1px_minmax(50px,1fr)] overflow-hidden", children: [jsxRuntimeExports.jsx("div", { className: "block overflow-visible", children: jsxRuntimeExports.jsx("ul", { className: "block divide-y divide-gray-alpha-400 border-b border-gray-alpha-400", children: ROWS.map((row) => jsxRuntimeExports.jsxs("li", { className: "h-10 flex items-center pl-4 pr-2", children: [jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [jsxRuntimeExports.jsx(Skeleton, { className: "w-4 h-4 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton, { className: `h-3.5 ${row.nameClassName}` })] }), jsxRuntimeExports.jsx(Skeleton, { className: "ml-2 h-3.5 w-10 shrink-0" })] }, row.id)) }) }), jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }), jsxRuntimeExports.jsx("div", { className: "relative min-h-0", children: ROWS.map((row) => jsxRuntimeExports.jsx("div", { className: "relative h-10", children: jsxRuntimeExports.jsx("div", { className: "absolute inset-x-4 inset-y-0", children: jsxRuntimeExports.jsx(Skeleton, { className: `absolute top-1/2 h-6 -translate-y-1/2 rounded-[0.25rem] ${row.offsetClassName} ${row.barClassName}` }) }) }, row.id)) })] })] });
1858
1964
  }
1859
1965
  function useIntersectionObserver(elementRef, { threshold = 0, rootRef, rootMargin = "0%", freezeOnceVisible = false } = {}) {
1860
1966
  const [entry, setEntry] = reactExports.useState();
@@ -2398,7 +2504,7 @@ const formatEventTimestamp = (date) => date.toLocaleString(void 0, {
2398
2504
  fractionalSecondDigits: 3,
2399
2505
  timeZoneName: "short"
2400
2506
  });
2401
- function EventItem({ event, onLoadEventData, encryptionKey, showSeparateEventOccurrenceTimestamps = false }) {
2507
+ function EventItem({ event, onLoadEventData, encryptionKey, showSeparateEventOccurrenceTimestamps = false, isDuplicate = false }) {
2402
2508
  const [loadedData, setLoadedData] = reactExports.useState(null);
2403
2509
  const [isLoading, setIsLoading] = reactExports.useState(false);
2404
2510
  const [loadError, setLoadError] = reactExports.useState(null);
@@ -2450,7 +2556,7 @@ function EventItem({ event, onLoadEventData, encryptionKey, showSeparateEventOcc
2450
2556
  return jsxRuntimeExports.jsxs(CollapsibleRoot, { variant: "card", onOpenChange: canHaveData ? (open) => {
2451
2557
  if (open)
2452
2558
  handleExpand();
2453
- } : void 0, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { className: "px-3 py-2", children: jsxRuntimeExports.jsxs("div", { className: "flex w-full items-center justify-between gap-3", children: [jsxRuntimeExports.jsx("span", { className: "text-gray-1000 text-label-12 font-mono", children: event.eventType }), jsxRuntimeExports.jsx("span", { className: "shrink-0 text-label-13 text-gray-900", children: displayedCreatedAtTime })] }) }), jsxRuntimeExports.jsxs(CollapsibleContent, { children: [jsxRuntimeExports.jsxs("div", { className: "flex flex-col bg-background-200 [&:has(+_*)]:border-b [&:has(+_*)]:border-gray-alpha-400", children: [showSeparateEventOccurrenceTimestamps && occurredAt && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Occurred" }), jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: formatEventTimestamp(occurredAt) }) })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Event ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.eventId })] }), event.correlationId && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Correlation ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.correlationId })] })] }), isLoading && jsxRuntimeExports.jsxs("div", { className: "p-3", children: [jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-[35%]" }), jsxRuntimeExports.jsx(Skeleton, { className: "mt-2 h-4 w-[90%]" }), jsxRuntimeExports.jsx(Skeleton, { className: "mt-2 h-4 w-[75%]" })] }), loadError && jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load event data", details: loadError, className: "mt-2" }), displayPayload != null && jsxRuntimeExports.jsx("div", { className: "[&>div]:border-none [&>div]:rounded-none", children: jsxRuntimeExports.jsx(EventDataBlock, { eventType: event.eventType, data: displayPayload }) })] })] });
2559
+ } : void 0, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { className: "px-3 py-2", children: jsxRuntimeExports.jsxs("div", { className: "flex w-full items-center justify-between gap-3", children: [jsxRuntimeExports.jsx(DuplicateEventTooltip, { isDuplicate, children: jsxRuntimeExports.jsx("span", { className: `text-label-12 font-mono ${isDuplicate ? "text-gray-700" : "text-gray-1000"}`, children: event.eventType }) }), jsxRuntimeExports.jsx("span", { className: "shrink-0 text-label-13 text-gray-900", children: displayedCreatedAtTime })] }) }), jsxRuntimeExports.jsxs(CollapsibleContent, { children: [jsxRuntimeExports.jsxs("div", { className: "flex flex-col bg-background-200 [&:has(+_*)]:border-b [&:has(+_*)]:border-gray-alpha-400", children: [showSeparateEventOccurrenceTimestamps && occurredAt && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Occurred" }), jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: formatEventTimestamp(occurredAt) }) })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Event ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.eventId })] }), event.correlationId && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Correlation ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.correlationId })] })] }), isLoading && jsxRuntimeExports.jsxs("div", { className: "p-3", children: [jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-[35%]" }), jsxRuntimeExports.jsx(Skeleton, { className: "mt-2 h-4 w-[90%]" }), jsxRuntimeExports.jsx(Skeleton, { className: "mt-2 h-4 w-[75%]" })] }), loadError && jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load event data", details: loadError, className: "mt-2" }), displayPayload != null && jsxRuntimeExports.jsx("div", { className: "[&>div]:border-none [&>div]:rounded-none", children: jsxRuntimeExports.jsx(EventDataBlock, { eventType: event.eventType, data: displayPayload }) })] })] });
2454
2560
  }
2455
2561
  function hasOnlyExpiredFields(data, eventType) {
2456
2562
  if (data === null || typeof data !== "object" || Array.isArray(data)) {
@@ -2486,13 +2592,13 @@ function EventDataBlock({ eventType, data }) {
2486
2592
  }
2487
2593
  return jsxRuntimeExports.jsx(CopyableDataBlock, { data });
2488
2594
  }
2489
- function EventsList({ events, isLoading = false, error, onLoadEventData, onStreamClick, onRunClick, encryptionKey, showSeparateEventOccurrenceTimestamps = false }) {
2595
+ function EventsList({ events, isLoading = false, error, onLoadEventData, onStreamClick, onRunClick, encryptionKey, showSeparateEventOccurrenceTimestamps = false, duplicateEventIds }) {
2490
2596
  const sortedEvents = reactExports.useMemo(() => [...events].sort((a, b) => getEffectiveEventDate(a).getTime() - getEffectiveEventDate(b).getTime()), [events]);
2491
2597
  const hasEvents = sortedEvents.length > 0 && !error;
2492
2598
  if (!hasEvents && !isLoading) {
2493
2599
  return jsxRuntimeExports.jsx(Collapsible, { label: "Events", disabled: true });
2494
2600
  }
2495
- return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsxs(CollapsibleRoot, { defaultOpen: true, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { children: "Events" }), jsxRuntimeExports.jsx(CollapsibleContent, { className: "mb-0", children: isLoading ? jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: [0, 1, 2].map((i) => jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3 bg-background-200 px-4 py-2", children: [jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-32 rounded" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-16 rounded" })] }, i)) }) : jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: sortedEvents.map((event) => jsxRuntimeExports.jsx(EventItem, { event, onLoadEventData, encryptionKey, showSeparateEventOccurrenceTimestamps }, event.eventId)) }) })] }) }) });
2601
+ return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsxs(CollapsibleRoot, { defaultOpen: true, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { children: "Events" }), jsxRuntimeExports.jsx(CollapsibleContent, { className: "mb-0", children: isLoading ? jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: [0, 1, 2].map((i) => jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3 bg-background-200 px-4 py-2", children: [jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-32 rounded" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-16 rounded" })] }, i)) }) : jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: sortedEvents.map((event) => jsxRuntimeExports.jsx(EventItem, { event, onLoadEventData, encryptionKey, showSeparateEventOccurrenceTimestamps, isDuplicate: duplicateEventIds == null ? void 0 : duplicateEventIds.has(event.eventId) }, event.eventId)) }) })] }) }) });
2496
2602
  }
2497
2603
  const hasField = (value, key) => key in value;
2498
2604
  const RESOURCES_WITH_FETCHED_DETAIL = /* @__PURE__ */ new Set(["run", "step", "sleep"]);
@@ -2812,7 +2918,7 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, fetchSpanDetail, on
2812
2918
  }, children: [jsxRuntimeExports.jsx(Zap, { className: "h-4 w-4" }), stoppingSleep ? "Waking up..." : "Wake Up Sleep"] }), resource === "hook" && canResolveHook && jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => setShowResolveHookModal(true), disabled: resolvingHook, className: clsx("flex items-center justify-center gap-2 rounded-md px-3 py-2 text-button-14", "disabled:opacity-50 disabled:cursor-not-allowed transition-colors", resolvingHook ? "opacity-50 cursor-not-allowed" : "cursor-pointer"), style: {
2813
2919
  background: "var(--ds-gray-1000)",
2814
2920
  color: "var(--ds-background-100)"
2815
- }, children: [jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), "Resolve Hook"] })] })] }), jsxRuntimeExports.jsx(AttributePanel, { data: displayData, moduleSpecifier, moduleSourceUrl, expiredAt: run.expiredAt, isLoading: loading, error: error ?? void 0, onStreamClick, onRunClick, onDecrypt, isDecrypting, resource }), rawEvents && jsxRuntimeExports.jsx(EventsList, { events: rawEvents, onLoadEventData, onStreamClick, onRunClick, encryptionKey, showSeparateEventOccurrenceTimestamps })] }) }), jsxRuntimeExports.jsx(ResolveHookModal, { isOpen: showResolveHookModal, onClose: () => setShowResolveHookModal(false), onSubmit: handleResolveHook, isSubmitting: resolvingHook })] });
2921
+ }, children: [jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), "Resolve Hook"] })] })] }), jsxRuntimeExports.jsx(AttributePanel, { data: displayData, moduleSpecifier, moduleSourceUrl, expiredAt: run.expiredAt, isLoading: loading, error: error ?? void 0, onStreamClick, onRunClick, onDecrypt, isDecrypting, resource }), rawEvents && jsxRuntimeExports.jsx(EventsList, { events: rawEvents, onLoadEventData, onStreamClick, onRunClick, encryptionKey, showSeparateEventOccurrenceTimestamps, duplicateEventIds: selectedSpan == null ? void 0 : selectedSpan.duplicateEventIds })] }) }), jsxRuntimeExports.jsx(ResolveHookModal, { isOpen: showResolveHookModal, onClose: () => setShowResolveHookModal(false), onSubmit: handleResolveHook, isSubmitting: resolvingHook })] });
2816
2922
  }
2817
2923
  const PANEL_MIN_WIDTH = 280;
2818
2924
  const PANEL_HARD_MAX_WIDTH = 1300;
@@ -2990,7 +3096,8 @@ function useSelectedSpanInfo() {
2990
3096
  data: (_b = activeSpan.attributes) == null ? void 0 : _b.data,
2991
3097
  resource,
2992
3098
  spanId: activeSpan.spanId,
2993
- rawEvents
3099
+ rawEvents,
3100
+ duplicateEventIds: sidebar.duplicateEventIds
2994
3101
  };
2995
3102
  }, [activeSpan, sidebar]);
2996
3103
  }
@@ -3066,16 +3173,16 @@ function TraceDetailPanel({ containerRef, onNavigateToSpan, onClose }) {
3066
3173
  return jsxRuntimeExports.jsxs("aside", { ref: asideRef, id: DETAIL_PANEL_ID, className: "relative flex flex-col h-full max-h-full shrink-0 bg-background-100 border-l border-gray-alpha-400", style: { width: panelWidth }, children: [jsxRuntimeExports.jsx(DraggableBorder, { element: asideRef, position: "left", onWidthChange: handleResize, onReset: () => handleResize(PANEL_DEFAULT_WIDTH), "aria-label": "Resize span details panel", "aria-controls": DETAIL_PANEL_ID, "aria-valuemin": PANEL_MIN_WIDTH, "aria-valuemax": panelMaxWidth, "aria-valuenow": Math.min(Math.max(Math.round(panelWidth), PANEL_MIN_WIDTH), panelMaxWidth) }), jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 shrink-0 px-4 py-[7.5px]", children: [jsxRuntimeExports.jsx("span", { className: "text-label-14 font-medium text-gray-1000 truncate block", children: selectedSpanName }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0.5 shrink-0", children: [jsxRuntimeExports.jsxs(Tooltip, { children: [jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: jsxRuntimeExports.jsx(IconButton, { "aria-label": "Navigate up", "aria-keyshortcuts": "K", onClick: handleSelectPrev, disabled: !prevSpanId, children: jsxRuntimeExports.jsx(ChevronUp, { className: "w-4 h-4" }) }) }), prevSpanId ? jsxRuntimeExports.jsxs(TooltipContent, { children: ["Navigate up", jsxRuntimeExports.jsx(Kbd, { children: "K" })] }) : null] }), jsxRuntimeExports.jsxs(Tooltip, { children: [jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: jsxRuntimeExports.jsx(IconButton, { "aria-label": "Navigate down", "aria-keyshortcuts": "J", onClick: handleSelectNext, disabled: !nextSpanId, children: jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4" }) }) }), nextSpanId ? jsxRuntimeExports.jsxs(TooltipContent, { children: ["Navigate down", jsxRuntimeExports.jsx(Kbd, { children: "J" })] }) : null] }), jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "w-px h-4 bg-gray-alpha-400 mx-1" }), jsxRuntimeExports.jsx(IconButton, { "aria-label": "Close span details", "aria-keyshortcuts": "Escape", onClick: onClose, children: jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) })] })] }), jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto", children: jsxRuntimeExports.jsx(ErrorBoundary, { children: jsxRuntimeExports.jsx(EntityDetailPanel, { run: sidebar.run, onStreamClick: sidebar.onStreamClick, onRunClick: sidebar.onRunClick, fetchSpanDetail: sidebar.fetchSpanDetail, onWakeUpSleep: sidebar.onWakeUpSleep, onLoadEventData: sidebar.onLoadEventData, onResolveHook: sidebar.onResolveHook, encryptionKey: sidebar.encryptionKey, onDecrypt: sidebar.onDecrypt, isDecrypting: sidebar.isDecrypting, selectedSpan, showSeparateEventOccurrenceTimestamps: sidebar.showSeparateEventOccurrenceTimestamps, getModuleSourceUrl: sidebar.getModuleSourceUrl }) }) })] });
3067
3174
  }
3068
3175
  const WorkflowIcon = () => {
3069
- return jsxRuntimeExports.jsx("svg", { "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", style: { color: "currentColor" }, viewBox: "0 0 16 16", width: "16", children: jsxRuntimeExports.jsx("path", { d: "M5.75 7L6.4209 7.33594L4.85254 10.4717C5.38789 10.771 5.75 11.3431 5.75 12V14C5.75 14.9665 4.96648 15.75 4 15.75H2C1.03352 15.75 0.25 14.9665 0.25 14V12C0.25 11.0335 1.03352 10.25 2 10.25H3.28711L5.0791 6.66504L5.75 7ZM14 10.25C14.9665 10.25 15.75 11.0335 15.75 12V14C15.75 14.9665 14.9665 15.75 14 15.75H12C11.1185 15.75 10.3909 15.098 10.2695 14.25H7V12.75H10.25V12C10.25 11.0335 11.0335 10.25 12 10.25H14ZM2 11.75C1.86192 11.75 1.75 11.8619 1.75 12V14C1.75 14.1381 1.86192 14.25 2 14.25H4C4.13808 14.25 4.25 14.1381 4.25 14V12C4.25 11.8619 4.13808 11.75 4 11.75H2ZM12 11.75C11.8619 11.75 11.75 11.8619 11.75 12V14C11.75 14.1381 11.8619 14.25 12 14.25H14C14.1381 14.25 14.25 14.1381 14.25 14V12C14.25 11.8619 14.1381 11.75 14 11.75H12ZM9 0.25C9.96649 0.25 10.75 1.03351 10.75 2V4C10.75 4.44642 10.5808 4.85197 10.3057 5.16113L12.2041 8.6416L10.8877 9.36035L8.91895 5.75H7C6.03351 5.75 5.25 4.96649 5.25 4V2C5.25 1.03351 6.03351 0.25 7 0.25H9ZM7 1.75C6.86193 1.75 6.75 1.86193 6.75 2V4C6.75 4.13807 6.86193 4.25 7 4.25H9C9.13807 4.25 9.25 4.13807 9.25 4V2C9.25 1.86193 9.13807 1.75 9 1.75H7Z", fill: "currentColor" }) });
3176
+ return jsxRuntimeExports.jsx("svg", { "aria-hidden": "true", "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", children: jsxRuntimeExports.jsx("path", { d: "M5.75 7L6.4209 7.33594L4.85254 10.4717C5.38789 10.771 5.75 11.3431 5.75 12V14C5.75 14.9665 4.96648 15.75 4 15.75H2C1.03352 15.75 0.25 14.9665 0.25 14V12C0.25 11.0335 1.03352 10.25 2 10.25H3.28711L5.0791 6.66504L5.75 7ZM14 10.25C14.9665 10.25 15.75 11.0335 15.75 12V14C15.75 14.9665 14.9665 15.75 14 15.75H12C11.1185 15.75 10.3909 15.098 10.2695 14.25H7V12.75H10.25V12C10.25 11.0335 11.0335 10.25 12 10.25H14ZM2 11.75C1.86192 11.75 1.75 11.8619 1.75 12V14C1.75 14.1381 1.86192 14.25 2 14.25H4C4.13808 14.25 4.25 14.1381 4.25 14V12C4.25 11.8619 4.13808 11.75 4 11.75H2ZM12 11.75C11.8619 11.75 11.75 11.8619 11.75 12V14C11.75 14.1381 11.8619 14.25 12 14.25H14C14.1381 14.25 14.25 14.1381 14.25 14V12C14.25 11.8619 14.1381 11.75 14 11.75H12ZM9 0.25C9.96649 0.25 10.75 1.03351 10.75 2V4C10.75 4.44642 10.5808 4.85197 10.3057 5.16113L12.2041 8.6416L10.8877 9.36035L8.91895 5.75H7C6.03351 5.75 5.25 4.96649 5.25 4V2C5.25 1.03351 6.03351 0.25 7 0.25H9ZM7 1.75C6.86193 1.75 6.75 1.86193 6.75 2V4C6.75 4.13807 6.86193 4.25 7 4.25H9C9.13807 4.25 9.25 4.13807 9.25 4V2C9.25 1.86193 9.13807 1.75 9 1.75H7Z", fill: "currentColor" }) });
3070
3177
  };
3071
3178
  const WebhookIcon = () => {
3072
- return jsxRuntimeExports.jsx("svg", { "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", style: { color: "currentColor" }, children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M5.8349 3.24994C5.14454 4.44567 5.55423 5.97464 6.74996 6.665L7.39465 7.03721L7.02726 7.68466L5.14599 11C5.21289 11.1531 5.25 11.3222 5.25 11.5C5.25 12.1904 4.69036 12.75 4 12.75C3.30964 12.75 2.75 12.1904 2.75 11.5C2.75 10.8634 3.22584 10.338 3.84123 10.26L5.38944 7.5316C3.95909 6.30274 3.55857 4.19264 4.53586 2.49994C5.64043 0.586765 8.08679 -0.0687357 9.99996 1.03583C11.836 2.09584 12.5137 4.39156 11.5892 6.26591L10.4949 4.33754C10.4418 3.53274 10.0009 2.76843 9.24996 2.33487C8.05423 1.64452 6.52525 2.0542 5.8349 3.24994ZM9.146 4.99996C9.21289 4.84686 9.25 4.67776 9.25 4.5C9.25 3.80964 8.69036 3.25 8 3.25C7.30964 3.25 6.75 3.80964 6.75 4.5C6.75 5.13659 7.22586 5.66203 7.84127 5.74002L9.72266 9.05556L10.0956 9.71274L10.75 9.33493C11.9457 8.64458 13.4747 9.05427 14.165 10.25C14.8554 11.4457 14.4457 12.9747 13.25 13.6651C12.5047 14.0953 11.63 14.0983 10.9096 13.75H8.69252C9.85895 15.4685 12.1727 16.0191 14 14.9641C15.9131 13.8595 16.5686 11.4132 15.4641 9.5C14.4886 7.81038 12.4665 7.10169 10.6895 7.71998L9.146 4.99996ZM13.25 11.5C13.25 12.1904 12.6904 12.75 12 12.75C11.591 12.75 11.228 12.5536 10.9999 12.25H7.9298C7.57875 14.1006 5.95279 15.5 4 15.5C1.79086 15.5 0 13.7091 0 11.5C0 9.40018 1.61801 7.67826 3.67529 7.51299L2.58098 9.44147C1.92792 9.89251 1.5 10.6463 1.5 11.5C1.5 12.8807 2.61929 14 4 14C5.38071 14 6.5 12.8807 6.5 11.5V10.75H7.25H10.9999C11.228 10.4464 11.591 10.25 12 10.25C12.6904 10.25 13.25 10.8096 13.25 11.5Z", fill: "currentColor" }) });
3179
+ return jsxRuntimeExports.jsx("svg", { "aria-hidden": "true", "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M5.8349 3.24994C5.14454 4.44567 5.55423 5.97464 6.74996 6.665L7.39465 7.03721L7.02726 7.68466L5.14599 11C5.21289 11.1531 5.25 11.3222 5.25 11.5C5.25 12.1904 4.69036 12.75 4 12.75C3.30964 12.75 2.75 12.1904 2.75 11.5C2.75 10.8634 3.22584 10.338 3.84123 10.26L5.38944 7.5316C3.95909 6.30274 3.55857 4.19264 4.53586 2.49994C5.64043 0.586765 8.08679 -0.0687357 9.99996 1.03583C11.836 2.09584 12.5137 4.39156 11.5892 6.26591L10.4949 4.33754C10.4418 3.53274 10.0009 2.76843 9.24996 2.33487C8.05423 1.64452 6.52525 2.0542 5.8349 3.24994ZM9.146 4.99996C9.21289 4.84686 9.25 4.67776 9.25 4.5C9.25 3.80964 8.69036 3.25 8 3.25C7.30964 3.25 6.75 3.80964 6.75 4.5C6.75 5.13659 7.22586 5.66203 7.84127 5.74002L9.72266 9.05556L10.0956 9.71274L10.75 9.33493C11.9457 8.64458 13.4747 9.05427 14.165 10.25C14.8554 11.4457 14.4457 12.9747 13.25 13.6651C12.5047 14.0953 11.63 14.0983 10.9096 13.75H8.69252C9.85895 15.4685 12.1727 16.0191 14 14.9641C15.9131 13.8595 16.5686 11.4132 15.4641 9.5C14.4886 7.81038 12.4665 7.10169 10.6895 7.71998L9.146 4.99996ZM13.25 11.5C13.25 12.1904 12.6904 12.75 12 12.75C11.591 12.75 11.228 12.5536 10.9999 12.25H7.9298C7.57875 14.1006 5.95279 15.5 4 15.5C1.79086 15.5 0 13.7091 0 11.5C0 9.40018 1.61801 7.67826 3.67529 7.51299L2.58098 9.44147C1.92792 9.89251 1.5 10.6463 1.5 11.5C1.5 12.8807 2.61929 14 4 14C5.38071 14 6.5 12.8807 6.5 11.5V10.75H7.25H10.9999C11.228 10.4464 11.591 10.25 12 10.25C12.6904 10.25 13.25 10.8096 13.25 11.5Z", fill: "currentColor" }) });
3073
3180
  };
3074
3181
  const SleepIcon = () => {
3075
- return jsxRuntimeExports.jsx("svg", { "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", style: { color: "currentColor" }, children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M7.25 1.25V2.03971C5.87928 2.18571 4.62678 2.72736 3.6089 3.54824L3.03033 2.96967L2.5 2.43934L1.43934 3.5L1.96967 4.03033L2.54824 4.6089C1.57979 5.80976 1 7.33717 1 9C1 12.866 4.13401 16 8 16C11.866 16 15 12.866 15 9C15 7.33717 14.4202 5.80976 13.4518 4.6089L14.0303 4.03033L14.5607 3.5L13.5 2.43934L12.9697 2.96967L12.3911 3.54824C11.3732 2.72736 10.1207 2.18571 8.75 2.03971V1.25H9.25H10V-0.25H9.25H8.75H7.25H6.75H6V1.25H6.75H7.25ZM2.5 9C2.5 5.96243 4.96243 3.5 8 3.5C11.0376 3.5 13.5 5.96243 13.5 9C13.5 12.0376 11.0376 14.5 8 14.5C4.96243 14.5 2.5 12.0376 2.5 9ZM8.75 6.75V6H7.25V6.75V9V9.75H8.75V9V6.75Z", fill: "currentColor" }) });
3182
+ return jsxRuntimeExports.jsx("svg", { "aria-hidden": "true", "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M7.25 1.25V2.03971C5.87928 2.18571 4.62678 2.72736 3.6089 3.54824L3.03033 2.96967L2.5 2.43934L1.43934 3.5L1.96967 4.03033L2.54824 4.6089C1.57979 5.80976 1 7.33717 1 9C1 12.866 4.13401 16 8 16C11.866 16 15 12.866 15 9C15 7.33717 14.4202 5.80976 13.4518 4.6089L14.0303 4.03033L14.5607 3.5L13.5 2.43934L12.9697 2.96967L12.3911 3.54824C11.3732 2.72736 10.1207 2.18571 8.75 2.03971V1.25H9.25H10V-0.25H9.25H8.75H7.25H6.75H6V1.25H6.75H7.25ZM2.5 9C2.5 5.96243 4.96243 3.5 8 3.5C11.0376 3.5 13.5 5.96243 13.5 9C13.5 12.0376 11.0376 14.5 8 14.5C4.96243 14.5 2.5 12.0376 2.5 9ZM8.75 6.75V6H7.25V6.75V9V9.75H8.75V9V6.75Z", fill: "currentColor" }) });
3076
3183
  };
3077
3184
  const StepForwardIcon = () => {
3078
- return jsxRuntimeExports.jsx("svg", { "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", style: { color: "currentColor" }, children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.21969 12.5303L4.75002 13.0607L5.81068 12L5.28035 11.4697L1.81068 7.99999L5.28035 4.53032L5.81068 3.99999L4.75002 2.93933L4.21969 3.46966L0.39647 7.29289C0.00594562 7.68341 0.00594562 8.31658 0.39647 8.7071L4.21969 12.5303ZM11.7804 12.5303L11.25 13.0607L10.1894 12L10.7197 11.4697L14.1894 7.99999L10.7197 4.53032L10.1894 3.99999L11.25 2.93933L11.7804 3.46966L15.6036 7.29289C15.9941 7.68341 15.9941 8.31658 15.6036 8.7071L11.7804 12.5303Z", fill: "currentColor" }) });
3185
+ return jsxRuntimeExports.jsx("svg", { "aria-hidden": "true", "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.21969 12.5303L4.75002 13.0607L5.81068 12L5.28035 11.4697L1.81068 7.99999L5.28035 4.53032L5.81068 3.99999L4.75002 2.93933L4.21969 3.46966L0.39647 7.29289C0.00594562 7.68341 0.00594562 8.31658 0.39647 8.7071L4.21969 12.5303ZM11.7804 12.5303L11.25 13.0607L10.1894 12L10.7197 11.4697L14.1894 7.99999L10.7197 4.53032L10.1894 3.99999L11.25 2.93933L11.7804 3.46966L15.6036 7.29289C15.9941 7.68341 15.9941 8.31658 15.6036 8.7071L11.7804 12.5303Z", fill: "currentColor" }) });
3079
3186
  };
3080
3187
  const eventStyles = {
3081
3188
  run: { icon: WorkflowIcon, className: "text-blue-900", label: "Workflow" },
@@ -3111,6 +3218,12 @@ const EventList = ({ spans, activeSpanId, searchResult, onSelectSpan }) => {
3111
3218
  paddingBottom: (spans.length - end) * ROW_HEIGHT_PX
3112
3219
  }, children: spans.slice(start, end).map((span) => jsxRuntimeExports.jsx(EventRow, { span, isSelected: span.spanId === activeSpanId, isDimmed: isSpanDimmedBySearch(span.spanId, searchResult), onSelectSpan }, span.spanId)) });
3113
3220
  };
3221
+ const GUTTER_PX = 1;
3222
+ const MIN_PX = 50;
3223
+ const DEFAULT_START_PX = 340;
3224
+ function paneColTemplate(startPx) {
3225
+ return `${startPx}px ${GUTTER_PX}px minmax(${MIN_PX}px, 1fr)`;
3226
+ }
3114
3227
  const SPLIT_PANE_START_ID = "trace-split-start";
3115
3228
  function SplitPane({ children, className, startHeader, endHeader, scrollContainerRef }) {
3116
3229
  const parts = reactExports.Children.toArray(children);
@@ -3494,12 +3607,15 @@ const TraceViewer = ({ run, events, sidebarData, onLoadMore, hasMore, isLoadingM
3494
3607
  if (!(run == null ? void 0 : run.runId)) {
3495
3608
  return void 0;
3496
3609
  }
3497
- return buildTrace(run, events, /* @__PURE__ */ new Date());
3498
- }, [run, events]);
3610
+ return buildTrace(run, events, /* @__PURE__ */ new Date(), {
3611
+ isCompleteHistory: !hasMore
3612
+ });
3613
+ }, [run, events, hasMore]);
3614
+ const sidebarValue = reactExports.useMemo(() => ({ ...sidebarData, duplicateEventIds: trace == null ? void 0 : trace.duplicateEventIds }), [sidebarData, trace]);
3499
3615
  if (!trace || loading && events.length === 0) {
3500
3616
  return jsxRuntimeExports.jsx(TraceViewerSkeleton, {});
3501
3617
  }
3502
- return jsxRuntimeExports.jsx(SidebarDataProvider, { value: sidebarData, children: jsxRuntimeExports.jsx("div", { className: "relative w-full h-full flex", children: jsxRuntimeExports.jsx(TraceViewer$1, { trace, onLoadMore, hasMore, isLoadingMore }) }) });
3618
+ return jsxRuntimeExports.jsx(SidebarDataProvider, { value: sidebarValue, children: jsxRuntimeExports.jsx("div", { className: "relative w-full h-full flex", children: jsxRuntimeExports.jsx(TraceViewer$1, { trace, onLoadMore, hasMore, isLoadingMore }) }) });
3503
3619
  };
3504
3620
  async function fetchResourceWithCorrelationId(env, resource, resourceId, options = {}) {
3505
3621
  const resolveData = options.resolveData ?? "all";