@mastra/spanner 1.3.1 → 1.4.0-alpha.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/CHANGELOG.md +25 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +39 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +40 -3
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/metrics.d.ts.map +1 -1
- package/package.json +7 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @mastra/spanner
|
|
2
2
|
|
|
3
|
+
## 1.4.0-alpha.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added exact metadata filtering to message history queries across Memory APIs and supported storage providers. ([#19991](https://github.com/mastra-ai/mastra/pull/19991))
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
const messages = await memory.recall({
|
|
11
|
+
threadId: 'thread-1',
|
|
12
|
+
filter: {
|
|
13
|
+
metadata: {
|
|
14
|
+
status: 'done',
|
|
15
|
+
priority: 'high',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Multiple fields use AND semantics. Supported values are strings, finite numbers, booleans, and `null`.
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- Updated dependencies [[`0dca9d0`](https://github.com/mastra-ai/mastra/commit/0dca9d0b1356024a53b72ea6f040db528b126caa)]:
|
|
26
|
+
- @mastra/core@1.54.0-alpha.0
|
|
27
|
+
|
|
3
28
|
## 1.3.1
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
package/dist/docs/SKILL.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -6369,6 +6369,35 @@ var MCPServersSpanner = class _MCPServersSpanner extends storage.MCPServersStora
|
|
|
6369
6369
|
}
|
|
6370
6370
|
}
|
|
6371
6371
|
};
|
|
6372
|
+
function buildSpannerMessageMetadataFilter(metadataFilter) {
|
|
6373
|
+
if (!metadataFilter) return { clauses: [], params: {} };
|
|
6374
|
+
const clauses = [];
|
|
6375
|
+
const params = {};
|
|
6376
|
+
Object.entries(metadataFilter).forEach(([key, value], index) => {
|
|
6377
|
+
const path = `$.metadata.${key}`;
|
|
6378
|
+
const valueExpr = `JSON_VALUE(SAFE.PARSE_JSON(content), '${path}')`;
|
|
6379
|
+
const queryExpr = `JSON_QUERY(SAFE.PARSE_JSON(content), '${path}')`;
|
|
6380
|
+
const typeExpr = `JSON_TYPE(${queryExpr})`;
|
|
6381
|
+
if (value === null) {
|
|
6382
|
+
clauses.push(`${queryExpr} = 'null'`);
|
|
6383
|
+
return;
|
|
6384
|
+
}
|
|
6385
|
+
const paramName = `metadataValue${index}`;
|
|
6386
|
+
if (typeof value === "string") {
|
|
6387
|
+
params[paramName] = value;
|
|
6388
|
+
clauses.push(`${typeExpr} = 'string' AND ${valueExpr} = @${paramName}`);
|
|
6389
|
+
return;
|
|
6390
|
+
}
|
|
6391
|
+
if (typeof value === "number") {
|
|
6392
|
+
params[paramName] = String(value);
|
|
6393
|
+
clauses.push(`${typeExpr} = 'number' AND ${valueExpr} = @${paramName}`);
|
|
6394
|
+
return;
|
|
6395
|
+
}
|
|
6396
|
+
params[paramName] = value ? "true" : "false";
|
|
6397
|
+
clauses.push(`${typeExpr} = 'boolean' AND ${valueExpr} = @${paramName}`);
|
|
6398
|
+
});
|
|
6399
|
+
return { clauses, params };
|
|
6400
|
+
}
|
|
6372
6401
|
var MemorySpanner = class _MemorySpanner extends storage.MemoryStorage {
|
|
6373
6402
|
database;
|
|
6374
6403
|
db;
|
|
@@ -6847,6 +6876,7 @@ var MemorySpanner = class _MemorySpanner extends storage.MemoryStorage {
|
|
|
6847
6876
|
/** Paginated message listing for a thread, with optional pinned-include and date-range filters. */
|
|
6848
6877
|
async listMessages(args) {
|
|
6849
6878
|
const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
|
|
6879
|
+
const metadataFilter = storage.validateStorageMetadataFilter(filter?.metadata);
|
|
6850
6880
|
const threadIds = Array.isArray(threadId) ? threadId : [threadId];
|
|
6851
6881
|
if (threadIds.length === 0 || threadIds.some((id) => !id || !id.trim())) {
|
|
6852
6882
|
throw new error.MastraError(
|
|
@@ -6872,10 +6902,16 @@ var MemorySpanner = class _MemorySpanner extends storage.MemoryStorage {
|
|
|
6872
6902
|
...buildDateRangeFilter(filter?.dateRange, "createdAt")
|
|
6873
6903
|
};
|
|
6874
6904
|
const {
|
|
6875
|
-
sql:
|
|
6905
|
+
sql: preparedWhereSql,
|
|
6876
6906
|
params: whereParams,
|
|
6877
6907
|
types: whereTypes
|
|
6878
6908
|
} = this.db.prepareWhereClause(filters, storage.TABLE_MESSAGES);
|
|
6909
|
+
const metadataWhere = buildSpannerMessageMetadataFilter(metadataFilter);
|
|
6910
|
+
const whereSql = [preparedWhereSql, ...metadataWhere.clauses].reduce((sql, clause) => {
|
|
6911
|
+
if (!clause) return sql;
|
|
6912
|
+
return sql ? `${sql} AND ${clause}` : ` WHERE ${clause}`;
|
|
6913
|
+
}, "");
|
|
6914
|
+
Object.assign(whereParams, metadataWhere.params);
|
|
6879
6915
|
if (perPage === 0 && (!include || include.length === 0)) {
|
|
6880
6916
|
return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
|
|
6881
6917
|
}
|
|
@@ -6930,6 +6966,7 @@ var MemorySpanner = class _MemorySpanner extends storage.MemoryStorage {
|
|
|
6930
6966
|
const messages = baseRows.map(
|
|
6931
6967
|
(r) => transformFromSpannerRow({ tableName: storage.TABLE_MESSAGES, row: r })
|
|
6932
6968
|
);
|
|
6969
|
+
const primaryPageCount = messages.length;
|
|
6933
6970
|
if (total === 0 && messages.length === 0 && (!include || include.length === 0)) {
|
|
6934
6971
|
return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
|
|
6935
6972
|
}
|
|
@@ -6960,7 +6997,7 @@ var MemorySpanner = class _MemorySpanner extends storage.MemoryStorage {
|
|
|
6960
6997
|
finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)
|
|
6961
6998
|
);
|
|
6962
6999
|
const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
|
|
6963
|
-
const hasMore = perPageInput !== false && !allThreadMessagesReturned && offset + perPage < total;
|
|
7000
|
+
const hasMore = metadataFilter ? perPageInput !== false && offset + primaryPageCount < total : perPageInput !== false && !allThreadMessagesReturned && offset + perPage < total;
|
|
6964
7001
|
return {
|
|
6965
7002
|
messages: finalMessages,
|
|
6966
7003
|
total,
|