@agentmark-ai/ui-components 0.1.0 → 0.3.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.
package/dist/index.js CHANGED
@@ -212,7 +212,7 @@ var require_react_is_development = __commonJS({
212
212
  var ContextProvider = REACT_PROVIDER_TYPE;
213
213
  var Element = REACT_ELEMENT_TYPE;
214
214
  var ForwardRef2 = REACT_FORWARD_REF_TYPE;
215
- var Fragment4 = REACT_FRAGMENT_TYPE;
215
+ var Fragment5 = REACT_FRAGMENT_TYPE;
216
216
  var Lazy = REACT_LAZY_TYPE;
217
217
  var Memo2 = REACT_MEMO_TYPE;
218
218
  var Portal = REACT_PORTAL_TYPE;
@@ -271,7 +271,7 @@ var require_react_is_development = __commonJS({
271
271
  exports2.ContextProvider = ContextProvider;
272
272
  exports2.Element = Element;
273
273
  exports2.ForwardRef = ForwardRef2;
274
- exports2.Fragment = Fragment4;
274
+ exports2.Fragment = Fragment5;
275
275
  exports2.Lazy = Lazy;
276
276
  exports2.Memo = Memo2;
277
277
  exports2.Portal = Portal;
@@ -1220,11 +1220,17 @@ __export(index_exports, {
1220
1220
  SpanInfoProvider: () => SpanInfoProvider,
1221
1221
  SpanInfoTabs: () => SpanInfoTabs,
1222
1222
  SpanInfoTitle: () => SpanInfoTitle,
1223
+ TIMELINE_CONSTANTS: () => TIMELINE_CONSTANTS,
1223
1224
  TableEmptyRows: () => TableEmptyRows,
1224
1225
  TableHeadCustom: () => TableHeadCustom,
1225
1226
  TablePaginationCustom: () => TablePaginationCustom,
1226
1227
  TableSelectedAction: () => TableSelectedAction,
1227
1228
  TableSkeleton: () => TableSkeleton,
1229
+ TimelineBar: () => TimelineBar,
1230
+ TimelineErrorBoundary: () => TimelineErrorBoundary,
1231
+ TimelineLegend: () => TimelineLegend,
1232
+ TimelineRuler: () => TimelineRuler,
1233
+ TimelineTooltip: () => TimelineTooltip,
1228
1234
  TraceDrawer: () => TraceDrawer,
1229
1235
  TraceDrawerCloseButton: () => TraceDrawerCloseButton,
1230
1236
  TraceDrawerContainer: () => TraceDrawerContainer,
@@ -1241,11 +1247,14 @@ __export(index_exports, {
1241
1247
  TraceLabel: () => TraceLabel,
1242
1248
  TraceListItem: () => TraceListItem,
1243
1249
  TraceListProvider: () => TraceListProvider,
1250
+ TraceTimeline: () => TraceTimeline,
1244
1251
  TraceTree: () => TraceTree,
1245
1252
  TraceTreeItem: () => TraceTreeItem,
1246
1253
  TracesList: () => TracesList,
1247
1254
  applyDagreLayout: () => applyDagreLayout,
1248
1255
  calculateBranchFamilies: () => calculateBranchFamilies,
1256
+ computeTimelineLayout: () => computeTimelineLayout,
1257
+ formatDuration: () => formatDuration,
1249
1258
  getBranchColor: () => getBranchColor,
1250
1259
  getDisplayName: () => getDisplayName2,
1251
1260
  getNodeTypeStyle: () => getNodeTypeStyle,
@@ -1256,6 +1265,9 @@ __export(index_exports, {
1256
1265
  useEvaluationContext: () => useEvaluationContext,
1257
1266
  useSpanInfoContext: () => useSpanInfoContext,
1258
1267
  useTable: () => useTable,
1268
+ useTimelineLayout: () => useTimelineLayout,
1269
+ useTimelineViewPreference: () => useTimelineViewPreference,
1270
+ useTimelineZoom: () => useTimelineZoom,
1259
1271
  useTraceDrawer: () => useTraceDrawer,
1260
1272
  useTraceDrawerContext: () => useTraceDrawerContext,
1261
1273
  useTraceListContext: () => useTraceListContext
@@ -3582,7 +3594,7 @@ function createBox(options = {}) {
3582
3594
  const BoxRoot = styled2("div", {
3583
3595
  shouldForwardProp: (prop) => prop !== "theme" && prop !== "sx" && prop !== "as"
3584
3596
  })(styleFunctionSx_default);
3585
- const Box24 = /* @__PURE__ */ React3.forwardRef(function Box25(inProps, ref) {
3597
+ const Box29 = /* @__PURE__ */ React3.forwardRef(function Box30(inProps, ref) {
3586
3598
  const theme2 = useTheme_default(defaultTheme2);
3587
3599
  const {
3588
3600
  className,
@@ -3597,7 +3609,7 @@ function createBox(options = {}) {
3597
3609
  ...other
3598
3610
  });
3599
3611
  });
3600
- return Box24;
3612
+ return Box29;
3601
3613
  }
3602
3614
 
3603
3615
  // ../../node_modules/@mui/utils/esm/generateUtilityClass/generateUtilityClass.js
@@ -3661,29 +3673,29 @@ var Box_default = Box7;
3661
3673
 
3662
3674
  // ../../node_modules/@mui/utils/esm/getDisplayName/getDisplayName.js
3663
3675
  var import_react_is2 = __toESM(require_react_is2(), 1);
3664
- function getFunctionComponentName(Component, fallback = "") {
3665
- return Component.displayName || Component.name || fallback;
3676
+ function getFunctionComponentName(Component2, fallback = "") {
3677
+ return Component2.displayName || Component2.name || fallback;
3666
3678
  }
3667
3679
  function getWrappedName(outerType, innerType, wrapperName) {
3668
3680
  const functionName = getFunctionComponentName(innerType);
3669
3681
  return outerType.displayName || (functionName !== "" ? `${wrapperName}(${functionName})` : wrapperName);
3670
3682
  }
3671
- function getDisplayName(Component) {
3672
- if (Component == null) {
3683
+ function getDisplayName(Component2) {
3684
+ if (Component2 == null) {
3673
3685
  return void 0;
3674
3686
  }
3675
- if (typeof Component === "string") {
3676
- return Component;
3687
+ if (typeof Component2 === "string") {
3688
+ return Component2;
3677
3689
  }
3678
- if (typeof Component === "function") {
3679
- return getFunctionComponentName(Component, "Component");
3690
+ if (typeof Component2 === "function") {
3691
+ return getFunctionComponentName(Component2, "Component");
3680
3692
  }
3681
- if (typeof Component === "object") {
3682
- switch (Component.$$typeof) {
3693
+ if (typeof Component2 === "object") {
3694
+ switch (Component2.$$typeof) {
3683
3695
  case import_react_is2.ForwardRef:
3684
- return getWrappedName(Component, Component.render, "ForwardRef");
3696
+ return getWrappedName(Component2, Component2.render, "ForwardRef");
3685
3697
  case import_react_is2.Memo:
3686
- return getWrappedName(Component, Component.type, "memo");
3698
+ return getWrappedName(Component2, Component2.type, "memo");
3687
3699
  default:
3688
3700
  return void 0;
3689
3701
  }
@@ -3897,14 +3909,14 @@ function createStyled(input = {}) {
3897
3909
  expressionsHead.unshift(outputStrings);
3898
3910
  }
3899
3911
  const expressions = [...expressionsHead, ...expressionsBody, ...expressionsTail];
3900
- const Component = defaultStyledResolver(...expressions);
3912
+ const Component2 = defaultStyledResolver(...expressions);
3901
3913
  if (tag.muiName) {
3902
- Component.muiName = tag.muiName;
3914
+ Component2.muiName = tag.muiName;
3903
3915
  }
3904
3916
  if (process.env.NODE_ENV !== "production") {
3905
- Component.displayName = generateDisplayName(componentName, componentSlot, tag);
3917
+ Component2.displayName = generateDisplayName(componentName, componentSlot, tag);
3906
3918
  }
3907
- return Component;
3919
+ return Component2;
3908
3920
  };
3909
3921
  if (defaultStyledResolver.withConfig) {
3910
3922
  muiStyledResolver.withConfig = defaultStyledResolver.withConfig;
@@ -4168,7 +4180,7 @@ function createStack(options = {}) {
4168
4180
  return composeClasses(slots, (slot) => generateUtilityClass(componentName, slot), {});
4169
4181
  };
4170
4182
  const StackRoot = createStyledComponent(style3);
4171
- const Stack15 = /* @__PURE__ */ React4.forwardRef(function Grid(inProps, ref) {
4183
+ const Stack14 = /* @__PURE__ */ React4.forwardRef(function Grid(inProps, ref) {
4172
4184
  const themeProps = useThemeProps2(inProps);
4173
4185
  const props = extendSxProp(themeProps);
4174
4186
  const {
@@ -4196,14 +4208,14 @@ function createStack(options = {}) {
4196
4208
  children: divider ? joinChildren(children, divider) : children
4197
4209
  });
4198
4210
  });
4199
- process.env.NODE_ENV !== "production" ? Stack15.propTypes = {
4211
+ process.env.NODE_ENV !== "production" ? Stack14.propTypes = {
4200
4212
  children: import_prop_types3.default.node,
4201
4213
  direction: import_prop_types3.default.oneOfType([import_prop_types3.default.oneOf(["column-reverse", "column", "row-reverse", "row"]), import_prop_types3.default.arrayOf(import_prop_types3.default.oneOf(["column-reverse", "column", "row-reverse", "row"])), import_prop_types3.default.object]),
4202
4214
  divider: import_prop_types3.default.node,
4203
4215
  spacing: import_prop_types3.default.oneOfType([import_prop_types3.default.arrayOf(import_prop_types3.default.oneOfType([import_prop_types3.default.number, import_prop_types3.default.string])), import_prop_types3.default.number, import_prop_types3.default.object, import_prop_types3.default.string]),
4204
4216
  sx: import_prop_types3.default.oneOfType([import_prop_types3.default.arrayOf(import_prop_types3.default.oneOfType([import_prop_types3.default.func, import_prop_types3.default.object, import_prop_types3.default.bool])), import_prop_types3.default.func, import_prop_types3.default.object])
4205
4217
  } : void 0;
4206
- return Stack15;
4218
+ return Stack14;
4207
4219
  }
4208
4220
 
4209
4221
  // ../../node_modules/@mui/system/esm/Stack/Stack.js
@@ -19982,7 +19994,7 @@ var TraceDrawerCloseButton = ({
19982
19994
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_material10.IconButton, { onClick: onClose, size: "small", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Iconify, { icon: "eva:close-fill" }) });
19983
19995
  };
19984
19996
  var TraceDrawerHeader = ({ children }) => {
19985
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_material10.Box, { p: 2, children });
19997
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_material10.Box, { p: 2, sx: { flexShrink: 0, borderBottom: 1, borderColor: "divider" }, children });
19986
19998
  };
19987
19999
 
19988
20000
  // src/sections/traces/trace-drawer/trace-drawer-main.tsx
@@ -20110,7 +20122,18 @@ var import_jsx_runtime33 = require("react/jsx-runtime");
20110
20122
  var TraceDrawerContainer = ({
20111
20123
  children
20112
20124
  }) => {
20113
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_material14.Stack, { height: "100%", divider: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_material14.Divider, {}), children });
20125
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20126
+ import_material14.Box,
20127
+ {
20128
+ sx: {
20129
+ height: "100%",
20130
+ display: "flex",
20131
+ flexDirection: "column",
20132
+ overflow: "hidden"
20133
+ },
20134
+ children
20135
+ }
20136
+ );
20114
20137
  };
20115
20138
 
20116
20139
  // src/sections/traces/trace-drawer/trace-tree/trace-tree.tsx
@@ -20362,13 +20385,12 @@ var TraceTree = () => {
20362
20385
  setSelectedSpanId,
20363
20386
  traces,
20364
20387
  findCostAndTokens,
20365
- traceId,
20366
- treeHeight
20388
+ traceId
20367
20389
  } = useTraceDrawerContext();
20368
20390
  const tree = (0, import_react11.useMemo)(() => {
20369
20391
  return spanTree.map((node) => renderTree(node, findCostAndTokens));
20370
20392
  }, [spanTree]);
20371
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_material17.Box, { sx: { height: treeHeight, overflowY: "auto", p: 2 }, children: selectedSpan?.id && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
20393
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_material17.Box, { sx: { height: "100%", overflowY: "auto", p: 2 }, children: selectedSpan?.id && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
20372
20394
  import_x_tree_view.SimpleTreeView,
20373
20395
  {
20374
20396
  expansionTrigger: "iconContainer",
@@ -21140,168 +21162,1759 @@ function TraceGraphCanvas({
21140
21162
  );
21141
21163
  }
21142
21164
 
21143
- // src/sections/traces/trace-drawer/span-info/span-info-content.tsx
21144
- var import_material21 = require("@mui/material");
21145
- var import_jsx_runtime39 = require("react/jsx-runtime");
21146
- var SpanInfoTitle = ({ children }) => {
21147
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_material21.Typography, { variant: "h6", gutterBottom: true, children });
21148
- };
21149
- var SpanInfoContent = ({ children }) => {
21150
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_material21.Stack, { width: "100%", height: "100%", overflow: "hidden", children });
21165
+ // src/sections/traces/trace-drawer/trace-timeline/timeline-types.ts
21166
+ var TIMELINE_CONSTANTS = {
21167
+ /** Height of each span row in pixels */
21168
+ ROW_HEIGHT: 28,
21169
+ /** Minimum bar width in pixels (for very short spans) */
21170
+ MIN_BAR_WIDTH: 4,
21171
+ /** Indentation per depth level in pixels */
21172
+ DEPTH_INDENT: 16,
21173
+ /** Bar height as ratio of row height */
21174
+ BAR_HEIGHT_RATIO: 0.7,
21175
+ /** Minimum zoom scale */
21176
+ MIN_SCALE: 0.5,
21177
+ /** Maximum zoom scale */
21178
+ MAX_SCALE: 10,
21179
+ /** Height of the time ruler in pixels */
21180
+ RULER_HEIGHT: 24,
21181
+ /** Padding around the timeline content */
21182
+ PADDING: 8,
21183
+ /** Label area width for span names */
21184
+ LABEL_WIDTH: 120
21151
21185
  };
21152
21186
 
21153
- // src/sections/traces/trace-drawer/span-info/span-info-header.tsx
21154
- var import_material22 = require("@mui/material");
21155
-
21156
- // src/sections/traces/trace-drawer/span-info/span-info-provider.tsx
21157
- var import_react19 = require("react");
21158
-
21159
- // src/sections/traces/trace-drawer/span-info/hooks/use-span-info.ts
21160
- var import_react18 = require("react");
21161
- var useSpanInfo = ({ span }) => {
21162
- const [activeTab, setActiveTab] = (0, import_react18.useState)("attributes");
21163
- const [tabs, setTabs] = (0, import_react18.useState)([]);
21164
- const isLLMCall = (0, import_react18.useMemo)(() => {
21165
- return span?.data?.type === "GENERATION" || !!span?.data?.model;
21166
- }, [span?.data?.type, span?.data?.model]);
21167
- (0, import_react18.useEffect)(() => {
21168
- if (span?.id) {
21169
- const newTabs = [];
21170
- if (isLLMCall) {
21171
- newTabs.push({
21172
- value: "inputOutput",
21173
- label: "Input/Output"
21187
+ // src/sections/traces/trace-drawer/trace-timeline/compute-timeline-layout.ts
21188
+ function formatDuration(ms) {
21189
+ if (ms < 1e3) {
21190
+ return `${Math.round(ms)}ms`;
21191
+ }
21192
+ if (ms < 6e4) {
21193
+ return `${(ms / 1e3).toFixed(1)}s`;
21194
+ }
21195
+ const minutes = Math.floor(ms / 6e4);
21196
+ const seconds = Math.round(ms % 6e4 / 1e3);
21197
+ return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
21198
+ }
21199
+ function calculateTickIntervals(totalMs) {
21200
+ const targetMajorTicks = 6;
21201
+ const idealInterval = totalMs / targetMajorTicks;
21202
+ const niceIntervals = [
21203
+ 1,
21204
+ 2,
21205
+ 5,
21206
+ 10,
21207
+ 20,
21208
+ 50,
21209
+ 100,
21210
+ 200,
21211
+ 500,
21212
+ 1e3,
21213
+ 2e3,
21214
+ 5e3,
21215
+ 1e4,
21216
+ 2e4,
21217
+ 3e4,
21218
+ 6e4,
21219
+ 12e4,
21220
+ 3e5,
21221
+ 6e5
21222
+ ];
21223
+ let major = niceIntervals[0];
21224
+ for (const interval of niceIntervals) {
21225
+ if (interval >= idealInterval) {
21226
+ major = interval;
21227
+ break;
21228
+ }
21229
+ major = interval;
21230
+ }
21231
+ const minor = major / 5;
21232
+ return { major, minor };
21233
+ }
21234
+ function hasErrorStatus(span) {
21235
+ const status = span.data?.status?.toLowerCase();
21236
+ return status === "error" || status === "failed" || status === "failure";
21237
+ }
21238
+ function buildSpanLookup(spans) {
21239
+ const lookup = /* @__PURE__ */ new Map();
21240
+ for (const span of spans) {
21241
+ lookup.set(span.id, span);
21242
+ }
21243
+ return lookup;
21244
+ }
21245
+ function buildChildrenMap(spans) {
21246
+ const childrenMap = /* @__PURE__ */ new Map();
21247
+ for (const span of spans) {
21248
+ const parentId = span.parentId;
21249
+ const children = childrenMap.get(parentId) || [];
21250
+ children.push(span);
21251
+ childrenMap.set(parentId, children);
21252
+ }
21253
+ for (const [, children] of childrenMap) {
21254
+ children.sort((a, b) => a.timestamp - b.timestamp);
21255
+ }
21256
+ return childrenMap;
21257
+ }
21258
+ function spanHasChildren(spanId, childrenMap) {
21259
+ const children = childrenMap.get(spanId);
21260
+ return children !== void 0 && children.length > 0;
21261
+ }
21262
+ function sanitizeSpan(span) {
21263
+ if (!span || typeof span.id !== "string" || !span.id) {
21264
+ return null;
21265
+ }
21266
+ const timestamp = typeof span.timestamp === "number" && Number.isFinite(span.timestamp) ? span.timestamp : Date.now();
21267
+ const duration = typeof span.duration === "number" && Number.isFinite(span.duration) && span.duration >= 0 ? span.duration : 0;
21268
+ const name = typeof span.name === "string" ? span.name : String(span.id);
21269
+ return {
21270
+ ...span,
21271
+ timestamp,
21272
+ duration,
21273
+ name
21274
+ };
21275
+ }
21276
+ function computeTimelineLayout(spans) {
21277
+ if (!Array.isArray(spans) || spans.length === 0) {
21278
+ return {
21279
+ layouts: [],
21280
+ metrics: {
21281
+ totalDurationMs: 0,
21282
+ startTimeMs: 0,
21283
+ endTimeMs: 0,
21284
+ spanCount: 0,
21285
+ maxDepth: 0,
21286
+ typeBreakdown: {}
21287
+ },
21288
+ rulerTicks: []
21289
+ };
21290
+ }
21291
+ const sanitizedSpans = spans.map(sanitizeSpan).filter((span) => span !== null);
21292
+ if (sanitizedSpans.length === 0) {
21293
+ return {
21294
+ layouts: [],
21295
+ metrics: {
21296
+ totalDurationMs: 0,
21297
+ startTimeMs: 0,
21298
+ endTimeMs: 0,
21299
+ spanCount: 0,
21300
+ maxDepth: 0,
21301
+ typeBreakdown: {}
21302
+ },
21303
+ rulerTicks: []
21304
+ };
21305
+ }
21306
+ const spanLookup = buildSpanLookup(sanitizedSpans);
21307
+ const childrenMap = buildChildrenMap(sanitizedSpans);
21308
+ let minTimestamp = Infinity;
21309
+ let maxEndTime = -Infinity;
21310
+ for (const span of sanitizedSpans) {
21311
+ const startTime = span.timestamp;
21312
+ const endTime = span.timestamp + Math.max(0, span.duration);
21313
+ if (startTime < minTimestamp) {
21314
+ minTimestamp = startTime;
21315
+ }
21316
+ if (endTime > maxEndTime) {
21317
+ maxEndTime = endTime;
21318
+ }
21319
+ }
21320
+ const totalDurationMs = maxEndTime - minTimestamp;
21321
+ const normalizeTime = (timestamp) => {
21322
+ if (totalDurationMs === 0) return 0;
21323
+ return (timestamp - minTimestamp) / totalDurationMs;
21324
+ };
21325
+ const normalizeDuration = (duration) => {
21326
+ if (totalDurationMs === 0) return 1;
21327
+ return Math.max(0, duration) / totalDurationMs;
21328
+ };
21329
+ const layouts = [];
21330
+ let rowIndex = 0;
21331
+ let maxDepth = 0;
21332
+ const typeBreakdown = {};
21333
+ function traverse(parentId, depth) {
21334
+ const children = childrenMap.get(parentId) || [];
21335
+ for (const span of children) {
21336
+ if (depth > maxDepth) {
21337
+ maxDepth = depth;
21338
+ }
21339
+ const hasChildren = spanHasChildren(span.id, childrenMap);
21340
+ const nodeType = inferNodeType(
21341
+ {
21342
+ spanId: span.id,
21343
+ parentSpanId: span.parentId,
21344
+ name: span.name,
21345
+ startTime: span.timestamp,
21346
+ type: span.data?.type,
21347
+ data: span.data
21348
+ },
21349
+ hasChildren
21350
+ );
21351
+ typeBreakdown[nodeType] = (typeBreakdown[nodeType] || 0) + 1;
21352
+ const startTimeMs = span.timestamp - minTimestamp;
21353
+ const durationMs = Math.max(0, span.duration);
21354
+ const percentOfTrace = totalDurationMs > 0 ? durationMs / totalDurationMs * 100 : 100;
21355
+ const layout = {
21356
+ spanId: span.id,
21357
+ name: span.name,
21358
+ x: normalizeTime(span.timestamp),
21359
+ width: normalizeDuration(durationMs),
21360
+ row: rowIndex,
21361
+ depth,
21362
+ durationMs,
21363
+ startTimeMs,
21364
+ percentOfTrace,
21365
+ nodeType,
21366
+ hasError: hasErrorStatus(span),
21367
+ span
21368
+ };
21369
+ layouts.push(layout);
21370
+ rowIndex++;
21371
+ traverse(span.id, depth + 1);
21372
+ }
21373
+ }
21374
+ traverse(void 0, 0);
21375
+ for (const span of sanitizedSpans) {
21376
+ if (span.parentId && !spanLookup.has(span.parentId)) {
21377
+ const hasChildren = spanHasChildren(span.id, childrenMap);
21378
+ const nodeType = inferNodeType(
21379
+ {
21380
+ spanId: span.id,
21381
+ parentSpanId: span.parentId,
21382
+ name: span.name,
21383
+ startTime: span.timestamp,
21384
+ type: span.data?.type,
21385
+ data: span.data
21386
+ },
21387
+ hasChildren
21388
+ );
21389
+ if (!layouts.find((l) => l.spanId === span.id)) {
21390
+ typeBreakdown[nodeType] = (typeBreakdown[nodeType] || 0) + 1;
21391
+ const startTimeMs = span.timestamp - minTimestamp;
21392
+ const durationMs = Math.max(0, span.duration);
21393
+ const percentOfTrace = totalDurationMs > 0 ? durationMs / totalDurationMs * 100 : 100;
21394
+ layouts.push({
21395
+ spanId: span.id,
21396
+ name: span.name,
21397
+ x: normalizeTime(span.timestamp),
21398
+ width: normalizeDuration(durationMs),
21399
+ row: rowIndex,
21400
+ depth: 0,
21401
+ // Treat as root since parent is missing
21402
+ durationMs,
21403
+ startTimeMs,
21404
+ percentOfTrace,
21405
+ nodeType,
21406
+ hasError: hasErrorStatus(span),
21407
+ span
21174
21408
  });
21175
- setActiveTab("inputOutput");
21176
- } else {
21177
- setActiveTab("evaluation");
21409
+ rowIndex++;
21410
+ traverse(span.id, 1);
21178
21411
  }
21179
- newTabs.push({
21180
- value: "evaluation",
21181
- label: `Evaluations`
21412
+ }
21413
+ }
21414
+ const { major, minor } = calculateTickIntervals(totalDurationMs);
21415
+ const rulerTicks = [];
21416
+ if (totalDurationMs > 0) {
21417
+ for (let time = 0; time <= totalDurationMs; time += minor) {
21418
+ const isMajor = time % major === 0;
21419
+ rulerTicks.push({
21420
+ position: time / totalDurationMs,
21421
+ label: isMajor ? formatDuration(time) : "",
21422
+ isMajor
21182
21423
  });
21183
- newTabs.push({
21184
- value: "attributes",
21185
- label: "Attributes"
21424
+ }
21425
+ if (rulerTicks.length === 0 || rulerTicks[rulerTicks.length - 1].position < 1) {
21426
+ rulerTicks.push({
21427
+ position: 1,
21428
+ label: formatDuration(totalDurationMs),
21429
+ isMajor: true
21186
21430
  });
21187
- setTabs(newTabs);
21188
21431
  }
21189
- }, [span?.id, isLLMCall]);
21190
- (0, import_react18.useEffect)(() => {
21191
- const isTabValid = activeTab === "inputOutput" && isLLMCall || activeTab === "evaluation" || activeTab === "attributes";
21192
- if (!isTabValid) {
21193
- if (isLLMCall) {
21194
- setActiveTab("inputOutput");
21195
- } else {
21196
- setActiveTab("evaluation");
21432
+ }
21433
+ const metrics = {
21434
+ totalDurationMs,
21435
+ startTimeMs: minTimestamp,
21436
+ endTimeMs: maxEndTime,
21437
+ spanCount: sanitizedSpans.length,
21438
+ maxDepth,
21439
+ typeBreakdown
21440
+ };
21441
+ return { layouts, metrics, rulerTicks };
21442
+ }
21443
+
21444
+ // src/sections/traces/trace-drawer/trace-timeline/use-timeline-layout.ts
21445
+ var import_react18 = require("react");
21446
+ function useTimelineLayout(spans) {
21447
+ return (0, import_react18.useMemo)(() => computeTimelineLayout(spans), [spans]);
21448
+ }
21449
+
21450
+ // src/sections/traces/trace-drawer/trace-timeline/use-timeline-zoom.ts
21451
+ var import_react19 = require("react");
21452
+ var { MIN_SCALE, MAX_SCALE } = TIMELINE_CONSTANTS;
21453
+ var ZOOM_FACTOR = 1.2;
21454
+ function useTimelineZoom(contentWidth = 1e3, contentHeight = 500) {
21455
+ const [viewState, setViewState] = (0, import_react19.useState)(() => ({
21456
+ viewBox: {
21457
+ x: 0,
21458
+ y: 0,
21459
+ width: contentWidth,
21460
+ height: contentHeight
21461
+ },
21462
+ scale: 1,
21463
+ isPanning: false
21464
+ }));
21465
+ const panStartRef = (0, import_react19.useRef)(
21466
+ null
21467
+ );
21468
+ const clampScale = (0, import_react19.useCallback)((scale) => {
21469
+ return Math.max(MIN_SCALE, Math.min(MAX_SCALE, scale));
21470
+ }, []);
21471
+ const zoomIn = (0, import_react19.useCallback)(() => {
21472
+ setViewState((prev) => {
21473
+ const newScale = clampScale(prev.scale * ZOOM_FACTOR);
21474
+ const scaleRatio = prev.scale / newScale;
21475
+ const centerX = prev.viewBox.x + prev.viewBox.width / 2;
21476
+ const centerY = prev.viewBox.y + prev.viewBox.height / 2;
21477
+ const newWidth = prev.viewBox.width * scaleRatio;
21478
+ const newHeight = prev.viewBox.height * scaleRatio;
21479
+ return {
21480
+ ...prev,
21481
+ viewBox: {
21482
+ x: centerX - newWidth / 2,
21483
+ y: centerY - newHeight / 2,
21484
+ width: newWidth,
21485
+ height: newHeight
21486
+ },
21487
+ scale: newScale
21488
+ };
21489
+ });
21490
+ }, [clampScale]);
21491
+ const zoomOut = (0, import_react19.useCallback)(() => {
21492
+ setViewState((prev) => {
21493
+ const newScale = clampScale(prev.scale / ZOOM_FACTOR);
21494
+ const scaleRatio = prev.scale / newScale;
21495
+ const centerX = prev.viewBox.x + prev.viewBox.width / 2;
21496
+ const centerY = prev.viewBox.y + prev.viewBox.height / 2;
21497
+ const newWidth = prev.viewBox.width * scaleRatio;
21498
+ const newHeight = prev.viewBox.height * scaleRatio;
21499
+ return {
21500
+ ...prev,
21501
+ viewBox: {
21502
+ x: centerX - newWidth / 2,
21503
+ y: centerY - newHeight / 2,
21504
+ width: newWidth,
21505
+ height: newHeight
21506
+ },
21507
+ scale: newScale
21508
+ };
21509
+ });
21510
+ }, [clampScale]);
21511
+ const resetZoom = (0, import_react19.useCallback)(() => {
21512
+ setViewState({
21513
+ viewBox: {
21514
+ x: 0,
21515
+ y: 0,
21516
+ width: contentWidth,
21517
+ height: contentHeight
21518
+ },
21519
+ scale: 1,
21520
+ isPanning: false
21521
+ });
21522
+ }, [contentWidth, contentHeight]);
21523
+ const setScale = (0, import_react19.useCallback)(
21524
+ (scale) => {
21525
+ setViewState((prev) => {
21526
+ const newScale = clampScale(scale);
21527
+ const scaleRatio = prev.scale / newScale;
21528
+ const centerX = prev.viewBox.x + prev.viewBox.width / 2;
21529
+ const centerY = prev.viewBox.y + prev.viewBox.height / 2;
21530
+ const newWidth = prev.viewBox.width * scaleRatio;
21531
+ const newHeight = prev.viewBox.height * scaleRatio;
21532
+ return {
21533
+ ...prev,
21534
+ viewBox: {
21535
+ x: centerX - newWidth / 2,
21536
+ y: centerY - newHeight / 2,
21537
+ width: newWidth,
21538
+ height: newHeight
21539
+ },
21540
+ scale: newScale
21541
+ };
21542
+ });
21543
+ },
21544
+ [clampScale]
21545
+ );
21546
+ const onWheel = (0, import_react19.useCallback)(
21547
+ (event) => {
21548
+ if (!event.ctrlKey && !event.metaKey) {
21549
+ return;
21550
+ }
21551
+ try {
21552
+ event.preventDefault();
21553
+ } catch {
21197
21554
  }
21555
+ const svg2 = event.currentTarget;
21556
+ if (!svg2) return;
21557
+ const rect = svg2.getBoundingClientRect();
21558
+ if (!rect || rect.width === 0 || rect.height === 0) return;
21559
+ const delta = event.deltaY;
21560
+ const zoomDirection = delta > 0 ? -1 : 1;
21561
+ setViewState((prev) => {
21562
+ const factor = zoomDirection > 0 ? ZOOM_FACTOR : 1 / ZOOM_FACTOR;
21563
+ const newScale = clampScale(prev.scale * factor);
21564
+ if (newScale === prev.scale) {
21565
+ return prev;
21566
+ }
21567
+ const scaleRatio = prev.scale / newScale;
21568
+ const mouseX = event.clientX - rect.left;
21569
+ const mouseY = event.clientY - rect.top;
21570
+ const viewBoxMouseX = prev.viewBox.x + mouseX / rect.width * prev.viewBox.width;
21571
+ const viewBoxMouseY = prev.viewBox.y + mouseY / rect.height * prev.viewBox.height;
21572
+ const newWidth = prev.viewBox.width * scaleRatio;
21573
+ const newHeight = prev.viewBox.height * scaleRatio;
21574
+ const newX = viewBoxMouseX - mouseX / rect.width * newWidth;
21575
+ const newY = viewBoxMouseY - mouseY / rect.height * newHeight;
21576
+ return {
21577
+ ...prev,
21578
+ viewBox: {
21579
+ x: newX,
21580
+ y: newY,
21581
+ width: newWidth,
21582
+ height: newHeight
21583
+ },
21584
+ scale: newScale
21585
+ };
21586
+ });
21587
+ },
21588
+ [clampScale]
21589
+ );
21590
+ const onMouseDown = (0, import_react19.useCallback)((event) => {
21591
+ if (event.button !== 0) return;
21592
+ event.preventDefault();
21593
+ setViewState((prev) => {
21594
+ panStartRef.current = {
21595
+ x: event.clientX,
21596
+ y: event.clientY,
21597
+ viewBoxX: prev.viewBox.x,
21598
+ viewBoxY: prev.viewBox.y
21599
+ };
21600
+ return {
21601
+ ...prev,
21602
+ isPanning: true
21603
+ };
21604
+ });
21605
+ }, []);
21606
+ const onMouseMove = (0, import_react19.useCallback)((event) => {
21607
+ if (!panStartRef.current) return;
21608
+ const svg2 = event.currentTarget;
21609
+ const rect = svg2.getBoundingClientRect();
21610
+ const deltaX = event.clientX - panStartRef.current.x;
21611
+ const deltaY = event.clientY - panStartRef.current.y;
21612
+ setViewState((prev) => {
21613
+ const viewBoxDeltaX = deltaX / rect.width * prev.viewBox.width;
21614
+ const viewBoxDeltaY = deltaY / rect.height * prev.viewBox.height;
21615
+ return {
21616
+ ...prev,
21617
+ viewBox: {
21618
+ ...prev.viewBox,
21619
+ x: panStartRef.current.viewBoxX - viewBoxDeltaX,
21620
+ y: panStartRef.current.viewBoxY - viewBoxDeltaY
21621
+ }
21622
+ };
21623
+ });
21624
+ }, []);
21625
+ const onMouseUp = (0, import_react19.useCallback)(() => {
21626
+ panStartRef.current = null;
21627
+ setViewState((prev) => ({
21628
+ ...prev,
21629
+ isPanning: false
21630
+ }));
21631
+ }, []);
21632
+ const onMouseLeave = (0, import_react19.useCallback)(() => {
21633
+ if (panStartRef.current) {
21634
+ panStartRef.current = null;
21635
+ setViewState((prev) => ({
21636
+ ...prev,
21637
+ isPanning: false
21638
+ }));
21198
21639
  }
21199
- }, [activeTab, isLLMCall]);
21640
+ }, []);
21200
21641
  return {
21201
- activeTab,
21202
- setActiveTab,
21203
- tabs,
21204
- isLLMCall
21642
+ viewState,
21643
+ zoomIn,
21644
+ zoomOut,
21645
+ resetZoom,
21646
+ setScale,
21647
+ onWheel,
21648
+ panHandlers: {
21649
+ onMouseDown,
21650
+ onMouseMove,
21651
+ onMouseUp,
21652
+ onMouseLeave
21653
+ }
21205
21654
  };
21206
- };
21655
+ }
21207
21656
 
21208
- // src/sections/traces/trace-drawer/span-info/span-info-provider.tsx
21209
- var import_jsx_runtime40 = require("react/jsx-runtime");
21210
- var SpanInfoContext = (0, import_react19.createContext)(
21211
- void 0
21212
- );
21213
- var SpanInfoProvider = ({
21214
- children
21215
- }) => {
21216
- const { selectedSpan } = useTraceDrawerContext();
21217
- const { activeTab, setActiveTab, tabs } = useSpanInfo({
21218
- span: selectedSpan || void 0
21657
+ // src/sections/traces/trace-drawer/trace-timeline/use-timeline-view-preference.ts
21658
+ var import_react20 = require("react");
21659
+ var STORAGE_KEY = "agentmark-trace-view-preference";
21660
+ var DEFAULT_VIEW = "graph";
21661
+ function useTimelineViewPreference() {
21662
+ const [view, setViewState] = (0, import_react20.useState)(() => {
21663
+ if (typeof window !== "undefined") {
21664
+ try {
21665
+ const stored = localStorage.getItem(STORAGE_KEY);
21666
+ if (stored === "graph" || stored === "timeline") {
21667
+ return stored;
21668
+ }
21669
+ } catch {
21670
+ }
21671
+ }
21672
+ return DEFAULT_VIEW;
21219
21673
  });
21220
- if (!selectedSpan) {
21221
- return null;
21222
- }
21223
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
21224
- SpanInfoContext.Provider,
21225
- {
21226
- value: {
21227
- span: selectedSpan,
21228
- activeTab,
21229
- setActiveTab,
21230
- tabs
21231
- },
21232
- children
21674
+ (0, import_react20.useEffect)(() => {
21675
+ if (typeof window !== "undefined") {
21676
+ try {
21677
+ localStorage.setItem(STORAGE_KEY, view);
21678
+ } catch {
21679
+ }
21233
21680
  }
21234
- );
21235
- };
21236
- var useSpanInfoContext = () => {
21237
- const context = (0, import_react19.useContext)(SpanInfoContext);
21238
- if (!context) {
21239
- throw new Error("useSpanInfo must be used within a SpanInfoProvider");
21240
- }
21241
- return context;
21242
- };
21681
+ }, [view]);
21682
+ const setView = (0, import_react20.useCallback)((newView) => {
21683
+ setViewState(newView);
21684
+ }, []);
21685
+ const toggleView = (0, import_react20.useCallback)(() => {
21686
+ setViewState((current) => current === "graph" ? "timeline" : "graph");
21687
+ }, []);
21688
+ return {
21689
+ /** Current view type */
21690
+ view,
21691
+ /** Set view to specific type */
21692
+ setView,
21693
+ /** Toggle between graph and timeline */
21694
+ toggleView,
21695
+ /** Whether current view is timeline */
21696
+ isTimeline: view === "timeline",
21697
+ /** Whether current view is graph */
21698
+ isGraph: view === "graph"
21699
+ };
21700
+ }
21243
21701
 
21244
- // src/sections/traces/trace-drawer/span-info/span-info-header.tsx
21245
- var import_jsx_runtime41 = require("react/jsx-runtime");
21246
- var SpanInfoHeader = () => {
21247
- const { span } = useSpanInfoContext();
21248
- const { t } = useTraceDrawerContext();
21249
- const modelName = span.data.model;
21250
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
21251
- import_material22.Stack,
21702
+ // src/sections/traces/trace-drawer/trace-timeline/trace-timeline.tsx
21703
+ var import_react26 = require("react");
21704
+ var import_material24 = require("@mui/material");
21705
+ var import_styles10 = require("@mui/material/styles");
21706
+
21707
+ // src/sections/traces/trace-drawer/trace-timeline/timeline-bar.tsx
21708
+ var import_react21 = require("react");
21709
+ var import_styles6 = require("@mui/material/styles");
21710
+ var import_jsx_runtime39 = require("react/jsx-runtime");
21711
+ var { ROW_HEIGHT, MIN_BAR_WIDTH, BAR_HEIGHT_RATIO } = TIMELINE_CONSTANTS;
21712
+ function formatBarDuration(ms) {
21713
+ if (ms < 1e3) {
21714
+ return `${Math.round(ms)}ms`;
21715
+ }
21716
+ return `${(ms / 1e3).toFixed(1)}s`;
21717
+ }
21718
+ var TimelineBar = (0, import_react21.memo)(function TimelineBar2({
21719
+ layout,
21720
+ isSelected,
21721
+ isFocused = false,
21722
+ onSelect,
21723
+ onMouseEnter,
21724
+ onMouseLeave,
21725
+ timelineWidth
21726
+ }) {
21727
+ const theme2 = (0, import_styles6.useTheme)();
21728
+ const nodeStyle = getNodeTypeStyle(layout.nodeType, theme2);
21729
+ const barHeight = ROW_HEIGHT * BAR_HEIGHT_RATIO;
21730
+ const barY = layout.row * ROW_HEIGHT + (ROW_HEIGHT - barHeight) / 2;
21731
+ const xPixels = layout.x * timelineWidth;
21732
+ const widthPixels = Math.max(MIN_BAR_WIDTH, layout.width * timelineWidth);
21733
+ let barColor = nodeStyle.color;
21734
+ if (layout.hasError) {
21735
+ barColor = theme2.palette.error.main;
21736
+ }
21737
+ const strokeColor = isSelected ? theme2.palette.primary.main : isFocused ? theme2.palette.action.focus : "transparent";
21738
+ const strokeWidth = isSelected || isFocused ? 2 : 0;
21739
+ const opacity = layout.hasError ? 1 : 0.85;
21740
+ const handleClick = (event) => {
21741
+ event.stopPropagation();
21742
+ onSelect?.(layout.spanId);
21743
+ };
21744
+ const handleMouseEnter = (event) => {
21745
+ onMouseEnter?.(layout, event);
21746
+ };
21747
+ const showLabel = widthPixels > 60;
21748
+ const durationLabel = formatBarDuration(layout.durationMs);
21749
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
21750
+ "g",
21252
21751
  {
21253
- direction: "row",
21254
- spacing: 3,
21255
- sx: {
21256
- px: 2,
21257
- py: 1.5,
21258
- borderBottom: 1,
21259
- borderColor: "divider"
21260
- },
21752
+ className: "timeline-bar",
21753
+ "data-span-id": layout.spanId,
21754
+ onClick: handleClick,
21755
+ onMouseEnter: handleMouseEnter,
21756
+ onMouseLeave,
21757
+ style: { cursor: "pointer" },
21758
+ role: "gridcell",
21759
+ "aria-label": `${layout.name}: ${durationLabel}, ${layout.percentOfTrace.toFixed(1)}% of trace`,
21760
+ tabIndex: -1,
21261
21761
  children: [
21262
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_material22.Typography, { variant: "subtitle2", children: [
21263
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_material22.Typography, { component: "span", color: "text.secondary", variant: "subtitle2", children: [
21264
- t("spanId"),
21265
- ":"
21266
- ] }),
21267
- " ",
21268
- span.id
21269
- ] }),
21270
- modelName && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_material22.Typography, { variant: "subtitle2", children: [
21271
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
21272
- import_material22.Typography,
21273
- {
21274
- component: "span",
21275
- color: "text.secondary",
21276
- variant: "subtitle2",
21277
- children: [
21278
- t("modelName"),
21279
- ":"
21280
- ]
21281
- }
21282
- ),
21283
- " ",
21284
- modelName
21285
- ] })
21762
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
21763
+ "rect",
21764
+ {
21765
+ x: xPixels,
21766
+ y: barY,
21767
+ width: widthPixels,
21768
+ height: barHeight,
21769
+ rx: 3,
21770
+ ry: 3,
21771
+ fill: barColor,
21772
+ opacity,
21773
+ stroke: strokeColor,
21774
+ strokeWidth
21775
+ }
21776
+ ),
21777
+ showLabel && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
21778
+ "text",
21779
+ {
21780
+ x: xPixels + widthPixels / 2,
21781
+ y: barY + barHeight / 2,
21782
+ textAnchor: "middle",
21783
+ dominantBaseline: "central",
21784
+ fontSize: 10,
21785
+ fill: theme2.palette.getContrastText(barColor),
21786
+ style: { pointerEvents: "none", userSelect: "none" },
21787
+ children: durationLabel
21788
+ }
21789
+ ),
21790
+ layout.hasError && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
21791
+ "circle",
21792
+ {
21793
+ cx: xPixels + widthPixels - 8,
21794
+ cy: barY + barHeight / 2,
21795
+ r: 4,
21796
+ fill: theme2.palette.error.contrastText,
21797
+ style: { pointerEvents: "none" }
21798
+ }
21799
+ )
21286
21800
  ]
21287
21801
  }
21288
21802
  );
21803
+ });
21804
+
21805
+ // src/sections/traces/trace-drawer/trace-timeline/timeline-ruler.tsx
21806
+ var import_react22 = require("react");
21807
+ var import_styles7 = require("@mui/material/styles");
21808
+ var import_jsx_runtime40 = require("react/jsx-runtime");
21809
+ var { RULER_HEIGHT } = TIMELINE_CONSTANTS;
21810
+ var TimelineRuler = (0, import_react22.memo)(function TimelineRuler2({
21811
+ ticks,
21812
+ width: width2,
21813
+ height: height2 = RULER_HEIGHT
21814
+ }) {
21815
+ const theme2 = (0, import_styles7.useTheme)();
21816
+ const majorTickHeight = height2 * 0.6;
21817
+ const minorTickHeight = height2 * 0.3;
21818
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("g", { className: "timeline-ruler", role: "presentation", children: [
21819
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
21820
+ "rect",
21821
+ {
21822
+ x: 0,
21823
+ y: 0,
21824
+ width: width2,
21825
+ height: height2,
21826
+ fill: theme2.palette.background.paper
21827
+ }
21828
+ ),
21829
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
21830
+ "line",
21831
+ {
21832
+ x1: 0,
21833
+ y1: height2,
21834
+ x2: width2,
21835
+ y2: height2,
21836
+ stroke: theme2.palette.divider,
21837
+ strokeWidth: 1
21838
+ }
21839
+ ),
21840
+ ticks.map((tick, index) => {
21841
+ const x = tick.position * width2;
21842
+ const tickHeight = tick.isMajor ? majorTickHeight : minorTickHeight;
21843
+ const y1 = height2 - tickHeight;
21844
+ const y2 = height2;
21845
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("g", { children: [
21846
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
21847
+ "line",
21848
+ {
21849
+ x1: x,
21850
+ y1,
21851
+ x2: x,
21852
+ y2,
21853
+ stroke: theme2.palette.text.secondary,
21854
+ strokeWidth: tick.isMajor ? 1 : 0.5,
21855
+ opacity: tick.isMajor ? 0.8 : 0.4
21856
+ }
21857
+ ),
21858
+ tick.isMajor && tick.label && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
21859
+ "text",
21860
+ {
21861
+ x,
21862
+ y: y1 - 4,
21863
+ textAnchor: "middle",
21864
+ fontSize: 10,
21865
+ fill: theme2.palette.text.secondary,
21866
+ style: { userSelect: "none" },
21867
+ children: tick.label
21868
+ }
21869
+ )
21870
+ ] }, index);
21871
+ })
21872
+ ] });
21873
+ });
21874
+
21875
+ // src/sections/traces/trace-drawer/trace-timeline/timeline-tooltip.tsx
21876
+ var import_react23 = require("react");
21877
+ var import_material21 = require("@mui/material");
21878
+ var import_styles8 = require("@mui/material/styles");
21879
+ var import_jsx_runtime41 = require("react/jsx-runtime");
21880
+ function formatDuration2(ms) {
21881
+ if (ms < 1) {
21882
+ return "<1ms";
21883
+ }
21884
+ if (ms < 1e3) {
21885
+ return `${Math.round(ms)}ms`;
21886
+ }
21887
+ if (ms < 6e4) {
21888
+ return `${(ms / 1e3).toFixed(2)}s`;
21889
+ }
21890
+ const minutes = Math.floor(ms / 6e4);
21891
+ const seconds = (ms % 6e4 / 1e3).toFixed(1);
21892
+ return `${minutes}m ${seconds}s`;
21893
+ }
21894
+ function formatStartTime(ms) {
21895
+ if (ms < 1e3) {
21896
+ return `+${Math.round(ms)}ms`;
21897
+ }
21898
+ return `+${(ms / 1e3).toFixed(2)}s`;
21899
+ }
21900
+ function formatCost(cost) {
21901
+ if (cost < 0.01) {
21902
+ return `$${cost.toFixed(6)}`;
21903
+ }
21904
+ if (cost < 1) {
21905
+ return `$${cost.toFixed(4)}`;
21906
+ }
21907
+ return `$${cost.toFixed(2)}`;
21908
+ }
21909
+ function formatTokens(tokens) {
21910
+ if (tokens >= 1e6) {
21911
+ return `${(tokens / 1e6).toFixed(1)}M`;
21912
+ }
21913
+ if (tokens >= 1e3) {
21914
+ return `${(tokens / 1e3).toFixed(1)}K`;
21915
+ }
21916
+ return String(tokens);
21917
+ }
21918
+ function truncateText(text, maxLength) {
21919
+ if (!text) return "";
21920
+ const cleanText = text.replace(/\n/g, " ").trim();
21921
+ if (cleanText.length <= maxLength) return cleanText;
21922
+ return cleanText.slice(0, maxLength) + "...";
21923
+ }
21924
+ var TimelineTooltip = (0, import_react23.memo)(function TimelineTooltip2({
21925
+ layout,
21926
+ position,
21927
+ visible
21928
+ }) {
21929
+ const theme2 = (0, import_styles8.useTheme)();
21930
+ const parsedAttributes = (0, import_react23.useMemo)(() => {
21931
+ const attributes = layout?.span?.data?.attributes;
21932
+ if (!attributes) return null;
21933
+ try {
21934
+ return typeof attributes === "string" ? JSON.parse(attributes) : attributes;
21935
+ } catch {
21936
+ return null;
21937
+ }
21938
+ }, [layout?.span?.data?.attributes]);
21939
+ if (!visible || !layout || !position) {
21940
+ return null;
21941
+ }
21942
+ const nodeStyle = getNodeTypeStyle(layout.nodeType, theme2);
21943
+ const spanData = layout.span.data;
21944
+ const hasModelInfo = spanData.model || spanData.totalTokens || spanData.cost;
21945
+ const hasInputOutput = spanData.input || spanData.output;
21946
+ const hasToolCalls = spanData.toolCalls;
21947
+ const hasAttributes = parsedAttributes && Object.keys(parsedAttributes).length > 0;
21948
+ const tooltipWidth = 340;
21949
+ const tooltipHeight = 280;
21950
+ const padding2 = 12;
21951
+ let left = position.x + padding2;
21952
+ let top2 = position.y + padding2;
21953
+ if (typeof window !== "undefined") {
21954
+ if (left + tooltipWidth > window.innerWidth - padding2) {
21955
+ left = position.x - tooltipWidth - padding2;
21956
+ }
21957
+ if (top2 + tooltipHeight > window.innerHeight - padding2) {
21958
+ top2 = position.y - tooltipHeight - padding2;
21959
+ }
21960
+ left = Math.max(padding2, left);
21961
+ top2 = Math.max(padding2, top2);
21962
+ }
21963
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
21964
+ import_material21.Paper,
21965
+ {
21966
+ elevation: 8,
21967
+ sx: {
21968
+ position: "fixed",
21969
+ left,
21970
+ top: top2,
21971
+ zIndex: theme2.zIndex.tooltip,
21972
+ p: 1.5,
21973
+ maxWidth: tooltipWidth,
21974
+ maxHeight: 400,
21975
+ overflow: "auto",
21976
+ pointerEvents: "none",
21977
+ backgroundColor: theme2.palette.background.paper,
21978
+ border: `1px solid ${theme2.palette.divider}`
21979
+ },
21980
+ children: [
21981
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_material21.Box, { sx: { display: "flex", alignItems: "center", gap: 1, mb: 1 }, children: [
21982
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
21983
+ import_material21.Box,
21984
+ {
21985
+ sx: {
21986
+ width: 8,
21987
+ height: 8,
21988
+ borderRadius: "50%",
21989
+ backgroundColor: nodeStyle.color,
21990
+ flexShrink: 0
21991
+ }
21992
+ }
21993
+ ),
21994
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
21995
+ import_material21.Typography,
21996
+ {
21997
+ variant: "subtitle2",
21998
+ sx: {
21999
+ fontWeight: 600,
22000
+ wordBreak: "break-word",
22001
+ color: theme2.palette.text.primary
22002
+ },
22003
+ children: layout.name
22004
+ }
22005
+ )
22006
+ ] }),
22007
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
22008
+ import_material21.Box,
22009
+ {
22010
+ sx: {
22011
+ display: "grid",
22012
+ gridTemplateColumns: "auto 1fr",
22013
+ gap: 0.5,
22014
+ rowGap: 0.25
22015
+ },
22016
+ children: [
22017
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", color: "text.secondary", children: "Duration:" }),
22018
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", fontWeight: 500, children: formatDuration2(layout.durationMs) }),
22019
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", color: "text.secondary", children: "Start:" }),
22020
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", children: formatStartTime(layout.startTimeMs) }),
22021
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", color: "text.secondary", children: "% of trace:" }),
22022
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_material21.Typography, { variant: "caption", children: [
22023
+ layout.percentOfTrace.toFixed(1),
22024
+ "%"
22025
+ ] }),
22026
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", color: "text.secondary", children: "Type:" }),
22027
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", sx: { textTransform: "capitalize" }, children: layout.nodeType }),
22028
+ layout.hasError && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
22029
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", color: "error.main", children: "Status:" }),
22030
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", color: "error.main", fontWeight: 500, children: spanData.statusMessage || "Error" })
22031
+ ] })
22032
+ ]
22033
+ }
22034
+ ),
22035
+ hasModelInfo && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
22036
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Divider, { sx: { my: 1 } }),
22037
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
22038
+ import_material21.Box,
22039
+ {
22040
+ sx: {
22041
+ display: "grid",
22042
+ gridTemplateColumns: "auto 1fr",
22043
+ gap: 0.5,
22044
+ rowGap: 0.25
22045
+ },
22046
+ children: [
22047
+ spanData.model && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
22048
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", color: "text.secondary", children: "Model:" }),
22049
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", fontWeight: 500, children: spanData.model })
22050
+ ] }),
22051
+ (spanData.inputTokens || spanData.outputTokens) && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
22052
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", color: "text.secondary", children: "Tokens:" }),
22053
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_material21.Typography, { variant: "caption", children: [
22054
+ spanData.inputTokens ? `${formatTokens(spanData.inputTokens)} in` : "",
22055
+ spanData.inputTokens && spanData.outputTokens ? " / " : "",
22056
+ spanData.outputTokens ? `${formatTokens(spanData.outputTokens)} out` : "",
22057
+ spanData.totalTokens && ` (${formatTokens(spanData.totalTokens)} total)`
22058
+ ] })
22059
+ ] }),
22060
+ spanData.reasoningTokens && spanData.reasoningTokens > 0 && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
22061
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", color: "text.secondary", children: "Reasoning:" }),
22062
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_material21.Typography, { variant: "caption", children: [
22063
+ formatTokens(spanData.reasoningTokens),
22064
+ " tokens"
22065
+ ] })
22066
+ ] }),
22067
+ spanData.cost != null && spanData.cost > 0 && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
22068
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", color: "text.secondary", children: "Cost:" }),
22069
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", fontWeight: 500, children: formatCost(spanData.cost) })
22070
+ ] }),
22071
+ spanData.finishReason && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
22072
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", color: "text.secondary", children: "Finish:" }),
22073
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Typography, { variant: "caption", children: spanData.finishReason })
22074
+ ] })
22075
+ ]
22076
+ }
22077
+ )
22078
+ ] }),
22079
+ hasInputOutput && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
22080
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Divider, { sx: { my: 1 } }),
22081
+ spanData.input && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_material21.Box, { sx: { mb: 0.5 }, children: [
22082
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
22083
+ import_material21.Typography,
22084
+ {
22085
+ variant: "caption",
22086
+ color: "text.secondary",
22087
+ sx: { display: "block", mb: 0.25 },
22088
+ children: "Input:"
22089
+ }
22090
+ ),
22091
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
22092
+ import_material21.Typography,
22093
+ {
22094
+ variant: "caption",
22095
+ sx: {
22096
+ display: "block",
22097
+ backgroundColor: theme2.palette.action.hover,
22098
+ borderRadius: 0.5,
22099
+ p: 0.5,
22100
+ fontFamily: "monospace",
22101
+ fontSize: "0.7rem",
22102
+ whiteSpace: "pre-wrap",
22103
+ wordBreak: "break-word"
22104
+ },
22105
+ children: truncateText(spanData.input, 100)
22106
+ }
22107
+ )
22108
+ ] }),
22109
+ spanData.output && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_material21.Box, { children: [
22110
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
22111
+ import_material21.Typography,
22112
+ {
22113
+ variant: "caption",
22114
+ color: "text.secondary",
22115
+ sx: { display: "block", mb: 0.25 },
22116
+ children: "Output:"
22117
+ }
22118
+ ),
22119
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
22120
+ import_material21.Typography,
22121
+ {
22122
+ variant: "caption",
22123
+ sx: {
22124
+ display: "block",
22125
+ backgroundColor: theme2.palette.action.hover,
22126
+ borderRadius: 0.5,
22127
+ p: 0.5,
22128
+ fontFamily: "monospace",
22129
+ fontSize: "0.7rem",
22130
+ whiteSpace: "pre-wrap",
22131
+ wordBreak: "break-word"
22132
+ },
22133
+ children: truncateText(spanData.output, 100)
22134
+ }
22135
+ )
22136
+ ] })
22137
+ ] }),
22138
+ hasToolCalls && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
22139
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Divider, { sx: { my: 1 } }),
22140
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
22141
+ import_material21.Typography,
22142
+ {
22143
+ variant: "caption",
22144
+ color: "text.secondary",
22145
+ sx: { display: "block", mb: 0.25 },
22146
+ children: "Tool Calls:"
22147
+ }
22148
+ ),
22149
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
22150
+ import_material21.Typography,
22151
+ {
22152
+ variant: "caption",
22153
+ sx: {
22154
+ display: "block",
22155
+ backgroundColor: theme2.palette.action.hover,
22156
+ borderRadius: 0.5,
22157
+ p: 0.5,
22158
+ fontFamily: "monospace",
22159
+ fontSize: "0.7rem",
22160
+ whiteSpace: "pre-wrap",
22161
+ wordBreak: "break-word"
22162
+ },
22163
+ children: truncateText(spanData.toolCalls, 80)
22164
+ }
22165
+ )
22166
+ ] }),
22167
+ hasAttributes && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
22168
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_material21.Divider, { sx: { my: 1 } }),
22169
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
22170
+ import_material21.Typography,
22171
+ {
22172
+ variant: "caption",
22173
+ color: "text.secondary",
22174
+ sx: { display: "block", mb: 0.5 },
22175
+ children: "Attributes:"
22176
+ }
22177
+ ),
22178
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_material21.Box, { sx: { display: "flex", flexWrap: "wrap", gap: 0.5 }, children: [
22179
+ Object.entries(parsedAttributes).slice(0, 5).map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
22180
+ import_material21.Chip,
22181
+ {
22182
+ label: `${key}: ${truncateText(String(value), 20)}`,
22183
+ size: "small",
22184
+ variant: "outlined",
22185
+ sx: {
22186
+ height: 20,
22187
+ fontSize: "0.65rem",
22188
+ "& .MuiChip-label": { px: 0.75 }
22189
+ }
22190
+ },
22191
+ key
22192
+ )),
22193
+ Object.keys(parsedAttributes).length > 5 && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
22194
+ import_material21.Chip,
22195
+ {
22196
+ label: `+${Object.keys(parsedAttributes).length - 5} more`,
22197
+ size: "small",
22198
+ sx: {
22199
+ height: 20,
22200
+ fontSize: "0.65rem",
22201
+ "& .MuiChip-label": { px: 0.75 }
22202
+ }
22203
+ }
22204
+ )
22205
+ ] })
22206
+ ] })
22207
+ ]
22208
+ }
22209
+ );
22210
+ });
22211
+
22212
+ // src/sections/traces/trace-drawer/trace-timeline/timeline-legend.tsx
22213
+ var import_react24 = require("react");
22214
+ var import_material22 = require("@mui/material");
22215
+ var import_styles9 = require("@mui/material/styles");
22216
+ var import_jsx_runtime42 = require("react/jsx-runtime");
22217
+ var NODE_TYPE_LABELS = {
22218
+ llm: "LLM",
22219
+ tool: "Tool",
22220
+ agent: "Agent",
22221
+ retrieval: "Retrieval",
22222
+ router: "Router",
22223
+ memory: "Memory",
22224
+ default: "Other",
22225
+ start: "Start",
22226
+ end: "End"
21289
22227
  };
