@mastra/duckdb 1.14.0 → 1.14.1-alpha.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.
@@ -108,7 +108,22 @@ CREATE TABLE IF NOT EXISTS span_events (
108
108
  links JSON,
109
109
  input JSON,
110
110
  output JSON,
111
- error JSON
111
+ error JSON,
112
+
113
+ -- Previews of input/output/error in the shared core format, set on the
114
+ -- event rows that carry the matching payload ('' = nothing to preview).
115
+ -- NULL marks a row written before previews were stored, or a row that does
116
+ -- not carry that payload.
117
+ inputPreview VARCHAR,
118
+ outputPreview VARCHAR,
119
+ errorPreview VARCHAR,
120
+
121
+ -- Whether this row carries a non-null input/output/error payload. Lets the
122
+ -- light trace list pick each preview's row without reading the payloads.
123
+ -- NULL on rows written before these columns existed.
124
+ hasInputPayload BOOLEAN,
125
+ hasOutputPayload BOOLEAN,
126
+ hasErrorPayload BOOLEAN
112
127
  )`;
113
128
  /** DDL for the metric_events append-only table. */
114
129
  const METRIC_EVENTS_DDL = `
@@ -349,6 +364,12 @@ const ALL_MIGRATIONS = [
349
364
  `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS entityVersionId VARCHAR`,
350
365
  `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS parentEntityVersionId VARCHAR`,
351
366
  `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS rootEntityVersionId VARCHAR`,
367
+ `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS inputPreview VARCHAR`,
368
+ `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS outputPreview VARCHAR`,
369
+ `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS errorPreview VARCHAR`,
370
+ `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS hasInputPayload BOOLEAN`,
371
+ `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS hasOutputPayload BOOLEAN`,
372
+ `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS hasErrorPayload BOOLEAN`,
352
373
  `ALTER TABLE metric_events ADD COLUMN IF NOT EXISTS cursorId BIGINT`,
353
374
  `ALTER TABLE metric_events ADD COLUMN IF NOT EXISTS entityVersionId VARCHAR`,
354
375
  `ALTER TABLE metric_events ADD COLUMN IF NOT EXISTS parentEntityVersionId VARCHAR`,
@@ -679,6 +700,46 @@ function buildPaginationClause(pagination) {
679
700
  };
680
701
  }
681
702
  //#endregion
703
+ //#region src/storage/domains/observability/preview-compat.ts
704
+ const generator = _mastra_core_storage.buildStoredPreview;
705
+ const canGeneratePreviews = typeof generator === "function";
706
+ /** SQL detection only; preview formatting stays in TypeScript. Empty strings are intentional. */
707
+ function missingPreviewSql(column) {
708
+ return canGeneratePreviews ? `${column} IS NULL` : "FALSE";
709
+ }
710
+ function needsPreview(value) {
711
+ return canGeneratePreviews && value == null;
712
+ }
713
+ function storedPreview(preview, value, serialized) {
714
+ return canGeneratePreviews ? generator(preview, value, serialized) : preview ?? null;
715
+ }
716
+ function readPreview(preview, payload, jsonEncoded = false) {
717
+ const supplied = preview;
718
+ if (!canGeneratePreviews) return supplied ?? null;
719
+ if (supplied != null) return supplied.trim() || null;
720
+ let value = payload;
721
+ if (needsPreview(preview) && jsonEncoded && typeof payload === "string") try {
722
+ value = JSON.parse(payload);
723
+ } catch {
724
+ value = null;
725
+ }
726
+ return storedPreview(supplied, value, jsonEncoded && typeof payload === "string" ? payload : void 0) || null;
727
+ }
728
+ /** Older response builders may shorten previews or turn empty strings into null. */
729
+ function buildSpanQueryResponse(...args) {
730
+ if (canGeneratePreviews) return _mastra_core_storage.buildSpanQueryResponse(...args);
731
+ const [plan, selected, payloads, metrics] = args;
732
+ const response = _mastra_core_storage.buildSpanQueryResponse(plan, selected, [], metrics);
733
+ const byIdentity = new Map(payloads.map((payload) => [_mastra_core_storage.spanQueryIdentityKey(payload), payload]));
734
+ for (const span of response.spans) {
735
+ const payload = byIdentity.get(_mastra_core_storage.spanQueryIdentityKey(span));
736
+ span.inputPreview = payload?.inputPreview ?? null;
737
+ span.outputPreview = payload?.outputPreview ?? null;
738
+ span.errorPreview = payload?.errorPreview ?? null;
739
+ }
740
+ return response;
741
+ }
742
+ //#endregion
682
743
  //#region src/storage/domains/observability/helpers.ts
