@mastra/pg 1.23.0 → 1.24.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.
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-rag-vector-databases.md +1 -1
- package/dist/index.cjs +149 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +149 -40
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/experiments/index.d.ts.map +1 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/trace-query.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -7084,6 +7084,12 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
|
|
|
7084
7084
|
name: "idx_experiment_results_org_project",
|
|
7085
7085
|
table: TABLE_EXPERIMENT_RESULTS,
|
|
7086
7086
|
columns: ["organizationId", "projectId"]
|
|
7087
|
+
},
|
|
7088
|
+
{
|
|
7089
|
+
name: "idx_experiment_results_tags_gin",
|
|
7090
|
+
table: TABLE_EXPERIMENT_RESULTS,
|
|
7091
|
+
columns: ["tags"],
|
|
7092
|
+
method: "gin"
|
|
7087
7093
|
}
|
|
7088
7094
|
];
|
|
7089
7095
|
}
|
|
@@ -7692,6 +7698,10 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
|
|
|
7692
7698
|
conditions.push(`"status" = $${paramIndex++}`);
|
|
7693
7699
|
queryParams.push(args.status);
|
|
7694
7700
|
}
|
|
7701
|
+
for (const tag of args.tags ?? []) {
|
|
7702
|
+
conditions.push(`"tags" @> $${paramIndex++}::jsonb`);
|
|
7703
|
+
queryParams.push(JSON.stringify([tag]));
|
|
7704
|
+
}
|
|
7695
7705
|
if (args.filters) {
|
|
7696
7706
|
const { organizationId, projectId } = args.filters;
|
|
7697
7707
|
if (organizationId !== void 0) {
|
|
@@ -11040,13 +11050,36 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
|
|
|
11040
11050
|
* asked for a page after the last row, because there is then no row to carry the
|
|
11041
11051
|
* count on.
|
|
11042
11052
|
*/
|
|
11043
|
-
async #fetchMessagePage({ selectStatement, tableName, whereClause, orderByStatement, queryParams, perPageInput, perPage, offset }) {
|
|
11053
|
+
async #fetchMessagePage({ selectStatement, tableName, whereClause, orderByStatement, queryParams, perPageInput, perPage, offset, includeTotal = true }) {
|
|
11054
|
+
if (includeTotal === false && perPageInput !== false) {
|
|
11055
|
+
const peekLimit = perPage + 1;
|
|
11056
|
+
const rows = await this.#db.readClient.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement} LIMIT $${queryParams.length + 1} OFFSET $${queryParams.length + 2}`, [
|
|
11057
|
+
...queryParams,
|
|
11058
|
+
peekLimit,
|
|
11059
|
+
offset
|
|
11060
|
+
]) || [];
|
|
11061
|
+
const hasMore = rows.length > perPage;
|
|
11062
|
+
const messages = hasMore ? rows.slice(0, perPage) : rows;
|
|
11063
|
+
return {
|
|
11064
|
+
total: offset + messages.length,
|
|
11065
|
+
messages,
|
|
11066
|
+
hasMore
|
|
11067
|
+
};
|
|
11068
|
+
}
|
|
11044
11069
|
const limitClause = perPageInput === false ? "" : ` LIMIT $${queryParams.length + 1} OFFSET $${queryParams.length + 2}`;
|
|
11045
11070
|
const dataParams = perPageInput === false ? queryParams : [
|
|
11046
11071
|
...queryParams,
|
|
11047
11072
|
perPage,
|
|
11048
11073
|
offset
|
|
11049
11074
|
];
|
|
11075
|
+
if (includeTotal === false) {
|
|
11076
|
+
const rows = await this.#db.readClient.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, dataParams) || [];
|
|
11077
|
+
return {
|
|
11078
|
+
total: rows.length,
|
|
11079
|
+
messages: rows,
|
|
11080
|
+
hasMore: false
|
|
11081
|
+
};
|
|
11082
|
+
}
|
|
11050
11083
|
const rows = await this.#db.readClient.manyOrNone(`${selectStatement}, (SELECT COUNT(*) FROM ${tableName} ${whereClause}) AS "__total" FROM ${tableName} ${whereClause} ${orderByStatement}${limitClause}`, dataParams) || [];
|
|
11051
11084
|
if (rows.length > 0) return {
|
|
11052
11085
|
total: Number(rows[0].__total),
|
|
@@ -11063,7 +11096,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
|
|
|
11063
11096
|
};
|
|
11064
11097
|
}
|
|
11065
11098
|
async listMessages(args) {
|
|
11066
|
-
const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
|
|
11099
|
+
const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy, includeTotal = true } = args;
|
|
11067
11100
|
const threadIds = (Array.isArray(threadId) ? threadId : [threadId]).filter((id) => typeof id === "string");
|
|
11068
11101
|
if (threadIds.length === 0 || threadIds.some((id) => !id.trim())) throw new MastraError({
|
|
11069
11102
|
id: createStorageErrorId("PG", "LIST_MESSAGES", "INVALID_THREAD_ID"),
|
|
@@ -11149,20 +11182,27 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
|
|
|
11149
11182
|
}) : null;
|
|
11150
11183
|
let total;
|
|
11151
11184
|
let messages;
|
|
11185
|
+
let peekedHasMore;
|
|
11152
11186
|
if (metadataFilter) {
|
|
11153
11187
|
const filteredRows = (await this.#db.readClient.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, queryParams) || []).filter((row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter));
|
|
11154
11188
|
total = filteredRows.length;
|
|
11155
11189
|
messages = perPageInput === false ? filteredRows : filteredRows.slice(offset, offset + perPage);
|
|
11156
|
-
} else
|
|
11157
|
-
|
|
11158
|
-
|
|
11159
|
-
|
|
11160
|
-
|
|
11161
|
-
|
|
11162
|
-
|
|
11163
|
-
|
|
11164
|
-
|
|
11165
|
-
|
|
11190
|
+
} else {
|
|
11191
|
+
const pageResult = await this.#fetchMessagePage({
|
|
11192
|
+
selectStatement,
|
|
11193
|
+
tableName,
|
|
11194
|
+
whereClause,
|
|
11195
|
+
orderByStatement,
|
|
11196
|
+
queryParams,
|
|
11197
|
+
perPageInput,
|
|
11198
|
+
perPage,
|
|
11199
|
+
offset,
|
|
11200
|
+
includeTotal
|
|
11201
|
+
});
|
|
11202
|
+
total = pageResult.total;
|
|
11203
|
+
messages = pageResult.messages;
|
|
11204
|
+
peekedHasMore = pageResult.hasMore;
|
|
11205
|
+
}
|
|
11166
11206
|
const primaryPageCount = messages.length;
|
|
11167
11207
|
if (total === 0 && messages.length === 0 && (!include || include.length === 0)) return {
|
|
11168
11208
|
messages: [],
|
|
@@ -11187,7 +11227,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
|
|
|
11187
11227
|
const finalMessages = this._sortMessages(list.get.all.db(), field, direction);
|
|
11188
11228
|
const threadIdSet = new Set(threadIds);
|
|
11189
11229
|
const allThreadMessagesReturned = new Set(finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)).size >= total;
|
|
11190
|
-
const hasMore = metadataFilter ? perPageInput !== false && offset + primaryPageCount < total : perPageInput !== false && !allThreadMessagesReturned && offset + perPage < total;
|
|
11230
|
+
const hasMore = peekedHasMore !== void 0 ? peekedHasMore : metadataFilter ? perPageInput !== false && offset + primaryPageCount < total : perPageInput !== false && !allThreadMessagesReturned && offset + perPage < total;
|
|
11191
11231
|
return {
|
|
11192
11232
|
messages: finalMessages,
|
|
11193
11233
|
total,
|
|
@@ -11212,7 +11252,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
|
|
|
11212
11252
|
}
|
|
11213
11253
|
}
|
|
11214
11254
|
async listMessagesByResourceId(args) {
|
|
11215
|
-
const { resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
|
|
11255
|
+
const { resourceId, include, filter, perPage: perPageInput, page = 0, orderBy, includeTotal = true } = args;
|
|
11216
11256
|
if (!(resourceId !== void 0 && resourceId !== null && resourceId.trim() !== "")) throw new MastraError({
|
|
11217
11257
|
id: createStorageErrorId("PG", "LIST_MESSAGES_BY_RESOURCE_ID", "INVALID_QUERY"),
|
|
11218
11258
|
domain: ErrorDomain.STORAGE,
|
|
@@ -11295,20 +11335,27 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
|
|
|
11295
11335
|
}) : null;
|
|
11296
11336
|
let total;
|
|
11297
11337
|
let messages;
|
|
11338
|
+
let peekedHasMore;
|
|
11298
11339
|
if (metadataFilter) {
|
|
11299
11340
|
const filteredRows = (await this.#db.readClient.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, queryParams) || []).filter((row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter));
|
|
11300
11341
|
total = filteredRows.length;
|
|
11301
11342
|
messages = perPageInput === false ? filteredRows : filteredRows.slice(offset, offset + perPage);
|
|
11302
|
-
} else
|
|
11303
|
-
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
11311
|
-
|
|
11343
|
+
} else {
|
|
11344
|
+
const pageResult = await this.#fetchMessagePage({
|
|
11345
|
+
selectStatement,
|
|
11346
|
+
tableName,
|
|
11347
|
+
whereClause,
|
|
11348
|
+
orderByStatement,
|
|
11349
|
+
queryParams,
|
|
11350
|
+
perPageInput,
|
|
11351
|
+
perPage,
|
|
11352
|
+
offset,
|
|
11353
|
+
includeTotal
|
|
11354
|
+
});
|
|
11355
|
+
total = pageResult.total;
|
|
11356
|
+
messages = pageResult.messages;
|
|
11357
|
+
peekedHasMore = pageResult.hasMore;
|
|
11358
|
+
}
|
|
11312
11359
|
if (total === 0 && messages.length === 0 && (!include || include.length === 0)) return {
|
|
11313
11360
|
messages: [],
|
|
11314
11361
|
total: 0,
|
|
@@ -11330,7 +11377,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
|
|
|
11330
11377
|
const messagesWithParsedContent = messages.map((row) => this.parseRow(row));
|
|
11331
11378
|
const list = new MessageList().add(messagesWithParsedContent, "memory");
|
|
11332
11379
|
const finalMessages = this._sortMessages(list.get.all.db(), field, direction);
|
|
11333
|
-
const hasMore = perPageInput !== false && offset + perPage < total;
|
|
11380
|
+
const hasMore = peekedHasMore !== void 0 ? peekedHasMore : perPageInput !== false && offset + perPage < total;
|
|
11334
11381
|
return {
|
|
11335
11382
|
messages: finalMessages,
|
|
11336
11383
|
total,
|
|
@@ -17020,12 +17067,32 @@ const TRACE_FIELDS = {
|
|
|
17020
17067
|
status: TRACE_STATUS_SQL
|
|
17021
17068
|
};
|
|
17022
17069
|
const SPAN_FIELDS = {
|
|
17070
|
+
name: "s.\"name\"",
|
|
17023
17071
|
spanType: "s.\"spanType\"",
|
|
17024
|
-
|
|
17072
|
+
model: "s.\"model\"",
|
|
17073
|
+
provider: "s.\"provider\"",
|
|
17074
|
+
startedAt: "s.\"startedAt\"",
|
|
17075
|
+
endedAt: "s.\"endedAt\"",
|
|
17076
|
+
durationMs: "s.\"durationMs\"",
|
|
17077
|
+
status: "s.\"status\"",
|
|
17078
|
+
error: "s.\"error\"",
|
|
17079
|
+
entityType: "s.\"entityType\"",
|
|
17080
|
+
entityId: "s.\"entityId\"",
|
|
17081
|
+
entityName: "s.\"entityName\"",
|
|
17082
|
+
entityVersionId: "s.\"entityVersionId\"",
|
|
17083
|
+
parentEntityVersionId: "s.\"parentEntityVersionId\"",
|
|
17084
|
+
rootEntityVersionId: "s.\"rootEntityVersionId\""
|
|
17025
17085
|
};
|
|
17026
17086
|
const SCORE_FIELDS = {
|
|
17027
17087
|
scorerId: "s.\"scorerId\"",
|
|
17028
|
-
|
|
17088
|
+
scorerVersion: "s.\"scorerVersion\"",
|
|
17089
|
+
scoreSource: "s.\"scoreSource\"",
|
|
17090
|
+
score: "s.\"score\"",
|
|
17091
|
+
timestamp: "s.\"timestamp\"",
|
|
17092
|
+
spanId: "s.\"spanId\"",
|
|
17093
|
+
entityVersionId: "s.\"entityVersionId\"",
|
|
17094
|
+
parentEntityVersionId: "s.\"parentEntityVersionId\"",
|
|
17095
|
+
rootEntityVersionId: "s.\"rootEntityVersionId\""
|
|
17029
17096
|
};
|
|
17030
17097
|
const TRACE_SELECT = `
|
|
17031
17098
|
r."traceId" AS "traceId",
|
|
@@ -17043,15 +17110,18 @@ function fieldSql(registry, field) {
|
|
|
17043
17110
|
if (sql === void 0) throw new Error(`Unsupported trusted trace-query field: ${field}`);
|
|
17044
17111
|
return sql;
|
|
17045
17112
|
}
|
|
17113
|
+
function isMetadataField(field) {
|
|
17114
|
+
return field.startsWith("metadata.");
|
|
17115
|
+
}
|
|
17046
17116
|
function placeholders(values, offset) {
|
|
17047
17117
|
return values.map((_, index) => `$${offset + index}`).join(", ");
|
|
17048
17118
|
}
|
|
17049
|
-
function compileScalarPredicate(predicate, registry, parameterOffset) {
|
|
17119
|
+
function compileScalarPredicate(predicate, registry, parameterOffset, allowMetadata = false) {
|
|
17050
17120
|
if (predicate.type === "boolean") {
|
|
17051
17121
|
const values = [];
|
|
17052
17122
|
return {
|
|
17053
17123
|
sql: predicate.args.map((arg) => {
|
|
17054
|
-
const compiled = compileScalarPredicate(arg, registry, parameterOffset + values.length);
|
|
17124
|
+
const compiled = compileScalarPredicate(arg, registry, parameterOffset + values.length, allowMetadata);
|
|
17055
17125
|
values.push(...compiled.values);
|
|
17056
17126
|
return `(${compiled.sql})`;
|
|
17057
17127
|
}).join(predicate.operator === "and" ? " AND " : " OR "),
|
|
@@ -17059,26 +17129,36 @@ function compileScalarPredicate(predicate, registry, parameterOffset) {
|
|
|
17059
17129
|
};
|
|
17060
17130
|
}
|
|
17061
17131
|
if (predicate.type === "not") {
|
|
17062
|
-
const compiled = compileScalarPredicate(predicate.arg, registry, parameterOffset);
|
|
17132
|
+
const compiled = compileScalarPredicate(predicate.arg, registry, parameterOffset, allowMetadata);
|
|
17063
17133
|
return {
|
|
17064
17134
|
sql: `NOT (${compiled.sql})`,
|
|
17065
17135
|
values: compiled.values
|
|
17066
17136
|
};
|
|
17067
17137
|
}
|
|
17068
|
-
|
|
17138
|
+
let field;
|
|
17139
|
+
let fieldValues = [];
|
|
17140
|
+
if (isMetadataField(predicate.field)) {
|
|
17141
|
+
if (!allowMetadata) throw new Error(`Unsupported trusted trace-query field: ${predicate.field}`);
|
|
17142
|
+
const keyParameter = `$${parameterOffset++}`;
|
|
17143
|
+
field = `COALESCE(
|
|
17144
|
+
CASE WHEN jsonb_typeof(r."metadataSearch" -> ${keyParameter}) = 'string' THEN r."metadataSearch" ->> ${keyParameter} END,
|
|
17145
|
+
CASE WHEN jsonb_typeof(r."metadataRaw" -> ${keyParameter}) = 'string' THEN NULLIF(btrim(r."metadataRaw" ->> ${keyParameter}), '') END
|
|
17146
|
+
)`;
|
|
17147
|
+
fieldValues = [predicate.field.slice(9)];
|
|
17148
|
+
} else field = fieldSql(registry, predicate.field);
|
|
17069
17149
|
if (predicate.type === "presence") return {
|
|
17070
17150
|
sql: `${field} IS ${predicate.operator === "exists" ? "NOT " : ""}NULL`,
|
|
17071
|
-
values:
|
|
17151
|
+
values: fieldValues
|
|
17072
17152
|
};
|
|
17073
17153
|
if (predicate.type === "membership") {
|
|
17074
17154
|
const list = placeholders(predicate.values, parameterOffset);
|
|
17075
17155
|
if (predicate.operator === "in") return {
|
|
17076
17156
|
sql: `${field} IS NOT NULL AND ${field} IN (${list})`,
|
|
17077
|
-
values: predicate.values
|
|
17157
|
+
values: [...fieldValues, ...predicate.values]
|
|
17078
17158
|
};
|
|
17079
17159
|
return {
|
|
17080
17160
|
sql: `${field} IS NULL OR ${field} NOT IN (${list})`,
|
|
17081
|
-
values: predicate.values
|
|
17161
|
+
values: [...fieldValues, ...predicate.values]
|
|
17082
17162
|
};
|
|
17083
17163
|
}
|
|
17084
17164
|
const parameter = `$${parameterOffset}`;
|
|
@@ -17090,17 +17170,17 @@ function compileScalarPredicate(predicate, registry, parameterOffset) {
|
|
|
17090
17170
|
};
|
|
17091
17171
|
if (predicate.operator === "eq") return {
|
|
17092
17172
|
sql: `${field} IS NOT DISTINCT FROM ${parameter}`,
|
|
17093
|
-
values: [predicate.value]
|
|
17173
|
+
values: [...fieldValues, predicate.value]
|
|
17094
17174
|
};
|
|
17095
17175
|
if (predicate.operator === "ne") return {
|
|
17096
17176
|
sql: `${field} IS DISTINCT FROM ${parameter}`,
|
|
17097
|
-
values: [predicate.value]
|
|
17177
|
+
values: [...fieldValues, predicate.value]
|
|
17098
17178
|
};
|
|
17099
17179
|
const operator = operators[predicate.operator];
|
|
17100
17180
|
if (operator === void 0) throw new Error(`Unsupported trusted trace-query operator: ${predicate.operator}`);
|
|
17101
17181
|
return {
|
|
17102
17182
|
sql: `${field} IS NOT NULL AND ${field} ${operator} ${parameter}`,
|
|
17103
|
-
values: [predicate.value]
|
|
17183
|
+
values: [...fieldValues, predicate.value]
|
|
17104
17184
|
};
|
|
17105
17185
|
}
|
|
17106
17186
|
function latestRootPredicate$1(spanTable) {
|
|
@@ -17165,7 +17245,7 @@ function compilePredicate(predicate, parameterOffset) {
|
|
|
17165
17245
|
values: compiled.values
|
|
17166
17246
|
};
|
|
17167
17247
|
}
|
|
17168
|
-
return compileScalarPredicate(predicate, TRACE_FIELDS, parameterOffset);
|
|
17248
|
+
return compileScalarPredicate(predicate, TRACE_FIELDS, parameterOffset, true);
|
|
17169
17249
|
}
|
|
17170
17250
|
function compilePostgresTraceQuery(schema, plan) {
|
|
17171
17251
|
const spanTable = qualifiedTable(schema, TABLE_SPAN_EVENTS);
|
|
@@ -17185,14 +17265,43 @@ function compilePostgresTraceQuery(schema, plan) {
|
|
|
17185
17265
|
].join("\n AND ")}
|
|
17186
17266
|
)`];
|
|
17187
17267
|
if (relationCollections.has("spans")) ctes.push(`current_spans AS MATERIALIZED (
|
|
17188
|
-
SELECT
|
|
17268
|
+
SELECT
|
|
17269
|
+
s."traceId",
|
|
17270
|
+
s."name",
|
|
17271
|
+
s."spanType",
|
|
17272
|
+
CASE WHEN jsonb_typeof(s."attributes" -> 'model') = 'string' THEN s."attributes" ->> 'model' END AS "model",
|
|
17273
|
+
CASE WHEN jsonb_typeof(s."attributes" -> 'provider') = 'string' THEN s."attributes" ->> 'provider' END AS "provider",
|
|
17274
|
+
s."startedAt",
|
|
17275
|
+
CASE WHEN s."isPending" THEN NULL ELSE s."endedAt" END AS "endedAt",
|
|
17276
|
+
CASE
|
|
17277
|
+
WHEN s."isPending" THEN NULL
|
|
17278
|
+
ELSE EXTRACT(EPOCH FROM (s."endedAt" - s."startedAt")) * 1000
|
|
17279
|
+
END AS "durationMs",
|
|
17280
|
+
CASE WHEN s."error" IS NOT NULL THEN 'error' ELSE 'success' END AS "status",
|
|
17281
|
+
s."error",
|
|
17282
|
+
s."entityType",
|
|
17283
|
+
s."entityId",
|
|
17284
|
+
s."entityName",
|
|
17285
|
+
s."entityVersionId",
|
|
17286
|
+
s."parentEntityVersionId",
|
|
17287
|
+
s."rootEntityVersionId"
|
|
17189
17288
|
FROM ${spanTable} s
|
|
17190
17289
|
WHERE s."traceId" IS NOT NULL
|
|
17191
17290
|
AND s."traceId" IN (SELECT "traceId" FROM root_scope)
|
|
17192
17291
|
AND ${latestSpanPredicate$1(spanTable)}
|
|
17193
17292
|
)`);
|
|
17194
17293
|
if (relationCollections.has("scores")) ctes.push(`current_scores AS MATERIALIZED (
|
|
17195
|
-
SELECT
|
|
17294
|
+
SELECT
|
|
17295
|
+
s."traceId",
|
|
17296
|
+
s."spanId",
|
|
17297
|
+
s."timestamp",
|
|
17298
|
+
s."scorerId",
|
|
17299
|
+
s."scorerVersion",
|
|
17300
|
+
s."scoreSource",
|
|
17301
|
+
s."score",
|
|
17302
|
+
s."entityVersionId",
|
|
17303
|
+
s."parentEntityVersionId",
|
|
17304
|
+
s."rootEntityVersionId"
|
|
17196
17305
|
FROM ${scoreTable} s
|
|
17197
17306
|
WHERE s."traceId" IS NOT NULL
|
|
17198
17307
|
AND s."traceId" IN (SELECT "traceId" FROM root_scope)
|