@mastra/libsql 0.10.2-alpha.1 → 0.10.2-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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +8 -0
- package/dist/_tsup-dts-rollup.d.cts +3 -0
- package/dist/_tsup-dts-rollup.d.ts +3 -0
- package/dist/index.cjs +83 -39
- package/dist/index.js +83 -39
- package/package.json +4 -4
- package/src/storage/index.ts +89 -40
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.2 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 9592ms
|
|
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 10548ms
|
|
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.54 KB[39m
|
|
21
|
+
[32mESM[39m ⚡️ Build success in 1646ms
|
|
22
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m58.83 KB[39m
|
|
23
|
+
[32mCJS[39m ⚡️ Build success in 1647ms
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @mastra/libsql
|
|
2
2
|
|
|
3
|
+
## 0.10.2-alpha.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 48eddb9: update filter logic in Memory class to support semantic recall search scope
|
|
8
|
+
- Updated dependencies [48eddb9]
|
|
9
|
+
- @mastra/core@0.10.4-alpha.2
|
|
10
|
+
|
|
3
11
|
## 0.10.2-alpha.1
|
|
4
12
|
|
|
5
13
|
### 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,55 @@ 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
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
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 dedupedRows = Object.values(
|
|
1196
|
+
includedRows.reduce(
|
|
1197
|
+
(acc, row) => {
|
|
1198
|
+
acc[row.id] = row;
|
|
1199
|
+
return acc;
|
|
1200
|
+
},
|
|
1201
|
+
{}
|
|
1202
|
+
)
|
|
1203
|
+
);
|
|
1204
|
+
return dedupedRows;
|
|
1180
1205
|
}
|
|
1181
1206
|
async getMessages({
|
|
1182
1207
|
threadId,
|
|
@@ -1187,19 +1212,27 @@ var LibSQLStore = class extends storage.MastraStorage {
|
|
|
1187
1212
|
const messages = [];
|
|
1188
1213
|
const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
|
|
1189
1214
|
if (selectBy?.include?.length) {
|
|
1190
|
-
const includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
1215
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
1191
1216
|
if (includeMessages) {
|
|
1192
1217
|
messages.push(...includeMessages);
|
|
1193
1218
|
}
|
|
1194
1219
|
}
|
|
1195
1220
|
const excludeIds = messages.map((m) => m.id);
|
|
1196
1221
|
const remainingSql = `
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1222
|
+
SELECT
|
|
1223
|
+
id,
|
|
1224
|
+
content,
|
|
1225
|
+
role,
|
|
1226
|
+
type,
|
|
1227
|
+
"createdAt",
|
|
1228
|
+
thread_id,
|
|
1229
|
+
"resourceId"
|
|
1230
|
+
FROM "${storage.TABLE_MESSAGES}"
|
|
1231
|
+
WHERE thread_id = ?
|
|
1232
|
+
${excludeIds.length ? `AND id NOT IN (${excludeIds.map(() => "?").join(", ")})` : ""}
|
|
1233
|
+
ORDER BY "createdAt" DESC
|
|
1234
|
+
LIMIT ?
|
|
1235
|
+
`;
|
|
1203
1236
|
const remainingArgs = [threadId, ...excludeIds.length ? excludeIds : [], limit];
|
|
1204
1237
|
const remainingResult = await this.client.execute({ sql: remainingSql, args: remainingArgs });
|
|
1205
1238
|
if (remainingResult.rows) {
|
|
@@ -1221,7 +1254,7 @@ var LibSQLStore = class extends storage.MastraStorage {
|
|
|
1221
1254
|
const toDate = dateRange?.end;
|
|
1222
1255
|
const messages = [];
|
|
1223
1256
|
if (selectBy?.include?.length) {
|
|
1224
|
-
const includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
1257
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
1225
1258
|
if (includeMessages) {
|
|
1226
1259
|
messages.push(...includeMessages);
|
|
1227
1260
|
}
|
|
@@ -1283,16 +1316,27 @@ var LibSQLStore = class extends storage.MastraStorage {
|
|
|
1283
1316
|
}
|
|
1284
1317
|
const batchStatements = messages.map((message) => {
|
|
1285
1318
|
const time = message.createdAt || /* @__PURE__ */ new Date();
|
|
1319
|
+
if (!message.threadId) {
|
|
1320
|
+
throw new Error(
|
|
1321
|
+
`Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`
|
|
1322
|
+
);
|
|
1323
|
+
}
|
|
1324
|
+
if (!message.resourceId) {
|
|
1325
|
+
throw new Error(
|
|
1326
|
+
`Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`
|
|
1327
|
+
);
|
|
1328
|
+
}
|
|
1286
1329
|
return {
|
|
1287
|
-
sql: `INSERT INTO ${storage.TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt)
|
|
1288
|
-
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
1330
|
+
sql: `INSERT INTO ${storage.TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt, resourceId)
|
|
1331
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
1289
1332
|
args: [
|
|
1290
1333
|
message.id,
|
|
1291
|
-
threadId,
|
|
1334
|
+
message.threadId,
|
|
1292
1335
|
typeof message.content === "object" ? JSON.stringify(message.content) : message.content,
|
|
1293
1336
|
message.role,
|
|
1294
1337
|
message.type || "v2",
|
|
1295
|
-
time instanceof Date ? time.toISOString() : time
|
|
1338
|
+
time instanceof Date ? time.toISOString() : time,
|
|
1339
|
+
message.resourceId
|
|
1296
1340
|
]
|
|
1297
1341
|
};
|
|
1298
1342
|
});
|
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,55 @@ 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
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
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 dedupedRows = Object.values(
|
|
1194
|
+
includedRows.reduce(
|
|
1195
|
+
(acc, row) => {
|
|
1196
|
+
acc[row.id] = row;
|
|
1197
|
+
return acc;
|
|
1198
|
+
},
|
|
1199
|
+
{}
|
|
1200
|
+
)
|
|
1201
|
+
);
|
|
1202
|
+
return dedupedRows;
|
|
1178
1203
|
}
|
|
1179
1204
|
async getMessages({
|
|
1180
1205
|
threadId,
|
|
@@ -1185,19 +1210,27 @@ var LibSQLStore = class extends MastraStorage {
|
|
|
1185
1210
|
const messages = [];
|
|
1186
1211
|
const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
|
|
1187
1212
|
if (selectBy?.include?.length) {
|
|
1188
|
-
const includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
1213
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
1189
1214
|
if (includeMessages) {
|
|
1190
1215
|
messages.push(...includeMessages);
|
|
1191
1216
|
}
|
|
1192
1217
|
}
|
|
1193
1218
|
const excludeIds = messages.map((m) => m.id);
|
|
1194
1219
|
const remainingSql = `
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1220
|
+
SELECT
|
|
1221
|
+
id,
|
|
1222
|
+
content,
|
|
1223
|
+
role,
|
|
1224
|
+
type,
|
|
1225
|
+
"createdAt",
|
|
1226
|
+
thread_id,
|
|
1227
|
+
"resourceId"
|
|
1228
|
+
FROM "${TABLE_MESSAGES}"
|
|
1229
|
+
WHERE thread_id = ?
|
|
1230
|
+
${excludeIds.length ? `AND id NOT IN (${excludeIds.map(() => "?").join(", ")})` : ""}
|
|
1231
|
+
ORDER BY "createdAt" DESC
|
|
1232
|
+
LIMIT ?
|
|
1233
|
+
`;
|
|
1201
1234
|
const remainingArgs = [threadId, ...excludeIds.length ? excludeIds : [], limit];
|
|
1202
1235
|
const remainingResult = await this.client.execute({ sql: remainingSql, args: remainingArgs });
|
|
1203
1236
|
if (remainingResult.rows) {
|
|
@@ -1219,7 +1252,7 @@ var LibSQLStore = class extends MastraStorage {
|
|
|
1219
1252
|
const toDate = dateRange?.end;
|
|
1220
1253
|
const messages = [];
|
|
1221
1254
|
if (selectBy?.include?.length) {
|
|
1222
|
-
const includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
1255
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
1223
1256
|
if (includeMessages) {
|
|
1224
1257
|
messages.push(...includeMessages);
|
|
1225
1258
|
}
|
|
@@ -1281,16 +1314,27 @@ var LibSQLStore = class extends MastraStorage {
|
|
|
1281
1314
|
}
|
|
1282
1315
|
const batchStatements = messages.map((message) => {
|
|
1283
1316
|
const time = message.createdAt || /* @__PURE__ */ new Date();
|
|
1317
|
+
if (!message.threadId) {
|
|
1318
|
+
throw new Error(
|
|
1319
|
+
`Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`
|
|
1320
|
+
);
|
|
1321
|
+
}
|
|
1322
|
+
if (!message.resourceId) {
|
|
1323
|
+
throw new Error(
|
|
1324
|
+
`Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1284
1327
|
return {
|
|
1285
|
-
sql: `INSERT INTO ${TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt)
|
|
1286
|
-
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
1328
|
+
sql: `INSERT INTO ${TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt, resourceId)
|
|
1329
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
1287
1330
|
args: [
|
|
1288
1331
|
message.id,
|
|
1289
|
-
threadId,
|
|
1332
|
+
message.threadId,
|
|
1290
1333
|
typeof message.content === "object" ? JSON.stringify(message.content) : message.content,
|
|
1291
1334
|
message.role,
|
|
1292
1335
|
message.type || "v2",
|
|
1293
|
-
time instanceof Date ? time.toISOString() : time
|
|
1336
|
+
time instanceof Date ? time.toISOString() : time,
|
|
1337
|
+
message.resourceId
|
|
1294
1338
|
]
|
|
1295
1339
|
};
|
|
1296
1340
|
});
|
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.2",
|
|
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
|
-
"@
|
|
33
|
-
"@
|
|
34
|
-
"@internal/
|
|
32
|
+
"@internal/lint": "0.0.10",
|
|
33
|
+
"@mastra/core": "0.10.4-alpha.2",
|
|
34
|
+
"@internal/storage-test-utils": "0.0.6"
|
|
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,60 @@ 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
|
-
|
|
535
|
-
|
|
536
|
-
|
|
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 dedupedRows = Object.values(
|
|
558
|
+
includedRows.reduce(
|
|
559
|
+
(acc, row) => {
|
|
560
|
+
acc[row.id] = row;
|
|
561
|
+
return acc;
|
|
562
|
+
},
|
|
563
|
+
{} as Record<string, MastraMessageV2>,
|
|
564
|
+
),
|
|
565
|
+
);
|
|
566
|
+
return dedupedRows;
|
|
537
567
|
}
|
|
538
568
|
|
|
539
569
|
/**
|
|
@@ -553,7 +583,7 @@ export class LibSQLStore extends MastraStorage {
|
|
|
553
583
|
const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
|
|
554
584
|
|
|
555
585
|
if (selectBy?.include?.length) {
|
|
556
|
-
const includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
586
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
557
587
|
if (includeMessages) {
|
|
558
588
|
messages.push(...includeMessages);
|
|
559
589
|
}
|
|
@@ -561,12 +591,20 @@ export class LibSQLStore extends MastraStorage {
|
|
|
561
591
|
|
|
562
592
|
const excludeIds = messages.map(m => m.id);
|
|
563
593
|
const remainingSql = `
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
594
|
+
SELECT
|
|
595
|
+
id,
|
|
596
|
+
content,
|
|
597
|
+
role,
|
|
598
|
+
type,
|
|
599
|
+
"createdAt",
|
|
600
|
+
thread_id,
|
|
601
|
+
"resourceId"
|
|
602
|
+
FROM "${TABLE_MESSAGES}"
|
|
603
|
+
WHERE thread_id = ?
|
|
604
|
+
${excludeIds.length ? `AND id NOT IN (${excludeIds.map(() => '?').join(', ')})` : ''}
|
|
605
|
+
ORDER BY "createdAt" DESC
|
|
606
|
+
LIMIT ?
|
|
607
|
+
`;
|
|
570
608
|
const remainingArgs = [threadId, ...(excludeIds.length ? excludeIds : []), limit];
|
|
571
609
|
const remainingResult = await this.client.execute({ sql: remainingSql, args: remainingArgs });
|
|
572
610
|
if (remainingResult.rows) {
|
|
@@ -595,7 +633,7 @@ export class LibSQLStore extends MastraStorage {
|
|
|
595
633
|
const messages: MastraMessageV2[] = [];
|
|
596
634
|
|
|
597
635
|
if (selectBy?.include?.length) {
|
|
598
|
-
const includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
636
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
599
637
|
if (includeMessages) {
|
|
600
638
|
messages.push(...includeMessages);
|
|
601
639
|
}
|
|
@@ -677,16 +715,27 @@ export class LibSQLStore extends MastraStorage {
|
|
|
677
715
|
// Prepare batch statements for all messages
|
|
678
716
|
const batchStatements = messages.map(message => {
|
|
679
717
|
const time = message.createdAt || new Date();
|
|
718
|
+
if (!message.threadId) {
|
|
719
|
+
throw new Error(
|
|
720
|
+
`Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`,
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
if (!message.resourceId) {
|
|
724
|
+
throw new Error(
|
|
725
|
+
`Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`,
|
|
726
|
+
);
|
|
727
|
+
}
|
|
680
728
|
return {
|
|
681
|
-
sql: `INSERT INTO ${TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt)
|
|
682
|
-
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
729
|
+
sql: `INSERT INTO ${TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt, resourceId)
|
|
730
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
683
731
|
args: [
|
|
684
732
|
message.id,
|
|
685
|
-
threadId
|
|
733
|
+
message.threadId!,
|
|
686
734
|
typeof message.content === 'object' ? JSON.stringify(message.content) : message.content,
|
|
687
735
|
message.role,
|
|
688
736
|
message.type || 'v2',
|
|
689
737
|
time instanceof Date ? time.toISOString() : time,
|
|
738
|
+
message.resourceId,
|
|
690
739
|
],
|
|
691
740
|
};
|
|
692
741
|
});
|