@mastra/pg 1.24.0-alpha.1 → 1.24.0-alpha.3

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.
@@ -3,7 +3,7 @@ name: mastra-pg
3
3
  description: Documentation for @mastra/pg. Use when working with @mastra/pg APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/pg"
6
- version: "1.24.0-alpha.1"
6
+ version: "1.24.0-alpha.3"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.24.0-alpha.1",
2
+ "version": "1.24.0-alpha.3",
3
3
  "package": "@mastra/pg",
4
4
  "exports": {},
5
5
  "modules": {}
package/dist/index.cjs CHANGED
@@ -16102,6 +16102,8 @@ ${buildSelectColumns(FEEDBACK_EVENT_COLUMNS)}`;
16102
16102
  * aggregate, breakdown, time series, and percentiles. OLAP aggregates run
16103
16103
  * over `valueNumber` only; string-valued feedback is excluded.
16104
16104
  */
16105
+ const FEEDBACK_CONFLICT_KEYS = /* @__PURE__ */ new Set(["feedbackId", "timestamp"]);
16106
+ const FEEDBACK_UPSERT_CLAUSE = `ON CONFLICT ("feedbackId", "timestamp") DO UPDATE SET ${FEEDBACK_EVENT_COLUMNS.map((column) => column.name).filter((column) => !FEEDBACK_CONFLICT_KEYS.has(column)).map((column) => `"${column}" = EXCLUDED."${column}"`).join(", ")}`;
16105
16107
  function applyFeedbackFilters(acc, filters) {
16106
16108
  applyCommonFilters(acc, filters);
16107
16109
  applySingleOrArrayFilter(acc, "feedbackType", filters?.feedbackType);
@@ -16132,12 +16134,12 @@ function pushFeedbackIdentity(acc, feedbackType, feedbackSource) {
16132
16134
  acc.conditions.push(`"valueNumber" IS NOT NULL`);
16133
16135
  }
16134
16136
  async function createFeedback(client, schema, args) {
16135
- const insert = buildInsert(schema, TABLE_FEEDBACK_EVENTS, [feedbackRecordToRow(args.feedback)]);
16137
+ const insert = buildInsert(schema, TABLE_FEEDBACK_EVENTS, [feedbackRecordToRow(args.feedback)], FEEDBACK_UPSERT_CLAUSE);
16136
16138
  if (insert) await client.query(insert.text, insert.values);
16137
16139
  }
16138
16140
  async function batchCreateFeedback(client, schema, args) {
16139
16141
  if (args.feedbacks.length === 0) return;
16140
- const insert = buildInsert(schema, TABLE_FEEDBACK_EVENTS, args.feedbacks.map(feedbackRecordToRow));
16142
+ const insert = buildInsert(schema, TABLE_FEEDBACK_EVENTS, [...new Map(args.feedbacks.map((feedback) => [feedback.feedbackId, feedback])).values()].map(feedbackRecordToRow), FEEDBACK_UPSERT_CLAUSE);
16141
16143
  if (insert) await client.query(insert.text, insert.values);
16142
16144
  }
16143
16145
  async function updateFeedbackReviewStatus(client, schema, args) {
@@ -16155,6 +16157,26 @@ async function updateFeedbackReviewStatus(client, schema, args) {
16155
16157
  });
16156
16158
  return rowToFeedbackRecord(row);
16157
16159
  }
16160
+ /**
16161
+ * Delete feedback events by feedbackId. Optional `organizationId` and
16162
+ * `resourceId` values are ANDed into the predicate to restrict deletion to
16163
+ * records with matching scope fields.
16164
+ */
16165
+ async function deleteFeedback(client, schema, args) {
16166
+ if (args.feedbackIds.length === 0) return;
16167
+ const table = qualifiedTable(schema, TABLE_FEEDBACK_EVENTS);
16168
+ const values = [...args.feedbackIds];
16169
+ const conditions = [`"feedbackId" IN (${args.feedbackIds.map((_, i) => `$${i + 1}`).join(", ")})`];
16170
+ if (args.organizationId !== void 0) {
16171
+ values.push(args.organizationId);
16172
+ conditions.push(`"organizationId" = $${values.length}`);
16173
+ }
16174
+ if (args.resourceId !== void 0) {
16175
+ values.push(args.resourceId);
16176
+ conditions.push(`"resourceId" = $${values.length}`);
16177
+ }
16178
+ await client.query(`DELETE FROM ${table} WHERE ${conditions.join(" AND ")}`, values);
16179
+ }
16158
16180
  async function listFeedback(client, schema, args) {
16159
16181
  const { mode, filters, pagination, orderBy, after, limit } = _mastra_core_storage.listFeedbackArgsSchema.parse(args);
16160
16182
  const table = qualifiedTable(schema, TABLE_FEEDBACK_EVENTS);
@@ -16915,6 +16937,26 @@ async function batchCreateScores(client, schema, args) {
16915
16937
  const insert = buildInsert(schema, TABLE_SCORE_EVENTS, args.scores.map(scoreRecordToRow));
16916
16938
  if (insert) await client.query(insert.text, insert.values);
16917
16939
  }
16940
+ /**
16941
+ * Delete score events by scoreId. Optional `organizationId` and `resourceId`
16942
+ * values are ANDed into the predicate to restrict deletion to records with
16943
+ * matching scope fields.
16944
+ */
16945
+ async function deleteScores(client, schema, args) {
16946
+ if (args.scoreIds.length === 0) return;
16947
+ const table = qualifiedTable(schema, TABLE_SCORE_EVENTS);
16948
+ const values = [...args.scoreIds];
16949
+ const conditions = [`"scoreId" IN (${args.scoreIds.map((_, i) => `$${i + 1}`).join(", ")})`];
16950
+ if (args.organizationId !== void 0) {
16951
+ values.push(args.organizationId);
16952
+ conditions.push(`"organizationId" = $${values.length}`);
16953
+ }
16954
+ if (args.resourceId !== void 0) {
16955
+ values.push(args.resourceId);
16956
+ conditions.push(`"resourceId" = $${values.length}`);
16957
+ }
16958
+ await client.query(`DELETE FROM ${table} WHERE ${conditions.join(" AND ")}`, values);
16959
+ }
16918
16960
  async function listScores(client, schema, args) {
16919
16961
  const { mode, filters, pagination, orderBy, after, limit } = _mastra_core_storage.listScoresArgsSchema.parse(args);
16920
16962
  const table = qualifiedTable(schema, TABLE_SCORE_EVENTS);
@@ -17118,6 +17160,17 @@ const SCORE_FIELDS = {
17118
17160
  parentEntityVersionId: "s.\"parentEntityVersionId\"",
17119
17161
  rootEntityVersionId: "s.\"rootEntityVersionId\""
17120
17162
  };
17163
+ const FEEDBACK_FIELDS = {
17164
+ feedbackType: "s.\"feedbackType\"",
17165
+ feedbackSource: "s.\"feedbackSource\"",
17166
+ feedbackUserId: "s.\"feedbackUserId\"",
17167
+ sourceId: "s.\"sourceId\"",
17168
+ entityVersionId: "s.\"entityVersionId\"",
17169
+ parentEntityVersionId: "s.\"parentEntityVersionId\"",
17170
+ rootEntityVersionId: "s.\"rootEntityVersionId\"",
17171
+ timestamp: "s.\"timestamp\"",
17172
+ comment: "s.\"comment\""
17173
+ };
17121
17174
  const TRACE_SELECT = `
