@mastra/clickhouse 1.15.0-alpha.0 → 1.15.0-alpha.2

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,33 @@
1
1
  # @mastra/clickhouse
2
2
 
3
+ ## 1.15.0-alpha.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed generated thread titles being clobbered during a turn ([#21041](https://github.com/mastra-ai/mastra/pull/21041))
8
+
9
+ `updateThread` required both `title` and `metadata`, so callers that only needed to
10
+ change metadata (message persistence, working memory, observational memory, channel
11
+ subscriptions) had to read the thread and pass its title back. When title generation
12
+ finished between that read and the write, the freshly generated title was overwritten
13
+ with the stale one.
14
+
15
+ `title` and `metadata` are now independently optional: omitting one leaves that column
16
+ untouched. Callers that only change metadata no longer send a title, and message
17
+ persistence no longer rewrites a thread row it just read.
18
+
19
+ - Updated dependencies [[`1c75e32`](https://github.com/mastra-ai/mastra/commit/1c75e32f7fc0b9fb6f548b4407feaec8a1440212), [`c47165c`](https://github.com/mastra-ai/mastra/commit/c47165c983c87594c6952f1fd2fa51a90205034c), [`e08e789`](https://github.com/mastra-ai/mastra/commit/e08e789c1bf4cd2fe46363f7a4728536ceccc9bd), [`35cc901`](https://github.com/mastra-ai/mastra/commit/35cc90102cf834a84827acaf9eee0b6d6d1e2a3b), [`a8b4cf0`](https://github.com/mastra-ai/mastra/commit/a8b4cf02823cffebc4751a53337dfacf097c1ae1), [`f33264f`](https://github.com/mastra-ai/mastra/commit/f33264f517ae603279afd5c4251e2b40f6dd3618), [`689f2c4`](https://github.com/mastra-ai/mastra/commit/689f2c4b6c0835fe455702b01d21daa8abcd9331), [`eeae63e`](https://github.com/mastra-ai/mastra/commit/eeae63e7fbe8e1f237adc69bca6e2ac13c5ca907), [`4c186a0`](https://github.com/mastra-ai/mastra/commit/4c186a017275f45e6ed4c09de0f89550e2d09e8c), [`b0fa077`](https://github.com/mastra-ai/mastra/commit/b0fa077bcbc9b08551846fe372a0d3d15b71ed72)]:
20
+ - @mastra/core@1.58.0-alpha.8
21
+
22
+ ## 1.15.0-alpha.1
23
+
24
+ ### Patch Changes
25
+
26
+ - Fixed resource-scoped message includes across storage adapters so included context cannot cross resource boundaries. ([#20984](https://github.com/mastra-ai/mastra/pull/20984))
27
+
28
+ - Updated dependencies [[`6445eba`](https://github.com/mastra-ai/mastra/commit/6445eba6020abac681aba1cc9289f446cb400cbe), [`df31eb0`](https://github.com/mastra-ai/mastra/commit/df31eb0c7087d782a0d9346e467f9a4af4b0eef6), [`fcd0667`](https://github.com/mastra-ai/mastra/commit/fcd0667a4e378be35c9a1b1eb19cce78fbfd7282), [`bab06b1`](https://github.com/mastra-ai/mastra/commit/bab06b18923873a584bdfc71a6b4ec7fb4727fb7)]:
29
+ - @mastra/core@1.58.0-alpha.5
30
+
3
31
  ## 1.15.0-alpha.0
4
32
 
5
33
  ### Minor Changes
@@ -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.15.0-alpha.0"
6
+ version: "1.15.0-alpha.2"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.15.0-alpha.0",
2
+ "version": "1.15.0-alpha.2",
3
3
  "package": "@mastra/clickhouse",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -251,6 +251,64 @@ const memoryStore = await storage.getStore('memory')
251
251
  const thread = await memoryStore?.getThreadById({ threadId: '...' })
252
252
  ```
253
253
 
254
+ ## Closing connections
255
+
256
+ `close()` releases the connections of the stores a composite was built from: the `default` and `editor` stores, plus any domain that owns its own client. Each store is closed once, even when it backs several domains. When passed to the Mastra class, `close()` is called by `shutdown()`:
257
+
258
+ ```typescript
259
+ import { MastraCompositeStore } from '@mastra/core/storage'
260
+ import { PostgresStore } from '@mastra/pg'
261
+ import { Mastra } from '@mastra/core'
262
+
263
+ const pgStore = new PostgresStore({
264
+ id: 'pg-storage',
265
+ connectionString: process.env.DATABASE_URL,
266
+ })
267
+
268
+ export const mastra = new Mastra({
269
+ storage: new MastraCompositeStore({ id: 'composite', default: pgStore }),
270
+ })
271
+
272
+ process.on('SIGTERM', async () => {
273
+ // Releases the Postgres pool, so the process can exit
274
+ await mastra.shutdown()
275
+ })
276
+ ```
277
+
278
+ A store you construct only to supply a domain isn't reachable through the composite. Keep a reference to it and close it yourself:
279
+
280
+ ```typescript
281
+ import { MastraCompositeStore } from '@mastra/core/storage'
282
+ import { ClickhouseStore } from '@mastra/clickhouse'
283
+ import { PostgresStore } from '@mastra/pg'
284
+ import { Mastra } from '@mastra/core'
285
+
286
+ const pgStore = new PostgresStore({
287
+ id: 'pg-storage',
288
+ connectionString: process.env.DATABASE_URL,
289
+ })
290
+
291
+ const clickhouseStore = new ClickhouseStore({
292
+ id: 'clickhouse-storage',
293
+ url: process.env.CLICKHOUSE_URL,
294
+ username: process.env.CLICKHOUSE_USERNAME,
295
+ password: process.env.CLICKHOUSE_PASSWORD,
296
+ })
297
+
298
+ export const mastra = new Mastra({
299
+ storage: new MastraCompositeStore({
300
+ id: 'composite',
301
+ default: pgStore,
302
+ domains: { observability: clickhouseStore.stores?.observability },
303
+ }),
304
+ })
305
+
306
+ process.on('SIGTERM', async () => {
307
+ await mastra.shutdown()
308
+ await clickhouseStore.close()
309
+ })
310
+ ```
311
+
254
312
  ## Use cases
255
313
 
256
314
  ### Separate databases for different workloads
package/dist/index.cjs CHANGED
@@ -1185,7 +1185,10 @@ var MemoryStorageClickhouse = class extends _mastra_core_storage.MemoryStorage {
1185
1185
  hasMore: false
1186
1186
  };
1187
1187
  if (perPageForQuery === 0 && include && include.length > 0) {
1188
- const includeResult = await this._getIncludedMessages({ include });
1188
+ const includeResult = await this._getIncludedMessages({
1189
+ include,
1190
+ resourceId
1191
+ });
1189
1192
  const list = new _mastra_core_agent.MessageList().add(includeResult, "memory");
1190
1193
  return {
1191
1194
  messages: this._sortMessages(list.get.all.db(), field, direction),
@@ -1252,7 +1255,10 @@ var MemoryStorageClickhouse = class extends _mastra_core_storage.MemoryStorage {
1252
1255
  };
1253
1256
  const messageIds = new Set(paginatedMessages.map((m) => m.id));
1254
1257
  if (include && include.length > 0) {
1255
- const includeMessages = await this._getIncludedMessages({ include });
1258
+ const includeMessages = await this._getIncludedMessages({
1259
+ include,
1260
+ resourceId
1261
+ });
1256
1262
  for (const includeMsg of includeMessages) if (!messageIds.has(includeMsg.id)) {
1257
1263
  paginatedMessages.push(includeMsg);
1258
1264
  messageIds.add(includeMsg.id);
@@ -1295,15 +1301,24 @@ var MemoryStorageClickhouse = class extends _mastra_core_storage.MemoryStorage {
1295
1301
  return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
1296
1302
  });
1297
1303
  }
1298
- async _getIncludedMessages({ include }) {
1304
+ /**
1305
+ * Fetches the messages named by `include` together with their surrounding context.
1306
+ *
1307
+ * @param include - Message ids to pin, each with an optional before/after window.
1308
+ * @param resourceId - When set, restricts both the pinned messages and their context
1309
+ * to that resource so an id from another resource returns nothing.
1310
+ */
1311
+ async _getIncludedMessages({ include, resourceId }) {
1299
1312
  if (!include || include.length === 0) return [];
1300
1313
  const targetIds = include.map((inc) => inc.id).filter(Boolean);
1301
1314
  if (targetIds.length === 0) return [];
1302
1315
  const { messages: targetDocs } = await this.listMessagesById({ messageIds: targetIds });
1303
- const targetMap = new Map(targetDocs.map((msg) => [msg.id, {
1316
+ const scopedTargetDocs = resourceId ? targetDocs.filter((msg) => msg.resourceId === resourceId) : targetDocs;
1317
+ const targetMap = new Map(scopedTargetDocs.map((msg) => [msg.id, {
1304
1318
  threadId: msg.threadId,
1305
1319
  createdAt: msg.createdAt
1306
1320
  }]));
1321
+ const resourceCondition = resourceId ? ` AND "resourceId" = {var_resource:String}` : "";
1307
1322
  const unionQueries = [];
1308
1323
  const params = {};
1309
1324
  let paramIdx = 1;
@@ -1318,7 +1333,7 @@ var MemoryStorageClickhouse = class extends _mastra_core_storage.MemoryStorage {
1318
1333
  SELECT id, content, role, type, "createdAt", thread_id AS "threadId", "resourceId"
1319
1334
  FROM "${_mastra_core_storage.TABLE_MESSAGES}"
1320
1335
  WHERE thread_id = {${threadParam}:String}
1321
- AND createdAt <= parseDateTime64BestEffort({${createdAtParam}:String}, 3)
1336
+ AND createdAt <= parseDateTime64BestEffort({${createdAtParam}:String}, 3)${resourceCondition}
1322
1337
  ORDER BY createdAt DESC, id DESC
1323
1338
  LIMIT {${limitParam}:Int64}
1324
1339
  `);
@@ -1334,7 +1349,7 @@ var MemoryStorageClickhouse = class extends _mastra_core_storage.MemoryStorage {
1334
1349
  SELECT id, content, role, type, "createdAt", thread_id AS "threadId", "resourceId"
1335
1350
  FROM "${_mastra_core_storage.TABLE_MESSAGES}"
1336
1351
  WHERE thread_id = {${threadParam2}:String}
1337
- AND createdAt > parseDateTime64BestEffort({${createdAtParam2}:String}, 3)
1352
+ AND createdAt > parseDateTime64BestEffort({${createdAtParam2}:String}, 3)${resourceCondition}
1338
1353
  ORDER BY createdAt ASC, id ASC
1339
1354
  LIMIT {${limitParam2}:Int64}
1340
1355
  `);
@@ -1345,6 +1360,7 @@ var MemoryStorageClickhouse = class extends _mastra_core_storage.MemoryStorage {
1345
1360
  }
1346
1361
  }
1347
1362
  if (unionQueries.length === 0) return [];
1363
+ if (resourceId) params.var_resource = resourceId;
1348
1364
  let finalQuery;
1349
1365
  if (unionQueries.length === 1) finalQuery = unionQueries[0];
1350
1366
  else finalQuery = `SELECT * FROM (${unionQueries.join(" UNION ALL ")}) ORDER BY "createdAt" ASC, id ASC`;
@@ -1558,7 +1574,7 @@ var MemoryStorageClickhouse = class extends _mastra_core_storage.MemoryStorage {
1558
1574
  };
1559
1575
  const updatedThread = {
1560
1576
  ...existingThread,
1561
- title,
1577
+ title: title ?? existingThread.title,
1562
1578
  metadata: mergedMetadata,
1563
1579
  updatedAt: /* @__PURE__ */ new Date()
1564
1580
  };
@@ -1587,7 +1603,7 @@ var MemoryStorageClickhouse = class extends _mastra_core_storage.MemoryStorage {
1587
1603
  category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1588
1604
  details: {
1589
1605
  threadId: id,
1590
- title
1606
+ title: title ?? null
1591
1607
  }
1592
1608
  }, error);
1593
1609
  }