@mastra/mysql 0.7.0-alpha.0 → 0.7.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/mysql
2
2
 
3
+ ## 0.7.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
+ ## 0.7.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
  ## 0.7.0-alpha.0
4
32
 
5
33
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -4922,9 +4922,17 @@ var MemoryMySQL = class MemoryMySQL extends _mastra_core_storage.MemoryStorage {
4922
4922
  if (row.type && row.type !== "v2") message.type = row.type;
4923
4923
  return message;
4924
4924
  }
4925
- async fetchMessagesForThread(threadId, limit) {
4926
- let sql = `SELECT id, thread_id, content, role, type, createdAt, resourceId FROM ${formatTableName(_mastra_core_storage.TABLE_MESSAGES)} WHERE ${quoteIdentifier("thread_id", "column name")} = ? ORDER BY ${quoteIdentifier("createdAt", "column name")} ASC`;
4927
- const params = [threadId];
4925
+ /**
4926
+ * Loads a thread's messages in chronological order.
4927
+ *
4928
+ * @param threadId - Thread to read.
4929
+ * @param limit - Optional cap on the number of rows.
4930
+ * @param resourceId - When set, returns only the rows owned by that resource.
4931
+ */
4932
+ async fetchMessagesForThread(threadId, limit, resourceId) {
4933
+ const resourceCondition = resourceId ? ` AND ${quoteIdentifier("resourceId", "column name")} = ?` : "";
4934
+ let sql = `SELECT id, thread_id, content, role, type, createdAt, resourceId FROM ${formatTableName(_mastra_core_storage.TABLE_MESSAGES)} WHERE ${quoteIdentifier("thread_id", "column name")} = ?${resourceCondition} ORDER BY ${quoteIdentifier("createdAt", "column name")} ASC`;
4935
+ const params = resourceId ? [threadId, resourceId] : [threadId];
4928
4936
  if (limit && limit > 0) {
4929
4937
  sql += ` LIMIT ?`;
4930
4938
  params.push(limit);
@@ -4935,15 +4943,20 @@ var MemoryMySQL = class MemoryMySQL extends _mastra_core_storage.MemoryStorage {
4935
4943
  /**
4936
4944
  * Fetches included messages by ID, discovering their thread automatically.
4937
4945
  * This handles cross-thread includes where the include item doesn't specify a threadId.
4946
+ *
4947
+ * @param include - Message ids to pin, each with an optional before/after window.
4948
+ * @param resourceId - When set, restricts both the pinned messages and their context
4949
+ * to that resource so an id from another resource returns nothing.
4938
4950
  */
4939
- async _getIncludedMessages({ include }) {
4951
+ async _getIncludedMessages({ include, resourceId }) {
4940
4952
  if (!include || include.length === 0) return null;
4941
4953
  const tableName = formatTableName(_mastra_core_storage.TABLE_MESSAGES);
4942
4954
  const selectColumns = `id, thread_id, content, role, type, createdAt, resourceId`;
4955
+ const resourceCondition = resourceId ? ` AND m.${quoteIdentifier("resourceId", "column name")} = ?` : "";
4943
4956
  const targetIds = include.map((inc) => inc.id).filter(Boolean);
4944
4957
  if (targetIds.length === 0) return null;
4945
4958
  const idPlaceholders = targetIds.map(() => "?").join(", ");
4946
- const [targetRows] = await this.pool.execute(`SELECT id, thread_id, createdAt FROM ${tableName} WHERE id IN (${idPlaceholders})`, targetIds);
4959
+ const [targetRows] = await this.pool.execute(`SELECT id, thread_id, createdAt FROM ${tableName} WHERE id IN (${idPlaceholders})${resourceId ? ` AND ${quoteIdentifier("resourceId", "column name")} = ?` : ""}`, resourceId ? [...targetIds, resourceId] : targetIds);
4947
4960
  if (!targetRows || targetRows.length === 0) return null;
4948
4961
  const targetMap = new Map(targetRows.map((r) => [r.id, {
4949
4962
  threadId: r.thread_id,
@@ -4961,21 +4974,23 @@ var MemoryMySQL = class MemoryMySQL extends _mastra_core_storage.MemoryStorage {
4961
4974
  SELECT ${selectColumns}
4962
4975
  FROM ${tableName} m
4963
4976
  WHERE m.thread_id = ?
4964
- AND m.createdAt <= ?
4977
+ AND m.createdAt <= ?${resourceCondition}
4965
4978
  ORDER BY m.createdAt DESC, m.id DESC
4966
4979
  LIMIT ${prevLimit}
4967
4980
  )`);
4968
4981
  params.push(target.threadId, target.createdAt);
4982
+ if (resourceId) params.push(resourceId);
4969
4983
  if (nextLimit > 0) {
4970
4984
  unionQueries.push(`(
4971
4985
  SELECT ${selectColumns}
4972
4986
  FROM ${tableName} m
4973
4987
  WHERE m.thread_id = ?
4974
- AND m.createdAt > ?
4988
+ AND m.createdAt > ?${resourceCondition}
4975
4989
  ORDER BY m.createdAt ASC, m.id ASC
4976
4990
  LIMIT ${nextLimit}
4977
4991
  )`);
4978
4992
  params.push(target.threadId, target.createdAt);
4993
+ if (resourceId) params.push(resourceId);
4979
4994
  }
4980
4995
  }
4981
4996
  if (unionQueries.length === 0) return null;
@@ -4983,7 +4998,17 @@ var MemoryMySQL = class MemoryMySQL extends _mastra_core_storage.MemoryStorage {
4983
4998
  const [rows] = await this.pool.execute(finalQuery, params);
4984
4999
  return rows;
4985
5000
  }
4986
- async collectIncludeMessages({ threadId, include, messagesByThread }) {
5001
+ /**
5002
+ * Resolves include items against loaded threads, adding each pinned message and its
5003
+ * before/after window.
5004
+ *
5005
+ * @param threadId - Thread used when an include item names no thread of its own.
5006
+ * @param include - Message ids to pin, each with an optional before/after window.
5007
+ * @param messagesByThread - Cache of thread snapshots, reused and filled as threads load.
5008
+ * @param resourceId - When set, restricts both the pinned messages and their context
5009
+ * to that resource so an id from another resource returns nothing.
5010
+ */
5011
+ async collectIncludeMessages({ threadId, include, messagesByThread, resourceId }) {
4987
5012
  if (!include?.length) return [];
4988
5013
  const includeMessages = [];
4989
5014
  const seenIds = /* @__PURE__ */ new Set();
@@ -4991,18 +5016,18 @@ var MemoryMySQL = class MemoryMySQL extends _mastra_core_storage.MemoryStorage {
4991
5016
  const resolvedThreadIds = /* @__PURE__ */ new Map();
4992
5017
  if (unresolvedIds.length > 0) {
4993
5018
  const placeholders = unresolvedIds.map(() => "?").join(", ");
4994
- const [rows] = await this.pool.execute(`SELECT id, thread_id FROM ${formatTableName(_mastra_core_storage.TABLE_MESSAGES)} WHERE id IN (${placeholders})`, unresolvedIds);
5019
+ const [rows] = await this.pool.execute(`SELECT id, thread_id FROM ${formatTableName(_mastra_core_storage.TABLE_MESSAGES)} WHERE id IN (${placeholders})${resourceId ? ` AND ${quoteIdentifier("resourceId", "column name")} = ?` : ""}`, resourceId ? [...unresolvedIds, resourceId] : unresolvedIds);
4995
5020
  for (const row of rows) resolvedThreadIds.set(row.id, row.thread_id);
4996
5021
  }
4997
5022
  for (const inc of include) {
4998
5023
  const targetThreadId = inc.threadId ?? resolvedThreadIds.get(inc.id) ?? threadId;
4999
5024
  let threadMessages = messagesByThread.get(targetThreadId);
5000
5025
  if (!threadMessages) {
5001
- threadMessages = (await this.fetchMessagesForThread(targetThreadId)).map((row) => this.mapMessage(row));
5026
+ threadMessages = (await this.fetchMessagesForThread(targetThreadId, void 0, resourceId)).map((row) => this.mapMessage(row));
5002
5027
  messagesByThread.set(targetThreadId, threadMessages);
5003
5028
  }
5004
5029
  if (!threadMessages.some((message) => message.id === inc.id) || (inc.withPreviousMessages ?? 0) > 0 || (inc.withNextMessages ?? 0) > 0 || threadMessages.length < (inc.withNextMessages ?? 0) + (inc.withPreviousMessages ?? 0) + 1) {
5005
- threadMessages = (await this.fetchMessagesForThread(targetThreadId)).map((row) => this.mapMessage(row));
5030
+ threadMessages = (await this.fetchMessagesForThread(targetThreadId, void 0, resourceId)).map((row) => this.mapMessage(row));
5006
5031
  messagesByThread.set(targetThreadId, threadMessages);
5007
5032
  }
5008
5033
  const targetIndex = threadMessages.findIndex((msg) => msg.id === inc.id);
@@ -5186,14 +5211,14 @@ var MemoryMySQL = class MemoryMySQL extends _mastra_core_storage.MemoryStorage {
5186
5211
  tableName: _mastra_core_storage.TABLE_THREADS,
5187
5212
  keys: { id },
5188
5213
  data: {
5189
- title,
5214
+ title: title ?? existing.title,
5190
5215
  metadata: JSON.stringify(mergedMetadata),
5191
5216
  updatedAt
5192
5217
  }
5193
5218
  });
5194
5219
  return {
5195
5220
  ...existing,
5196
- title,
5221
+ title: title ?? existing.title,
5197
5222
  metadata: mergedMetadata,
5198
5223
  updatedAt
5199
5224
  };
@@ -5596,7 +5621,10 @@ var MemoryMySQL = class MemoryMySQL extends _mastra_core_storage.MemoryStorage {
5596
5621
  hasMore: false
5597
5622
  };
5598
5623
  if (perPage === 0 && include && include.length > 0) {
5599
- const includeRows = await this._getIncludedMessages({ include });
5624
+ const includeRows = await this._getIncludedMessages({
5625
+ include,
5626
+ resourceId
5627
+ });
5600
5628
  if (!includeRows || includeRows.length === 0) return {
5601
5629
  messages: [],
5602
5630
  total: 0,
@@ -5634,7 +5662,8 @@ var MemoryMySQL = class MemoryMySQL extends _mastra_core_storage.MemoryStorage {
5634
5662
  const includeMessages = await this.collectIncludeMessages({
5635
5663
  threadId: primaryThreadId,
5636
5664
  include,
5637
- messagesByThread
5665
+ messagesByThread,
5666
+ resourceId
5638
5667
  });
5639
5668
  const combinedMap = /* @__PURE__ */ new Map();
5640
5669
  for (const msg of paginatedMain) combinedMap.set(msg.id, msg);
@@ -5722,7 +5751,7 @@ var MemoryMySQL = class MemoryMySQL extends _mastra_core_storage.MemoryStorage {
5722
5751
  if (include && include.length > 0) {
5723
5752
  const validInclude = (await Promise.all(include.map(async (inc) => {
5724
5753
  if (inc.threadId) return inc;
5725
- const [msgRows] = await this.pool.execute(`SELECT thread_id FROM ${tableName} WHERE id = ? LIMIT 1`, [inc.id]);
5754
+ const [msgRows] = await this.pool.execute(`SELECT thread_id FROM ${tableName} WHERE id = ? AND ${quoteIdentifier("resourceId", "column name")} = ? LIMIT 1`, [inc.id, resourceId]);
5726
5755
  const threadId = msgRows?.[0]?.thread_id;
5727
5756
  return threadId ? {
5728
5757
  ...inc,
@@ -5734,7 +5763,8 @@ var MemoryMySQL = class MemoryMySQL extends _mastra_core_storage.MemoryStorage {
5734
5763
  const includeMessages = await this.collectIncludeMessages({
5735
5764
  threadId: validInclude[0].threadId,
5736
5765
  include: validInclude,
5737
- messagesByThread
5766
+ messagesByThread,
5767
+ resourceId
5738
5768
  });
5739
5769
  for (const includeMsg of includeMessages) if (!messageIds.has(includeMsg.id)) {
5740
5770
  messages.push(includeMsg);