@mastra/duckdb 1.8.0-alpha.0 → 1.8.0-alpha.2

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.
@@ -745,6 +745,45 @@ function parseUpdateFeedbackReviewStatusArgs(args) {
745
745
  }
746
746
  //#endregion
747
747
  //#region src/storage/domains/observability/feedback.ts
748
+ const FEEDBACK_UPSERT_CLAUSE = `ON CONFLICT (feedbackId) DO UPDATE SET ${[
749
+ "timestamp",
750
+ "cursorId",
751
+ "traceId",
752
+ "spanId",
753
+ "experimentId",
754
+ "entityType",
755
+ "entityId",
756
+ "entityName",
757
+ "entityVersionId",
758
+ "parentEntityVersionId",
759
+ "parentEntityType",
760
+ "parentEntityId",
761
+ "parentEntityName",
762
+ "rootEntityVersionId",
763
+ "rootEntityType",
764
+ "rootEntityId",
765
+ "rootEntityName",
766
+ "userId",
767
+ "organizationId",
768
+ "resourceId",
769
+ "runId",
770
+ "sessionId",
771
+ "threadId",
772
+ "requestId",
773
+ "environment",
774
+ "executionSource",
775
+ "serviceName",
776
+ "feedbackUserId",
777
+ "sourceId",
778
+ "reviewStatus",
779
+ "feedbackSource",
780
+ "feedbackType",
781
+ "value",
782
+ "comment",
783
+ "tags",
784
+ "metadata",
785
+ "scope"
786
+ ].map((column) => `${column} = excluded.${column}`).join(", ")}`;
748
787
  const FEEDBACK_GROUP_BY_COLUMNS = /* @__PURE__ */ new Set([
749
788
  "timestamp",
750
789
  "traceId",
@@ -961,12 +1000,12 @@ async function createFeedback(db, args) {
961
1000
  jsonV(f.metadata),
962
1001
  jsonV(f.scope ?? null)
963
1002
  ].join(", ")})
964
- ON CONFLICT DO NOTHING`);
1003
+ ${FEEDBACK_UPSERT_CLAUSE}`);
965
1004
  }
966
1005
  /** Insert multiple feedback events in a single statement. */
