@mastra/libsql 1.20.0-alpha.0 → 1.20.0-alpha.1
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 +17 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-storage-composite.md +58 -0
- package/dist/docs/references/reference-storage-retention.md +1 -1
- package/dist/index.cjs +34 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +34 -11
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +6 -0
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @mastra/libsql
|
|
2
2
|
|
|
3
|
+
## 1.20.0-alpha.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fixed `include` in `listMessages` and `listMessagesByResourceId` so it can no longer return a message that belongs to a different resource. When you pass a `resourceId`, the target message and its surrounding context messages now stay inside that resource. Includes that cross threads inside the same resource keep working, so semantic recall with `scope: 'resource'` is unchanged. ([#20984](https://github.com/mastra-ai/mastra/pull/20984))
|
|
8
|
+
|
|
9
|
+
**Behaviour change in the in-memory store**
|
|
10
|
+
|
|
11
|
+
The in-memory store read the context window from the thread you queried. It now reads the window from the thread that owns the target message, which is what the SQL stores already did. This only changes the result when an `include` entry names a message from another thread.
|
|
12
|
+
|
|
13
|
+
The in-memory store also ignored `include` in `listMessagesByResourceId`. It now returns the included messages, like `@mastra/libsql` and `@mastra/pg` do.
|
|
14
|
+
|
|
15
|
+
Fixes #20604.
|
|
16
|
+
|
|
17
|
+
- 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)]:
|
|
18
|
+
- @mastra/core@1.58.0-alpha.5
|
|
19
|
+
|
|
3
20
|
## 1.20.0-alpha.0
|
|
4
21
|
|
|
5
22
|
### Minor Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -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
|
|
@@ -92,7 +92,7 @@ Each domain declares which of its tables can be age-pruned and which timestamp c
|
|
|
92
92
|
> - Experiments prune as whole units: an aged experiment's result rows are deleted together with it (results cascade with their parent), so a run is never left partially deleted. Retention doesn't have a separate `results` key.
|
|
93
93
|
> - For `schedules`, the growth table is the fire history (`schedule_triggers`, one row per fire): schedule definitions are config and aren't pruned.
|
|
94
94
|
> - On PostgreSQL, timestamp anchors use the timezone-aware mirror columns (for example `createdAtZ`, `completedAtZ`).
|
|
95
|
-
> - LibSQL
|
|
95
|
+
> - LibSQL and PostgreSQL support all domains above except `harness`, which PostgreSQL doesn't implement. MongoDB supports all except `threadState` and `harness`.
|
|
96
96
|
> - The v-next PostgreSQL observability domain stores signal events in day-partitioned tables (`spans`, `metrics`, `logs`, `scores`, `feedback`). For it, `prune()` drops whole day partitions (or TimescaleDB chunks) that are entirely older than the cutoff instead of deleting rows: effective level of detail is one day, and a partition is only dropped once its entire day is past `maxAge`. `PruneResult.deleted` reports the number of rows in the dropped partitions.
|
|
97
97
|
|
|
98
98
|
## Methods
|
package/dist/index.cjs
CHANGED
|
@@ -6722,14 +6722,21 @@ var MemoryLibSQL = class MemoryLibSQL extends _mastra_core_storage.MemoryStorage
|
|
|
6722
6722
|
return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
|
|
6723
6723
|
});
|
|
6724
6724
|
}
|
|
6725
|
-
|
|
6725
|
+
/**
|
|
6726
|
+
* Fetches included messages by ID, discovering their thread automatically.
|
|
6727
|
+
* This handles cross-thread includes where the include item doesn't specify a threadId.
|
|
6728
|
+
* When a resourceId is given, both the target lookup and the surrounding window stay
|
|
6729
|
+
* inside that resource, so an include never leaks another resource's messages.
|
|
6730
|
+
*/
|
|
6731
|
+
async _getIncludedMessages({ include, resourceId }) {
|
|
6726
6732
|
if (!include || include.length === 0) return null;
|
|
6727
6733
|
const targetIds = include.map((inc) => inc.id).filter(Boolean);
|
|
6728
6734
|
if (targetIds.length === 0) return null;
|
|
6735
|
+
const resourceCondition = resourceId ? ` AND "resourceId" = ?` : "";
|
|
6729
6736
|
const idPlaceholders = targetIds.map(() => "?").join(", ");
|
|
6730
6737
|
const targetResult = await this.#client.execute({
|
|
6731
|
-
sql: `SELECT id, thread_id, "createdAt" FROM "${_mastra_core_storage.TABLE_MESSAGES}" WHERE id IN (${idPlaceholders})`,
|
|
6732
|
-
args: targetIds
|
|
6738
|
+
sql: `SELECT id, thread_id, "createdAt" FROM "${_mastra_core_storage.TABLE_MESSAGES}" WHERE id IN (${idPlaceholders})${resourceCondition}`,
|
|
6739
|
+
args: resourceId ? [...targetIds, resourceId] : targetIds
|
|
6733
6740
|
});
|
|
6734
6741
|
if (!targetResult.rows || targetResult.rows.length === 0) return null;
|
|
6735
6742
|
const targetMap = new Map(targetResult.rows.map((r) => [r.id, {
|
|
@@ -6746,21 +6753,25 @@ var MemoryLibSQL = class MemoryLibSQL extends _mastra_core_storage.MemoryStorage
|
|
|
6746
6753
|
SELECT id, content, role, type, "createdAt", thread_id, "resourceId"
|
|
6747
6754
|
FROM "${_mastra_core_storage.TABLE_MESSAGES}"
|
|
6748
6755
|
WHERE thread_id = ?
|
|
6749
|
-
AND "createdAt" <=
|
|
6756
|
+
AND "createdAt" <= ?${resourceCondition}
|
|
6750
6757
|
ORDER BY "createdAt" DESC, id DESC
|
|
6751
6758
|
LIMIT ?
|
|
6752
6759
|
)`);
|
|
6753
|
-
params.push(target.threadId, target.createdAt
|
|
6760
|
+
params.push(target.threadId, target.createdAt);
|
|
6761
|
+
if (resourceId) params.push(resourceId);
|
|
6762
|
+
params.push(withPreviousMessages + 1);
|
|
6754
6763
|
if (withNextMessages > 0) {
|
|
6755
6764
|
unionQueries.push(`SELECT * FROM (
|
|
6756
6765
|
SELECT id, content, role, type, "createdAt", thread_id, "resourceId"
|
|
6757
6766
|
FROM "${_mastra_core_storage.TABLE_MESSAGES}"
|
|
6758
6767
|
WHERE thread_id = ?
|
|
6759
|
-
AND "createdAt" >
|
|
6768
|
+
AND "createdAt" > ?${resourceCondition}
|
|
6760
6769
|
ORDER BY "createdAt" ASC, id ASC
|
|
6761
6770
|
LIMIT ?
|
|
6762
6771
|
)`);
|
|
6763
|
-
params.push(target.threadId, target.createdAt
|
|
6772
|
+
params.push(target.threadId, target.createdAt);
|
|
6773
|
+
if (resourceId) params.push(resourceId);
|
|
6774
|
+
params.push(withNextMessages);
|
|
6764
6775
|
}
|
|
6765
6776
|
}
|
|
6766
6777
|
if (unionQueries.length === 0) return null;
|
|
@@ -6856,7 +6867,10 @@ var MemoryLibSQL = class MemoryLibSQL extends _mastra_core_storage.MemoryStorage
|
|
|
6856
6867
|
hasMore: false
|
|
6857
6868
|
};
|
|
6858
6869
|
if (perPage === 0 && include && include.length > 0) {
|
|
6859
|
-
const includeMessages = await this._getIncludedMessages({
|
|
6870
|
+
const includeMessages = await this._getIncludedMessages({
|
|
6871
|
+
include,
|
|
6872
|
+
resourceId
|
|
6873
|
+
});
|
|
6860
6874
|
if (!includeMessages || includeMessages.length === 0) return {
|
|
6861
6875
|
messages: [],
|
|
6862
6876
|
total: 0,
|
|
@@ -6897,7 +6911,10 @@ var MemoryLibSQL = class MemoryLibSQL extends _mastra_core_storage.MemoryStorage
|
|
|
6897
6911
|
};
|
|
6898
6912
|
const messageIds = new Set(messages.map((m) => m.id));
|
|
6899
6913
|
if (include && include.length > 0) {
|
|
6900
|
-
const includeMessages = await this._getIncludedMessages({
|
|
6914
|
+
const includeMessages = await this._getIncludedMessages({
|
|
6915
|
+
include,
|
|
6916
|
+
resourceId
|
|
6917
|
+
});
|
|
6901
6918
|
if (includeMessages) {
|
|
6902
6919
|
for (const includeMsg of includeMessages) if (!messageIds.has(includeMsg.id)) {
|
|
6903
6920
|
messages.push(includeMsg);
|
|
@@ -6976,7 +6993,10 @@ var MemoryLibSQL = class MemoryLibSQL extends _mastra_core_storage.MemoryStorage
|
|
|
6976
6993
|
hasMore: false
|
|
6977
6994
|
};
|
|
6978
6995
|
if (perPage === 0 && include && include.length > 0) {
|
|
6979
|
-
const includeMessages = await this._getIncludedMessages({
|
|
6996
|
+
const includeMessages = await this._getIncludedMessages({
|
|
6997
|
+
include,
|
|
6998
|
+
resourceId
|
|
6999
|
+
});
|
|
6980
7000
|
if (!includeMessages || includeMessages.length === 0) return {
|
|
6981
7001
|
messages: [],
|
|
6982
7002
|
total: 0,
|
|
@@ -7016,7 +7036,10 @@ var MemoryLibSQL = class MemoryLibSQL extends _mastra_core_storage.MemoryStorage
|
|
|
7016
7036
|
};
|
|
7017
7037
|
const messageIds = new Set(messages.map((m) => m.id));
|
|
7018
7038
|
if (include && include.length > 0) {
|
|
7019
|
-
const includeMessages = await this._getIncludedMessages({
|
|
7039
|
+
const includeMessages = await this._getIncludedMessages({
|
|
7040
|
+
include,
|
|
7041
|
+
resourceId
|
|
7042
|
+
});
|
|
7020
7043
|
if (includeMessages) {
|
|
7021
7044
|
for (const includeMsg of includeMessages) if (!messageIds.has(includeMsg.id)) {
|
|
7022
7045
|
messages.push(includeMsg);
|