17122
17175
  r."traceId" AS "traceId",
17123
17176
  r."spanId" AS "rootSpanId",
@@ -17207,6 +17260,35 @@ function compileScalarPredicate(predicate, registry, parameterOffset, allowMetad
17207
17260
  values: [...fieldValues, predicate.value]
17208
17261
  };
17209
17262
  }
17263
+ function compileFeedbackScalarPredicate(predicate, parameterOffset) {
17264
+ if (predicate.type === "boolean") {
17265
+ const values = [];
17266
+ return {
17267
+ sql: predicate.args.map((arg) => {
17268
+ const compiled = compileFeedbackScalarPredicate(arg, parameterOffset + values.length);
17269
+ values.push(...compiled.values);
17270
+ return `(${compiled.sql})`;
17271
+ }).join(predicate.operator === "and" ? " AND " : " OR "),
17272
+ values
17273
+ };
17274
+ }
17275
+ if (predicate.type === "not") {
17276
+ const compiled = compileFeedbackScalarPredicate(predicate.arg, parameterOffset);
17277
+ return {
17278
+ sql: `NOT (${compiled.sql})`,
17279
+ values: compiled.values
17280
+ };
17281
+ }
17282
+ if (predicate.field !== "value") return compileScalarPredicate(predicate, FEEDBACK_FIELDS, parameterOffset);
17283
+ if (predicate.type === "presence") {
17284
+ const present = `(s."valueString" IS NOT NULL OR s."valueNumber" IS NOT NULL)`;
17285
+ return {
17286
+ sql: predicate.operator === "exists" ? present : `NOT ${present}`,
17287
+ values: []
17288
+ };
17289
+ }
17290
+ return compileScalarPredicate(predicate, { value: typeof (predicate.type === "membership" ? predicate.values[0] : predicate.value) === "number" ? "s.\"valueNumber\"" : "s.\"valueString\"" }, parameterOffset);
17291
+ }
17210
17292
  function latestRootPredicate$1(spanTable) {
17211
17293
  return `NOT EXISTS (
17212
17294
  SELECT 1 FROM ${spanTable} newer
@@ -17230,6 +17312,13 @@ function latestScorePredicate(scoreTable) {
17230
17312
  AND newer."cursorId" > s."cursorId"
17231
17313
  )`;
17232
17314
  }
