@mastra/libsql 0.10.2-alpha.1 → 0.10.2-alpha.3
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +16 -0
- package/dist/_tsup-dts-rollup.d.cts +3 -0
- package/dist/_tsup-dts-rollup.d.ts +3 -0
- package/dist/index.cjs +79 -38
- package/dist/index.js +79 -38
- package/package.json +3 -3
- package/src/storage/index.ts +85 -39
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @mastra/libsql@0.10.2-alpha.
|
|
2
|
+
> @mastra/libsql@0.10.2-alpha.3 build /home/runner/work/mastra/mastra/stores/libsql
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
6
6
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
7
|
[34mCLI[39m tsup v8.5.0
|
|
8
8
|
[34mTSC[39m Build start
|
|
9
|
-
[32mTSC[39m ⚡️ Build success in
|
|
9
|
+
[32mTSC[39m ⚡️ Build success in 9552ms
|
|
10
10
|
[34mDTS[39m Build start
|
|
11
11
|
[34mCLI[39m Target: es2022
|
|
12
12
|
Analysis will use the bundled TypeScript version 5.8.3
|
|
13
13
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/libsql/dist/_tsup-dts-rollup.d.ts[39m
|
|
14
14
|
Analysis will use the bundled TypeScript version 5.8.3
|
|
15
15
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/libsql/dist/_tsup-dts-rollup.d.cts[39m
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 11177ms
|
|
17
17
|
[34mCLI[39m Cleaning output folder
|
|
18
18
|
[34mESM[39m Build start
|
|
19
19
|
[34mCJS[39m Build start
|
|
20
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
21
|
-
[32mESM[39m ⚡️ Build success in
|
|
22
|
-
[32mCJS[39m [1mdist/index.cjs [22m[
|
|
23
|
-
[32mCJS[39m ⚡️ Build success in
|
|
20
|
+
[32mESM[39m [1mdist/index.js [22m[32m58.55 KB[39m
|
|
21
|
+
[32mESM[39m ⚡️ Build success in 1246ms
|
|
22
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m58.84 KB[39m
|
|
23
|
+
[32mCJS[39m ⚡️ Build success in 1247ms
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @mastra/libsql
|
|
2
2
|
|
|
3
|
+
## 0.10.2-alpha.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e0f9201: change how dedupe works for libsql and pg
|
|
8
|
+
- Updated dependencies [925ab94]
|
|
9
|
+
- @mastra/core@0.10.4-alpha.3
|
|
10
|
+
|
|
11
|
+
## 0.10.2-alpha.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 48eddb9: update filter logic in Memory class to support semantic recall search scope
|
|
16
|
+
- Updated dependencies [48eddb9]
|
|
17
|
+
- @mastra/core@0.10.4-alpha.2
|
|
18
|
+
|
|
3
19
|
## 0.10.2-alpha.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -84,6 +84,9 @@ declare class LibSQLStore extends MastraStorage {
|
|
|
84
84
|
private readonly maxRetries;
|
|
85
85
|
private readonly initialBackoffMs;
|
|
86
86
|
constructor(config: LibSQLConfig);
|
|
87
|
+
get supports(): {
|
|
88
|
+
selectByIncludeResourceScope: boolean;
|
|
89
|
+
};
|
|
87
90
|
private getCreateTableSQL;
|
|
88
91
|
createTable({ tableName, schema, }: {
|
|
89
92
|
tableName: TABLE_NAMES;
|
|
@@ -84,6 +84,9 @@ declare class LibSQLStore extends MastraStorage {
|
|
|
84
84
|
private readonly maxRetries;
|
|
85
85
|
private readonly initialBackoffMs;
|
|
86
86
|
constructor(config: LibSQLConfig);
|
|
87
|
+
get supports(): {
|
|
88
|
+
selectByIncludeResourceScope: boolean;
|
|
89
|
+
};
|
|
87
90
|
private getCreateTableSQL;
|
|
88
91
|
createTable({ tableName, schema, }: {
|
|
89
92
|
tableName: TABLE_NAMES;
|
package/dist/index.cjs
CHANGED
|
@@ -818,6 +818,11 @@ var LibSQLStore = class extends storage.MastraStorage {
|
|
|
818
818
|
this.client.execute("PRAGMA busy_timeout = 5000;").then(() => this.logger.debug("LibSQLStore: PRAGMA busy_timeout=5000 set.")).catch((err) => this.logger.warn("LibSQLStore: Failed to set PRAGMA busy_timeout.", err));
|
|
819
819
|
}
|
|
820
820
|
}
|
|
821
|
+
get supports() {
|
|
822
|
+
return {
|
|
823
|
+
selectByIncludeResourceScope: true
|
|
824
|
+
};
|
|
825
|
+
}
|
|
821
826
|
getCreateTableSQL(tableName, schema) {
|
|
822
827
|
const parsedTableName = utils.parseSqlIdentifier(tableName, "table name");
|
|
823
828
|
const columns = Object.entries(schema).map(([name, col]) => {
|
|
@@ -1148,35 +1153,52 @@ var LibSQLStore = class extends storage.MastraStorage {
|
|
|
1148
1153
|
if (row.type && row.type !== `v2`) result.type = row.type;
|
|
1149
1154
|
return result;
|
|
1150
1155
|
}
|
|
1151
|
-
async _getIncludedMessages(
|
|
1156
|
+
async _getIncludedMessages({
|
|
1157
|
+
threadId,
|
|
1158
|
+
selectBy
|
|
1159
|
+
}) {
|
|
1152
1160
|
const include = selectBy?.include;
|
|
1153
1161
|
if (!include) return null;
|
|
1154
|
-
const
|
|
1155
|
-
const
|
|
1156
|
-
const
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1162
|
+
const unionQueries = [];
|
|
1163
|
+
const params = [];
|
|
1164
|
+
for (const inc of include) {
|
|
1165
|
+
const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
|
|
1166
|
+
const searchId = inc.threadId || threadId;
|
|
1167
|
+
unionQueries.push(
|
|
1168
|
+
`
|
|
1169
|
+
SELECT * FROM (
|
|
1170
|
+
WITH numbered_messages AS (
|
|
1171
|
+
SELECT
|
|
1172
|
+
id, content, role, type, "createdAt", thread_id, "resourceId",
|
|
1173
|
+
ROW_NUMBER() OVER (ORDER BY "createdAt" ASC) as row_num
|
|
1174
|
+
FROM "${storage.TABLE_MESSAGES}"
|
|
1175
|
+
WHERE thread_id = ?
|
|
1176
|
+
),
|
|
1177
|
+
target_positions AS (
|
|
1178
|
+
SELECT row_num as target_pos
|
|
1179
|
+
FROM numbered_messages
|
|
1180
|
+
WHERE id = ?
|
|
1181
|
+
)
|
|
1182
|
+
SELECT DISTINCT m.*
|
|
1183
|
+
FROM numbered_messages m
|
|
1184
|
+
CROSS JOIN target_positions t
|
|
1185
|
+
WHERE m.row_num BETWEEN (t.target_pos - ?) AND (t.target_pos + ?)
|
|
1186
|
+
)
|
|
1187
|
+
`
|
|
1188
|
+
// Keep ASC for final sorting after fetching context
|
|
1189
|
+
);
|
|
1190
|
+
params.push(searchId, id, withPreviousMessages, withNextMessages);
|
|
1191
|
+
}
|
|
1192
|
+
const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" ASC';
|
|
1193
|
+
const includedResult = await this.client.execute({ sql: finalQuery, args: params });
|
|
1194
|
+
const includedRows = includedResult.rows?.map((row) => this.parseRow(row));
|
|
1195
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1196
|
+
const dedupedRows = includedRows.filter((row) => {
|
|
1197
|
+
if (seen.has(row.id)) return false;
|
|
1198
|
+
seen.add(row.id);
|
|
1199
|
+
return true;
|
|
1178
1200
|
});
|
|
1179
|
-
return
|
|
1201
|
+
return dedupedRows;
|
|
1180
1202
|
}
|
|
1181
1203
|
async getMessages({
|
|
1182
1204
|
threadId,
|
|
@@ -1187,19 +1209,27 @@ var LibSQLStore = class extends storage.MastraStorage {
|
|
|
1187
1209
|
const messages = [];
|
|
1188
1210
|
const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
|
|
1189
1211
|
if (selectBy?.include?.length) {
|
|
1190
|
-
const includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
1212
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
1191
1213
|
if (includeMessages) {
|
|
1192
1214
|
messages.push(...includeMessages);
|
|
1193
1215
|
}
|
|
1194
1216
|
}
|
|
1195
1217
|
const excludeIds = messages.map((m) => m.id);
|
|
1196
1218
|
const remainingSql = `
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1219
|
+
SELECT
|
|
1220
|
+
id,
|
|
1221
|
+
content,
|
|
1222
|
+
role,
|
|
1223
|
+
type,
|
|
1224
|
+
"createdAt",
|
|
1225
|
+
thread_id,
|
|
1226
|
+
"resourceId"
|
|
1227
|
+
FROM "${storage.TABLE_MESSAGES}"
|
|
1228
|
+
WHERE thread_id = ?
|
|
1229
|
+
${excludeIds.length ? `AND id NOT IN (${excludeIds.map(() => "?").join(", ")})` : ""}
|
|
1230
|
+
ORDER BY "createdAt" DESC
|
|
1231
|
+
LIMIT ?
|
|
1232
|
+
`;
|
|
1203
1233
|
const remainingArgs = [threadId, ...excludeIds.length ? excludeIds : [], limit];
|
|
1204
1234
|
const remainingResult = await this.client.execute({ sql: remainingSql, args: remainingArgs });
|
|
1205
1235
|
if (remainingResult.rows) {
|
|
@@ -1221,7 +1251,7 @@ var LibSQLStore = class extends storage.MastraStorage {
|
|
|
1221
1251
|
const toDate = dateRange?.end;
|
|
1222
1252
|
const messages = [];
|
|
1223
1253
|
if (selectBy?.include?.length) {
|
|
1224
|
-
const includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
1254
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
1225
1255
|
if (includeMessages) {
|
|
1226
1256
|
messages.push(...includeMessages);
|
|
1227
1257
|
}
|
|
@@ -1283,16 +1313,27 @@ var LibSQLStore = class extends storage.MastraStorage {
|
|
|
1283
1313
|
}
|
|
1284
1314
|
const batchStatements = messages.map((message) => {
|
|
1285
1315
|
const time = message.createdAt || /* @__PURE__ */ new Date();
|
|
1316
|
+
if (!message.threadId) {
|
|
1317
|
+
throw new Error(
|
|
1318
|
+
`Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`
|
|
1319
|
+
);
|
|
1320
|
+
}
|
|
1321
|
+
if (!message.resourceId) {
|
|
1322
|
+
throw new Error(
|
|
1323
|
+
`Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`
|
|
1324
|
+
);
|
|
1325
|
+
}
|
|
1286
1326
|
return {
|
|
1287
|
-
sql: `INSERT INTO ${storage.TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt)
|
|
1288
|
-
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
1327
|
+
sql: `INSERT INTO ${storage.TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt, resourceId)
|
|
1328
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
1289
1329
|
args: [
|
|
1290
1330
|
message.id,
|
|
1291
|
-
threadId,
|
|
1331
|
+
message.threadId,
|
|
1292
1332
|
typeof message.content === "object" ? JSON.stringify(message.content) : message.content,
|
|
1293
1333
|
message.role,
|
|
1294
1334
|
message.type || "v2",
|
|
1295
|
-
time instanceof Date ? time.toISOString() : time
|
|
1335
|
+
time instanceof Date ? time.toISOString() : time,
|
|
1336
|
+
message.resourceId
|
|
1296
1337
|
]
|
|
1297
1338
|
};
|
|
1298
1339
|
});
|
package/dist/index.js
CHANGED
|
@@ -816,6 +816,11 @@ var LibSQLStore = class extends MastraStorage {
|
|
|
816
816
|
this.client.execute("PRAGMA busy_timeout = 5000;").then(() => this.logger.debug("LibSQLStore: PRAGMA busy_timeout=5000 set.")).catch((err) => this.logger.warn("LibSQLStore: Failed to set PRAGMA busy_timeout.", err));
|
|
817
817
|
}
|
|
818
818
|
}
|
|
819
|
+
get supports() {
|
|
820
|
+
return {
|
|
821
|
+
selectByIncludeResourceScope: true
|
|
822
|
+
};
|
|
823
|
+
}
|
|
819
824
|
getCreateTableSQL(tableName, schema) {
|
|
820
825
|
const parsedTableName = parseSqlIdentifier(tableName, "table name");
|
|
821
826
|
const columns = Object.entries(schema).map(([name, col]) => {
|
|
@@ -1146,35 +1151,52 @@ var LibSQLStore = class extends MastraStorage {
|
|
|
1146
1151
|
if (row.type && row.type !== `v2`) result.type = row.type;
|
|
1147
1152
|
return result;
|
|
1148
1153
|
}
|
|
1149
|
-
async _getIncludedMessages(
|
|
1154
|
+
async _getIncludedMessages({
|
|
1155
|
+
threadId,
|
|
1156
|
+
selectBy
|
|
1157
|
+
}) {
|
|
1150
1158
|
const include = selectBy?.include;
|
|
1151
1159
|
if (!include) return null;
|
|
1152
|
-
const
|
|
1153
|
-
const
|
|
1154
|
-
const
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1160
|
+
const unionQueries = [];
|
|
1161
|
+
const params = [];
|
|
1162
|
+
for (const inc of include) {
|
|
1163
|
+
const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
|
|
1164
|
+
const searchId = inc.threadId || threadId;
|
|
1165
|
+
unionQueries.push(
|
|
1166
|
+
`
|
|
1167
|
+
SELECT * FROM (
|
|
1168
|
+
WITH numbered_messages AS (
|
|
1169
|
+
SELECT
|
|
1170
|
+
id, content, role, type, "createdAt", thread_id, "resourceId",
|
|
1171
|
+
ROW_NUMBER() OVER (ORDER BY "createdAt" ASC) as row_num
|
|
1172
|
+
FROM "${TABLE_MESSAGES}"
|
|
1173
|
+
WHERE thread_id = ?
|
|
1174
|
+
),
|
|
1175
|
+
target_positions AS (
|
|
1176
|
+
SELECT row_num as target_pos
|
|
1177
|
+
FROM numbered_messages
|
|
1178
|
+
WHERE id = ?
|
|
1179
|
+
)
|
|
1180
|
+
SELECT DISTINCT m.*
|
|
1181
|
+
FROM numbered_messages m
|
|
1182
|
+
CROSS JOIN target_positions t
|
|
1183
|
+
WHERE m.row_num BETWEEN (t.target_pos - ?) AND (t.target_pos + ?)
|
|
1184
|
+
)
|
|
1185
|
+
`
|
|
1186
|
+
// Keep ASC for final sorting after fetching context
|
|
1187
|
+
);
|
|
1188
|
+
params.push(searchId, id, withPreviousMessages, withNextMessages);
|
|
1189
|
+
}
|
|
1190
|
+
const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" ASC';
|
|
1191
|
+
const includedResult = await this.client.execute({ sql: finalQuery, args: params });
|
|
1192
|
+
const includedRows = includedResult.rows?.map((row) => this.parseRow(row));
|
|
1193
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1194
|
+
const dedupedRows = includedRows.filter((row) => {
|
|
1195
|
+
if (seen.has(row.id)) return false;
|
|
1196
|
+
seen.add(row.id);
|
|
1197
|
+
return true;
|
|
1176
1198
|
});
|
|
1177
|
-
return
|
|
1199
|
+
return dedupedRows;
|
|
1178
1200
|
}
|
|
1179
1201
|
async getMessages({
|
|
1180
1202
|
threadId,
|
|
@@ -1185,19 +1207,27 @@ var LibSQLStore = class extends MastraStorage {
|
|
|
1185
1207
|
const messages = [];
|
|
1186
1208
|
const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
|
|
1187
1209
|
if (selectBy?.include?.length) {
|
|
1188
|
-
const includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
1210
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
1189
1211
|
if (includeMessages) {
|
|
1190
1212
|
messages.push(...includeMessages);
|
|
1191
1213
|
}
|
|
1192
1214
|
}
|
|
1193
1215
|
const excludeIds = messages.map((m) => m.id);
|
|
1194
1216
|
const remainingSql = `
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1217
|
+
SELECT
|
|
1218
|
+
id,
|
|
1219
|
+
content,
|
|
1220
|
+
role,
|
|
1221
|
+
type,
|
|
1222
|
+
"createdAt",
|
|
1223
|
+
thread_id,
|
|
1224
|
+
"resourceId"
|
|
1225
|
+
FROM "${TABLE_MESSAGES}"
|
|
1226
|
+
WHERE thread_id = ?
|
|
1227
|
+
${excludeIds.length ? `AND id NOT IN (${excludeIds.map(() => "?").join(", ")})` : ""}
|
|
1228
|
+
ORDER BY "createdAt" DESC
|
|
1229
|
+
LIMIT ?
|
|
1230
|
+
`;
|
|
1201
1231
|
const remainingArgs = [threadId, ...excludeIds.length ? excludeIds : [], limit];
|
|
1202
1232
|
const remainingResult = await this.client.execute({ sql: remainingSql, args: remainingArgs });
|
|
1203
1233
|
if (remainingResult.rows) {
|
|
@@ -1219,7 +1249,7 @@ var LibSQLStore = class extends MastraStorage {
|
|
|
1219
1249
|
const toDate = dateRange?.end;
|
|
1220
1250
|
const messages = [];
|
|
1221
1251
|
if (selectBy?.include?.length) {
|
|
1222
|
-
const includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
1252
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
1223
1253
|
if (includeMessages) {
|
|
1224
1254
|
messages.push(...includeMessages);
|
|
1225
1255
|
}
|
|
@@ -1281,16 +1311,27 @@ var LibSQLStore = class extends MastraStorage {
|
|
|
1281
1311
|
}
|
|
1282
1312
|
const batchStatements = messages.map((message) => {
|
|
1283
1313
|
const time = message.createdAt || /* @__PURE__ */ new Date();
|
|
1314
|
+
if (!message.threadId) {
|
|
1315
|
+
throw new Error(
|
|
1316
|
+
`Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
if (!message.resourceId) {
|
|
1320
|
+
throw new Error(
|
|
1321
|
+
`Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`
|
|
1322
|
+
);
|
|
1323
|
+
}
|
|
1284
1324
|
return {
|
|
1285
|
-
sql: `INSERT INTO ${TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt)
|
|
1286
|
-
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
1325
|
+
sql: `INSERT INTO ${TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt, resourceId)
|
|
1326
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
1287
1327
|
args: [
|
|
1288
1328
|
message.id,
|
|
1289
|
-
threadId,
|
|
1329
|
+
message.threadId,
|
|
1290
1330
|
typeof message.content === "object" ? JSON.stringify(message.content) : message.content,
|
|
1291
1331
|
message.role,
|
|
1292
1332
|
message.type || "v2",
|
|
1293
|
-
time instanceof Date ? time.toISOString() : time
|
|
1333
|
+
time instanceof Date ? time.toISOString() : time,
|
|
1334
|
+
message.resourceId
|
|
1294
1335
|
]
|
|
1295
1336
|
};
|
|
1296
1337
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/libsql",
|
|
3
|
-
"version": "0.10.2-alpha.
|
|
3
|
+
"version": "0.10.2-alpha.3",
|
|
4
4
|
"description": "Libsql provider for Mastra - includes both vector and db storage capabilities",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
"tsup": "^8.5.0",
|
|
30
30
|
"typescript": "^5.8.3",
|
|
31
31
|
"vitest": "^3.2.2",
|
|
32
|
-
"@
|
|
32
|
+
"@internal/lint": "0.0.10",
|
|
33
33
|
"@internal/storage-test-utils": "0.0.6",
|
|
34
|
-
"@
|
|
34
|
+
"@mastra/core": "0.10.4-alpha.3"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@mastra/core": "^0.10.2-alpha.0"
|
package/src/storage/index.ts
CHANGED
|
@@ -81,6 +81,14 @@ export class LibSQLStore extends MastraStorage {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
public get supports(): {
|
|
85
|
+
selectByIncludeResourceScope: boolean;
|
|
86
|
+
} {
|
|
87
|
+
return {
|
|
88
|
+
selectByIncludeResourceScope: true,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
84
92
|
private getCreateTableSQL(tableName: TABLE_NAMES, schema: Record<string, StorageColumn>): string {
|
|
85
93
|
const parsedTableName = parseSqlIdentifier(tableName, 'table name');
|
|
86
94
|
const columns = Object.entries(schema).map(([name, col]) => {
|
|
@@ -476,7 +484,6 @@ export class LibSQLStore extends MastraStorage {
|
|
|
476
484
|
sql: `DELETE FROM ${TABLE_MESSAGES} WHERE thread_id = ?`,
|
|
477
485
|
args: [threadId],
|
|
478
486
|
});
|
|
479
|
-
|
|
480
487
|
await this.client.execute({
|
|
481
488
|
sql: `DELETE FROM ${TABLE_THREADS} WHERE id = ?`,
|
|
482
489
|
args: [threadId],
|
|
@@ -503,37 +510,57 @@ export class LibSQLStore extends MastraStorage {
|
|
|
503
510
|
return result;
|
|
504
511
|
}
|
|
505
512
|
|
|
506
|
-
private async _getIncludedMessages(
|
|
513
|
+
private async _getIncludedMessages({
|
|
514
|
+
threadId,
|
|
515
|
+
selectBy,
|
|
516
|
+
}: {
|
|
517
|
+
threadId: string;
|
|
518
|
+
selectBy: StorageGetMessagesArg['selectBy'];
|
|
519
|
+
}) {
|
|
507
520
|
const include = selectBy?.include;
|
|
508
521
|
if (!include) return null;
|
|
509
522
|
|
|
510
|
-
const
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
523
|
+
const unionQueries: string[] = [];
|
|
524
|
+
const params: any[] = [];
|
|
525
|
+
|
|
526
|
+
for (const inc of include) {
|
|
527
|
+
const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
|
|
528
|
+
// if threadId is provided, use it, otherwise use threadId from args
|
|
529
|
+
const searchId = inc.threadId || threadId;
|
|
530
|
+
unionQueries.push(
|
|
531
|
+
`
|
|
532
|
+
SELECT * FROM (
|
|
533
|
+
WITH numbered_messages AS (
|
|
534
|
+
SELECT
|
|
535
|
+
id, content, role, type, "createdAt", thread_id, "resourceId",
|
|
536
|
+
ROW_NUMBER() OVER (ORDER BY "createdAt" ASC) as row_num
|
|
537
|
+
FROM "${TABLE_MESSAGES}"
|
|
538
|
+
WHERE thread_id = ?
|
|
539
|
+
),
|
|
540
|
+
target_positions AS (
|
|
541
|
+
SELECT row_num as target_pos
|
|
542
|
+
FROM numbered_messages
|
|
543
|
+
WHERE id = ?
|
|
544
|
+
)
|
|
545
|
+
SELECT DISTINCT m.*
|
|
546
|
+
FROM numbered_messages m
|
|
547
|
+
CROSS JOIN target_positions t
|
|
548
|
+
WHERE m.row_num BETWEEN (t.target_pos - ?) AND (t.target_pos + ?)
|
|
549
|
+
)
|
|
550
|
+
`, // Keep ASC for final sorting after fetching context
|
|
551
|
+
);
|
|
552
|
+
params.push(searchId, id, withPreviousMessages, withNextMessages);
|
|
553
|
+
}
|
|
554
|
+
const finalQuery = unionQueries.join(' UNION ALL ') + ' ORDER BY "createdAt" ASC';
|
|
555
|
+
const includedResult = await this.client.execute({ sql: finalQuery, args: params });
|
|
556
|
+
const includedRows = includedResult.rows?.map(row => this.parseRow(row));
|
|
557
|
+
const seen = new Set<string>();
|
|
558
|
+
const dedupedRows = includedRows.filter(row => {
|
|
559
|
+
if (seen.has(row.id)) return false;
|
|
560
|
+
seen.add(row.id);
|
|
561
|
+
return true;
|
|
535
562
|
});
|
|
536
|
-
return
|
|
563
|
+
return dedupedRows;
|
|
537
564
|
}
|
|
538
565
|
|
|
539
566
|
/**
|
|
@@ -553,7 +580,7 @@ export class LibSQLStore extends MastraStorage {
|
|
|
553
580
|
const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
|
|
554
581
|
|
|
555
582
|
if (selectBy?.include?.length) {
|
|
556
|
-
const includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
583
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
557
584
|
if (includeMessages) {
|
|
558
585
|
messages.push(...includeMessages);
|
|
559
586
|
}
|
|
@@ -561,12 +588,20 @@ export class LibSQLStore extends MastraStorage {
|
|
|
561
588
|
|
|
562
589
|
const excludeIds = messages.map(m => m.id);
|
|
563
590
|
const remainingSql = `
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
591
|
+
SELECT
|
|
592
|
+
id,
|
|
593
|
+
content,
|
|
594
|
+
role,
|
|
595
|
+
type,
|
|
596
|
+
"createdAt",
|
|
597
|
+
thread_id,
|
|
598
|
+
"resourceId"
|
|
599
|
+
FROM "${TABLE_MESSAGES}"
|
|
600
|
+
WHERE thread_id = ?
|
|
601
|
+
${excludeIds.length ? `AND id NOT IN (${excludeIds.map(() => '?').join(', ')})` : ''}
|
|
602
|
+
ORDER BY "createdAt" DESC
|
|
603
|
+
LIMIT ?
|
|
604
|
+
`;
|
|
570
605
|
const remainingArgs = [threadId, ...(excludeIds.length ? excludeIds : []), limit];
|
|
571
606
|
const remainingResult = await this.client.execute({ sql: remainingSql, args: remainingArgs });
|
|
572
607
|
if (remainingResult.rows) {
|
|
@@ -595,7 +630,7 @@ export class LibSQLStore extends MastraStorage {
|
|
|
595
630
|
const messages: MastraMessageV2[] = [];
|
|
596
631
|
|
|
597
632
|
if (selectBy?.include?.length) {
|
|
598
|
-
const includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
633
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
599
634
|
if (includeMessages) {
|
|
600
635
|
messages.push(...includeMessages);
|
|
601
636
|
}
|
|
@@ -677,16 +712,27 @@ export class LibSQLStore extends MastraStorage {
|
|
|
677
712
|
// Prepare batch statements for all messages
|
|
678
713
|
const batchStatements = messages.map(message => {
|
|
679
714
|
const time = message.createdAt || new Date();
|
|
715
|
+
if (!message.threadId) {
|
|
716
|
+
throw new Error(
|
|
717
|
+
`Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`,
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
if (!message.resourceId) {
|
|
721
|
+
throw new Error(
|
|
722
|
+
`Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`,
|
|
723
|
+
);
|
|
724
|
+
}
|
|
680
725
|
return {
|
|
681
|
-
sql: `INSERT INTO ${TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt)
|
|
682
|
-
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
726
|
+
sql: `INSERT INTO ${TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt, resourceId)
|
|
727
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
683
728
|
args: [
|
|
684
729
|
message.id,
|
|
685
|
-
threadId
|
|
730
|
+
message.threadId!,
|
|
686
731
|
typeof message.content === 'object' ? JSON.stringify(message.content) : message.content,
|
|
687
732
|
message.role,
|
|
688
733
|
message.type || 'v2',
|
|
689
734
|
time instanceof Date ? time.toISOString() : time,
|
|
735
|
+
message.resourceId,
|
|
690
736
|
],
|
|
691
737
|
};
|
|
692
738
|
});
|