@mastra/clickhouse 1.12.0 → 1.13.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 CHANGED
@@ -1,5 +1,30 @@
1
1
  # @mastra/clickhouse
2
2
 
3
+ ## 1.13.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.12.0
4
29
 
5
30
  ### Minor Changes
@@ -293,9 +318,7 @@
293
318
  **Example**
294
319
 
295
320
  ```ts
296
- const storage = new LibSQLStore({
297
- /* config */
298
- });
321
+ const storage = new LibSQLStore({/* config */});
299
322
  const favorites = await storage.getStore('favorites');
300
323
 
301
324
  await favorites?.favorite({
@@ -321,9 +344,7 @@
321
344
  **Example**
322
345
 
323
346
  ```ts
324
- const storage = new LibSQLStore({
325
- /* config */
326
- });
347
+ const storage = new LibSQLStore({/* config */});
327
348
  const favorites = await storage.getStore('favorites');
328
349
 
329
350
  await favorites?.favorite({
@@ -3,7 +3,7 @@ name: mastra-clickhouse
3
3
  description: Documentation for @mastra/clickhouse. Use when working with @mastra/clickhouse APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/clickhouse"
6
- version: "1.12.0"
6
+ version: "1.13.0-alpha.0"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.12.0",
2
+ "version": "1.13.0-alpha.0",
3
3
  "package": "@mastra/clickhouse",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -131,7 +131,7 @@ bun x mastra migrate
131
131
 
132
132
  The migration copies span data from `mastra_ai_spans` into `mastra_span_events` in day-sized batches. It handles column mapping, deduplicates legacy rows, and preserves the original table as a backup. After migration, traces appear in Studio through the vNext adapter.
133
133
 
134
- > **Note:** The legacy table is not deleted. Drop it manually after verifying the migration.
134
+ > **Note:** The legacy table isn't deleted. Drop it manually after verifying the migration.
135
135
 
136
136
  ### ClickHouse for every domain
137
137
 
package/dist/index.cjs CHANGED
@@ -1092,6 +1092,23 @@ function parseMetadata(metadata) {
1092
1092
  return {};
1093
1093
  }
1094
1094
  }
1095
+ function appendClickhouseMessageMetadataFilter(query, params, metadataFilter) {
1096
+ if (!metadataFilter) return query;
1097
+ let nextQuery = query;
1098
+ Object.entries(metadataFilter).forEach(([key, value], index) => {
1099
+ const keyParam = `metadataKey${index}`;
1100
+ params[keyParam] = key;
1101
+ nextQuery += ` AND isValidJSON(content) AND JSONHas(content, 'metadata') AND JSONHas(JSONExtractRaw(content, 'metadata'), {${keyParam}:String})`;
1102
+ if (value === null) {
1103
+ nextQuery += ` AND JSONExtractRaw(content, 'metadata', {${keyParam}:String}) = 'null'`;
1104
+ return;
1105
+ }
1106
+ const valueParam = `metadataValue${index}`;
1107
+ params[valueParam] = JSON.stringify(value);
1108
+ nextQuery += ` AND JSONExtractRaw(content, 'metadata', {${keyParam}:String}) = {${valueParam}:String}`;
1109
+ });
1110
+ return nextQuery;
1111
+ }
1095
1112
  var MemoryStorageClickhouse = class extends storage.MemoryStorage {
1096
1113
  client;
1097
1114
  #db;
@@ -1203,6 +1220,7 @@ var MemoryStorageClickhouse = class extends storage.MemoryStorage {
1203
1220
  }
1204
1221
  async listMessages(args) {
1205
1222
  const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
1223
+ const metadataFilter = storage.validateStorageMetadataFilter(filter?.metadata);
1206
1224
  const rawThreadIds = Array.isArray(threadId) ? threadId : [threadId];
1207
1225
  const threadIds = rawThreadIds.filter((id) => id !== void 0 && id !== null).map((id) => (typeof id === "string" ? id : String(id)).trim()).filter((id) => id.length > 0);
1208
1226
  if (page < 0) {
@@ -1263,6 +1281,7 @@ var MemoryStorageClickhouse = class extends storage.MemoryStorage {
1263
1281
  dataQuery += ` AND createdAt ${endOp} parseDateTime64BestEffort({toDate:String}, 3)`;
1264
1282
  dataParams.toDate = endDate;
1265
1283
  }
1284
+ dataQuery = appendClickhouseMessageMetadataFilter(dataQuery, dataParams, metadataFilter);
1266
1285
  const { field, direction } = this.parseOrderBy(orderBy, "ASC");
1267
1286
  dataQuery += ` ORDER BY "${field}" ${direction}`;
1268
1287
  if (perPageForQuery === 0 && (!include || include.length === 0)) {
@@ -1318,6 +1337,7 @@ var MemoryStorageClickhouse = class extends storage.MemoryStorage {
1318
1337
  countQuery += ` AND createdAt ${endOp} parseDateTime64BestEffort({toDate:String}, 3)`;
1319
1338
  countParams.toDate = endDate;
1320
1339
  }
1340
+ countQuery = appendClickhouseMessageMetadataFilter(countQuery, countParams, metadataFilter);
1321
1341
  const countResult = await this.client.query({
1322
1342
  query: countQuery,
1323
1343
  query_params: countParams,
@@ -1356,7 +1376,7 @@ var MemoryStorageClickhouse = class extends storage.MemoryStorage {
1356
1376
  finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)
1357
1377
  );
1358
1378
  const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
1359
- const hasMore = perPageForResponse === false ? false : allThreadMessagesReturned ? false : offset + paginatedCount < total;
1379
+ const hasMore = metadataFilter && perPageForResponse !== false ? offset + paginatedCount < total : perPageForResponse === false ? false : allThreadMessagesReturned ? false : offset + paginatedCount < total;
1360
1380
  return {
1361
1381
  messages: finalMessages,
1362
1382
  total,