22228
+ var NODE_TYPE_ORDER = [
22229
+ "llm",
22230
+ "tool",
22231
+ "agent",
22232
+ "retrieval",
22233
+ "router",
22234
+ "memory",
22235
+ "default"
22236
+ ];
22237
+ var TimelineLegend = (0, import_react24.memo)(function TimelineLegend2({
22238
+ typeBreakdown,
22239
+ showCounts = false
22240
+ }) {
22241
+ const theme2 = (0, import_styles9.useTheme)();
22242
+ const visibleTypes = NODE_TYPE_ORDER.filter(
22243
+ (type) => typeBreakdown[type] !== void 0 && typeBreakdown[type] > 0
22244
+ );
22245
+ if (visibleTypes.length === 0) {
22246
+ return null;
22247
+ }
22248
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
22249
+ import_material22.Box,
22250
+ {
22251
+ sx: {
22252
+ display: "flex",
22253
+ flexWrap: "wrap",
22254
+ gap: 1.5,
22255
+ px: 1,
22256
+ py: 0.5,
22257
+ borderTop: `1px solid ${theme2.palette.divider}`,
22258
+ backgroundColor: theme2.palette.background.paper
22259
+ },
22260
+ role: "legend",
22261
+ "aria-label": "Span type legend",
22262
+ children: visibleTypes.map((type) => {
22263
+ const style4 = getNodeTypeStyle(type, theme2);
22264
+ const count = typeBreakdown[type] || 0;
22265
+ const label = NODE_TYPE_LABELS[type];
22266
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
22267
+ import_material22.Box,
22268
+ {
22269
+ sx: {
22270
+ display: "flex",
22271
+ alignItems: "center",
22272
+ gap: 0.5
22273
+ },
22274
+ children: [
22275
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
22276
+ import_material22.Box,
22277
+ {
22278
+ sx: {
22279
+ width: 12,
22280
+ height: 12,
22281
+ borderRadius: 0.5,
22282
+ backgroundColor: style4.color,
22283
+ flexShrink: 0
22284
+ }
22285
+ }
22286
+ ),
22287
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
22288
+ import_material22.Typography,
22289
+ {
22290
+ variant: "caption",
22291
+ sx: {
22292
+ color: theme2.palette.text.secondary,
22293
+ lineHeight: 1,
22294
+ whiteSpace: "nowrap"
22295
+ },
22296
+ children: [
22297
+ label,
22298
+ showCounts && count > 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
22299
+ import_material22.Typography,
22300
+ {
22301
+ component: "span",
22302
+ variant: "caption",
22303
+ sx: {
22304
+ color: theme2.palette.text.disabled,
22305
+ ml: 0.5
22306
+ },
22307
+ children: [
22308
+ "(",
22309
+ count,
22310
+ ")"
22311
+ ]
22312
+ }
22313
+ )
22314
+ ]
22315
+ }
22316
+ )
22317
+ ]
22318
+ },
22319
+ type
22320
+ );
22321
+ })
22322
+ }
22323
+ );
22324
+ });
21290
22325
 
