@mastra/duckdb 1.2.0 → 1.3.0-alpha.1

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.
@@ -1,6 +1,6 @@
1
1
  import { DuckDBConnection } from './chunk-37GBWD4M.js';
2
2
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
3
- import { ObservabilityStorage, createStorageErrorId, toTraceSpans } from '@mastra/core/storage';
3
+ import { BRANCH_SPAN_TYPES, ObservabilityStorage, createStorageErrorId, toTraceSpans, METRIC_DISTINCT_COLUMNS } from '@mastra/core/storage';
4
4
  import { EntityType } from '@mastra/core/observability';
5
5
  import { parseFieldKey } from '@mastra/core/utils';
6
6
 
@@ -1186,7 +1186,16 @@ async function listLogs(db, args) {
1186
1186
  logs
1187
1187
  };
1188
1188
  }
1189
- function getAggregationSql2(aggregation, measure = "value") {
1189
+ function resolveDistinctColumnSql(distinctColumn) {
1190
+ if (!distinctColumn) {
1191
+ throw new Error(`count_distinct aggregation requires a 'distinctColumn' argument`);
1192
+ }
1193
+ if (!METRIC_DISTINCT_COLUMNS.includes(distinctColumn)) {
1194
+ throw new Error(`Invalid distinctColumn: ${distinctColumn}`);
1195
+ }
1196
+ return parseFieldKey(distinctColumn);
1197
+ }
1198
+ function getAggregationSql2(aggregation, measure = "value", distinctColumn) {
1190
1199
  switch (aggregation) {
1191
1200
  case "sum":
1192
1201
  return `SUM(${measure})`;
@@ -1198,6 +1207,9 @@ function getAggregationSql2(aggregation, measure = "value") {
1198
1207
  return `MAX(${measure})`;
1199
1208
  case "count":
1200
1209
  return `CAST(COUNT(${measure}) AS DOUBLE)`;
1210
+ case "count_distinct": {
1211
+ return `CAST(approx_count_distinct(${resolveDistinctColumnSql(distinctColumn)}) AS DOUBLE)`;
1212
+ }
1201
1213
  case "last":
1202
1214
  return `arg_max(${measure}, timestamp)`;
1203
1215
  default:
@@ -1443,7 +1455,7 @@ async function listMetrics(db, args) {
1443
1455
  };
1444
1456
  }
1445
1457
  async function getMetricAggregate(db, args) {
1446
- const aggSql = getAggregationSql2(args.aggregation);
1458
+ const aggSql = getAggregationSql2(args.aggregation, "value", args.distinctColumn);
1447
1459
  const { clause: nameClause, params: nameParams } = buildMetricNameFilter(args.name);
1448
1460
  const { clause: filterClause, params: filterParams } = buildWhereClause(
1449
1461
  args.filters
@@ -1527,7 +1539,7 @@ async function getMetricAggregate(db, args) {
1527
1539
  return { value, estimatedCost: costSummary.estimatedCost, costUnit: costSummary.costUnit };
1528
1540
  }
1529
1541
  async function getMetricBreakdown(db, args) {
1530
- const aggSql = getAggregationSql2(args.aggregation);
1542
+ const aggSql = getAggregationSql2(args.aggregation, "value", args.distinctColumn);
1531
1543
  const { clause: nameClause, params: nameParams } = buildMetricNameFilter(args.name);
1532
1544
  const { clause: filterClause, params: filterParams } = buildWhereClause(
1533
1545
  args.filters
@@ -1541,8 +1553,11 @@ async function getMetricBreakdown(db, args) {
1541
1553
  const resolvedGroupBy = resolveGroupBy(args.groupBy);
1542
1554
  const selectGroupBy = resolvedGroupBy.map((entry) => entry.selectSql).join(", ");
1543
1555
  const groupByCols = resolvedGroupBy.map((entry) => entry.groupSql).join(", ");
1544
- const sql = `SELECT ${selectGroupBy}, ${aggSql} AS value, ${getCostSummarySelect()} FROM metric_events ${whereClause} GROUP BY ${groupByCols} ORDER BY value DESC`;
1545
- const rows = await db.query(sql, allParams);
1556
+ const orderDirection = args.orderDirection === "ASC" ? "ASC" : "DESC";
1557
+ const limitClause = typeof args.limit === "number" ? `LIMIT ?` : "";
1558
+ const limitParams = typeof args.limit === "number" ? [args.limit] : [];
1559
+ const sql = `SELECT ${selectGroupBy}, ${aggSql} AS value, ${getCostSummarySelect()} FROM metric_events ${whereClause} GROUP BY ${groupByCols} ORDER BY value ${orderDirection} ${limitClause}`;
1560
+ const rows = await db.query(sql, [...allParams, ...limitParams]);
1546
1561
  const groups = rows.map((row) => {
1547
1562
  const dimensions = {};
1548
1563
  for (const entry of resolvedGroupBy) {
@@ -1560,7 +1575,7 @@ async function getMetricBreakdown(db, args) {
1560
1575
  return { groups };
1561
1576
  }
1562
1577
  async function getMetricTimeSeries(db, args) {
1563
- const aggSql = getAggregationSql2(args.aggregation);
1578
+ const aggSql = getAggregationSql2(args.aggregation, "value", args.distinctColumn);
1564
1579
  const intervalSql = getIntervalSql2(args.interval);
1565
1580
  const { clause: nameClause, params: nameParams } = buildMetricNameFilter(args.name);
1566
1581
  const { clause: filterClause, params: filterParams } = buildWhereClause(
@@ -2144,6 +2159,12 @@ async function listScores(db, args) {
2144
2159
  scores: rows.map((row) => rowToScoreRecord(row))
2145
2160
  };
2146
2161
  }
2162
+ async function getScoreById(db, scoreId) {
2163
+ const rows = await db.query(`SELECT * FROM score_events WHERE scoreId = ? LIMIT 1`, [
2164
+ scoreId
2165
+ ]);
2166
+ return rows[0] ? rowToScoreRecord(rows[0]) : null;
2167
+ }
2147
2168
  async function getScoreAggregate(db, args) {
2148
2169
  const aggSql = getAggregationSql3(args.aggregation);
2149
2170
  const { clause, params } = buildScoreWhereClause(args);
@@ -2413,11 +2434,91 @@ function rowToSpanRecord(row) {
2413
2434
  updatedAt: null
2414
2435
  };
2415
2436
  }
2416
- function buildHasChildErrorClause(hasChildError) {
2437
+ function buildHasChildErrorClause(hasChildError, rootAlias) {
2417
2438
  if (hasChildError === void 0) return "";
2418
- const base = `SELECT 1 FROM reconstructed_spans c WHERE c.traceId = root_spans.traceId AND c.spanId != root_spans.spanId AND c.error IS NOT NULL`;
2439
+ const base = `SELECT 1 FROM span_events c WHERE c.traceId = ${rootAlias}.traceId AND c.spanId != ${rootAlias}.spanId AND c.error IS NOT NULL`;
2419
2440
  return hasChildError ? `EXISTS (${base})` : `NOT EXISTS (${base})`;
2420
2441
  }
2442
+ var PREFILTER_KEYS = /* @__PURE__ */ new Set([
2443
+ "traceId",
2444
+ "spanId",
2445
+ "parentSpanId",
2446
+ "name",
2447
+ "spanType",
2448
+ "source",
2449
+ "entityType",
2450
+ "entityId",
2451
+ "entityName",
2452
+ "entityVersionId",
2453
+ "experimentId",
2454
+ "userId",
2455
+ "organizationId",
2456
+ "resourceId",
2457
+ "runId",
2458
+ "sessionId",
2459
+ "threadId",
2460
+ "requestId",
2461
+ "environment",
2462
+ "serviceName"
2463
+ ]);
2464
+ var SAFE_PREFILTER_ORDER_FIELDS = /* @__PURE__ */ new Set(["startedAt"]);
2465
+ function intersectTimestampRange(existing, incoming) {
2466
+ if (!existing) return { ...incoming };
2467
+ const merged = { ...existing };
2468
+ if (incoming.start !== void 0) {
2469
+ if (merged.start === void 0 || incoming.start.getTime() > merged.start.getTime()) {
2470
+ merged.start = incoming.start;
2471
+ merged.startExclusive = incoming.startExclusive;
2472
+ } else if (incoming.start.getTime() === merged.start.getTime()) {
2473
+ merged.startExclusive = (merged.startExclusive ?? false) || (incoming.startExclusive ?? false);
2474
+ }
2475
+ }
2476
+ if (incoming.end !== void 0) {
2477
+ if (merged.end === void 0 || incoming.end.getTime() < merged.end.getTime()) {
2478
+ merged.end = incoming.end;
2479
+ merged.endExclusive = incoming.endExclusive;
2480
+ } else if (incoming.end.getTime() === merged.end.getTime()) {
2481
+ merged.endExclusive = (merged.endExclusive ?? false) || (incoming.endExclusive ?? false);
2482
+ }
2483
+ }
2484
+ return merged;
2485
+ }
2486
+ function partitionAnchorFilters(filters) {
2487
+ const prefilter = {};
2488
+ const postAgg = {};
2489
+ let hasChildError;
2490
+ for (const [key, value] of Object.entries(filters)) {
2491
+ if (value === void 0 || value === null) continue;
2492
+ if (key === "hasChildError") {
2493
+ if (typeof value === "boolean") hasChildError = value;
2494
+ continue;
2495
+ }
2496
+ if (key === "startedAt") {
2497
+ prefilter.timestamp = intersectTimestampRange(
2498
+ prefilter.timestamp,
2499
+ value
2500
+ );
2501
+ continue;
2502
+ }
2503
+ if (key === "endedAt") {
2504
+ postAgg.endedAt = value;
2505
+ const dateRange = value;
2506
+ if (dateRange?.end) {
2507
+ prefilter.timestamp = intersectTimestampRange(prefilter.timestamp, {
2508
+ end: dateRange.end,
2509
+ endExclusive: dateRange.endExclusive
2510
+ });
2511
+ }
2512
+ continue;
2513
+ }
2514
+ if (PREFILTER_KEYS.has(key)) {
2515
+ prefilter[key] = value;
2516
+ continue;
2517
+ }
2518
+ postAgg[key] = value;
2519
+ }
2520
+ return { prefilter, postAgg, hasChildError };
2521
+ }
2421
2522
  function toValuesTuple(row) {
2422
2523
  return [
2423
2524
  v(row.eventType),
@@ -2596,47 +2697,211 @@ async function listTraces(db, args) {
2596
2697
  const page = Number(args.pagination?.page ?? 0);
2597
2698
  const perPage = Number(args.pagination?.perPage ?? 10);
2598
2699
  const orderBy = { field: args.orderBy?.field ?? "startedAt", direction: args.orderBy?.direction ?? "DESC" };
2599
- const { clause: filterClause, params: filterParams } = buildWhereClause(filters);
2600
- const orderByClause = buildOrderByClause(orderBy);
2601
- const { clause: paginationClause, params: paginationParams } = buildPaginationClause({ page, perPage });
2602
- const filterParts = [];
2603
- if (filterClause) filterParts.push(filterClause.replace(/^WHERE\s+/i, ""));
2604
- const hasChildError = typeof filters.hasChildError === "boolean" ? filters.hasChildError : void 0;
2605
- const childErrorClause = buildHasChildErrorClause(hasChildError);
2606
- if (childErrorClause) filterParts.push(childErrorClause);
2607
- const combinedFilterClause = filterParts.length > 0 ? `WHERE ${filterParts.join(" AND ")}` : "";
2608
- const cteSql = `
2609
- WITH reconstructed_spans AS (
2700
+ const { prefilter, postAgg, hasChildError } = partitionAnchorFilters(filters);
2701
+ const { clause: prefilterClause, params: prefilterParams } = buildWhereClause(prefilter);
2702
+ const prefilterParts = [`eventType = 'start'`, `parentSpanId IS NULL`];
2703
+ if (prefilterClause) prefilterParts.push(prefilterClause.replace(/^WHERE\s+/i, ""));
2704
+ const prefilterWhere = `WHERE ${prefilterParts.join(" AND ")}`;
2705
+ const outerAlias = "outer_root";
2706
+ const orderDir = orderBy.direction.toUpperCase();
2707
+ if (orderDir !== "ASC" && orderDir !== "DESC") {
2708
+ throw new Error(`Invalid sort direction: ${orderBy.direction}`);
2709
+ }
2710
+ const canOrderInPrefilter = SAFE_PREFILTER_ORDER_FIELDS.has(orderBy.field);
2711
+ const hasPostAggFilters = Object.keys(postAgg).length > 0 || hasChildError !== void 0 || !canOrderInPrefilter;
2712
+ if (!hasPostAggFilters) {
2713
+ const prefilterOrderBy = `ORDER BY timestamp ${orderDir}`;
2714
+ const offset = page * perPage;
2715
+ const countSql2 = `
2716
+ SELECT COUNT(*) as total
2717
+ FROM span_events AS ${outerAlias}
2718
+ ${prefilterWhere}
2719
+ `;
2720
+ const countResult2 = await db.query(countSql2, prefilterParams);
2721
+ const total2 = Number(countResult2[0]?.total ?? 0);
2722
+ const pageSql = `
2723
+ WITH page_roots AS (
2724
+ SELECT traceId, spanId
2725
+ FROM span_events AS ${outerAlias}
2726
+ ${prefilterWhere}
2727
+ ${prefilterOrderBy}
2728
+ LIMIT ? OFFSET ?
2729
+ )
2610
2730
  ${SPAN_RECONSTRUCT_SELECT}
2731
+ WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM page_roots)
2611
2732
  GROUP BY traceId, spanId
2733
+ ${buildOrderByClause(orderBy)}
2734
+ `;
2735
+ const rows2 = await db.query(pageSql, [...prefilterParams, perPage, offset]);
2736
+ const spans2 = rows2.map((row) => rowToSpanRecord(row));
2737
+ return {
2738
+ pagination: { total: total2, page, perPage, hasMore: (page + 1) * perPage < total2 },
2739
+ spans: toTraceSpans(spans2)
2740
+ };
2741
+ }
2742
+ const { clause: postAggClause, params: postAggParams } = buildWhereClause(postAgg);
2743
+ const postAggParts = [];
2744
+ if (postAggClause) postAggParts.push(postAggClause.replace(/^WHERE\s+/i, ""));
2745
+ const childErrorClause = buildHasChildErrorClause(hasChildError, "root_spans");
2746
+ if (childErrorClause) postAggParts.push(childErrorClause);
2747
+ const postAggWhere = postAggParts.length > 0 ? `WHERE ${postAggParts.join(" AND ")}` : "";
2748
+ const cteSql = `
2749
+ WITH candidate_roots AS (
2750
+ SELECT traceId, spanId
2751
+ FROM span_events AS ${outerAlias}
2752
+ ${prefilterWhere}
2612
2753
  ),
2613
2754
  root_spans AS (
2614
- SELECT * FROM reconstructed_spans
2615
- WHERE parentSpanId IS NULL
2755
+ ${SPAN_RECONSTRUCT_SELECT}
2756
+ WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM candidate_roots)
2757
+ GROUP BY traceId, spanId
2616
2758
  )
2617
2759
  `;
2760
+ const orderByClause = buildOrderByClause(orderBy);
2761
+ const { clause: paginationClause, params: paginationParams } = buildPaginationClause({ page, perPage });
2618
2762
  const countSql = `
2619
2763
  ${cteSql}
2620
- SELECT COUNT(*) as total FROM root_spans ${combinedFilterClause}
2764
+ SELECT COUNT(*) as total FROM root_spans ${postAggWhere}
2621
2765
  `;
2622
- const countResult = await db.query(countSql, filterParams);
2766
+ const countResult = await db.query(countSql, [...prefilterParams, ...postAggParams]);
2623
2767
  const total = Number(countResult[0]?.total ?? 0);
2624
2768
  const dataSql = `
2625
2769
  ${cteSql}
2626
- SELECT * FROM root_spans ${combinedFilterClause} ${orderByClause} ${paginationClause}
2770
+ SELECT * FROM root_spans ${postAggWhere} ${orderByClause} ${paginationClause}
2627
2771
  `;
2628
- const rows = await db.query(dataSql, [...filterParams, ...paginationParams]);
2772
+ const rows = await db.query(dataSql, [...prefilterParams, ...postAggParams, ...paginationParams]);
2629
2773
  const spans = rows.map((row) => rowToSpanRecord(row));
2630
2774
  return {
2631
- pagination: {
2632
- total,
2633
- page,
2634
- perPage,
2635
- hasMore: (page + 1) * perPage < total
2636
- },
2775
+ pagination: { total, page, perPage, hasMore: (page + 1) * perPage < total },
2637
2776
  spans: toTraceSpans(spans)
2638
2777
  };
2639
2778
  }
2779
+ var BRANCH_SPAN_TYPE_PLACEHOLDERS = BRANCH_SPAN_TYPES.map(() => "?").join(", ");
2780
+ async function getSpans(db, args) {
2781
+ if (args.spanIds.length === 0) {
2782
+ return { traceId: args.traceId, spans: [] };
2783
+ }
2784
+ const placeholders = args.spanIds.map(() => "?").join(", ");
2785
+ const rows = await db.query(
2786
+ `${SPAN_RECONSTRUCT_SELECT}
2787
+ WHERE traceId = ? AND spanId IN (${placeholders})
2788
+ GROUP BY traceId, spanId`,
2789
+ [args.traceId, ...args.spanIds]
2790
+ );
2791
+ return {
2792
+ traceId: args.traceId,
2793
+ spans: rows.map((row) => rowToSpanRecord(row))
2794
+ };
2795
+ }
2796
+ async function listBranches(db, args) {
2797
+ const filters = args.filters ?? {};
2798
+ const page = Number(args.pagination?.page ?? 0);
2799
+ const perPage = Number(args.pagination?.perPage ?? 10);
2800
+ const orderBy = { field: args.orderBy?.field ?? "startedAt", direction: args.orderBy?.direction ?? "DESC" };
2801
+ const userSpanType = filters.spanType;
2802
+ if (typeof userSpanType === "string" && !BRANCH_SPAN_TYPES.includes(userSpanType)) {
2803
+ return {
2804
+ pagination: { total: 0, page, perPage, hasMore: false },
2805
+ branches: []
2806
+ };
2807
+ }
2808
+ const { spanType: _spanType, ...rest } = filters;
2809
+ const { prefilter, postAgg} = partitionAnchorFilters(rest);
2810
+ const { clause: prefilterClause, params: prefilterFilterParams } = buildWhereClause(prefilter);
2811
+ const prefilterParts = [`eventType = 'start'`];
2812
+ let spanTypeParams;
2813
+ if (typeof userSpanType === "string") {
2814
+ prefilterParts.push(`spanType = ?`);
2815
+ spanTypeParams = [userSpanType];
2816
+ } else {
2817
+ prefilterParts.push(`spanType IN (${BRANCH_SPAN_TYPE_PLACEHOLDERS})`);
2818
+ spanTypeParams = [...BRANCH_SPAN_TYPES];
2819
+ }
2820
+ if (prefilterClause) prefilterParts.push(prefilterClause.replace(/^WHERE\s+/i, ""));
2821
+ const prefilterWhere = `WHERE ${prefilterParts.join(" AND ")}`;
2822
+ const prefilterParams = [...spanTypeParams, ...prefilterFilterParams];
2823
+ const outerAlias = "outer_anchor";
2824
+ const orderDir = orderBy.direction.toUpperCase();
2825
+ if (orderDir !== "ASC" && orderDir !== "DESC") {
2826
+ throw new Error(`Invalid sort direction: ${orderBy.direction}`);
2827
+ }
2828
+ const canOrderInPrefilter = SAFE_PREFILTER_ORDER_FIELDS.has(orderBy.field);
2829
+ const hasPostAggFilters = Object.keys(postAgg).length > 0 || !canOrderInPrefilter;
2830
+ if (!hasPostAggFilters) {
2831
+ const prefilterOrderBy = `ORDER BY timestamp ${orderDir}`;
2832
+ const offset = page * perPage;
2833
+ const countSql2 = `
2834
+ SELECT COUNT(*) as total
2835
+ FROM span_events AS ${outerAlias}
2836
+ ${prefilterWhere}
2837
+ `;
2838
+ const countResult2 = await db.query(countSql2, prefilterParams);
2839
+ const total2 = Number(countResult2[0]?.total ?? 0);
2840
+ if (total2 === 0) {
2841
+ return {
2842
+ pagination: { total: 0, page, perPage, hasMore: false },
2843
+ branches: []
2844
+ };
2845
+ }
2846
+ const pageSql = `
2847
+ WITH page_anchors AS (
2848
+ SELECT traceId, spanId
2849
+ FROM span_events AS ${outerAlias}
2850
+ ${prefilterWhere}
2851
+ ${prefilterOrderBy}
2852
+ LIMIT ? OFFSET ?
2853
+ )
2854
+ ${SPAN_RECONSTRUCT_SELECT}
2855
+ WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM page_anchors)
2856
+ GROUP BY traceId, spanId
2857
+ ${buildOrderByClause(orderBy)}
2858
+ `;
2859
+ const rows2 = await db.query(pageSql, [...prefilterParams, perPage, offset]);
2860
+ const spans2 = rows2.map((row) => rowToSpanRecord(row));
2861
+ return {
2862
+ pagination: { total: total2, page, perPage, hasMore: (page + 1) * perPage < total2 },
2863
+ branches: toTraceSpans(spans2)
2864
+ };
2865
+ }
2866
+ const { clause: postAggClause, params: postAggParams } = buildWhereClause(postAgg);
2867
+ const postAggWhere = postAggClause ? postAggClause : "";
2868
+ const orderByClause = buildOrderByClause(orderBy);
2869
+ const { clause: paginationClause, params: paginationParams } = buildPaginationClause({ page, perPage });
2870
+ const cteSql = `
2871
+ WITH candidate_anchors AS (
2872
+ SELECT traceId, spanId
2873
+ FROM span_events AS ${outerAlias}
2874
+ ${prefilterWhere}
2875
+ ),
2876
+ branch_anchors AS (
2877
+ ${SPAN_RECONSTRUCT_SELECT}
2878
+ WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM candidate_anchors)
2879
+ GROUP BY traceId, spanId
2880
+ )
2881
+ `;
2882
+ const countSql = `
2883
+ ${cteSql}
2884
+ SELECT COUNT(*) as total FROM branch_anchors ${postAggWhere}
2885
+ `;
2886
+ const countResult = await db.query(countSql, [...prefilterParams, ...postAggParams]);
2887
+ const total = Number(countResult[0]?.total ?? 0);
2888
+ if (total === 0) {
2889
+ return {
2890
+ pagination: { total: 0, page, perPage, hasMore: false },
2891
+ branches: []
2892
+ };
2893
+ }
2894
+ const dataSql = `
2895
+ ${cteSql}
2896
+ SELECT * FROM branch_anchors ${postAggWhere} ${orderByClause} ${paginationClause}
2897
+ `;
2898
+ const rows = await db.query(dataSql, [...prefilterParams, ...postAggParams, ...paginationParams]);
2899
+ const spans = rows.map((row) => rowToSpanRecord(row));
2900
+ return {
2901
+ pagination: { total, page, perPage, hasMore: (page + 1) * perPage < total },
2902
+ branches: toTraceSpans(spans)
2903
+ };
2904
+ }
2640
2905
 
2641
2906
  // src/storage/domains/observability/index.ts
2642
2907
  function buildSignalMigrationRequiredMessage(args) {
@@ -2739,6 +3004,9 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
2739
3004
  async getSpan(args) {
2740
3005
  return getSpan(this.db, args);
2741
3006
  }
3007
+ async getSpans(args) {
3008
+ return getSpans(this.db, args);
3009
+ }
2742
3010
  async getRootSpan(args) {
2743
3011
  return getRootSpan(this.db, args);
2744
3012
  }
@@ -2751,6 +3019,9 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
2751
3019
  async listTraces(args) {
2752
3020
  return listTraces(this.db, args);
2753
3021
  }
3022
+ async listBranches(args) {
3023
+ return listBranches(this.db, args);
3024
+ }
2754
3025
  // Logs
2755
3026
  async batchCreateLogs(args) {
2756
3027
  return batchCreateLogs(this.db, args);
@@ -2813,6 +3084,9 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
2813
3084
  async listScores(args) {
2814
3085
  return listScores(this.db, args);
2815
3086
  }
3087
+ async getScoreById(scoreId) {
3088
+ return getScoreById(this.db, scoreId);
3089
+ }
2816
3090
  async getScoreAggregate(args) {
2817
3091
  return getScoreAggregate(this.db, args);
2818
3092
  }
@@ -2850,5 +3124,5 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
2850
3124
  };
2851
3125
 
2852
3126
  export { ObservabilityStorageDuckDB };
2853
- //# sourceMappingURL=observability-YJBOVLPV.js.map
2854
- //# sourceMappingURL=observability-YJBOVLPV.js.map
3127
+ //# sourceMappingURL=observability-7LL4LLXY.js.map
3128
+ //# sourceMappingURL=observability-7LL4LLXY.js.map