@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.cjs CHANGED
@@ -1000,6 +1000,8 @@ async function extractMetadata(filePath, _quickScan) {
1000
1000
  }
1001
1001
 
1002
1002
  // packages/core/src/timeline.ts
1003
+ var ROOT_TIMELINE_DEPTH = 0;
1004
+ var MAX_TIMELINE_DEPTH = 1e3;
1003
1005
  function finite(n) {
1004
1006
  return typeof n === "number" && Number.isFinite(n);
1005
1007
  }
@@ -1070,16 +1072,51 @@ function buildRunTimeline(events, options = {}) {
1070
1072
  const computeDepth = (stepId) => {
1071
1073
  const cached = depthCache.get(stepId);
1072
1074
  if (cached !== void 0) return cached;
1073
- const node = steps.get(stepId);
1074
- if (!node) return 0;
1075
- const parent = node.parentId;
1076
- if (typeof parent !== "string" || parent.trim() === "" || !steps.has(parent)) {
1077
- depthCache.set(stepId, 0);
1078
- return 0;
1075
+ const ancestry = [];
1076
+ const ancestryIndexes = /* @__PURE__ */ new Map();
1077
+ let currentStepId = stepId;
1078
+ let resolvedDepth;
1079
+ while (resolvedDepth === void 0) {
1080
+ const cachedDepth = depthCache.get(currentStepId);
1081
+ if (cachedDepth !== void 0) {
1082
+ resolvedDepth = cachedDepth;
1083
+ continue;
1084
+ }
1085
+ const cycleStart = ancestryIndexes.get(currentStepId);
1086
+ if (cycleStart !== void 0) {
1087
+ const cycleStepIds = ancestry.splice(cycleStart);
1088
+ for (const cycleStepId of cycleStepIds) {
1089
+ depthCache.set(cycleStepId, ROOT_TIMELINE_DEPTH);
1090
+ }
1091
+ resolvedDepth = ROOT_TIMELINE_DEPTH;
1092
+ continue;
1093
+ }
1094
+ const currentStep = steps.get(currentStepId);
1095
+ if (!currentStep) {
1096
+ resolvedDepth = ROOT_TIMELINE_DEPTH;
1097
+ continue;
1098
+ }
1099
+ ancestryIndexes.set(currentStepId, ancestry.length);
1100
+ ancestry.push(currentStepId);
1101
+ const parentId = currentStep.parentId;
1102
+ if (typeof parentId !== "string" || parentId.trim() === "" || !steps.has(parentId)) {
1103
+ ancestry.pop();
1104
+ depthCache.set(currentStepId, ROOT_TIMELINE_DEPTH);
1105
+ resolvedDepth = ROOT_TIMELINE_DEPTH;
1106
+ continue;
1107
+ }
1108
+ currentStepId = parentId;
1109
+ }
1110
+ ancestry.reverse();
1111
+ for (const ancestorStepId of ancestry) {
1112
+ resolvedDepth = Math.min(MAX_TIMELINE_DEPTH, resolvedDepth + 1);
1113
+ depthCache.set(ancestorStepId, resolvedDepth);
1114
+ }
1115
+ const resolvedStepDepth = depthCache.get(stepId);
1116
+ if (resolvedStepDepth === void 0) {
1117
+ throw new Error(`Failed to resolve timeline depth for step "${stepId}"`);
1079
1118
  }
1080
- const d = Math.min(1e3, computeDepth(parent) + 1);
1081
- depthCache.set(stepId, d);
1082
- return d;
1119
+ return resolvedStepDepth;
1083
1120
  };
1084
1121
  const entries = [];
1085
1122
  for (const [stepId, s] of steps.entries()) {
@@ -3820,6 +3857,23 @@ function persistedInspectEventToInspectEvent(event) {
3820
3857
  if (event.durationMs !== void 0 && Number.isFinite(event.durationMs) && event.durationMs >= 0) {
3821
3858
  out.durationMs = event.durationMs;
3822
3859
  }
3860
+ if (event.startedAt !== void 0) {
3861
+ const started = parseIsoToMs3(event.startedAt);
3862
+ if (!started.invalidTimestamp) {
3863
+ attrs.startedAtMs = started.ms;
3864
+ out.timestamp = started.ms;
3865
+ }
3866
+ }
3867
+ if (event.endedAt !== void 0) {
3868
+ const ended = parseIsoToMs3(event.endedAt);
3869
+ if (!ended.invalidTimestamp) {
3870
+ attrs.endedAtMs = ended.ms;
3871
+ if (out.durationMs === void 0 && typeof attrs.startedAtMs === "number" && ended.ms >= attrs.startedAtMs) {
3872
+ out.durationMs = ended.ms - attrs.startedAtMs;
3873
+ }
3874
+ }
3875
+ }
3876
+ out.attributes = compactAttributes2(attrs);
3823
3877
  return out;
3824
3878
  }
3825
3879
  function persistedInspectEventsToInspectEvents(events, options) {
@@ -3838,8 +3892,13 @@ function persistedInspectEventsToInspectEvents(events, options) {
3838
3892
  }
3839
3893
 
3840
3894
  // packages/core/src/persisted/tree-bridge.ts
3895
+ function logicalToPersisted(event) {
3896
+ const { sourceEventIds: _sourceEventIds, projection: _projection, ...rest } = event;
3897
+ return rest;
3898
+ }
3841
3899
  function persistedInspectEventsToRunTrees(events, options) {
3842
- const inspectEvents = persistedInspectEventsToInspectEvents(events, {
3900
+ const sourceEvents = options?.coalesceLifecycle === true ? projectLogicalEvents(events).logicalEvents.map(logicalToPersisted) : events;
3901
+ const inspectEvents = persistedInspectEventsToInspectEvents(sourceEvents, {
3843
3902
  skipInvalid: options?.skipInvalid
3844
3903
  });
3845
3904
  return new TreeBuilder().build(inspectEvents);
@@ -4533,7 +4592,7 @@ function mapOpenInferenceSpan(span, index, version) {
4533
4592
  const errorMessage = isRecord7(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
4534
4593
  const event = {
4535
4594
  schemaVersion: "0.2",
4536
- eventId: typeof rawAttributes["agent_inspect.event_id"] === "string" ? rawAttributes["agent_inspect.event_id"] : spanId,
4595
+ eventId: typeof rawAttributes["agent_inspect.event_id"] === "string" ? rawAttributes["agent_inspect.event_id"] : `${traceId}:${spanId}`,
4537
4596
  runId: typeof rawAttributes["agent_inspect.run_id"] === "string" ? rawAttributes["agent_inspect.run_id"] : traceId,
4538
4597
  kind,
4539
4598
  name,
@@ -4584,12 +4643,16 @@ function mapOpenInferenceEvents(document) {
4584
4643
  const mapped = document.spans.map(
4585
4644
  (span, index) => mapOpenInferenceSpan(span, index, document.version)
4586
4645
  );
4587
- const spanIdToEventId = new Map(
4588
- mapped.map((span) => [span.spanId, span.event.eventId])
4646
+ const spanKeyToEventId = new Map(
4647
+ mapped.map((span) => {
4648
+ const traceId = typeof span.event.trace?.traceId === "string" ? span.event.trace.traceId : "";
4649
+ return [`${traceId}:${span.spanId}`, span.event.eventId];
4650
+ })
4589
4651
  );
4590
4652
  for (const span of mapped) {
4591
4653
  if (span.parentSpanId === void 0) continue;
4592
- span.event.parentId = spanIdToEventId.get(span.parentSpanId) ?? span.parentSpanId;
4654
+ const traceId = typeof span.event.trace?.traceId === "string" ? span.event.trace.traceId : "";
4655
+ span.event.parentId = spanKeyToEventId.get(`${traceId}:${span.parentSpanId}`) ?? span.parentSpanId;
4593
4656
  }
4594
4657
  return {
4595
4658
  events: mapped.map((span) => span.event),
@@ -4881,20 +4944,38 @@ function extractOtlpDocument(root) {
4881
4944
  function mapOtlpStatus(status) {
4882
4945
  if (!isRecord7(status)) return void 0;
4883
4946
  const rawCode = status.code;
4884
- if (typeof rawCode !== "string") return void 0;
4885
- switch (rawCode.toUpperCase()) {
4886
- case "STATUS_CODE_OK":
4887
- case "OK":
4888
- return "ok";
4889
- case "STATUS_CODE_ERROR":
4890
- case "ERROR":
4891
- return "error";
4892
- case "STATUS_CODE_UNSET":
4893
- case "UNSET":
4894
- return "unknown";
4895
- default:
4896
- return "unknown";
4947
+ if (typeof rawCode === "number" && Number.isFinite(rawCode)) {
4948
+ switch (rawCode) {
4949
+ case 0:
4950
+ return "unknown";
4951
+ case 1:
4952
+ return "ok";
4953
+ case 2:
4954
+ return "error";
4955
+ default:
4956
+ return "unknown";
4957
+ }
4958
+ }
4959
+ if (typeof rawCode === "string") {
4960
+ const trimmed = rawCode.trim();
4961
+ if (/^\d+$/.test(trimmed)) {
4962
+ return mapOtlpStatus({ code: Number(trimmed) });
4963
+ }
4964
+ switch (trimmed.toUpperCase()) {
4965
+ case "STATUS_CODE_OK":
4966
+ case "OK":
4967
+ return "ok";
4968
+ case "STATUS_CODE_ERROR":
4969
+ case "ERROR":
4970
+ return "error";
4971
+ case "STATUS_CODE_UNSET":
4972
+ case "UNSET":
4973
+ return "unknown";
4974
+ default:
4975
+ return "unknown";
4976
+ }
4897
4977
  }
4978
+ return void 0;
4898
4979
  }
4899
4980
  function readOtlpKind(attributes, pathPrefix) {
4900
4981
  const warnings = [];
@@ -5120,7 +5201,7 @@ function mapOtlpSpan(context) {
5120
5201
  const errorMessage = isRecord7(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
5121
5202
  const event = {
5122
5203
  schemaVersion: "0.2",
5123
- eventId: typeof parsedSpanAttributes.attributes["agent_inspect.event_id"] === "string" ? parsedSpanAttributes.attributes["agent_inspect.event_id"] : spanId,
5204
+ eventId: typeof parsedSpanAttributes.attributes["agent_inspect.event_id"] === "string" ? parsedSpanAttributes.attributes["agent_inspect.event_id"] : `${traceId}:${spanId}`,
5124
5205
  runId: typeof parsedSpanAttributes.attributes["agent_inspect.run_id"] === "string" ? parsedSpanAttributes.attributes["agent_inspect.run_id"] : traceId,
5125
5206
  kind,
5126
5207
  name: readStringField(span, ["name"]) ?? spanId,
@@ -5169,12 +5250,16 @@ function mapOtlpSpan(context) {
5169
5250
  }
5170
5251
  function mapOtlpEventsToPersisted(document) {
5171
5252
  const mapped = document.spans.map((span) => mapOtlpSpan(span));
5172
- const spanIdToEventId = new Map(
5173
- mapped.map((span) => [span.spanId, span.event.eventId])
5253
+ const spanKeyToEventId = new Map(
5254
+ mapped.map((span) => {
5255
+ const traceId = typeof span.event.trace?.traceId === "string" ? span.event.trace.traceId : "";
5256
+ return [`${traceId}:${span.spanId}`, span.event.eventId];
5257
+ })
5174
5258
  );
5175
5259
  for (const span of mapped) {
5176
5260
  if (span.parentSpanId === void 0) continue;
5177
- span.event.parentId = spanIdToEventId.get(span.parentSpanId) ?? span.parentSpanId;
5261
+ const traceId = typeof span.event.trace?.traceId === "string" ? span.event.trace.traceId : "";
5262
+ span.event.parentId = spanKeyToEventId.get(`${traceId}:${span.parentSpanId}`) ?? span.parentSpanId;
5178
5263
  }
5179
5264
  return {
5180
5265
  events: mapped.map((span) => span.event),