683
744
  /** Shorthand for {@link DuckDBConnection.sqlValue}. */
684
745
  const v = require_features.DuckDBConnection.sqlValue;
@@ -759,6 +820,18 @@ function parseJsonArray(value) {
759
820
  const parsed = parseJson(value);
760
821
  return Array.isArray(parsed) ? parsed : null;
761
822
  }
823
+ /**
824
+ * Preview of a payload read back from a span_events JSON column, for rows written before previews
825
+ * were stored. JSON text goes through `buildPreviewFromJson`, so the result matches what the writer
826
+ * would have stored for the same value; an already decoded value goes through `buildPreview`.
827
+ */
828
+ function previewFromPayload(value) {
829
+ return readPreview(null, value, typeof value === "string");
830
+ }
831
+ /** A stored preview as the API returns it: `''` (nothing to preview) and NULL both become null. */
832
+ function apiPreview(value) {
833
+ return readPreview(value);
834
+ }
762
835
  //#endregion
763
836
  //#region src/storage/domains/observability/polling.ts
764
837
  const OBSERVABILITY_DELTA_POLLING_FEATURE = "observability-delta-polling";
@@ -2962,7 +3035,12 @@ const TRACE_SELECT = `
2962
3035
  r.entityId AS entityId,
2963
3036
  r.parentSpanId AS parentSpanId,
2964
3037
  r.metadata AS metadata,
2965
- ${payloadColumnSql("r.input")} AS input,
3038
+ r.inputPreview AS inputPreview,
3039
+ r.outputPreview AS outputPreview,
3040
+ r.errorPreview AS errorPreview,
3041
+ r.eventType AS rootEventType,
3042
+ r.timestamp AS rootTimestamp,
3043
+ r.cursorId AS rootCursorId,
2966
3044
  r.threadId AS threadId,
2967
3045
  r.resourceId AS resourceId,
2968
3046
  r.startedAt AS startedAt,
@@ -3613,12 +3691,44 @@ async function getTraceQueryValues(db, plan) {
3613
3691
  function asIsoTimestamp(value) {
3614
3692
  return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
3615
3693
  }
3694
+ const TRACE_PREVIEW_PAYLOADS = [
3695
+ ["inputPreview", "input"],
3696
+ ["outputPreview", "output"],
3697
+ ["errorPreview", "error"]
3698
+ ];
3699
+ /**
3700
+ * Builds the previews of listed roots whose current row was written before previews were stored
3701
+ * (NULL preview), from that same row's payload. Only the flagged rows' payloads are read, so the
3702
+ * fallback fades out as old rows age out of the listed range. Rows written since then carry a
3703
+ * non-NULL preview (`''` when there is nothing to preview) for every payload they hold.
3704
+ */
3705
+ async function fillMissingTracePreviews(db, rows) {
3706
+ const flagged = rows.filter((row) => row.traceId != null && TRACE_PREVIEW_PAYLOADS.some(([preview]) => needsPreview(row[preview])));
3707
+ if (flagged.length === 0) return;
3708
+ const values = [];
3709
+ const where = flagged.map((row) => {
3710
+ values.push(row.traceId, row.rootSpanId, row.rootEventType, row.rootTimestamp, row.rootCursorId);
3711
+ return "(traceId = ? AND spanId = ? AND eventType = ? AND timestamp = ? AND cursorId IS NOT DISTINCT FROM ?)";
3712
+ }).join(" OR ");
3713
+ const payloads = await db.query(`SELECT traceId,
3714
+ ${payloadColumnSql("input")} AS input,
3715
+ ${payloadColumnSql("output")} AS output,
3716
+ error
3717
+ FROM span_events
3718
+ WHERE parentSpanId IS NULL AND (${where})`, values);
3719
+ const byTrace = new Map(payloads.map((payload) => [String(payload.traceId), payload]));
3720
+ for (const row of flagged) {
3721
+ const payload = byTrace.get(String(row.traceId));
3722
+ for (const [preview, column] of TRACE_PREVIEW_PAYLOADS) if (needsPreview(row[preview])) row[preview] = previewFromPayload(payload?.[column] ?? null);
3723
+ }
3724
+ }
3616
3725
  async function queryTraces(db, plan) {
3617
3726
  if (plan.paginationMode === "delta") assertDeltaPollingEnabled();
3618
3727
  if (plan.paginationMode === "page") {
3619
3728
  const query = compileDuckDBTraceQuery(plan);
3620
3729
  const rows = await db.query(query.sql, query.values);
3621
3730
  const total = Number(rows[0]?.total ?? 0);
3731
+ await fillMissingTracePreviews(db, rows);
3622
3732
  const traces = rows.filter((row) => row.traceId != null).map((row) => ({
3623
3733
  traceId: String(row.traceId),
3624
3734
  rootSpanId: String(row.rootSpanId),
@@ -3627,7 +3737,9 @@ async function queryTraces(db, plan) {
3627
3737
  parentSpanId: row.parentSpanId ?? null,
3628
3738
  createdAt: asIsoTimestamp(row.startedAt),
3629
3739
  metadata: parseJson(row.metadata) ?? null,
3630
- inputPreview: _mastra_core_storage.buildInputPreview(row.input) ?? null,
3740
+ inputPreview: apiPreview(row.inputPreview),
3741
+ outputPreview: apiPreview(row.outputPreview),
3742
+ errorPreview: apiPreview(row.errorPreview),
3631
3743
  threadId: row.threadId == null ? null : String(row.threadId),
3632
3744
  resourceId: row.resourceId == null ? null : String(row.resourceId),
3633
3745
  startedAt: asIsoTimestamp(row.startedAt),
@@ -3663,6 +3775,7 @@ async function queryTraces(db, plan) {
3663
3775
  }) : null }
3664
3776
  });
3665
3777
  }
3778
+ await fillMissingTracePreviews(db, visibleRows);
3666
3779
  const traces = visibleRows.map((row) => ({
3667
3780
  traceId: String(row.traceId),
3668
3781
  rootSpanId: String(row.rootSpanId),
@@ -3671,7 +3784,9 @@ async function queryTraces(db, plan) {
3671
3784
  parentSpanId: row.parentSpanId ?? null,
3672
3785
  createdAt: asIsoTimestamp(row.startedAt),
3673
3786
  metadata: parseJson(row.metadata) ?? null,
3674
- inputPreview: _mastra_core_storage.buildInputPreview(row.input) ?? null,
3787
+ inputPreview: apiPreview(row.inputPreview),
3788
+ outputPreview: apiPreview(row.outputPreview),
3789
+ errorPreview: apiPreview(row.errorPreview),
3675
3790
  threadId: row.threadId == null ? null : String(row.threadId),
3676
3791
  resourceId: row.resourceId == null ? null : String(row.resourceId),
3677
3792
  startedAt: asIsoTimestamp(row.startedAt),
@@ -3834,6 +3949,11 @@ function compileDuckDBSpanQuery(plan) {
3834
3949
  values
3835
3950
  };
3836
3951
  }
3952
+ const previewPayloads = [
3953
+ ["inputPreview", payloadColumnSql("input")],
3954
+ ["outputPreview", payloadColumnSql("output")],
3955
+ ["errorPreview", "error"]
3956
+ ];
3837
3957
  async function querySpans(db, plan) {
3838
3958
  const deadline = performance.now() + _mastra_core_storage.TRACE_QUERY_DEFAULT_TIMEOUT_MS;
3839
3959
  const query = async (sql, values) => {
@@ -3862,9 +3982,24 @@ async function querySpans(db, plan) {
3862
3982
  payloadValues.push(row.cursorId, row.endedAt);
3863
3983
  return `(${key} AND cursorId IS NOT DISTINCT FROM ? AND endedAt = ?)`;
3864
3984
  }).join(" OR ");
3865
- const payloads = await query(`SELECT DISTINCT ${identities},
3866
- substring(CAST(${payloadColumnSql("input")} AS VARCHAR), 1, ${_mastra_core_storage.SPAN_QUERY_MAX_PREVIEW_CHARACTERS + 1}) AS inputPreview, substring(CAST(${payloadColumnSql("output")} AS VARCHAR), 1, ${_mastra_core_storage.SPAN_QUERY_MAX_PREVIEW_CHARACTERS + 1}) AS outputPreview
3867
- FROM span_events WHERE ${payloadWhere}`, payloadValues);
3985
+ const payloads = (await query(`SELECT DISTINCT ${identities},
3986
+ ${previewPayloads.map(([preview, payload]) => `${preview}, CASE WHEN ${missingPreviewSql(preview)} THEN CAST(${payload} AS VARCHAR) END AS ${preview}Payload`).join(",\n ")}
3987
+ FROM span_events WHERE ${payloadWhere}`, payloadValues)).map((row) => {
3988
+ const payload = {
3989
+ organizationId: row.organizationId,
3990
+ resourceId: row.resourceId,
3991
+ traceId: row.traceId,
3992
+ spanId: row.spanId,
3993
+ inputPreview: null,
3994
+ outputPreview: null,
3995
+ errorPreview: null
3996
+ };
3997
+ for (const [preview] of previewPayloads) {
3998
+ const stored = row[preview];
3999
+ payload[preview] = readPreview(stored, row[`${preview}Payload`], true);
4000
+ }
4001
+ return payload;
4002
+ });
3868
4003
  const metricValues = [];
3869
4004
  const metricWhere = keys(page, metricValues);
3870
4005
  const metrics = await query(`SELECT ${identities}, name, estimatedCost, costUnit,
