@mastra/pg 1.26.0-alpha.2 → 1.26.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.
- 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 +34 -0
- package/dist/index.cjs +156 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +156 -34
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/ddl.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/scores.d.ts +1 -0
- package/dist/storage/domains/observability/v-next/scores.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/trace-query.d.ts +4 -2
- package/dist/storage/domains/observability/v-next/trace-query.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/docs/SKILL.md
CHANGED
|
@@ -345,6 +345,29 @@ await store.upsert({
|
|
|
345
345
|
|
|
346
346
|
For detailed setup instructions and best practices, see the [official Elasticsearch documentation](https://www.elastic.co/docs/solutions/search/get-started).
|
|
347
347
|
|
|
348
|
+
**Azure AI Search**:
|
|
349
|
+
|
|
350
|
+
```ts
|
|
351
|
+
import { AzureAISearchVector } from '@mastra/azure-ai-search'
|
|
352
|
+
|
|
353
|
+
const store = new AzureAISearchVector({
|
|
354
|
+
id: 'azure-search-vectors',
|
|
355
|
+
endpoint: process.env.AZURE_AI_SEARCH_ENDPOINT!,
|
|
356
|
+
credential: process.env.AZURE_AI_SEARCH_CREDENTIAL!,
|
|
357
|
+
})
|
|
358
|
+
|
|
359
|
+
await store.createIndex({
|
|
360
|
+
indexName: 'my-collection',
|
|
361
|
+
dimension: 1536,
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
await store.upsert({
|
|
365
|
+
indexName: 'my-collection',
|
|
366
|
+
vectors: embeddings,
|
|
367
|
+
metadata: chunks.map(chunk => ({ text: chunk.text })),
|
|
368
|
+
})
|
|
369
|
+
```
|
|
370
|
+
|
|
348
371
|
**Couchbase**:
|
|
349
372
|
|
|
350
373
|
```ts
|
|
@@ -626,6 +649,17 @@ Index names must:
|
|
|
626
649
|
- Example: `myindex-` isn't valid (ends with hyphen)
|
|
627
650
|
- Example: `MyIndex` isn't valid (contains uppercase letters)
|
|
628
651
|
|
|
652
|
+
**Azure AI Search**:
|
|
653
|
+
|
|
654
|
+
Index names must:
|
|
655
|
+
|
|
656
|
+
- Use only lowercase letters, numbers, dashes (`-`), and underscore (`_`) characters
|
|
657
|
+
- Not start or end with a dash
|
|
658
|
+
- Be between 2 and 128 characters long
|
|
659
|
+
- Example: `my-index-123` and `my_index` are valid
|
|
660
|
+
- Example: `MyIndex` isn't valid (contains uppercase letters)
|
|
661
|
+
- Example: `my-index-` isn't valid (ends with a dash)
|
|
662
|
+
|
|
629
663
|
### Upserting Embeddings
|
|
630
664
|
|
|
631
665
|
After creating an index, you can store embeddings along with their basic metadata:
|
package/dist/index.cjs
CHANGED
|
@@ -10782,7 +10782,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
|
|
|
10782
10782
|
hasMore: false
|
|
10783
10783
|
};
|
|
10784
10784
|
const limitValue = perPageInput === false ? total : perPage;
|
|
10785
|
-
const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "createdAtZ", "updatedAt", "updatedAtZ" ${baseQuery} ORDER BY COALESCE("${field}Z", "${field}") ${direction} LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`;
|
|
10785
|
+
const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "createdAtZ", "updatedAt", "updatedAtZ" ${baseQuery} ORDER BY COALESCE("${field}Z", "${field}") ${direction}, "id" ${direction} LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`;
|
|
10786
10786
|
return {
|
|
10787
10787
|
threads: (await this.#db.readClient.manyOrNone(dataQuery, [
|
|
10788
10788
|
...queryParams,
|
|
@@ -10975,10 +10975,11 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
|
|
|
10975
10975
|
return messages.sort((a, b) => {
|
|
10976
10976
|
const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
|
|
10977
10977
|
const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
|
|
10978
|
-
|
|
10978
|
+
const idOrder = direction === "ASC" ? a.id.localeCompare(b.id) : b.id.localeCompare(a.id);
|
|
10979
|
+
if (aValue == null && bValue == null) return idOrder;
|
|
10979
10980
|
if (aValue == null) return 1;
|
|
10980
10981
|
if (bValue == null) return -1;
|
|
10981
|
-
if (aValue === bValue) return
|
|
10982
|
+
if (aValue === bValue) return idOrder;
|
|
10982
10983
|
if (typeof aValue === "number" && typeof bValue === "number") return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
10983
10984
|
return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
|
|
10984
10985
|
});
|
|
@@ -11181,7 +11182,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
|
|
|
11181
11182
|
const metadataFilter = (0, _mastra_core_storage.validateStorageMetadataFilter)(filter?.metadata);
|
|
11182
11183
|
try {
|
|
11183
11184
|
const { field, direction } = this.parseOrderBy(orderBy, "ASC");
|
|
11184
|
-
const orderByStatement = `ORDER BY "${field}" ${direction}`;
|
|
11185
|
+
const orderByStatement = `ORDER BY "${field}" ${direction}, "id" ${direction}`;
|
|
11185
11186
|
const selectStatement = `SELECT id, content, role, type, "createdAt", "createdAtZ", thread_id AS "threadId", "resourceId"`;
|
|
11186
11187
|
const tableName = getTableName$3({
|
|
11187
11188
|
indexName: _mastra_core_storage.TABLE_MESSAGES,
|
|
@@ -11336,7 +11337,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
|
|
|
11336
11337
|
const metadataFilter = (0, _mastra_core_storage.validateStorageMetadataFilter)(filter?.metadata);
|
|
11337
11338
|
try {
|
|
11338
11339
|
const { field, direction } = this.parseOrderBy(orderBy, "ASC");
|
|
11339
|
-
const orderByStatement = `ORDER BY "${field}" ${direction}`;
|
|
11340
|
+
const orderByStatement = `ORDER BY "${field}" ${direction}, "id" ${direction}`;
|
|
11340
11341
|
const selectStatement = `SELECT id, content, role, type, "createdAt", "createdAtZ", thread_id AS "threadId", "resourceId"`;
|
|
11341
11342
|
const tableName = getTableName$3({
|
|
11342
11343
|
indexName: _mastra_core_storage.TABLE_MESSAGES,
|
|
@@ -14831,6 +14832,11 @@ function tableIndexes() {
|
|
|
14831
14832
|
columns: "(\"tags\")",
|
|
14832
14833
|
using: "gin"
|
|
14833
14834
|
},
|
|
14835
|
+
{
|
|
14836
|
+
name: "mastra_score_events_scoreid_cursor_idx",
|
|
14837
|
+
table: TABLE_SCORE_EVENTS,
|
|
14838
|
+
columns: "(\"scoreId\", \"cursorId\" DESC)"
|
|
14839
|
+
},
|
|
14834
14840
|
{
|
|
14835
14841
|
name: "mastra_score_events_cursor_idx",
|
|
14836
14842
|
table: TABLE_SCORE_EVENTS,
|
|
@@ -16963,13 +16969,32 @@ function pushScoreIdentity(acc, scorerId, scoreSource) {
|
|
|
16963
16969
|
acc.params.push(scoreSource);
|
|
16964
16970
|
}
|
|
16965
16971
|
}
|
|
16972
|
+
function scoreRewriteConflict(row) {
|
|
16973
|
+
return `ON CONFLICT ("scoreId", "timestamp") DO UPDATE SET ${[
|
|
16974
|
+
...Object.keys(row).filter((column) => column !== "scoreId" && column !== "timestamp").map((column) => `"${column}" = EXCLUDED."${column}"`),
|
|
16975
|
+
"\"cursorId\" = EXCLUDED.\"cursorId\"",
|
|
16976
|
+
"\"xactId\" = EXCLUDED.\"xactId\""
|
|
16977
|
+
].join(", ")}`;
|
|
16978
|
+
}
|
|
16979
|
+
function collapseExactScoreConflicts(rows) {
|
|
16980
|
+
const records = /* @__PURE__ */ new Map();
|
|
16981
|
+
for (const row of rows) {
|
|
16982
|
+
const timestamp = new Date(row.timestamp).toISOString();
|
|
16983
|
+
const key = `${String(row.scoreId)}\u0000${timestamp}`;
|
|
16984
|
+
records.delete(key);
|
|
16985
|
+
records.set(key, row);
|
|
16986
|
+
}
|
|
16987
|
+
return [...records.values()];
|
|
16988
|
+
}
|
|
16966
16989
|
async function createScore(client, schema, args) {
|
|
16967
|
-
const
|
|
16990
|
+
const row = scoreRecordToRow(args.score);
|
|
16991
|
+
const insert = buildInsert(schema, TABLE_SCORE_EVENTS, [row], scoreRewriteConflict(row));
|
|
16968
16992
|
if (insert) await client.query(insert.text, insert.values);
|
|
16969
16993
|
}
|
|
16970
16994
|
async function batchCreateScores(client, schema, args) {
|
|
16971
16995
|
if (args.scores.length === 0) return;
|
|
16972
|
-
const
|
|
16996
|
+
const rows = collapseExactScoreConflicts(args.scores.map(scoreRecordToRow));
|
|
16997
|
+
const insert = buildInsert(schema, TABLE_SCORE_EVENTS, rows, scoreRewriteConflict(rows[0]));
|
|
16973
16998
|
if (insert) await client.query(insert.text, insert.values);
|
|
16974
16999
|
}
|
|
16975
17000
|
/**
|
|
@@ -16992,6 +17017,16 @@ async function deleteScores(client, schema, args) {
|
|
|
16992
17017
|
}
|
|
16993
17018
|
await client.query(`DELETE FROM ${table} WHERE ${conditions.join(" AND ")}`, values);
|
|
16994
17019
|
}
|
|
17020
|
+
function latestScorePredicate(table, alias = "s") {
|
|
17021
|
+
return `NOT EXISTS (
|
|
17022
|
+
SELECT 1 FROM ${table} newer
|
|
17023
|
+
WHERE newer."scoreId" = ${alias}."scoreId"
|
|
17024
|
+
AND newer."cursorId" > ${alias}."cursorId"
|
|
17025
|
+
)`;
|
|
17026
|
+
}
|
|
17027
|
+
function applyLatestScorePredicate(acc, table) {
|
|
17028
|
+
acc.conditions.push(latestScorePredicate(table));
|
|
17029
|
+
}
|
|
16995
17030
|
async function listScores(client, schema, args) {
|
|
16996
17031
|
const { mode, filters, pagination, orderBy, after, limit } = _mastra_core_storage.listScoresArgsSchema.parse(args);
|
|
16997
17032
|
const table = qualifiedTable(schema, TABLE_SCORE_EVENTS);
|
|
@@ -17002,28 +17037,50 @@ async function listScores(client, schema, args) {
|
|
|
17002
17037
|
return listScoresPage(client, table, filters, pagination.page, pagination.perPage, orderBy.field, orderBy.direction);
|
|
17003
17038
|
}
|
|
17004
17039
|
async function getScoreById(client, schema, scoreId) {
|
|
17040
|
+
const table = qualifiedTable(schema, TABLE_SCORE_EVENTS);
|
|
17005
17041
|
const row = await client.oneOrNone(`SELECT ${SCORE_SELECT_COLUMNS}
|
|
17006
|
-
FROM ${
|
|
17042
|
+
FROM ${table}
|
|
17007
17043
|
WHERE "scoreId" = $1
|
|
17008
|
-
ORDER BY "
|
|
17044
|
+
ORDER BY "cursorId" DESC
|
|
17009
17045
|
LIMIT 1`, [scoreId]);
|
|
17010
17046
|
return row ? rowToScoreRecord(row) : null;
|
|
17011
17047
|
}
|
|
17012
17048
|
async function listScoresPage(client, table, filters, page, perPage, orderField, orderDir) {
|
|
17013
|
-
|
|
17049
|
+
const acc = newFilterAccumulator();
|
|
17050
|
+
applyScoreFilters(acc, filters);
|
|
17051
|
+
applyLatestScorePredicate(acc, table);
|
|
17052
|
+
const whereClause = whereOrEmpty(acc);
|
|
17053
|
+
const countRow = await client.oneOrNone(`SELECT COUNT(*)::text AS count FROM ${table} s ${whereClause}`, acc.params);
|
|
17054
|
+
const total = Number(countRow?.count ?? 0);
|
|
17055
|
+
let scores = [];
|
|
17056
|
+
if (total > 0) {
|
|
17057
|
+
const safeOrderField = (0, _mastra_core_utils.parseSqlIdentifier)(orderField, "order field");
|
|
17058
|
+
scores = (await client.manyOrNone(`SELECT ${SCORE_SELECT_COLUMNS}
|
|
17059
|
+
FROM ${table} s
|
|
17060
|
+
${whereClause}
|
|
17061
|
+
ORDER BY "${safeOrderField}" ${orderDir}, "cursorId" ${orderDir}
|
|
17062
|
+
LIMIT $${acc.next++} OFFSET $${acc.next++}`, [
|
|
17063
|
+
...acc.params,
|
|
17064
|
+
perPage,
|
|
17065
|
+
page * perPage
|
|
17066
|
+
])).map(rowToScoreRecord);
|
|
17067
|
+
}
|
|
17068
|
+
const deltaCursor = deltaPollingFeatureEnabled() ? await readSignalStreamHeadCursor({
|
|
17014
17069
|
client,
|
|
17015
17070
|
table,
|
|
17016
17071
|
filters,
|
|
17017
|
-
|
|
17018
|
-
|
|
17019
|
-
|
|
17020
|
-
|
|
17021
|
-
|
|
17022
|
-
|
|
17023
|
-
|
|
17024
|
-
|
|
17025
|
-
|
|
17026
|
-
|
|
17072
|
+
applyFilters: applyScoreFilters
|
|
17073
|
+
}) : void 0;
|
|
17074
|
+
return {
|
|
17075
|
+
scores,
|
|
17076
|
+
pagination: {
|
|
17077
|
+
total,
|
|
17078
|
+
page,
|
|
17079
|
+
perPage,
|
|
17080
|
+
hasMore: (page + 1) * perPage < total
|
|
17081
|
+
},
|
|
17082
|
+
...deltaCursor !== void 0 ? { deltaCursor } : {}
|
|
17083
|
+
};
|
|
17027
17084
|
}
|
|
17028
17085
|
async function listScoresDelta(client, table, filters, after, limit) {
|
|
17029
17086
|
return listSignalDelta({
|
|
@@ -17039,12 +17096,14 @@ async function listScoresDelta(client, table, filters, after, limit) {
|
|
|
17039
17096
|
});
|
|
17040
17097
|
}
|
|
17041
17098
|
async function runScoreAggregateQuery(client, schema, args, filters) {
|
|
17099
|
+
const table = qualifiedTable(schema, TABLE_SCORE_EVENTS);
|
|
17042
17100
|
const acc = newFilterAccumulator();
|
|
17043
17101
|
pushScoreIdentity(acc, args.scorerId, args.scoreSource);
|
|
17044
17102
|
applyScoreFilters(acc, filters);
|
|
17103
|
+
applyLatestScorePredicate(acc, table);
|
|
17045
17104
|
const sql = `
|
|
17046
17105
|
SELECT ${aggregationSql(args.aggregation, "\"score\"")} AS "value"
|
|
17047
|
-
FROM ${
|
|
17106
|
+
FROM ${table} s
|
|
17048
17107
|
${whereOrEmpty(acc)}
|
|
17049
17108
|
`;
|
|
17050
17109
|
const row = await client.oneOrNone(sql, acc.params);
|
|
@@ -17076,10 +17135,12 @@ async function getScoreBreakdown(client, schema, args) {
|
|
|
17076
17135
|
});
|
|
17077
17136
|
pushScoreIdentity(acc, args.scorerId, args.scoreSource);
|
|
17078
17137
|
applyScoreFilters(acc, args.filters);
|
|
17138
|
+
const table = qualifiedTable(schema, TABLE_SCORE_EVENTS);
|
|
17139
|
+
applyLatestScorePredicate(acc, table);
|
|
17079
17140
|
const sql = `
|
|
17080
17141
|
SELECT ${resolved.map((e) => e.selectSql).join(", ")},
|
|
17081
17142
|
${aggregationSql(args.aggregation, "\"score\"")} AS "value"
|
|
17082
|
-
FROM ${
|
|
17143
|
+
FROM ${table} s
|
|
17083
17144
|
${whereOrEmpty(acc)}
|
|
17084
17145
|
GROUP BY ${resolved.map((e) => e.alias).join(", ")}
|
|
17085
17146
|
ORDER BY "value" DESC NULLS LAST
|
|
@@ -17099,11 +17160,13 @@ async function getScoreTimeSeries(client, schema, args) {
|
|
|
17099
17160
|
});
|
|
17100
17161
|
pushScoreIdentity(acc, args.scorerId, args.scoreSource);
|
|
17101
17162
|
applyScoreFilters(acc, args.filters);
|
|
17163
|
+
const table = qualifiedTable(schema, TABLE_SCORE_EVENTS);
|
|
17164
|
+
applyLatestScorePredicate(acc, table);
|
|
17102
17165
|
const sql = `
|
|
17103
17166
|
SELECT ${bucket} AS bucket,
|
|
17104
17167
|
${resolved.map((e) => e.selectSql).join(", ")},
|
|
17105
17168
|
${aggregationSql(args.aggregation, "\"score\"")} AS "value"
|
|
17106
|
-
FROM ${
|
|
17169
|
+
FROM ${table} s
|
|
17107
17170
|
${whereOrEmpty(acc)}
|
|
17108
17171
|
GROUP BY bucket, ${resolved.map((e) => e.alias).join(", ")}
|
|
17109
17172
|
ORDER BY bucket
|
|
@@ -17121,10 +17184,12 @@ async function getScoreTimeSeries(client, schema, args) {
|
|
|
17121
17184
|
const acc = newFilterAccumulator();
|
|
17122
17185
|
pushScoreIdentity(acc, args.scorerId, args.scoreSource);
|
|
17123
17186
|
applyScoreFilters(acc, args.filters);
|
|
17187
|
+
const table = qualifiedTable(schema, TABLE_SCORE_EVENTS);
|
|
17188
|
+
applyLatestScorePredicate(acc, table);
|
|
17124
17189
|
const sql = `
|
|
17125
17190
|
SELECT ${bucket} AS bucket,
|
|
17126
17191
|
${aggregationSql(args.aggregation, "\"score\"")} AS "value"
|
|
17127
|
-
FROM ${
|
|
17192
|
+
FROM ${table} s
|
|
17128
17193
|
${whereOrEmpty(acc)}
|
|
17129
17194
|
GROUP BY bucket
|
|
17130
17195
|
ORDER BY bucket
|
|
@@ -17144,9 +17209,11 @@ async function getScorePercentiles(client, schema, args) {
|
|
|
17144
17209
|
const acc = newFilterAccumulator();
|
|
17145
17210
|
pushScoreIdentity(acc, args.scorerId, args.scoreSource);
|
|
17146
17211
|
applyScoreFilters(acc, args.filters);
|
|
17212
|
+
const table = qualifiedTable(schema, TABLE_SCORE_EVENTS);
|
|
17213
|
+
applyLatestScorePredicate(acc, table);
|
|
17147
17214
|
const sql = `
|
|
17148
17215
|
SELECT ${bucket} AS bucket, ${percentileSelectSql(args.percentiles, "\"score\"")}
|
|
17149
|
-
FROM ${
|
|
17216
|
+
FROM ${table} s
|
|
17150
17217
|
${whereOrEmpty(acc)}
|
|
17151
17218
|
GROUP BY bucket
|
|
17152
17219
|
ORDER BY bucket
|
|
@@ -17345,13 +17412,6 @@ function latestSpanPredicate$1(spanTable) {
|
|
|
17345
17412
|
AND (newer."isPending" < s."isPending" OR (newer."isPending" = s."isPending" AND newer."cursorId" > s."cursorId"))
|
|
17346
17413
|
)`;
|
|
17347
17414
|
}
|
|
17348
|
-
function latestScorePredicate(scoreTable) {
|
|
17349
|
-
return `NOT EXISTS (
|
|
17350
|
-
SELECT 1 FROM ${scoreTable} newer
|
|
17351
|
-
WHERE newer."scoreId" = s."scoreId"
|
|
17352
|
-
AND newer."cursorId" > s."cursorId"
|
|
17353
|
-
)`;
|
|
17354
|
-
}
|
|
17355
17415
|
function latestFeedbackPredicate(feedbackTable) {
|
|
17356
17416
|
return `NOT EXISTS (
|
|
17357
17417
|
SELECT 1 FROM ${feedbackTable} newer
|
|
@@ -17521,7 +17581,7 @@ function compilePostgresTraceScope(schema, selection, relationCollections) {
|
|
|
17521
17581
|
values
|
|
17522
17582
|
};
|
|
17523
17583
|
}
|
|
17524
|
-
function compilePostgresTraceQuery(schema, plan) {
|
|
17584
|
+
function compilePostgresTraceQuery(schema, plan, mode = "data") {
|
|
17525
17585
|
const { ctes, values } = compilePostgresTraceScope(schema, plan, collectRelationCollections(plan.where));
|
|
17526
17586
|
let predicateSql = "TRUE";
|
|
17527
17587
|
if (plan.where) {
|
|
@@ -17535,6 +17595,12 @@ function compilePostgresTraceQuery(schema, plan) {
|
|
|
17535
17595
|
WHERE ${predicateSql}
|
|
17536
17596
|
)`);
|
|
17537
17597
|
const candidates = `WITH ${ctes.join(",\n")}`;
|
|
17598
|
+
if (plan.paginationMode === "page" && mode === "count") return {
|
|
17599
|
+
text: `${candidates}
|
|
17600
|
+
SELECT COUNT(*)::text AS count
|
|
17601
|
+
FROM candidates`,
|
|
17602
|
+
values
|
|
17603
|
+
};
|
|
17538
17604
|
if (plan.result === "groups") {
|
|
17539
17605
|
const pageCondition = plan.cursor ? `AND "threadId" > $${values.length + 1}` : "";
|
|
17540
17606
|
if (plan.cursor) values.push(plan.cursor.threadId);
|
|
@@ -17552,6 +17618,17 @@ LIMIT $${values.length}`,
|
|
|
17552
17618
|
}
|
|
17553
17619
|
const orderField = plan.orderBy.field === "startedAt" ? "\"startedAt\"" : "\"endedAt\"";
|
|
17554
17620
|
const direction = plan.orderBy.direction === "asc" ? "ASC" : "DESC";
|
|
17621
|
+
if (plan.paginationMode === "page") {
|
|
17622
|
+
values.push(plan.perPage, plan.page * plan.perPage);
|
|
17623
|
+
return {
|
|
17624
|
+
text: `${candidates}
|
|
17625
|
+
SELECT *
|
|
17626
|
+
FROM candidates
|
|
17627
|
+
ORDER BY ${orderField} ${direction}, "traceId" ASC
|
|
17628
|
+
LIMIT $${values.length - 1} OFFSET $${values.length}`,
|
|
17629
|
+
values
|
|
17630
|
+
};
|
|
17631
|
+
}
|
|
17555
17632
|
let pageCondition = "";
|
|
17556
17633
|
if (plan.cursor) {
|
|
17557
17634
|
const comparison = plan.orderBy.direction === "asc" ? ">" : "<";
|
|
@@ -17698,10 +17775,11 @@ function isPostgresResourceLimit(error) {
|
|
|
17698
17775
|
const candidate = error;
|
|
17699
17776
|
return candidate.code === "53200" || candidate.code === "53400";
|
|
17700
17777
|
}
|
|
17701
|
-
async function runWithPostgresTraceQueryTimeout(client, timeoutMs, execute) {
|
|
17778
|
+
async function runWithPostgresTraceQueryTimeout(client, timeoutMs, execute, options = {}) {
|
|
17702
17779
|
const resolvedTimeoutMs = _mastra_core_storage.resolveTraceQueryTimeoutMs(timeoutMs);
|
|
17703
17780
|
try {
|
|
17704
17781
|
return await client.tx(async (transaction) => {
|
|
17782
|
+
if (options.repeatableRead) await transaction.query("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ");
|
|
17705
17783
|
await transaction.query(`SELECT set_config('statement_timeout', $1, true)`, [`${resolvedTimeoutMs}ms`]);
|
|
17706
17784
|
return execute(transaction);
|
|
17707
17785
|
});
|
|
@@ -17735,6 +17813,50 @@ async function getTraceQueryValues(client, schema, plan, timeoutMs) {
|
|
|
17735
17813
|
});
|
|
17736
17814
|
}
|
|
17737
17815
|
async function queryTraces(client, schema, plan, timeoutMs) {
|
|
17816
|
+
if (plan.paginationMode === "page") {
|
|
17817
|
+
const resolvedTimeoutMs = _mastra_core_storage.resolveTraceQueryTimeoutMs(timeoutMs);
|
|
17818
|
+
const deadline = performance.now() + resolvedTimeoutMs;
|
|
17819
|
+
const countQuery = compilePostgresTraceQuery(schema, plan, "count");
|
|
17820
|
+
const dataQuery = compilePostgresTraceQuery(schema, plan);
|
|
17821
|
+
const { total, rows } = await runWithPostgresTraceQueryTimeout(client, resolvedTimeoutMs, async (transaction) => {
|
|
17822
|
+
const countRows = await transaction.any(countQuery.text, countQuery.values);
|
|
17823
|
+
const remainingTimeoutMs = Math.floor(deadline - performance.now());
|
|
17824
|
+
if (remainingTimeoutMs <= 0) throw new _mastra_core_storage.TraceQueryExecutionError();
|
|
17825
|
+
await transaction.query(`SELECT set_config('statement_timeout', $1, true)`, [`${remainingTimeoutMs}ms`]);
|
|
17826
|
+
const rows = await transaction.any(dataQuery.text, dataQuery.values);
|
|
17827
|
+
return {
|
|
17828
|
+
total: Number(countRows[0]?.count ?? 0),
|
|
17829
|
+
rows
|
|
17830
|
+
};
|
|
17831
|
+
}, { repeatableRead: true });
|
|
17832
|
+
const traces = rows.map((row) => ({
|
|
17833
|
+
traceId: String(row.traceId),
|
|
17834
|
+
rootSpanId: String(row.rootSpanId),
|
|
17835
|
+
name: row.name,
|
|
17836
|
+
entityId: row.entityId ?? null,
|
|
17837
|
+
parentSpanId: row.parentSpanId ?? null,
|
|
17838
|
+
createdAt: asIsoTimestamp$1(row.startedAt),
|
|
17839
|
+
metadata: row.metadata ?? null,
|
|
17840
|
+
inputPreview: _mastra_core_storage.buildInputPreview(row.input) ?? null,
|
|
17841
|
+
threadId: row.threadId == null ? null : String(row.threadId),
|
|
17842
|
+
resourceId: row.resourceId == null ? null : String(row.resourceId),
|
|
17843
|
+
startedAt: asIsoTimestamp$1(row.startedAt),
|
|
17844
|
+
endedAt: asIsoTimestamp$1(row.endedAt),
|
|
17845
|
+
entityName: row.entityName == null ? null : String(row.entityName),
|
|
17846
|
+
entityType: row.entityType == null ? null : String(row.entityType),
|
|
17847
|
+
environment: row.environment == null ? null : String(row.environment),
|
|
17848
|
+
status: row.status
|
|
17849
|
+
}));
|
|
17850
|
+
return _mastra_core_storage.traceQueryResponseSchema.parse({
|
|
17851
|
+
traces,
|
|
17852
|
+
pagination: {
|
|
17853
|
+
total,
|
|
17854
|
+
page: plan.page,
|
|
17855
|
+
perPage: plan.perPage,
|
|
17856
|
+
hasMore: (plan.page + 1) * plan.perPage < total
|
|
17857
|
+
}
|
|
17858
|
+
});
|
|
17859
|
+
}
|
|
17738
17860
|
const query = compilePostgresTraceQuery(schema, plan);
|
|
17739
17861
|
const rows = await runWithPostgresTraceQueryTimeout(client, timeoutMs, (transaction) => transaction.any(query.text, query.values));
|
|
17740
17862
|
const visibleRows = rows.slice(0, plan.limit);
|