@mastra/pg 1.24.0-alpha.2 → 1.24.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.
package/dist/index.js CHANGED
@@ -16078,6 +16078,8 @@ ${buildSelectColumns(FEEDBACK_EVENT_COLUMNS)}`;
16078
16078
  * aggregate, breakdown, time series, and percentiles. OLAP aggregates run
16079
16079
  * over `valueNumber` only; string-valued feedback is excluded.
16080
16080
  */
16081
+ const FEEDBACK_CONFLICT_KEYS = /* @__PURE__ */ new Set(["feedbackId", "timestamp"]);
16082
+ 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(", ")}`;
16081
16083
  function applyFeedbackFilters(acc, filters) {
16082
16084
  applyCommonFilters(acc, filters);
16083
16085
  applySingleOrArrayFilter(acc, "feedbackType", filters?.feedbackType);
@@ -16108,12 +16110,12 @@ function pushFeedbackIdentity(acc, feedbackType, feedbackSource) {
16108
16110
  acc.conditions.push(`"valueNumber" IS NOT NULL`);
16109
16111
  }
16110
16112
  async function createFeedback(client, schema, args) {
16111
- const insert = buildInsert(schema, TABLE_FEEDBACK_EVENTS, [feedbackRecordToRow(args.feedback)]);
16113
+ const insert = buildInsert(schema, TABLE_FEEDBACK_EVENTS, [feedbackRecordToRow(args.feedback)], FEEDBACK_UPSERT_CLAUSE);
16112
16114
  if (insert) await client.query(insert.text, insert.values);
16113
16115
  }
16114
16116
  async function batchCreateFeedback(client, schema, args) {
16115
16117
  if (args.feedbacks.length === 0) return;
16116
- const insert = buildInsert(schema, TABLE_FEEDBACK_EVENTS, args.feedbacks.map(feedbackRecordToRow));
16118
+ const insert = buildInsert(schema, TABLE_FEEDBACK_EVENTS, [...new Map(args.feedbacks.map((feedback) => [feedback.feedbackId, feedback])).values()].map(feedbackRecordToRow), FEEDBACK_UPSERT_CLAUSE);
16117
16119
  if (insert) await client.query(insert.text, insert.values);
16118
16120
  }
16119
16121
  async function updateFeedbackReviewStatus(client, schema, args) {
@@ -17134,6 +17136,17 @@ const SCORE_FIELDS = {
17134
17136
  parentEntityVersionId: "s.\"parentEntityVersionId\"",
17135
17137
  rootEntityVersionId: "s.\"rootEntityVersionId\""
17136
17138
  };
17139
+ const FEEDBACK_FIELDS = {
17140
+ feedbackType: "s.\"feedbackType\"",
17141
+ feedbackSource: "s.\"feedbackSource\"",
17142
+ feedbackUserId: "s.\"feedbackUserId\"",
17143
+ sourceId: "s.\"sourceId\"",
17144
+ entityVersionId: "s.\"entityVersionId\"",
17145
+ parentEntityVersionId: "s.\"parentEntityVersionId\"",
17146
+ rootEntityVersionId: "s.\"rootEntityVersionId\"",
17147
+ timestamp: "s.\"timestamp\"",
17148
+ comment: "s.\"comment\""
17149
+ };
17137
17150
  const TRACE_SELECT = `
17138
17151
  r."traceId" AS "traceId",
17139
17152
  r."spanId" AS "rootSpanId",
@@ -17223,6 +17236,35 @@ function compileScalarPredicate(predicate, registry, parameterOffset, allowMetad
17223
17236
  values: [...fieldValues, predicate.value]
17224
17237
  };
17225
17238
  }
17239
+ function compileFeedbackScalarPredicate(predicate, parameterOffset) {
17240
+ if (predicate.type === "boolean") {
17241
+ const values = [];
17242
+ return {
17243
+ sql: predicate.args.map((arg) => {
17244
+ const compiled = compileFeedbackScalarPredicate(arg, parameterOffset + values.length);
17245
+ values.push(...compiled.values);
17246
+ return `(${compiled.sql})`;
17247
+ }).join(predicate.operator === "and" ? " AND " : " OR "),
17248
+ values
17249
+ };
17250
+ }
17251
+ if (predicate.type === "not") {
17252
+ const compiled = compileFeedbackScalarPredicate(predicate.arg, parameterOffset);
17253
+ return {
17254
+ sql: `NOT (${compiled.sql})`,
17255
+ values: compiled.values
17256
+ };
17257
+ }
17258
+ if (predicate.field !== "value") return compileScalarPredicate(predicate, FEEDBACK_FIELDS, parameterOffset);
17259
+ if (predicate.type === "presence") {
17260
+ const present = `(s."valueString" IS NOT NULL OR s."valueNumber" IS NOT NULL)`;
17261
+ return {
17262
+ sql: predicate.operator === "exists" ? present : `NOT ${present}`,
17263
+ values: []
17264
+ };
17265
+ }
17266
+ return compileScalarPredicate(predicate, { value: typeof (predicate.type === "membership" ? predicate.values[0] : predicate.value) === "number" ? "s.\"valueNumber\"" : "s.\"valueString\"" }, parameterOffset);
17267
+ }
17226
17268
  function latestRootPredicate$1(spanTable) {
17227
17269
  return `NOT EXISTS (
17228
17270
  SELECT 1 FROM ${spanTable} newer
@@ -17246,6 +17288,13 @@ function latestScorePredicate(scoreTable) {
17246
17288
  AND newer."cursorId" > s."cursorId"
17247
17289
  )`;
17248
17290
  }
17291
+ function latestFeedbackPredicate(feedbackTable) {
17292
+ return `NOT EXISTS (
17293
+ SELECT 1 FROM ${feedbackTable} newer
17294
+ WHERE newer."feedbackId" = s."feedbackId"
17295
+ AND newer."cursorId" > s."cursorId"
17296
+ )`;
17297
+ }
17249
17298
  function collectRelationCollections(predicate, collections = /* @__PURE__ */ new Set()) {
17250
17299
  if (!predicate) return collections;
17251
17300
  if (predicate.type === "relation") collections.add(predicate.collection);
@@ -17255,11 +17304,11 @@ function collectRelationCollections(predicate, collections = /* @__PURE__ */ new
17255
17304
  }
17256
17305
  function compilePredicate(predicate, parameterOffset) {
17257
17306
  if (predicate.type === "relation") {
17258
- const registry = predicate.collection === "spans" ? SPAN_FIELDS : SCORE_FIELDS;
17259
- const compiled = compileScalarPredicate(predicate.predicate, registry, parameterOffset);
17307
+ const compiled = predicate.collection === "feedback" ? compileFeedbackScalarPredicate(predicate.predicate, parameterOffset) : compileScalarPredicate(predicate.predicate, predicate.collection === "spans" ? SPAN_FIELDS : SCORE_FIELDS, parameterOffset);
17260
17308
  const existence = `EXISTS (
17261
- SELECT 1 FROM ${predicate.collection === "spans" ? "current_spans" : "current_scores"} s
17262
- WHERE s."traceId" = r."traceId"
17309
+ SELECT 1 FROM ${predicate.collection === "spans" ? "current_spans" : predicate.collection === "scores" ? "current_scores" : "current_feedback"} s
17310
+ WHERE s."traceId" IS NOT NULL
17311
+ AND s."traceId" = r."traceId"
17263
17312
  AND (${compiled.sql})
17264
17313
  )`;
17265
17314
  return {
@@ -17290,6 +17339,7 @@ function compilePredicate(predicate, parameterOffset) {
17290
17339
  function compilePostgresTraceQuery(schema, plan) {
17291
17340
  const spanTable = qualifiedTable(schema, TABLE_SPAN_EVENTS);
17292
17341
  const scoreTable = qualifiedTable(schema, TABLE_SCORE_EVENTS);
17342
+ const feedbackTable = qualifiedTable(schema, TABLE_FEEDBACK_EVENTS);
17293
17343
  const values = [plan.timeRange.from, plan.timeRange.to];
17294
17344
  const relationCollections = collectRelationCollections(plan.where);
17295
17345
  const ctes = [`root_scope AS MATERIALIZED (
@@ -17346,6 +17396,25 @@ function compilePostgresTraceQuery(schema, plan) {
17346
17396
  WHERE s."traceId" IS NOT NULL
17347
17397
  AND s."traceId" IN (SELECT "traceId" FROM root_scope)
17348
17398
  AND ${latestScorePredicate(scoreTable)}
17399
+ )`);
17400
+ if (relationCollections.has("feedback")) ctes.push(`current_feedback AS MATERIALIZED (
17401
+ SELECT
17402
+ s."traceId",
17403
+ s."feedbackType",
17404
+ s."feedbackSource",
17405
+ s."feedbackUserId",
17406
+ s."sourceId",
17407
+ s."valueString",
17408
+ s."valueNumber",
17409
+ s."comment",
17410
+ s."timestamp",
17411
+ s."entityVersionId",
17412
+ s."parentEntityVersionId",
17413
+ s."rootEntityVersionId"
17414
+ FROM ${feedbackTable} s
17415
+ WHERE s."traceId" IS NOT NULL
17416
+ AND s."traceId" IN (SELECT "traceId" FROM root_scope)
17417
+ AND ${latestFeedbackPredicate(feedbackTable)}
17349
17418
  )`);
17350
17419
  let predicateSql = "TRUE";
17351
17420
  if (plan.where) {