21291
- // src/sections/traces/trace-drawer/span-info/span-info-tabs.tsx
22326
+ // src/sections/traces/trace-drawer/trace-timeline/timeline-error-boundary.tsx
22327
+ var import_react25 = require("react");
21292
22328
  var import_material23 = require("@mui/material");
22329
+ var import_jsx_runtime43 = require("react/jsx-runtime");
22330
+ var TimelineErrorBoundary = class extends import_react25.Component {
22331
+ constructor(props) {
22332
+ super(props);
22333
+ this.state = { hasError: false, error: null };
22334
+ }
22335
+ static getDerivedStateFromError(error) {
22336
+ return { hasError: true, error };
22337
+ }
22338
+ componentDidCatch(error, errorInfo) {
22339
+ console.error("Timeline rendering error:", error, errorInfo);
22340
+ }
22341
+ handleRetry = () => {
22342
+ this.setState({ hasError: false, error: null });
22343
+ };
22344
+ render() {
22345
+ if (this.state.hasError) {
22346
+ if (this.props.fallback) {
22347
+ return this.props.fallback;
22348
+ }
22349
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
22350
+ import_material23.Box,
22351
+ {
22352
+ sx: {
22353
+ p: 3,
22354
+ display: "flex",
22355
+ flexDirection: "column",
22356
+ alignItems: "center",
22357
+ justifyContent: "center",
22358
+ height: "100%",
22359
+ minHeight: 200,
22360
+ color: "text.secondary",
22361
+ textAlign: "center"
22362
+ },
22363
+ children: [
22364
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_material23.Typography, { variant: "body1", color: "error", gutterBottom: true, children: "Failed to render timeline" }),
22365
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_material23.Typography, { variant: "body2", sx: { mb: 2 }, children: "There was an error processing the span data." }),
22366
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
22367
+ import_material23.Button,
22368
+ {
22369
+ variant: "outlined",
22370
+ size: "small",
22371
+ onClick: this.handleRetry,
22372
+ children: "Retry"
22373
+ }
22374
+ )
22375
+ ]
22376
+ }
22377
+ );
22378
+ }
22379
+ return this.props.children;
22380
+ }
22381
+ };
22382
+
22383
+ // src/sections/traces/trace-drawer/trace-timeline/trace-timeline.tsx
22384
+ var import_jsx_runtime44 = require("react/jsx-runtime");
22385
+ var { ROW_HEIGHT: ROW_HEIGHT2, RULER_HEIGHT: RULER_HEIGHT2, PADDING, LABEL_WIDTH } = TIMELINE_CONSTANTS;
22386
+ var VIRTUALIZATION_THRESHOLD = 100;
22387
+ var VIRTUALIZATION_OVERSCAN = 5;
22388
+ var TraceTimeline = (0, import_react26.memo)(function TraceTimeline2({
22389
+ spans,
22390
+ selectedSpanId,
22391
+ onSelectSpan,
22392
+ showRuler = true,
22393
+ showLegend = true,
22394
+ enableZoom = true,
22395
+ enablePan = true,
22396
+ sx,
22397
+ isLoading = false
22398
+ }) {
22399
+ const theme2 = (0, import_styles10.useTheme)();
22400
+ const containerRef = (0, import_react26.useRef)(null);
22401
+ const [containerWidth, setContainerWidth] = (0, import_react26.useState)(800);
22402
+ const prevSelectedSpanIdRef = (0, import_react26.useRef)(void 0);
22403
+ const [tooltipData, setTooltipData] = (0, import_react26.useState)({ layout: null, position: null });
22404
+ const [scrollTop, setScrollTop] = (0, import_react26.useState)(0);
22405
+ const [containerHeight, setContainerHeight] = (0, import_react26.useState)(400);
22406
+ const { layouts, metrics, rulerTicks } = useTimelineLayout(spans);
22407
+ const timelineWidth = Math.max(400, containerWidth - LABEL_WIDTH - PADDING * 2);
22408
+ const contentHeight = layouts.length * ROW_HEIGHT2;
22409
+ const totalHeight = contentHeight + (showRuler ? RULER_HEIGHT2 : 0) + PADDING * 2;
22410
+ const {
22411
+ viewState,
22412
+ zoomIn,
22413
+ zoomOut,
22414
+ resetZoom,
22415
+ onWheel,
22416
+ panHandlers
22417
+ } = useTimelineZoom(timelineWidth, contentHeight);
22418
+ const { visibleLayouts } = (0, import_react26.useMemo)(() => {
22419
+ if (layouts.length < VIRTUALIZATION_THRESHOLD) {
22420
+ return {
22421
+ visibleLayouts: layouts,
22422
+ startIndex: 0,
22423
+ endIndex: layouts.length
22424
+ };
22425
+ }
22426
+ const headerOffset = showRuler ? RULER_HEIGHT2 : 0;
22427
+ const firstVisibleRow = Math.floor(
22428
+ (scrollTop - headerOffset - PADDING) / ROW_HEIGHT2
22429
+ );
22430
+ const visibleRowCount = Math.ceil(containerHeight / ROW_HEIGHT2);
22431
+ const start = Math.max(0, firstVisibleRow - VIRTUALIZATION_OVERSCAN);
22432
+ const end = Math.min(
22433
+ layouts.length,
22434
+ firstVisibleRow + visibleRowCount + VIRTUALIZATION_OVERSCAN
22435
+ );
22436
+ return {
22437
+ visibleLayouts: layouts.slice(start, end),
22438
+ startIndex: start,
22439
+ endIndex: end
22440
+ };
22441
+ }, [layouts, scrollTop, containerHeight, showRuler]);
22442
+ (0, import_react26.useEffect)(() => {
22443
+ const container = containerRef.current;
22444
+ if (!container) return;
22445
+ const resizeObserver = new ResizeObserver((entries) => {
22446
+ for (const entry of entries) {
22447
+ setContainerWidth(entry.contentRect.width);
22448
+ setContainerHeight(entry.contentRect.height);
22449
+ }
22450
+ });
22451
+ const handleScroll = () => {
22452
+ setScrollTop(container.scrollTop);
22453
+ };
22454
+ resizeObserver.observe(container);
22455
+ container.addEventListener("scroll", handleScroll, { passive: true });
22456
+ setContainerWidth(container.offsetWidth);
22457
+ setContainerHeight(container.offsetHeight);
22458
+ return () => {
22459
+ resizeObserver.disconnect();
22460
+ container.removeEventListener("scroll", handleScroll);
22461
+ };
22462
+ }, []);
22463
+ (0, import_react26.useEffect)(() => {
22464
+ if (!selectedSpanId || selectedSpanId === prevSelectedSpanIdRef.current) {
22465
+ prevSelectedSpanIdRef.current = selectedSpanId;
22466
+ return;
22467
+ }
22468
+ prevSelectedSpanIdRef.current = selectedSpanId;
22469
+ const container = containerRef.current;
22470
+ if (!container) return;
22471
+ const selectedLayout = layouts.find((l) => l.spanId === selectedSpanId);
22472
+ if (!selectedLayout) return;
22473
+ const spanY = PADDING + (showRuler ? RULER_HEIGHT2 : 0) + selectedLayout.row * ROW_HEIGHT2;
22474
+ const containerRect = container.getBoundingClientRect();
22475
+ const scrollTop2 = container.scrollTop;
22476
+ const viewportTop = scrollTop2;
22477
+ const viewportBottom = scrollTop2 + containerRect.height;
22478
+ if (spanY < viewportTop || spanY + ROW_HEIGHT2 > viewportBottom) {
22479
+ container.scrollTo({
22480
+ top: spanY - containerRect.height / 2 + ROW_HEIGHT2 / 2,
22481
+ behavior: "smooth"
22482
+ });
22483
+ }
22484
+ }, [selectedSpanId, layouts, showRuler]);
22485
+ const handleSelectSpan = (0, import_react26.useCallback)(
22486
+ (spanId) => {
22487
+ onSelectSpan?.(spanId);
22488
+ },
22489
+ [onSelectSpan]
22490
+ );
22491
+ const handleBarMouseEnter = (0, import_react26.useCallback)(
22492
+ (layout, event) => {
22493
+ setTooltipData({
22494
+ layout,
22495
+ position: { x: event.clientX, y: event.clientY }
22496
+ });
22497
+ },
22498
+ []
22499
+ );
22500
+ const handleBarMouseLeave = (0, import_react26.useCallback)(() => {
22501
+ setTooltipData({ layout: null, position: null });
22502
+ }, []);
22503
+ const [focusedIndex, setFocusedIndex] = (0, import_react26.useState)(-1);
22504
+ const handleKeyDown = (0, import_react26.useCallback)(
22505
+ (event) => {
22506
+ if (layouts.length === 0) return;
22507
+ switch (event.key) {
22508
+ case "ArrowDown":
22509
+ event.preventDefault();
22510
+ setFocusedIndex(
22511
+ (prev) => prev < layouts.length - 1 ? prev + 1 : prev
22512
+ );
22513
+ break;
22514
+ case "ArrowUp":
22515
+ event.preventDefault();
22516
+ setFocusedIndex((prev) => prev > 0 ? prev - 1 : 0);
22517
+ break;
22518
+ case "Enter":
22519
+ case " ":
22520
+ event.preventDefault();
22521
+ if (focusedIndex >= 0 && focusedIndex < layouts.length) {
22522
+ const focusedLayout = layouts[focusedIndex];
22523
+ if (focusedLayout) {
22524
+ handleSelectSpan(focusedLayout.spanId);
22525
+ }
22526
+ }
22527
+ break;
22528
+ case "Home":
22529
+ event.preventDefault();
22530
+ setFocusedIndex(0);
22531
+ break;
22532
+ case "End":
22533
+ event.preventDefault();
22534
+ setFocusedIndex(layouts.length - 1);
22535
+ break;
22536
+ }
22537
+ },
22538
+ [layouts, focusedIndex, handleSelectSpan]
22539
+ );
22540
+ if (isLoading) {
22541
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_material24.Box, { sx: { p: 2, ...sx }, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_material24.Skeleton, { variant: "rectangular", height: 200 }) });
22542
+ }
22543
+ if (spans.length === 0) {
22544
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
22545
+ import_material24.Box,
22546
+ {
22547
+ sx: {
22548
+ p: 4,
22549
+ display: "flex",
22550
+ alignItems: "center",
22551
+ justifyContent: "center",
22552
+ color: "text.secondary",
22553
+ ...sx
22554
+ },
22555
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_material24.Typography, { variant: "body2", children: "No spans to display" })
22556
+ }
22557
+ );
22558
+ }
22559
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TimelineErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
22560
+ import_material24.Box,
22561
+ {
22562
+ ref: containerRef,
22563
+ sx: {
22564
+ width: "100%",
22565
+ height: "100%",
22566
+ minHeight: 0,
22567
+ flex: 1,
22568
+ overflow: "auto",
22569
+ backgroundColor: theme2.palette.background.default,
22570
+ position: "relative",
22571
+ ...sx
22572
+ },
22573
+ children: [
22574
+ enableZoom && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
22575
+ import_material24.Box,
22576
+ {
22577
+ sx: {
22578
+ position: "sticky",
22579
+ top: 4,
22580
+ right: 4,
22581
+ zIndex: 10,
22582
+ display: "flex",
22583
+ gap: 0.5,
22584
+ justifyContent: "flex-end",
22585
+ pr: 1,
22586
+ pt: 0.5
22587
+ },
22588
+ children: [
22589
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_material24.Tooltip, { title: "Zoom in", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
22590
+ import_material24.IconButton,
22591
+ {
22592
+ size: "small",
22593
+ onClick: zoomIn,
22594
+ sx: {
22595
+ backgroundColor: theme2.palette.background.paper,
22596
+ "&:hover": { backgroundColor: theme2.palette.action.hover },
22597
+ fontSize: 16,
22598
+ fontWeight: "bold"
22599
+ },
22600
+ "aria-label": "Zoom in",
22601
+ children: "+"
22602
+ }
22603
+ ) }),
22604
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_material24.Tooltip, { title: "Zoom out", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
22605
+ import_material24.IconButton,
22606
+ {
22607
+ size: "small",
22608
+ onClick: zoomOut,
22609
+ sx: {
22610
+ backgroundColor: theme2.palette.background.paper,
22611
+ "&:hover": { backgroundColor: theme2.palette.action.hover },
22612
+ fontSize: 16,
22613
+ fontWeight: "bold"
22614
+ },
22615
+ "aria-label": "Zoom out",
22616
+ children: "\u2212"
22617
+ }
22618
+ ) }),
22619
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_material24.Tooltip, { title: "Fit all", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
22620
+ import_material24.IconButton,
22621
+ {
22622
+ size: "small",
22623
+ onClick: resetZoom,
22624
+ sx: {
22625
+ backgroundColor: theme2.palette.background.paper,
22626
+ "&:hover": { backgroundColor: theme2.palette.action.hover },
22627
+ fontSize: 12
22628
+ },
22629
+ "aria-label": "Fit all",
22630
+ children: "\u22A1"
22631
+ }
22632
+ ) })
22633
+ ]
22634
+ }
22635
+ ),
22636
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
22637
+ "svg",
22638
+ {
22639
+ width: containerWidth,
22640
+ height: totalHeight,
22641
+ viewBox: viewState.scale !== 1 ? `${viewState.viewBox.x} ${viewState.viewBox.y} ${viewState.viewBox.width} ${viewState.viewBox.height}` : void 0,
22642
+ style: {
22643
+ display: "block",
22644
+ cursor: enablePan && viewState.isPanning ? "grabbing" : enablePan ? "grab" : "default",
22645
+ outline: "none"
22646
+ },
22647
+ role: "grid",
22648
+ "aria-label": "Trace timeline",
22649
+ tabIndex: 0,
22650
+ onKeyDown: handleKeyDown,
22651
+ onWheel: enableZoom ? onWheel : void 0,
22652
+ ...enablePan ? panHandlers : {},
22653
+ children: [
22654
+ showRuler && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("g", { transform: `translate(${LABEL_WIDTH + PADDING}, ${PADDING})`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TimelineRuler, { ticks: rulerTicks, width: timelineWidth }) }),
22655
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
22656
+ "g",
22657
+ {
22658
+ transform: `translate(${PADDING}, ${PADDING + (showRuler ? RULER_HEIGHT2 : 0)})`,
22659
+ children: visibleLayouts.map((layout) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
22660
+ "text",
22661
+ {
22662
+ x: layout.depth * 12,
22663
+ y: layout.row * ROW_HEIGHT2 + ROW_HEIGHT2 / 2,
22664
+ dominantBaseline: "central",
22665
+ fontSize: 11,
22666
+ fill: theme2.palette.text.primary,
22667
+ style: {
22668
+ userSelect: "none",
22669
+ cursor: "pointer"
22670
+ },
22671
+ onClick: () => handleSelectSpan(layout.spanId),
22672
+ children: truncateLabel(layout.name, LABEL_WIDTH - layout.depth * 12 - 8)
22673
+ }
22674
+ ) }, `label-${layout.spanId}`))
22675
+ }
22676
+ ),
22677
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
22678
+ "g",
22679
+ {
22680
+ transform: `translate(${LABEL_WIDTH + PADDING}, ${PADDING + (showRuler ? RULER_HEIGHT2 : 0)})`,
22681
+ children: [
22682
+ rulerTicks.filter((tick) => tick.isMajor).map((tick, index) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
22683
+ "line",
22684
+ {
22685
+ x1: tick.position * timelineWidth,
22686
+ y1: 0,
22687
+ x2: tick.position * timelineWidth,
22688
+ y2: contentHeight,
22689
+ stroke: theme2.palette.divider,
22690
+ strokeWidth: 0.5,
22691
+ opacity: 0.5
22692
+ },
22693
+ `grid-${index}`
22694
+ )),
22695
+ visibleLayouts.map((layout) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
22696
+ "rect",
22697
+ {
22698
+ x: 0,
22699
+ y: layout.row * ROW_HEIGHT2,
22700
+ width: timelineWidth,
22701
+ height: ROW_HEIGHT2,
22702
+ fill: layout.row % 2 === 0 ? "transparent" : theme2.palette.action.hover,
22703
+ opacity: 0.3
22704
+ },
22705
+ `row-bg-${layout.spanId}`
22706
+ )),
22707
+ visibleLayouts.map((layout) => {
22708
+ const layoutIndex = layouts.findIndex((l) => l.spanId === layout.spanId);
22709
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
22710
+ TimelineBar,
22711
+ {
22712
+ layout,
22713
+ isSelected: selectedSpanId === layout.spanId,
22714
+ isFocused: focusedIndex === layoutIndex,
22715
+ onSelect: handleSelectSpan,
22716
+ onMouseEnter: handleBarMouseEnter,
22717
+ onMouseLeave: handleBarMouseLeave,
22718
+ timelineWidth
22719
+ },
22720
+ layout.spanId
22721
+ );
22722
+ })
22723
+ ]
22724
+ }
22725
+ )
22726
+ ]
22727
+ }
22728
+ ),
22729
+ showLegend && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
22730
+ TimelineLegend,
22731
+ {
22732
+ typeBreakdown: metrics.typeBreakdown,
22733
+ showCounts: true
22734
+ }
22735
+ ),
22736
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
22737
+ TimelineTooltip,
22738
+ {
22739
+ layout: tooltipData.layout,
22740
+ position: tooltipData.position,
22741
+ visible: tooltipData.layout !== null
22742
+ }
22743
+ )
22744
+ ]
22745
+ }
22746
+ ) });
22747
+ });
22748
+ function truncateLabel(label, maxWidth2) {
22749
+ const maxChars = Math.floor(maxWidth2 / 6);
22750
+ if (label.length <= maxChars) {
22751
+ return label;
22752
+ }
22753
+ return label.slice(0, maxChars - 3) + "...";
22754
+ }
22755
+
22756
+ // src/sections/traces/trace-drawer/span-info/span-info-content.tsx
22757
+ var import_material25 = require("@mui/material");
22758
+ var import_jsx_runtime45 = require("react/jsx-runtime");
22759
+ var SpanInfoTitle = ({ children }) => {
22760
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_material25.Typography, { variant: "h6", gutterBottom: true, children });
22761
+ };
22762
+ var SpanInfoContent = ({ children }) => {
22763
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_material25.Stack, { width: "100%", height: "100%", overflow: "hidden", children });
22764
+ };
22765
+
22766
+ // src/sections/traces/trace-drawer/span-info/span-info-header.tsx
22767
+ var import_material26 = require("@mui/material");
22768
+
22769
+ // src/sections/traces/trace-drawer/span-info/span-info-provider.tsx
22770
+ var import_react28 = require("react");
22771
+
22772
+ // src/sections/traces/trace-drawer/span-info/hooks/use-span-info.ts
22773
+ var import_react27 = require("react");
22774
+ var useSpanInfo = ({ span }) => {
22775
+ const [activeTab, setActiveTab] = (0, import_react27.useState)("attributes");
22776
+ const [tabs, setTabs] = (0, import_react27.useState)([]);
22777
+ const isLLMCall = (0, import_react27.useMemo)(() => {
22778
+ return span?.data?.type === "GENERATION" || !!span?.data?.model;
22779
+ }, [span?.data?.type, span?.data?.model]);
22780
+ (0, import_react27.useEffect)(() => {
22781
+ if (span?.id) {
22782
+ const newTabs = [];
22783
+ if (isLLMCall) {
22784
+ newTabs.push({
22785
+ value: "inputOutput",
22786
+ label: "Input/Output"
22787
+ });
22788
+ setActiveTab("inputOutput");
22789
+ } else {
22790
+ setActiveTab("evaluation");
22791
+ }
22792
+ newTabs.push({
22793
+ value: "evaluation",
22794
+ label: `Evaluations`
22795
+ });
22796
+ newTabs.push({
22797
+ value: "attributes",
22798
+ label: "Attributes"
22799
+ });
22800
+ setTabs(newTabs);
22801
+ }
22802
+ }, [span?.id, isLLMCall]);
22803
+ (0, import_react27.useEffect)(() => {
22804
+ const isTabValid = activeTab === "inputOutput" && isLLMCall || activeTab === "evaluation" || activeTab === "attributes";
22805
+ if (!isTabValid) {
22806
+ if (isLLMCall) {
22807
+ setActiveTab("inputOutput");
22808
+ } else {
22809
+ setActiveTab("evaluation");
22810
+ }
22811
+ }
22812
+ }, [activeTab, isLLMCall]);
22813
+ return {
22814
+ activeTab,
22815
+ setActiveTab,
22816
+ tabs,
22817
+ isLLMCall
22818
+ };
22819
+ };
22820
+
22821
+ // src/sections/traces/trace-drawer/span-info/span-info-provider.tsx
22822
+ var import_jsx_runtime46 = require("react/jsx-runtime");
22823
+ var SpanInfoContext = (0, import_react28.createContext)(
22824
+ void 0
22825
+ );
22826
+ var SpanInfoProvider = ({
22827
+ children
22828
+ }) => {
22829
+ const { selectedSpan } = useTraceDrawerContext();
22830
+ const { activeTab, setActiveTab, tabs } = useSpanInfo({
22831
+ span: selectedSpan || void 0
22832
+ });
22833
+ if (!selectedSpan) {
22834
+ return null;
22835
+ }
22836
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
22837
+ SpanInfoContext.Provider,
22838
+ {
22839
+ value: {
22840
+ span: selectedSpan,
22841
+ activeTab,
22842
+ setActiveTab,
22843
+ tabs
22844
+ },
22845
+ children
22846
+ }
22847
+ );
22848
+ };
22849
+ var useSpanInfoContext = () => {
22850
+ const context = (0, import_react28.useContext)(SpanInfoContext);
22851
+ if (!context) {
22852
+ throw new Error("useSpanInfo must be used within a SpanInfoProvider");
22853
+ }
22854
+ return context;
22855
+ };
22856
+
22857
+ // src/sections/traces/trace-drawer/span-info/span-info-header.tsx
22858
+ var import_jsx_runtime47 = require("react/jsx-runtime");
22859
+ var SpanInfoHeader = () => {
22860
+ const { span } = useSpanInfoContext();
22861
+ const { t } = useTraceDrawerContext();
22862
+ const modelName = span.data.model;
22863
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
22864
+ import_material26.Stack,
22865
+ {
22866
+ direction: "row",
22867
+ spacing: 3,
22868
+ sx: {
22869
+ px: 2,
22870
+ py: 1.5,
22871
+ borderBottom: 1,
22872
+ borderColor: "divider"
22873
+ },
22874
+ children: [
22875
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_material26.Typography, { variant: "subtitle2", children: [
22876
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_material26.Typography, { component: "span", color: "text.secondary", variant: "subtitle2", children: [
22877
+ t("spanId"),
22878
+ ":"
22879
+ ] }),
22880
+ " ",
22881
+ span.id
22882
+ ] }),
22883
+ modelName && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_material26.Typography, { variant: "subtitle2", children: [
22884
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
22885
+ import_material26.Typography,
22886
+ {
22887
+ component: "span",
22888
+ color: "text.secondary",
22889
+ variant: "subtitle2",
22890
+ children: [
22891
+ t("modelName"),
22892
+ ":"
22893
+ ]
22894
+ }
22895
+ ),
22896
+ " ",
22897
+ modelName
22898
+ ] })
22899
+ ]
22900
+ }
22901
+ );
22902
+ };
22903
+
22904
+ // src/sections/traces/trace-drawer/span-info/span-info-tabs.tsx
22905
+ var import_material27 = require("@mui/material");
21293
22906
  var import_lab = require("@mui/lab");