17315
+ function latestFeedbackPredicate(feedbackTable) {
17316
+ return `NOT EXISTS (
17317
+ SELECT 1 FROM ${feedbackTable} newer
17318
+ WHERE newer."feedbackId" = s."feedbackId"
17319
+ AND newer."cursorId" > s."cursorId"
17320
+ )`;
17321
+ }
17233
17322
  function collectRelationCollections(predicate, collections = /* @__PURE__ */ new Set()) {
17234
17323
  if (!predicate) return collections;
17235
17324
  if (predicate.type === "relation") collections.add(predicate.collection);
@@ -17239,11 +17328,11 @@ function collectRelationCollections(predicate, collections = /* @__PURE__ */ new
17239
17328
  }
17240
17329
  function compilePredicate(predicate, parameterOffset) {
17241
17330
  if (predicate.type === "relation") {
17242
- const registry = predicate.collection === "spans" ? SPAN_FIELDS : SCORE_FIELDS;
17243
- const compiled = compileScalarPredicate(predicate.predicate, registry, parameterOffset);
17331
+ const compiled = predicate.collection === "feedback" ? compileFeedbackScalarPredicate(predicate.predicate, parameterOffset) : compileScalarPredicate(predicate.predicate, predicate.collection === "spans" ? SPAN_FIELDS : SCORE_FIELDS, parameterOffset);
17244
17332
  const existence = `EXISTS (
17245
- SELECT 1 FROM ${predicate.collection === "spans" ? "current_spans" : "current_scores"} s
17246
- WHERE s."traceId" = r."traceId"
17333
+ SELECT 1 FROM ${predicate.collection === "spans" ? "current_spans" : predicate.collection === "scores" ? "current_scores" : "current_feedback"} s
17334
+ WHERE s."traceId" IS NOT NULL
17335
+ AND s."traceId" = r."traceId"
17247
17336
  AND (${compiled.sql})
17248
17337
  )`;
17249
17338
  return {
@@ -17274,6 +17363,7 @@ function compilePredicate(predicate, parameterOffset) {
17274
17363
  function compilePostgresTraceQuery(schema, plan) {
17275
17364
  const spanTable = qualifiedTable(schema, TABLE_SPAN_EVENTS);
17276
17365
  const scoreTable = qualifiedTable(schema, TABLE_SCORE_EVENTS);
17366
+ const feedbackTable = qualifiedTable(schema, TABLE_FEEDBACK_EVENTS);
17277
17367
  const values = [plan.timeRange.from, plan.timeRange.to];
17278
17368
  const relationCollections = collectRelationCollections(plan.where);
17279
17369
  const ctes = [`root_scope AS MATERIALIZED (
@@ -17330,6 +17420,25 @@ function compilePostgresTraceQuery(schema, plan) {
17330
17420
  WHERE s."traceId" IS NOT NULL
17331
17421
  AND s."traceId" IN (SELECT "traceId" FROM root_scope)
17332
17422
  AND ${latestScorePredicate(scoreTable)}
17423
+ )`);
17424
+ if (relationCollections.has("feedback")) ctes.push(`current_feedback AS MATERIALIZED (
17425
+ SELECT
17426
+ s."traceId",
17427
+ s."feedbackType",
17428
+ s."feedbackSource",
17429
+ s."feedbackUserId",
17430
+ s."sourceId",
17431
+ s."valueString",
17432
+ s."valueNumber",
17433
+ s."comment",
17434
+ s."timestamp",
17435
+ s."entityVersionId",
17436
+ s."parentEntityVersionId",
17437
+ s."rootEntityVersionId"
17438
+ FROM ${feedbackTable} s
17439
+ WHERE s."traceId" IS NOT NULL
17440
+ AND s."traceId" IN (SELECT "traceId" FROM root_scope)
17441
+ AND ${latestFeedbackPredicate(feedbackTable)}
17333
17442
  )`);
17334
17443
  let predicateSql = "TRUE";
17335
17444
  if (plan.where) {
@@ -18404,6 +18513,12 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
18404
18513
  async batchCreateFeedback(args) {
18405
18514
  await this.#run("BATCH_CREATE_FEEDBACK", () => batchCreateFeedback(this.#client, this.#schema, args), { count: args.feedbacks.length });
18406
18515
  }
18516
+ async deleteScores(args) {
18517
+ await this.#run("DELETE_SCORES", () => deleteScores(this.#client, this.#schema, args), { count: args.scoreIds.length });
18518
+ }
18519
+ async deleteFeedback(args) {
18520
+ await this.#run("DELETE_FEEDBACK", () => deleteFeedback(this.#client, this.#schema, args), { count: args.feedbackIds.length });
18521
+ }
18407
18522
  async listLogs(args) {
18408
18523
  return this.#run("LIST_LOGS", () => listLogs(this.#readClient, this.#schema, args));
18409
18524
  }