@@ -3873,7 +4008,7 @@ async function querySpans(db, plan) {
3873
4008
  FROM metric_events WHERE (${metricWhere}) AND name LIKE 'mastra_model_%'
3874
4009
  LIMIT ${_mastra_core_storage.SPAN_QUERY_MAX_COST_METRICS + 1}`, metricValues);
3875
4010
  if (metrics.length > _mastra_core_storage.SPAN_QUERY_MAX_COST_METRICS) throw new _mastra_core_storage.TraceQueryResourceLimitError();
3876
- return _mastra_core_storage.buildSpanQueryResponse(plan, selected, payloads, metrics);
4011
+ return buildSpanQueryResponse(plan, selected, payloads, metrics);
3877
4012
  }
3878
4013
  //#endregion
3879
4014
  //#region src/storage/domains/observability/trace-aggregate.ts
@@ -4233,7 +4368,13 @@ const COLUMNS_SQL = [
4233
4368
  "input",
4234
4369
  "output",
4235
4370
  "error",
4236
- "requestContext"
4371
+ "requestContext",
4372
+ "inputPreview",
4373
+ "outputPreview",
4374
+ "errorPreview",
4375
+ "hasInputPayload",
4376
+ "hasOutputPayload",
4377
+ "hasErrorPayload"
4237
4378
  ].join(", ");
4238
4379
  const PAYLOAD_COLUMN_SET = new Set(SPAN_PAYLOAD_COLUMNS);
4239
4380
  /**
@@ -4245,6 +4386,32 @@ const PAYLOAD_COLUMN_SET = new Set(SPAN_PAYLOAD_COLUMNS);
4245
4386
  function argMaxNonNull(col) {
4246
4387
  return `arg_max(${col}, timestamp) FILTER (WHERE ${col} IS NOT NULL${PAYLOAD_COLUMN_SET.has(col) ? ` AND ${col} <> '${JSON_NULL_PLACEHOLDER}'` : ""}) as ${col}`;
4247
4388
  }
4389
+ /** The payload column each stored preview column describes, and its payload-presence flag. */
4390
+ const PREVIEW_PAYLOADS = [
4391
+ [
4392
+ "inputPreview",
4393
+ "input",
4394
+ "hasInputPayload"
4395
+ ],
4396
+ [
4397
+ "outputPreview",
4398
+ "output",
4399
+ "hasOutputPayload"
4400
+ ],
4401
+ [
4402
+ "errorPreview",
4403
+ "error",
4404
+ "hasErrorPayload"
4405
+ ]
4406
+ ];
4407
+ /**
4408
+ * Select the preview from the latest event carrying its payload (or an explicit preview).
4409
+ * Wrapping the preview preserves NULL on that event instead of reviving an older preview.
4410
+ * The stored presence flag tells blank content from a payload-less event without reading the
4411
+ * payload. Rows written before the flag (NULL) always qualify: their NULL preview sends the span
4412
+ * to {@link fillMissingReconstructedPreviews}, which rebuilds it from the payloads.
4413
+ */
4414
+ const RECONSTRUCT_PREVIEWS_SQL = PREVIEW_PAYLOADS.map(([preview, , present]) => `(coalesce(arg_max(struct_pack(value := ${preview}), timestamp) FILTER (WHERE coalesce(${present}, true) OR ${preview} <> ''), arg_max(struct_pack(value := ${preview}), timestamp))).value as ${preview}`).join(",\n ");
4248
4415
  const SPAN_RECONSTRUCT_SELECT = `
4249
4416
  SELECT
4250
4417
  traceId, spanId,
@@ -4300,8 +4467,8 @@ const SPAN_RECONSTRUCT_SELECT_LIGHT = `
4300
4467
  `;
4301
4468
  /**
4302
4469
  * Lightweight list variant — also reconstructs `metadata` for the list's
4303
- * configurable columns and `input` so the row mapper can derive `inputPreview`
4304
- * without shipping the blob to the caller.
4470
+ * configurable columns and the stored previews (see {@link RECONSTRUCT_PREVIEWS_SQL}),
4471
+ * so the list never ships the payload blobs to the caller.
4305
4472
  */
4306
4473
  const SPAN_RECONSTRUCT_SELECT_LIGHT_LIST = `
4307
4474
  SELECT
@@ -4319,7 +4486,7 @@ const SPAN_RECONSTRUCT_SELECT_LIGHT_LIST = `
4319
4486
  ${argMaxNonNull("resourceId")},
4320
4487
  ${argMaxNonNull("error")},
4321
4488
  ${argMaxNonNull("metadata")},
4322
- ${argMaxNonNull("input")}
4489
+ ${RECONSTRUCT_PREVIEWS_SQL}
4323
4490
  FROM span_events
4324
4491
  `;
4325
4492
  /**
@@ -4441,6 +4608,26 @@ function rowToLightSpanRecord(row) {
4441
4608
  updatedAt: rowEndedAt(row)
4442
4609
  };
4443
4610
  }
4611
+ /**
4612
+ * Builds the previews of spans written before previews were stored (NULL after
4613
+ * {@link RECONSTRUCT_PREVIEWS_SQL}) from those spans' reconstructed payloads. Runs only while such
4614
+ * spans are on the page.
4615
+ */
4616
+ async function fillMissingReconstructedPreviews(db, rows) {
4617
+ const flagged = rows.filter((row) => PREVIEW_PAYLOADS.some(([preview]) => needsPreview(row[preview])));
4618
+ if (flagged.length === 0) return;
4619
+ const traceIds = [...new Set(flagged.map((row) => row.traceId))];
4620
+ const payloads = await db.query(`SELECT traceId, spanId, ${PREVIEW_PAYLOADS.map(([, payload]) => argMaxNonNull(payload)).join(", ")}
4621
+ FROM span_events
4622
+ WHERE traceId IN (${traceIds.map(() => "?").join(", ")})
4623
+ AND (traceId, spanId) IN (SELECT * FROM (VALUES ${flagged.map(() => "(?, ?)").join(", ")}))
4624
+ GROUP BY traceId, spanId`, [...traceIds, ...flagged.flatMap((row) => [row.traceId, row.spanId])]);
4625
+ const byKey = new Map(payloads.map((payload) => [`${payload.traceId}\u0000${payload.spanId}`, payload]));
4626
+ for (const row of flagged) {
4627
+ const payload = byKey.get(`${row.traceId}\u0000${row.spanId}`);
4628
+ for (const [preview, column] of PREVIEW_PAYLOADS) if (needsPreview(row[preview])) row[preview] = previewFromPayload(payload?.[column] ?? null);
4629
+ }
4630
+ }
4444
4631
  function rowToLightSpanRecordWithPreview(row) {
4445
4632
  const record = rowToLightSpanRecord(row);
4446
4633
  return {
@@ -4449,7 +4636,9 @@ function rowToLightSpanRecordWithPreview(row) {
4449
4636
  threadId: row.threadId ?? null,
4450
4637
  resourceId: row.resourceId ?? null,
4451
4638
  metadata: parseJson(row.metadata),
4452
- inputPreview: (0, _mastra_core_storage.buildInputPreview)(row.input)
4639
+ inputPreview: apiPreview(row.inputPreview),
4640
+ outputPreview: apiPreview(row.outputPreview),
4641
+ errorPreview: apiPreview(row.errorPreview)
4453
4642
  };
4454
4643
  }
4455
4644
  function rowToSpanRecord(row) {
@@ -4607,6 +4796,28 @@ function partitionAnchorFilters(filters) {
4607
4796
  hasChildError
4608
4797
  };
4609
4798
  }
4799
+ /** JSON text of a payload value, or null when it is missing. */
4800
+ function serializePayload(value) {
4801
+ if (value === null || value === void 0) return null;
4802
+ return JSON.stringify(value) ?? null;
4803
+ }
4804
+ /**
4805
+ * The payload JSON and stored preview for one payload slot of an event row. A row that carries the
4806
+ * slot gets a preview built from the serialized value actually written, unless the record carries
4807
+ * an upstream preview; `''` when there is nothing to preview. A row that does not carry the slot
4808
+ * gets no payload and `''`, so a NULL preview only ever means a row written before previews.
4809
+ */
4810
+ function previewOf(carried, value, upstream) {
4811
+ if (!carried) return {
4812
+ json: null,
4813
+ preview: ""
4814
+ };
4815
+ const json = serializePayload(value);
4816
+ return {
4817
+ json,
4818
+ preview: storedPreview(upstream, json === null ? null : value, json)
4819
+ };
4820
+ }
4610
4821
  function toValuesTuple(row) {
4611
4822
  return [
4612
4823
  v(row.eventType),
@@ -4641,10 +4852,16 @@ function toValuesTuple(row) {
4641
4852
  jsonV(row.tags),
4642
4853
  jsonV(row.scope),
4643
4854
  jsonV(row.links),
4644
- payloadJsonV(row.input),
4645
- payloadJsonV(row.output),
4646
- jsonV(row.error),
4647
- payloadJsonV(row.requestContext)
4855
+ row.input === null ? payloadJsonV(null) : v(row.input),
4856
+ row.output === null ? payloadJsonV(null) : v(row.output),
4857
+ row.error === null ? "NULL" : v(row.error),
4858
+ payloadJsonV(row.requestContext),
4859
+ v(row.inputPreview),
4860
+ v(row.outputPreview),
4861
+ v(row.errorPreview),
4862
+ v(row.hasInputPayload),
4863
+ v(row.hasOutputPayload),
4864
+ v(row.hasErrorPayload)
4648
4865
  ].join(", ");
4649
4866
  }
4650
4867
  async function insertSpanEvents(db, rows) {
@@ -4654,6 +4871,7 @@ async function insertSpanEvents(db, rows) {
4654
4871
  }
4655
4872
  function createStartSpanRow(s) {
4656
4873
  const payloadOnEndRow = !!s.endedAt && !s.isEvent;
4874
+ const input = previewOf(!payloadOnEndRow, s.input, s.inputPreview);
4657
4875
  return {
4658
4876
  eventType: "start",
4659
4877
  timestamp: s.startedAt,
@@ -4686,13 +4904,22 @@ function createStartSpanRow(s) {
4686
4904
  tags: s.tags == null ? null : normalizeTags(s.tags),
4687
4905
  scope: s.scope ?? null,
4688
4906
  links: null,
4689
- input: payloadOnEndRow ? null : s.input ?? null,
4907
+ input: input.json,
4690
4908
  output: null,
4691
4909
  error: null,
4692
- requestContext: payloadOnEndRow ? null : s.requestContext ?? null
4910
+ requestContext: payloadOnEndRow ? null : s.requestContext ?? null,
4911
+ inputPreview: input.preview,
4912
+ outputPreview: "",
4913
+ errorPreview: "",
4914
+ hasInputPayload: input.json !== null,
4915
+ hasOutputPayload: false,
4916
+ hasErrorPayload: false
4693
4917
  };
4694
4918
  }
4695
4919
  function createEndSpanRow(s) {
4920
+ const input = previewOf(true, s.input, s.inputPreview);
4921
+ const output = previewOf(true, s.output, s.outputPreview);
4922
+ const error = previewOf(true, s.error, s.errorPreview);
4696
4923
  return {
4697
4924
  eventType: "end",
4698
4925
  timestamp: s.endedAt,
@@ -4725,10 +4952,16 @@ function createEndSpanRow(s) {
4725
4952
  tags: s.tags == null ? null : normalizeTags(s.tags),
4726
4953
  scope: s.scope ?? null,
4727
4954
  links: s.links ?? null,
4728
- input: s.input ?? null,
4729
- output: s.output ?? null,
4730
- error: s.error ?? null,
4731
- requestContext: s.requestContext ?? null
4955
+ input: input.json,
4956
+ output: output.json,
4957
+ error: error.json,
4958
+ requestContext: s.requestContext ?? null,
4959
+ inputPreview: input.preview,
4960
+ outputPreview: output.preview,
4961
+ errorPreview: error.preview,
4962
+ hasInputPayload: input.json !== null,
4963
+ hasOutputPayload: output.json !== null,
4964
+ hasErrorPayload: error.json !== null
4732
4965
  };
4733
4966
  }
4734
4967
  /** Insert a 'start' event for a new span. */
@@ -5033,14 +5266,16 @@ async function listTraces(db, args) {
5033
5266
  async function listTracesLight(db, args) {
5034
5267
  const { filters, pagination, orderBy } = _mastra_core_storage.listTracesArgsSchema.parse(args);
5035
5268
  const currentDeltaCursor = deltaPollingFeatureEnabled() ? await getTraceDeltaCursor(db, filters) : void 0;
5036
- const { pagination: resultPagination, spans } = await listTraceRows(db, {
5269
+ const { pagination: resultPagination, spans: rows } = await listTraceRows(db, {
5037
5270
  filters,
5038
5271
  pagination,
5039
5272
  orderBy
5040
- }, SPAN_RECONSTRUCT_SELECT_LIGHT_LIST, rowToLightSpanRecordWithPreview, (spans) => spans);
5273
+ }, SPAN_RECONSTRUCT_SELECT_LIGHT_LIST, (row) => row, (rows) => rows);
5274
+ const pageRows = rows;
5275
+ await fillMissingReconstructedPreviews(db, pageRows);
5041
5276
  return {
5042
5277
  pagination: resultPagination,
5043
- spans,
5278
+ spans: pageRows.map(rowToLightSpanRecordWithPreview),
5044
5279
  ...deltaPollingFeatureEnabled() ? { deltaCursor: currentDeltaCursor } : {}
5045
5280
  };
5046
5281
  }
@@ -5731,4 +5966,4 @@ var ObservabilityStorageDuckDB = class ObservabilityStorageDuckDB extends _mastr
5731
5966
  //#endregion
5732
5967
  exports.ObservabilityStorageDuckDB = ObservabilityStorageDuckDB;
5733
5968
 
5734
- //# sourceMappingURL=observability-DJafBDSz.cjs.map
5969
+ //# sourceMappingURL=observability-G5gsNol7.cjs.map