21294
- var import_jsx_runtime42 = require("react/jsx-runtime");
22907
+ var import_jsx_runtime48 = require("react/jsx-runtime");
21295
22908
  var SpanInfoTabs = ({ children }) => {
21296
22909
  const { activeTab, tabs, setActiveTab } = useSpanInfoContext();
21297
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_lab.TabContext, { value: activeTab, children: [
21298
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
22910
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_lab.TabContext, { value: activeTab, children: [
22911
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
21299
22912
  import_lab.TabList,
21300
22913
  {
21301
22914
  onChange: (_, value) => setActiveTab(value),
21302
22915
  scrollButtons: false,
21303
22916
  sx: { borderBottom: 1, borderColor: "divider" },
21304
- children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_material23.Tab, { label: tab.label, value: tab.value }, tab.value))
22917
+ children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_material27.Tab, { label: tab.label, value: tab.value }, tab.value))
21305
22918
  }
21306
22919
  ),
21307
22920
  children
@@ -21312,7 +22925,7 @@ var SpanInfoTabs = ({ children }) => {
21312
22925
  var import_lab2 = require("@mui/lab");
21313
22926
 
21314
22927
  // src/sections/traces/trace-drawer/span-info/tabs/hooks/use-span-attributes.ts
21315
- var import_react20 = require("react");
22928
+ var import_react29 = require("react");
21316
22929
 
21317
22930
  // src/sections/traces/trace-drawer/span-info/tabs/attribute-transformer-registry.ts
21318
22931
  var AttributeTransformerRegistry = class {
@@ -21618,7 +23231,7 @@ var transformAttributes = (attributes, normalizedData) => {
21618
23231
  // src/sections/traces/trace-drawer/span-info/tabs/hooks/use-span-attributes.ts
21619
23232
  var useSpanAttributes = () => {
21620
23233
  const { selectedSpan } = useTraceDrawerContext();
21621
- const rawAttributes = (0, import_react20.useMemo)(() => {
23234
+ const rawAttributes = (0, import_react29.useMemo)(() => {
21622
23235
  if (!selectedSpan?.data?.attributes) return {};
21623
23236
  try {
21624
23237
  return JSON.parse(selectedSpan.data.attributes);
@@ -21626,7 +23239,7 @@ var useSpanAttributes = () => {
21626
23239
  return {};
21627
23240
  }
21628
23241
  }, [selectedSpan]);
21629
- const transformedAttributes = (0, import_react20.useMemo)(() => {
23242
+ const transformedAttributes = (0, import_react29.useMemo)(() => {
21630
23243
  return transformAttributes(rawAttributes, selectedSpan?.data);
21631
23244
  }, [rawAttributes, selectedSpan?.data]);
21632
23245
  return {
@@ -21637,12 +23250,12 @@ var useSpanAttributes = () => {
21637
23250
  };
21638
23251
 
21639
23252
  // src/sections/traces/trace-drawer/span-info/tabs/attributes-tab/attributes-viewer.tsx
21640
- var import_material24 = require("@mui/material");
23253
+ var import_material28 = require("@mui/material");
21641
23254
  var import_react_codemirror2 = __toESM(require("@uiw/react-codemirror"));
21642
23255
  var import_lang_json2 = require("@codemirror/lang-json");
21643
- var import_jsx_runtime43 = require("react/jsx-runtime");
21644
- var AttributesViewer = ({ attributes }) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_material24.Box, { position: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
21645
- import_material24.Box,
23256
+ var import_jsx_runtime49 = require("react/jsx-runtime");
23257
+ var AttributesViewer = ({ attributes }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_material28.Box, { position: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
23258
+ import_material28.Box,
21646
23259
  {
21647
23260
  position: "absolute",
21648
23261
  left: 0,
@@ -21657,7 +23270,7 @@ var AttributesViewer = ({ attributes }) => /* @__PURE__ */ (0, import_jsx_runtim
21657
23270
  overflow: "hidden"
21658
23271
  }
21659
23272
  },
21660
- children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
23273
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
21661
23274
  import_react_codemirror2.default,
21662
23275
  {
21663
23276
  value: JSON.stringify(attributes, null, 2),
@@ -21680,11 +23293,11 @@ var AttributesViewer = ({ attributes }) => /* @__PURE__ */ (0, import_jsx_runtim
21680
23293
  ) });
21681
23294
 
21682
23295
  // src/sections/traces/trace-drawer/span-info/tabs/attributes-tab/attributes-tab.tsx
21683
- var import_jsx_runtime44 = require("react/jsx-runtime");
23296
+ var import_jsx_runtime50 = require("react/jsx-runtime");
21684
23297
  var AttributesTab = () => {
21685
23298
  const { transformedAttributes } = useSpanAttributes();
21686
23299
  const Panel = ({ children }) => {
21687
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
23300
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
21688
23301
  import_lab2.TabPanel,
21689
23302
  {
21690
23303
  value: "attributes",
@@ -21698,11 +23311,11 @@ var AttributesTab = () => {
21698
23311
  }
21699
23312
  );
21700
23313
  };
21701
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Panel, { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(AttributesViewer, { attributes: transformedAttributes }) });
23314
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Panel, { children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(AttributesViewer, { attributes: transformedAttributes }) });
21702
23315
  };
21703
23316
 
21704
23317
  // src/sections/traces/trace-drawer/span-info/tabs/hooks/use-span-prompts.ts
21705
- var import_react21 = require("react");
23318
+ var import_react30 = require("react");
21706
23319
  var extractPromptsFromSpan = (span) => {
21707
23320
  if (!span?.data?.input) return [];
21708
23321
  try {
@@ -21745,10 +23358,10 @@ var extractOutputFromSpan = (span) => {
21745
23358
  };
21746
23359
  var useSpanPrompts = () => {
21747
23360
  const { selectedSpan } = useTraceDrawerContext();
21748
- const prompts = (0, import_react21.useMemo)(() => {
23361
+ const prompts = (0, import_react30.useMemo)(() => {
21749
23362
  return extractPromptsFromSpan(selectedSpan);
21750
23363
  }, [selectedSpan]);
21751
- const outputData = (0, import_react21.useMemo)(() => {
23364
+ const outputData = (0, import_react30.useMemo)(() => {
21752
23365
  return extractOutputFromSpan(selectedSpan);
21753
23366
  }, [selectedSpan]);
21754
23367
  return {
@@ -21759,18 +23372,18 @@ var useSpanPrompts = () => {
21759
23372
  };
21760
23373
 
21761
23374
  // src/sections/traces/trace-drawer/span-info/tabs/input-output-tab/prompt-list.tsx
21762
- var import_material27 = require("@mui/material");
23375
+ var import_material31 = require("@mui/material");
21763
23376
 
21764
23377
  // src/sections/traces/trace-drawer/span-info/tabs/span-prompt.tsx
21765
- var import_material26 = require("@mui/material");
23378
+ var import_material30 = require("@mui/material");
21766
23379
 
21767
23380
  // src/sections/traces/trace-drawer/span-info/tabs/markdown-renderer.tsx
21768
- var import_material25 = require("@mui/material");
23381
+ var import_material29 = require("@mui/material");
21769
23382
  var import_react_markdown = __toESM(require("react-markdown"));
21770
- var import_jsx_runtime45 = require("react/jsx-runtime");
23383
+ var import_jsx_runtime51 = require("react/jsx-runtime");
21771
23384
  var CodeBlock = ({ children }) => {
21772
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
21773
- import_material25.Box,
23385
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
23386
+ import_material29.Box,
21774
23387
  {
21775
23388
  component: "pre",
21776
23389
  sx: {
@@ -21785,16 +23398,16 @@ var CodeBlock = ({ children }) => {
21785
23398
  display: "block"
21786
23399
  }
21787
23400
  },
21788
- children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("code", { children })
23401
+ children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("code", { children })
21789
23402
  }
21790
23403
  );
21791
23404
  };
21792
- var MarkdownRenderer = ({ content }) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
23405
+ var MarkdownRenderer = ({ content }) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
21793
23406
  import_react_markdown.default,
21794
23407
  {
21795
23408
  components: {
21796
- p: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
21797
- import_material25.Typography,
23409
+ p: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
23410
+ import_material29.Typography,
21798
23411
  {
21799
23412
  variant: "body2",
21800
23413
  sx: {
@@ -21804,10 +23417,10 @@ var MarkdownRenderer = ({ content }) => /* @__PURE__ */ (0, import_jsx_runtime45
21804
23417
  children
21805
23418
  }
21806
23419
  ),
21807
- pre: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(CodeBlock, { children }),
23420
+ pre: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(CodeBlock, { children }),
21808
23421
  code: (props) => {
21809
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
21810
- import_material25.Typography,
23422
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
23423
+ import_material29.Typography,
21811
23424
  {
21812
23425
  component: "code",
21813
23426
  sx: {
@@ -21820,8 +23433,8 @@ var MarkdownRenderer = ({ content }) => /* @__PURE__ */ (0, import_jsx_runtime45
21820
23433
  }
21821
23434
  );
21822
23435
  },
21823
- strong: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
21824
- import_material25.Typography,
23436
+ strong: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
23437
+ import_material29.Typography,
21825
23438
  {
21826
23439
  component: "span",
21827
23440
  sx: {
@@ -21837,7 +23450,7 @@ var MarkdownRenderer = ({ content }) => /* @__PURE__ */ (0, import_jsx_runtime45
21837
23450
  );
21838
23451
 
21839
23452
  // src/sections/traces/trace-drawer/span-info/tabs/span-prompt.tsx
21840
- var import_jsx_runtime46 = require("react/jsx-runtime");
23453
+ var import_jsx_runtime52 = require("react/jsx-runtime");
21841
23454
  var formatToolCall = (content) => {
21842
23455
  if (content.type === "tool-call") {
21843
23456
  return `**Tool Call**: \`${content.toolName}\`
@@ -21885,38 +23498,38 @@ var SpanPrompt = ({ prompt }) => {
21885
23498
  return role;
21886
23499
  }
21887
23500
  };
21888
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_material26.Accordion, { sx: { backgroundColor: "white" }, defaultExpanded: true, children: [
21889
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
21890
- import_material26.AccordionSummary,
23501
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_material30.Accordion, { sx: { backgroundColor: "white" }, defaultExpanded: true, children: [
23502
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
23503
+ import_material30.AccordionSummary,
21891
23504
  {
21892
- expandIcon: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Iconify, { icon: "mdi:chevron-down" }),
23505
+ expandIcon: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Iconify, { icon: "mdi:chevron-down" }),
21893
23506
  sx: {
21894
23507
  "& .MuiAccordionSummary-content": {
21895
23508
  alignItems: "center"
21896
23509
  }
21897
23510
  },
21898
- children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_material26.Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
21899
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
23511
+ children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_material30.Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
23512
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
21900
23513
  Iconify,
21901
23514
  {
21902
23515
  icon: prompt.role === "system" ? "mdi:cog" : prompt.role === "user" ? "mdi:account" : prompt.role === "assistant" ? "mdi:robot" : prompt.role === "tool" ? "mdi:tools" : "mdi:message"
21903
23516
  }
21904
23517
  ),
21905
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_material26.Typography, { fontWeight: 700, variant: "body2", children: getTitle(prompt.role) })
23518
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material30.Typography, { fontWeight: 700, variant: "body2", children: getTitle(prompt.role) })
21906
23519
  ] })
21907
23520
  }
21908
23521
  ),
21909
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_material26.AccordionDetails, { children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(MarkdownRenderer, { content }) })
23522
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material30.AccordionDetails, { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(MarkdownRenderer, { content }) })
21910
23523
  ] });
21911
23524
  };
21912
23525
 
21913
23526
  // src/sections/traces/trace-drawer/span-info/tabs/input-output-tab/prompt-list.tsx
21914
- var import_jsx_runtime47 = require("react/jsx-runtime");
21915
- var PromptList = ({ prompts }) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_material27.Box, { children: prompts.map((prompt, index) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(SpanPrompt, { prompt }, index)) });
23527
+ var import_jsx_runtime53 = require("react/jsx-runtime");
23528
+ var PromptList = ({ prompts }) => /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material31.Box, { children: prompts.map((prompt, index) => /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(SpanPrompt, { prompt }, index)) });
21916
23529
 
21917
23530
  // src/sections/traces/trace-drawer/span-info/tabs/output-accordion.tsx
21918
- var import_material28 = require("@mui/material");
21919
- var import_jsx_runtime48 = require("react/jsx-runtime");
23531
+ var import_material32 = require("@mui/material");
23532
+ var import_jsx_runtime54 = require("react/jsx-runtime");
21920
23533
  var formatToolCalls = (toolCallsStr) => {
21921
23534
  if (!toolCallsStr) return null;
21922
23535
  try {
@@ -22000,46 +23613,46 @@ var OutputAccordion = ({ outputData }) => {
22000
23613
  const content = outputData?.text || toolCallsText || toolCallText || objectResponse;
22001
23614
  const isObjectResponse = !!outputData?.objectResponse;
22002
23615
  const isToolResponse = !!(outputData?.toolCall?.name || outputData?.toolCall?.toolName);
22003
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_material28.Accordion, { sx: { backgroundColor: "white" }, defaultExpanded: true, children: [
22004
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
22005
- import_material28.AccordionSummary,
23616
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_material32.Accordion, { sx: { backgroundColor: "white" }, defaultExpanded: true, children: [
23617
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
23618
+ import_material32.AccordionSummary,
22006
23619
  {
22007
- expandIcon: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Iconify, { icon: "mdi:chevron-down" }),
23620
+ expandIcon: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Iconify, { icon: "mdi:chevron-down" }),
22008
23621
  sx: {
22009
23622
  "& .MuiAccordionSummary-content": {
22010
23623
  alignItems: "center"
22011
23624
  }
22012
23625
  },
22013
- children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_material28.Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
22014
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
23626
+ children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_material32.Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
23627
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
22015
23628
  Iconify,
22016
23629
  {
22017
23630
  icon: isToolResponse ? "mdi:tools" : isObjectResponse ? "mdi:code-json" : "mdi:robot"
22018
23631
  }
22019
23632
  ),
22020
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_material28.Typography, { fontWeight: 700, variant: "body2", children: isToolResponse ? t("tool") : t("assistant") })
23633
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.Typography, { fontWeight: 700, variant: "body2", children: isToolResponse ? t("tool") : t("assistant") })
22021
23634
  ] })
22022
23635
  }
22023
23636
  ),
22024
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_material28.AccordionDetails, { children: content ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(MarkdownRenderer, { content }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_material28.Typography, { variant: "body2", children: t("noOutput") }) })
23637
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.AccordionDetails, { children: content ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(MarkdownRenderer, { content }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.Typography, { variant: "body2", children: t("noOutput") }) })
22025
23638
  ] });
22026
23639
  };
22027
23640
 
22028
23641
  // src/sections/traces/trace-drawer/span-info/tabs/input-output-tab/output-display.tsx
22029
- var import_jsx_runtime49 = require("react/jsx-runtime");
23642
+ var import_jsx_runtime55 = require("react/jsx-runtime");
22030
23643
  var OutputDisplay = ({ outputData }) => {
22031
23644
  if (!outputData) return null;
22032
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(OutputAccordion, { outputData });
23645
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(OutputAccordion, { outputData });
22033
23646
  };
22034
23647
 
22035
23648
  // src/sections/traces/trace-drawer/span-info/tabs/input-output-tab/input-output-tab.tsx
22036
23649
  var import_lab3 = require("@mui/lab");
22037
- var import_material29 = require("@mui/material");
22038
- var import_jsx_runtime50 = require("react/jsx-runtime");
23650
+ var import_material33 = require("@mui/material");
23651
+ var import_jsx_runtime56 = require("react/jsx-runtime");
22039
23652
  var InputOutputTab = () => {
22040
23653
  const { prompts, outputData } = useSpanPrompts();
22041
23654
  const { span } = useSpanInfoContext();
22042
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
23655
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
22043
23656
  import_lab3.TabPanel,
22044
23657
  {
22045
23658
  sx: {
@@ -22052,9 +23665,9 @@ var InputOutputTab = () => {
22052
23665
  },
22053
23666
  value: "inputOutput",
22054
23667
  children: [
22055
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(PromptList, { prompts }),
22056
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(OutputDisplay, { outputData }),
22057
- span.data.statusMessage && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_material29.Alert, { severity: "error", sx: { mt: 2 }, children: span.data.statusMessage })
23668
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(PromptList, { prompts }),
23669
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(OutputDisplay, { outputData }),
23670
+ span.data.statusMessage && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_material33.Alert, { severity: "error", sx: { mt: 2 }, children: span.data.statusMessage })
22058
23671
  ]
22059
23672
  }
22060
23673
  );
@@ -22062,9 +23675,9 @@ var InputOutputTab = () => {
22062
23675
 
22063
23676
  // src/sections/traces/trace-drawer/span-info/tabs/evaluation-tab/evaluation-tab.tsx
22064
23677
  var import_lab4 = require("@mui/lab");
22065
- var import_jsx_runtime51 = require("react/jsx-runtime");
23678
+ var import_jsx_runtime57 = require("react/jsx-runtime");
22066
23679
  var EvaluationTab = ({ children }) => {
22067
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
23680
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
22068
23681
  import_lab4.TabPanel,
22069
23682
  {
22070
23683
  value: "evaluation",
@@ -22080,12 +23693,12 @@ var EvaluationTab = ({ children }) => {
22080
23693
  };
22081
23694
 
22082
23695
  // src/sections/traces/trace-drawer/span-info/tabs/evaluation-tab/evaluation-list.tsx
22083
- var import_material33 = require("@mui/material");
23696
+ var import_material37 = require("@mui/material");
22084
23697
 
22085
23698
  // src/sections/traces/trace-drawer/span-info/tabs/evaluation-tab/evaluation-item.tsx
22086
- var import_material30 = require("@mui/material");
22087
- var import_material31 = require("@mui/material");
22088
- var import_jsx_runtime52 = require("react/jsx-runtime");
23699
+ var import_material34 = require("@mui/material");
23700
+ var import_material35 = require("@mui/material");
23701
+ var import_jsx_runtime58 = require("react/jsx-runtime");
22089
23702
  var EvaluationItem = ({
22090
23703
  name,
22091
23704
  score,
@@ -22093,13 +23706,13 @@ var EvaluationItem = ({
22093
23706
  reason,
22094
23707
  source
22095
23708
  }) => {
22096
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_material31.TableRow, { children: [
22097
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material30.TableCell, { children: name || "-" }),
22098
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material30.TableCell, { children: score }),
22099
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material30.TableCell, { children: label }),
22100
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material30.TableCell, { sx: { whiteSpace: "pre-wrap" }, children: reason }),
22101
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material30.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
22102
- import_material30.Chip,
23709
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_material35.TableRow, { children: [
23710
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_material34.TableCell, { children: name || "-" }),
23711
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_material34.TableCell, { children: score }),
23712
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_material34.TableCell, { children: label }),
23713
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_material34.TableCell, { sx: { whiteSpace: "pre-wrap" }, children: reason }),
23714
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_material34.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
23715
+ import_material34.Chip,
22103
23716
  {
22104
23717
  size: "small",
22105
23718
  label: source || "eval",
@@ -22111,13 +23724,13 @@ var EvaluationItem = ({
22111
23724
  };
22112
23725
 
22113
23726
  // src/sections/traces/trace-drawer/span-info/tabs/evaluation-tab/evaluation-provider.tsx
22114
- var import_react22 = require("react");
22115
- var import_jsx_runtime53 = require("react/jsx-runtime");
22116
- var EvaluationContext = (0, import_react22.createContext)(
23727
+ var import_react31 = require("react");
23728
+ var import_jsx_runtime59 = require("react/jsx-runtime");
23729
+ var EvaluationContext = (0, import_react31.createContext)(
22117
23730
  void 0
22118
23731
  );
22119
23732
  var useEvaluationContext = () => {
22120
- const context = (0, import_react22.useContext)(EvaluationContext);
23733
+ const context = (0, import_react31.useContext)(EvaluationContext);
22121
23734
  if (!context) {
22122
23735
  throw new Error(
22123
23736
  "useEvaluationContext must be used within EvaluationProvider"
@@ -22131,8 +23744,8 @@ var EvaluationProvider = ({
22131
23744
  scores,
22132
23745
  isLoading
22133
23746
  }) => {
22134
- const [openAddAnnotationDialog, setOpenAddAnnotationDialog] = (0, import_react22.useState)(false);
22135
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
23747
+ const [openAddAnnotationDialog, setOpenAddAnnotationDialog] = (0, import_react31.useState)(false);
23748
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
22136
23749
  EvaluationContext.Provider,
22137
23750
  {
22138
23751
  value: {
@@ -22148,67 +23761,67 @@ var EvaluationProvider = ({
22148
23761
  };
22149
23762
 
22150
23763
  // src/sections/traces/trace-drawer/span-info/tabs/evaluation-tab/evaluation-skeleton.tsx
22151
- var import_material32 = require("@mui/material");
22152
- var import_jsx_runtime54 = require("react/jsx-runtime");
23764
+ var import_material36 = require("@mui/material");
23765
+ var import_jsx_runtime60 = require("react/jsx-runtime");
22153
23766
  var EvaluationSkeleton = () => {
22154
23767
  const { canAddAnnotation, isLoading, scores } = useEvaluationContext();
22155
23768
  const { t } = useTraceDrawerContext();
22156
23769
  if (!isLoading || scores.length > 0) {
22157
23770
  return null;
22158
23771
  }
22159
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_material32.Box, { children: [
22160
- /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
22161
- import_material32.Stack,
23772
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_material36.Box, { children: [
23773
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
23774
+ import_material36.Stack,
22162
23775
  {
22163
23776
  direction: "row",
22164
23777
  justifyContent: "space-between",
22165
23778
  alignItems: "center",
22166
23779
  sx: { mb: 1 },
22167
23780
  children: [
22168
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.Box, {}),
22169
- canAddAnnotation && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.Skeleton, { variant: "rounded", width: 120, height: 32 })
23781
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.Box, {}),
23782
+ canAddAnnotation && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.Skeleton, { variant: "rounded", width: 120, height: 32 })
22170
23783
  ]
22171
23784
  }
22172
23785
  ),
22173
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableContainer, { component: import_material32.Paper, variant: "outlined", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_material32.Table, { children: [
22174
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableHead, { children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_material32.TableRow, { children: [
22175
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableCell, { children: t("evaluationName") }),
22176
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableCell, { children: t("evaluationScore") }),
22177
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableCell, { children: t("evaluationLabel") }),
22178
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableCell, { children: t("evaluationReason") }),
22179
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableCell, { width: 120, children: "Source" })
23786
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableContainer, { component: import_material36.Paper, variant: "outlined", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_material36.Table, { children: [
23787
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableHead, { children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_material36.TableRow, { children: [
23788
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableCell, { children: t("evaluationName") }),
23789
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableCell, { children: t("evaluationScore") }),
23790
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableCell, { children: t("evaluationLabel") }),
23791
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableCell, { children: t("evaluationReason") }),
23792
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableCell, { width: 120, children: "Source" })
22180
23793
  ] }) }),
22181
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableBody, { children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_material32.TableRow, { children: [
22182
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.Skeleton, { variant: "text", width: "60%" }) }),
22183
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.Skeleton, { variant: "text", width: "40%" }) }),
22184
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.Skeleton, { variant: "text", width: "50%" }) }),
22185
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.Skeleton, { variant: "text", width: "80%" }) }),
22186
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material32.Skeleton, { variant: "text", width: "60%" }) })
23794
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableBody, { children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_material36.TableRow, { children: [
23795
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.Skeleton, { variant: "text", width: "60%" }) }),
23796
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.Skeleton, { variant: "text", width: "40%" }) }),
23797
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.Skeleton, { variant: "text", width: "50%" }) }),
23798
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.Skeleton, { variant: "text", width: "80%" }) }),
23799
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material36.Skeleton, { variant: "text", width: "60%" }) })
22187
23800
  ] }, index)) })
22188
23801
  ] }) })
22189
23802
  ] });
22190
23803
  };
22191
23804
 
22192
23805
  // src/sections/traces/trace-drawer/span-info/tabs/evaluation-tab/evaluation-list.tsx
22193
- var import_jsx_runtime55 = require("react/jsx-runtime");
23806
+ var import_jsx_runtime61 = require("react/jsx-runtime");
22194
23807
  var EvaluationList = ({
22195
23808
  emptyContentImgUrl
22196
23809
  }) => {
22197
23810
  const { scores, isLoading } = useEvaluationContext();
22198
23811
  const { t } = useTraceDrawerContext();
22199
23812
  if (isLoading) {
22200
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(EvaluationSkeleton, {});
22201
- }
22202
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_material33.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_material33.TableContainer, { component: import_material33.Paper, variant: "outlined", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_material33.Table, { children: [
22203
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_material33.TableHead, { children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_material33.TableRow, { children: [
22204
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_material33.TableCell, { children: t("evaluationName") }),
22205
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_material33.TableCell, { children: t("evaluationScore") }),
22206
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_material33.TableCell, { children: t("evaluationLabel") }),
22207
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_material33.TableCell, { children: t("evaluationReason") }),
22208
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_material33.TableCell, { width: 120, children: "Source" })
23813
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(EvaluationSkeleton, {});
23814
+ }
23815
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_material37.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_material37.TableContainer, { component: import_material37.Paper, variant: "outlined", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_material37.Table, { children: [
23816
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_material37.TableHead, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_material37.TableRow, { children: [
23817
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_material37.TableCell, { children: t("evaluationName") }),
23818
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_material37.TableCell, { children: t("evaluationScore") }),
23819
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_material37.TableCell, { children: t("evaluationLabel") }),
23820
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_material37.TableCell, { children: t("evaluationReason") }),
23821
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_material37.TableCell, { width: 120, children: "Source" })
22209
23822
  ] }) }),
22210
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_material33.TableBody, { children: [
22211
- scores.map((scoreData, index) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
23823
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_material37.TableBody, { children: [
23824
+ scores.map((scoreData, index) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
22212
23825
  EvaluationItem,
22213
23826
  {
22214
23827
  name: scoreData.name,
@@ -22219,7 +23832,7 @@ var EvaluationList = ({
22219
23832
  },
22220
23833
  index
22221
23834
  )),
22222
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
23835
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
22223
23836
  TableNoData,
22224
23837
  {
22225
23838
  title: t("noEvaluationData"),
@@ -22233,8 +23846,8 @@ var EvaluationList = ({
22233
23846
  };
22234
23847
 
22235
23848
  // src/sections/traces/trace-drawer/span-info/tabs/evaluation-tab/add-annotations.tsx
22236
- var import_material34 = require("@mui/material");
22237
- var import_jsx_runtime56 = require("react/jsx-runtime");
23849
+ var import_material38 = require("@mui/material");
23850
+ var import_jsx_runtime62 = require("react/jsx-runtime");
22238
23851
  var AddAnnotations = () => {
22239
23852
  const { t } = useTraceDrawerContext();
22240
23853
  const { setOpenAddAnnotationDialog, canAddAnnotation } = useEvaluationContext();
@@ -22244,16 +23857,16 @@ var AddAnnotations = () => {
22244
23857
  if (!canAddAnnotation) {
22245
23858
  return null;
22246
23859
  }
22247
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_jsx_runtime56.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_material34.Button, { size: "small", variant: "outlined", onClick: handleAddAnnotation, children: t("addAnnotation") }) });
23860
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_jsx_runtime62.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_material38.Button, { size: "small", variant: "outlined", onClick: handleAddAnnotation, children: t("addAnnotation") }) });
22248
23861
  };
22249
23862
 
22250
23863
  // src/sections/traces/trace-drawer/span-info/tabs/evaluation-tab/add-annotation-dialog.tsx
22251
- var import_material35 = require("@mui/material");
23864
+ var import_material39 = require("@mui/material");
22252
23865
  var import_lab5 = require("@mui/lab");
22253
23866
  var Yup = __toESM(require("yup"));
22254
23867
  var import_yup = require("@hookform/resolvers/yup");
22255
23868
  var import_react_hook_form7 = require("react-hook-form");
22256
- var import_jsx_runtime57 = require("react/jsx-runtime");
23869
+ var import_jsx_runtime63 = require("react/jsx-runtime");
22257
23870
  function AddAnnotationDialog({ saveAnnotation }) {
22258
23871
  const {
22259
23872
  setOpenAddAnnotationDialog,
@@ -22300,18 +23913,18 @@ function AddAnnotationDialog({ saveAnnotation }) {
22300
23913
  setOpenAddAnnotationDialog(false);
22301
23914
  }
22302
23915
  };
22303
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
22304
- import_material35.Dialog,
23916
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
23917
+ import_material39.Dialog,
22305
23918
  {
22306
23919
  open: openAddAnnotationDialog,
22307
23920
  onClose: handleClose,
22308
23921
  fullWidth: true,
22309
23922
  maxWidth: "sm",
22310
23923
  children: [
22311
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_material35.DialogTitle, { children: t("addAnnotationTitle") }),
22312
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(FormProvider, { methods, onSubmit, children: [
22313
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_material35.DialogContent, { dividers: true, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_material35.Stack, { spacing: 2, sx: { mt: 1 }, children: [
22314
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
23924
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_material39.DialogTitle, { children: t("addAnnotationTitle") }),
23925
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(FormProvider, { methods, onSubmit, children: [
23926
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_material39.DialogContent, { dividers: true, children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_material39.Stack, { spacing: 2, sx: { mt: 1 }, children: [
23927
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22315
23928
  RHFTextField,
22316
23929
  {
22317
23930
  name: "name",
@@ -22319,7 +23932,7 @@ function AddAnnotationDialog({ saveAnnotation }) {
22319
23932
  placeholder: t("annotationNamePlaceholder")
22320
23933
  }
22321
23934
  ),
22322
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
23935
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22323
23936
  RHFTextField,
22324
23937
  {
22325
23938
  name: "label",
@@ -22327,7 +23940,7 @@ function AddAnnotationDialog({ saveAnnotation }) {
22327
23940
  placeholder: t("annotationLabelPlaceholder")
22328
23941
  }
22329
23942
  ),
22330
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
23943
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22331
23944
  RHFTextField,
22332
23945
  {
22333
23946
  name: "score",
@@ -22336,7 +23949,7 @@ function AddAnnotationDialog({ saveAnnotation }) {
22336
23949
  inputProps: { step: "0.01" }
22337
23950
  }
22338
23951
  ),
22339
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
23952
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22340
23953
  RHFTextField,
22341
23954
  {
22342
23955
  name: "reason",
@@ -22347,9 +23960,9 @@ function AddAnnotationDialog({ saveAnnotation }) {
22347
23960
  }
22348
23961
  )
22349
23962
  ] }) }),
22350
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_material35.DialogActions, { children: [
22351
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_material35.Button, { onClick: handleClose, disabled: isSubmitting, children: t("annotationCancel") }),
22352
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
23963
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_material39.DialogActions, { children: [
23964
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_material39.Button, { onClick: handleClose, disabled: isSubmitting, children: t("annotationCancel") }),
23965
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22353
23966
  import_lab5.LoadingButton,
22354
23967
  {
22355
23968
  type: "submit",
@@ -22396,11 +24009,17 @@ function AddAnnotationDialog({ saveAnnotation }) {
22396
24009
  SpanInfoProvider,
22397
24010
  SpanInfoTabs,
22398
24011
  SpanInfoTitle,
24012
+ TIMELINE_CONSTANTS,
22399
24013
  TableEmptyRows,
22400
24014
  TableHeadCustom,
22401
24015
  TablePaginationCustom,
22402
24016
  TableSelectedAction,
22403
24017
  TableSkeleton,
24018
+ TimelineBar,
24019
+ TimelineErrorBoundary,
24020
+ TimelineLegend,
24021
+ TimelineRuler,
24022
+ TimelineTooltip,
22404
24023
  TraceDrawer,
22405
24024
  TraceDrawerCloseButton,
22406
24025
  TraceDrawerContainer,
@@ -22417,11 +24036,14 @@ function AddAnnotationDialog({ saveAnnotation }) {
22417
24036
  TraceLabel,
22418
24037
  TraceListItem,
22419
24038
  TraceListProvider,
24039
+ TraceTimeline,
22420
24040
  TraceTree,
22421
24041
  TraceTreeItem,
22422
24042
  TracesList,
22423
24043
  applyDagreLayout,
22424
24044
  calculateBranchFamilies,
24045
+ computeTimelineLayout,
24046
+ formatDuration,
22425
24047
  getBranchColor,
22426
24048
  getDisplayName,
22427
24049
  getNodeTypeStyle,
@@ -22432,6 +24054,9 @@ function AddAnnotationDialog({ saveAnnotation }) {
22432
24054
  useEvaluationContext,
22433
24055
  useSpanInfoContext,
22434
24056
  useTable,
24057
+ useTimelineLayout,
24058
+ useTimelineViewPreference,
24059
+ useTimelineZoom,
22435
24060
  useTraceDrawer,
22436
24061
  useTraceDrawerContext,
22437
24062
  useTraceListContext