@agent-inspect/viewer 6.31.6 → 6.31.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -993,6 +993,8 @@ async function extractMetadata(filePath, _quickScan) {
993
993
  }
994
994
 
995
995
  // packages/core/src/timeline.ts
996
+ var ROOT_TIMELINE_DEPTH = 0;
997
+ var MAX_TIMELINE_DEPTH = 1e3;
996
998
  function finite(n) {
997
999
  return typeof n === "number" && Number.isFinite(n);
998
1000
  }
@@ -1063,16 +1065,51 @@ function buildRunTimeline(events, options = {}) {
1063
1065
  const computeDepth = (stepId) => {
1064
1066
  const cached = depthCache.get(stepId);
1065
1067
  if (cached !== void 0) return cached;
1066
- const node = steps.get(stepId);
1067
- if (!node) return 0;
1068
- const parent = node.parentId;
1069
- if (typeof parent !== "string" || parent.trim() === "" || !steps.has(parent)) {
1070
- depthCache.set(stepId, 0);
1071
- return 0;
1068
+ const ancestry = [];
1069
+ const ancestryIndexes = /* @__PURE__ */ new Map();
1070
+ let currentStepId = stepId;
1071
+ let resolvedDepth;
1072
+ while (resolvedDepth === void 0) {
1073
+ const cachedDepth = depthCache.get(currentStepId);
1074
+ if (cachedDepth !== void 0) {
1075
+ resolvedDepth = cachedDepth;
1076
+ continue;
1077
+ }
1078
+ const cycleStart = ancestryIndexes.get(currentStepId);
1079
+ if (cycleStart !== void 0) {
1080
+ const cycleStepIds = ancestry.splice(cycleStart);
1081
+ for (const cycleStepId of cycleStepIds) {
1082
+ depthCache.set(cycleStepId, ROOT_TIMELINE_DEPTH);
1083
+ }
1084
+ resolvedDepth = ROOT_TIMELINE_DEPTH;
1085
+ continue;
1086
+ }
1087
+ const currentStep = steps.get(currentStepId);
1088
+ if (!currentStep) {
1089
+ resolvedDepth = ROOT_TIMELINE_DEPTH;
1090
+ continue;
1091
+ }
1092
+ ancestryIndexes.set(currentStepId, ancestry.length);
1093
+ ancestry.push(currentStepId);
1094
+ const parentId = currentStep.parentId;
1095
+ if (typeof parentId !== "string" || parentId.trim() === "" || !steps.has(parentId)) {
1096
+ ancestry.pop();
1097
+ depthCache.set(currentStepId, ROOT_TIMELINE_DEPTH);
1098
+ resolvedDepth = ROOT_TIMELINE_DEPTH;
1099
+ continue;
1100
+ }
1101
+ currentStepId = parentId;
1102
+ }
1103
+ ancestry.reverse();
1104
+ for (const ancestorStepId of ancestry) {
1105
+ resolvedDepth = Math.min(MAX_TIMELINE_DEPTH, resolvedDepth + 1);
1106
+ depthCache.set(ancestorStepId, resolvedDepth);
1107
+ }
1108
+ const resolvedStepDepth = depthCache.get(stepId);
1109
+ if (resolvedStepDepth === void 0) {
1110
+ throw new Error(`Failed to resolve timeline depth for step "${stepId}"`);
1072
1111
  }
1073
- const d = Math.min(1e3, computeDepth(parent) + 1);
1074
- depthCache.set(stepId, d);
1075
- return d;
1112
+ return resolvedStepDepth;
1076
1113
  };
1077
1114
  const entries = [];
1078
1115
  for (const [stepId, s] of steps.entries()) {
@@ -3813,6 +3850,23 @@ function persistedInspectEventToInspectEvent(event) {
3813
3850
  if (event.durationMs !== void 0 && Number.isFinite(event.durationMs) && event.durationMs >= 0) {
3814
3851
  out.durationMs = event.durationMs;
3815
3852
  }
3853
+ if (event.startedAt !== void 0) {
3854
+ const started = parseIsoToMs3(event.startedAt);
3855
+ if (!started.invalidTimestamp) {
3856
+ attrs.startedAtMs = started.ms;
3857
+ out.timestamp = started.ms;
3858
+ }
3859
+ }
3860
+ if (event.endedAt !== void 0) {
3861
+ const ended = parseIsoToMs3(event.endedAt);
3862
+ if (!ended.invalidTimestamp) {
3863
+ attrs.endedAtMs = ended.ms;
3864
+ if (out.durationMs === void 0 && typeof attrs.startedAtMs === "number" && ended.ms >= attrs.startedAtMs) {
3865
+ out.durationMs = ended.ms - attrs.startedAtMs;
3866
+ }
3867
+ }
3868
+ }
3869
+ out.attributes = compactAttributes2(attrs);
3816
3870
  return out;
3817
3871
  }
3818
3872
  function persistedInspectEventsToInspectEvents(events, options) {
@@ -3831,8 +3885,13 @@ function persistedInspectEventsToInspectEvents(events, options) {
3831
3885
  }
3832
3886
 
3833
3887
  // packages/core/src/persisted/tree-bridge.ts
3888
+ function logicalToPersisted(event) {
3889
+ const { sourceEventIds: _sourceEventIds, projection: _projection, ...rest } = event;
3890
+ return rest;
3891
+ }
3834
3892
  function persistedInspectEventsToRunTrees(events, options) {
3835
- const inspectEvents = persistedInspectEventsToInspectEvents(events, {
3893
+ const sourceEvents = options?.coalesceLifecycle === true ? projectLogicalEvents(events).logicalEvents.map(logicalToPersisted) : events;
3894
+ const inspectEvents = persistedInspectEventsToInspectEvents(sourceEvents, {
3836
3895
  skipInvalid: options?.skipInvalid
3837
3896
  });
3838
3897
  return new TreeBuilder().build(inspectEvents);
@@ -4526,7 +4585,7 @@ function mapOpenInferenceSpan(span, index, version) {
4526
4585
  const errorMessage = isRecord7(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
4527
4586
  const event = {
4528
4587
  schemaVersion: "0.2",
4529
- eventId: typeof rawAttributes["agent_inspect.event_id"] === "string" ? rawAttributes["agent_inspect.event_id"] : spanId,
4588
+ eventId: typeof rawAttributes["agent_inspect.event_id"] === "string" ? rawAttributes["agent_inspect.event_id"] : `${traceId}:${spanId}`,
4530
4589
  runId: typeof rawAttributes["agent_inspect.run_id"] === "string" ? rawAttributes["agent_inspect.run_id"] : traceId,
4531
4590
  kind,
4532
4591
  name,
@@ -4577,12 +4636,16 @@ function mapOpenInferenceEvents(document) {
4577
4636
  const mapped = document.spans.map(
4578
4637
  (span, index) => mapOpenInferenceSpan(span, index, document.version)
4579
4638
  );
4580
- const spanIdToEventId = new Map(
4581
- mapped.map((span) => [span.spanId, span.event.eventId])
4639
+ const spanKeyToEventId = new Map(
4640
+ mapped.map((span) => {
4641
+ const traceId = typeof span.event.trace?.traceId === "string" ? span.event.trace.traceId : "";
4642
+ return [`${traceId}:${span.spanId}`, span.event.eventId];
4643
+ })
4582
4644
  );
4583
4645
  for (const span of mapped) {
4584
4646
  if (span.parentSpanId === void 0) continue;
4585
- span.event.parentId = spanIdToEventId.get(span.parentSpanId) ?? span.parentSpanId;
4647
+ const traceId = typeof span.event.trace?.traceId === "string" ? span.event.trace.traceId : "";
4648
+ span.event.parentId = spanKeyToEventId.get(`${traceId}:${span.parentSpanId}`) ?? span.parentSpanId;
4586
4649
  }
4587
4650
  return {
4588
4651
  events: mapped.map((span) => span.event),
@@ -4874,20 +4937,38 @@ function extractOtlpDocument(root) {
4874
4937
  function mapOtlpStatus(status) {
4875
4938
  if (!isRecord7(status)) return void 0;
4876
4939
  const rawCode = status.code;
4877
- if (typeof rawCode !== "string") return void 0;
4878
- switch (rawCode.toUpperCase()) {
4879
- case "STATUS_CODE_OK":
4880
- case "OK":
4881
- return "ok";
4882
- case "STATUS_CODE_ERROR":
4883
- case "ERROR":
4884
- return "error";
4885
- case "STATUS_CODE_UNSET":
4886
- case "UNSET":
4887
- return "unknown";
4888
- default:
4889
- return "unknown";
4940
+ if (typeof rawCode === "number" && Number.isFinite(rawCode)) {
4941
+ switch (rawCode) {
4942
+ case 0:
4943
+ return "unknown";
4944
+ case 1:
4945
+ return "ok";
4946
+ case 2:
4947
+ return "error";
4948
+ default:
4949
+ return "unknown";
4950
+ }
4951
+ }
4952
+ if (typeof rawCode === "string") {
4953
+ const trimmed = rawCode.trim();
4954
+ if (/^\d+$/.test(trimmed)) {
4955
+ return mapOtlpStatus({ code: Number(trimmed) });
4956
+ }
4957
+ switch (trimmed.toUpperCase()) {
4958
+ case "STATUS_CODE_OK":
4959
+ case "OK":
4960
+ return "ok";
4961
+ case "STATUS_CODE_ERROR":
4962
+ case "ERROR":
4963
+ return "error";
4964
+ case "STATUS_CODE_UNSET":
4965
+ case "UNSET":
4966
+ return "unknown";
4967
+ default:
4968
+ return "unknown";
4969
+ }
4890
4970
  }
4971
+ return void 0;
4891
4972
  }
4892
4973
  function readOtlpKind(attributes, pathPrefix) {
4893
4974
  const warnings = [];
@@ -5113,7 +5194,7 @@ function mapOtlpSpan(context) {
5113
5194
  const errorMessage = isRecord7(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
5114
5195
  const event = {
5115
5196
  schemaVersion: "0.2",
5116
- eventId: typeof parsedSpanAttributes.attributes["agent_inspect.event_id"] === "string" ? parsedSpanAttributes.attributes["agent_inspect.event_id"] : spanId,
5197
+ eventId: typeof parsedSpanAttributes.attributes["agent_inspect.event_id"] === "string" ? parsedSpanAttributes.attributes["agent_inspect.event_id"] : `${traceId}:${spanId}`,
5117
5198
  runId: typeof parsedSpanAttributes.attributes["agent_inspect.run_id"] === "string" ? parsedSpanAttributes.attributes["agent_inspect.run_id"] : traceId,
5118
5199
  kind,
5119
5200
  name: readStringField(span, ["name"]) ?? spanId,
@@ -5162,12 +5243,16 @@ function mapOtlpSpan(context) {
5162
5243
  }
5163
5244
  function mapOtlpEventsToPersisted(document) {
5164
5245
  const mapped = document.spans.map((span) => mapOtlpSpan(span));
5165
- const spanIdToEventId = new Map(
5166
- mapped.map((span) => [span.spanId, span.event.eventId])
5246
+ const spanKeyToEventId = new Map(
5247
+ mapped.map((span) => {
5248
+ const traceId = typeof span.event.trace?.traceId === "string" ? span.event.trace.traceId : "";
5249
+ return [`${traceId}:${span.spanId}`, span.event.eventId];
5250
+ })
5167
5251
  );
5168
5252
  for (const span of mapped) {
5169
5253
  if (span.parentSpanId === void 0) continue;
5170
- span.event.parentId = spanIdToEventId.get(span.parentSpanId) ?? span.parentSpanId;
5254
+ const traceId = typeof span.event.trace?.traceId === "string" ? span.event.trace.traceId : "";
5255
+ span.event.parentId = spanKeyToEventId.get(`${traceId}:${span.parentSpanId}`) ?? span.parentSpanId;
5171
5256
  }
5172
5257
  return {
5173
5258
  events: mapped.map((span) => span.event),