967
1006
  async function batchCreateFeedback(db, args) {
968
1007
  if (args.feedbacks.length === 0) return;
969
- const tuples = args.feedbacks.map((f) => {
1008
+ const tuples = [...new Map(args.feedbacks.map((feedback) => [feedback.feedbackId, feedback])).values()].map((f) => {
970
1009
  const legacyFeedback = f;
971
1010
  const feedbackSource = legacyFeedback.feedbackSource ?? legacyFeedback.source ?? "";
972
1011
  const feedbackUserId = legacyFeedback.feedbackUserId ?? legacyFeedback.userId ?? null;
@@ -1018,7 +1057,26 @@ async function batchCreateFeedback(db, args) {
1018
1057
  feedbackUserId, sourceId, reviewStatus, feedbackSource, feedbackType, value, comment, tags, metadata, scope
1019
1058
  )
1020
1059
  VALUES ${tuples.join(",\n ")}
1021
- ON CONFLICT DO NOTHING`);
1060
+ ${FEEDBACK_UPSERT_CLAUSE}`);
1061
+ }
1062
+ /**
1063
+ * Delete feedback events by feedbackId. Optional `organizationId` and
1064
+ * `resourceId` values are ANDed into the predicate to restrict deletion to
1065
+ * records with matching scope fields.
1066
+ */
1067
+ async function deleteFeedback(db, args) {
1068
+ if (args.feedbackIds.length === 0) return;
1069
+ const conditions = [`feedbackId IN (${args.feedbackIds.map(() => "?").join(", ")})`];
1070
+ const params = [...args.feedbackIds];
1071
+ if (args.organizationId !== void 0) {
1072
+ conditions.push("organizationId = ?");
1073
+ params.push(args.organizationId);
1074
+ }
1075
+ if (args.resourceId !== void 0) {
1076
+ conditions.push("resourceId = ?");
1077
+ params.push(args.resourceId);
1078
+ }
1079
+ await db.execute(`DELETE FROM feedback_events WHERE ${conditions.join(" AND ")}`, params);
1022
1080
  }
1023
1081
  /** Update the review workflow status of a single feedback event. */
1024
1082
  async function updateFeedbackReviewStatus(db, args) {
@@ -2377,6 +2435,25 @@ async function batchCreateScores(db, args) {
2377
2435
  VALUES ${tuples.join(",\n ")}
2378
2436
  ${SCORE_UPSERT_CLAUSE}`);
2379
2437
  }
2438
+ /**
2439
+ * Delete score events by scoreId. Optional `organizationId` and `resourceId`
2440
+ * values are ANDed into the predicate to restrict deletion to records with
2441
+ * matching scope fields.
2442
+ */
2443
+ async function deleteScores(db, args) {
2444
+ if (args.scoreIds.length === 0) return;
2445
+ const conditions = [`scoreId IN (${args.scoreIds.map(() => "?").join(", ")})`];
2446
+ const params = [...args.scoreIds];
2447
+ if (args.organizationId !== void 0) {
2448
+ conditions.push("organizationId = ?");
2449
+ params.push(args.organizationId);
2450
+ }
2451
+ if (args.resourceId !== void 0) {
2452
+ conditions.push("resourceId = ?");
2453
+ params.push(args.resourceId);
2454
+ }
2455
+ await db.execute(`DELETE FROM score_events WHERE ${conditions.join(" AND ")}`, params);
2456
+ }
2380
2457
  /** Query score events with filtering, ordering, and pagination. */
2381
2458
  async function listScores(db, args) {
2382
2459
  const { mode, filters, pagination, orderBy, after, limit } = listScoresArgsSchema.parse(args);
@@ -2701,6 +2778,44 @@ const SCORE_FIELDS = {
2701
2778
  parameterType: "scalar"
2702
2779
  }
2703
2780
  };
2781
+ const FEEDBACK_FIELDS = {
2782
+ feedbackType: {
2783
+ sql: "s.feedbackType",
2784
+ parameterType: "scalar"
2785
+ },
2786
+ feedbackSource: {
2787
+ sql: "s.feedbackSource",
2788
+ parameterType: "scalar"
2789
+ },
2790
+ feedbackUserId: {
2791
+ sql: "s.feedbackUserId",
2792
+ parameterType: "scalar"
2793
+ },
2794
+ sourceId: {
2795
+ sql: "s.sourceId",
2796
+ parameterType: "scalar"
2797
+ },
2798
+ entityVersionId: {
2799
+ sql: "s.entityVersionId",
2800
+ parameterType: "scalar"
2801
+ },
2802
+ parentEntityVersionId: {
2803
+ sql: "s.parentEntityVersionId",
2804
+ parameterType: "scalar"
2805
+ },
2806
+ rootEntityVersionId: {
2807
+ sql: "s.rootEntityVersionId",
2808
+ parameterType: "scalar"
2809
+ },
2810
+ timestamp: {
2811
+ sql: "s.timestamp",
2812
+ parameterType: "timestamp"
2813
+ },
2814
+ comment: {
2815
+ sql: "s.comment",
2816
+ parameterType: "scalar"
2817
+ }
2818
+ };
2704
2819
  const TRACE_SELECT = `
2705
2820
  r.traceId AS traceId,
2706
2821
  r.spanId AS rootSpanId,
@@ -2803,12 +2918,40 @@ function compileScalarPredicate(predicate, registry, allowMetadata = false) {
2803
2918
  ]
2804
2919
  };
2805
2920
  }
2921
+ function compileFeedbackScalarPredicate(predicate) {
2922
+ if (predicate.type === "boolean") {
2923
+ const values = [];
2924
+ return {
2925
+ sql: predicate.args.map((arg) => {
2926
+ const compiled = compileFeedbackScalarPredicate(arg);
2927
+ values.push(...compiled.values);
2928
+ return `(${compiled.sql})`;
2929
+ }).join(predicate.operator === "and" ? " AND " : " OR "),
2930
+ values
2931
+ };
2932
+ }
2933
+ if (predicate.type === "not") {
2934
+ const compiled = compileFeedbackScalarPredicate(predicate.arg);
2935
+ return {
2936
+ sql: `NOT (${compiled.sql})`,
2937
+ values: compiled.values
2938
+ };
2939
+ }
2940
+ if (predicate.field !== "value") return compileScalarPredicate(predicate, FEEDBACK_FIELDS);
2941
+ if (predicate.type === "presence") return {
2942
+ sql: `s.value IS ${predicate.operator === "exists" ? "NOT " : ""}NULL`,
2943
+ values: []
2944
+ };
2945
+ return compileScalarPredicate(predicate, { value: {
2946
+ sql: typeof (predicate.type === "membership" ? predicate.values[0] : predicate.value) === "number" ? "TRY_CAST(s.value AS DOUBLE)" : "s.value",
2947
+ parameterType: "scalar"
2948
+ } });
2949
+ }
2806
2950
  function compilePredicate(predicate) {
2807
2951
  if (predicate.type === "relation") {
2808
- const registry = predicate.collection === "spans" ? SPAN_FIELDS : SCORE_FIELDS;
2809
- const compiled = compileScalarPredicate(predicate.predicate, registry);
2952
+ const compiled = predicate.collection === "feedback" ? compileFeedbackScalarPredicate(predicate.predicate) : compileScalarPredicate(predicate.predicate, predicate.collection === "spans" ? SPAN_FIELDS : SCORE_FIELDS);
2810
2953
  const existence = `EXISTS (
2811
- SELECT 1 FROM ${predicate.collection === "spans" ? "current_spans" : "current_scores"} s
2954
+ SELECT 1 FROM ${predicate.collection === "spans" ? "current_spans" : predicate.collection === "scores" ? "current_scores" : "current_feedback"} s
2812
2955
  WHERE s.traceId IS NOT NULL
2813
2956
  AND s.traceId = r.traceId
2814
2957
  AND (${compiled.sql})
@@ -2928,6 +3071,11 @@ function compileDuckDBTraceQuery(plan) {
2928
3071
  SELECT s.*
2929
3072
  FROM score_events s
2930
3073
  INNER JOIN root_scope roots ON roots.traceId = s.traceId
3074
+ )`);
3075
+ if (relatedCollections.has("feedback")) ctes.push(`current_feedback AS (
3076
+ SELECT f.*
3077
+ FROM feedback_events f
3078
+ INNER JOIN root_scope roots ON roots.traceId = f.traceId
2931
3079
  )`);
2932
3080
  ctes.push(`candidates AS (
2933
3081
  SELECT ${TRACE_SELECT}
@@ -4347,6 +4495,9 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
4347
4495
  async batchCreateScores(args) {
4348
4496
  return batchCreateScores(this.db, args);
4349
4497
  }
4498
+ async deleteScores(args) {
4499
+ return deleteScores(this.db, args);
4500
+ }
4350
4501
  async listScores(args) {
4351
4502
  return listScores(this.db, args);
4352
4503
  }
@@ -4371,6 +4522,9 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
4371
4522
  async batchCreateFeedback(args) {
4372
4523
  return batchCreateFeedback(this.db, args);
4373
4524
  }
4525
+ async deleteFeedback(args) {
4526
+ return deleteFeedback(this.db, args);
4527
+ }
4374
4528
  async listFeedback(args) {
4375
4529
  return listFeedback(this.db, args);
4376
4530
  }
@@ -4393,4 +4547,4 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
4393
4547
  //#endregion
4394
4548
  export { ObservabilityStorageDuckDB };
4395
4549
 
4396
- //# sourceMappingURL=observability-CgtrnaKz.js.map
4550
+ //# sourceMappingURL=observability-COgD6BOK.js.map