@mastra/libsql 1.10.0 → 1.10.1-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 +18 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-overview.md +2 -1
- package/dist/docs/references/docs-memory-semantic-recall.md +68 -6
- package/dist/index.cjs +57 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +57 -9
- package/dist/index.js.map +1 -1
- package/dist/storage/db/utils.d.ts +11 -0
- package/dist/storage/db/utils.d.ts.map +1 -1
- package/dist/storage/domains/background-tasks/index.d.ts.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @mastra/libsql
|
|
2
2
|
|
|
3
|
+
## 1.10.1-alpha.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- **Fixed** Workflow runs no longer fail to persist when request context contains non-serializable values (for example functions, circular references, or platform proxy objects). This prevents errors when saving workflow snapshots and scorer results. See #12301. ([#12573](https://github.com/mastra-ai/mastra/pull/12573))
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`6742347`](https://github.com/mastra-ai/mastra/commit/6742347d71955d7639adc9ddf6ff8282de7ee3ba), [`7b0ad1f`](https://github.com/mastra-ai/mastra/commit/7b0ad1f5c53dc118c6da12ae82ae2587037dc2b8), [`62666c3`](https://github.com/mastra-ai/mastra/commit/62666c367eaeac3941ead454b1d38810cc855721), [`4af2160`](https://github.com/mastra-ai/mastra/commit/4af2160322f4718cac421930cce85641e9512389), [`136c959`](https://github.com/mastra-ai/mastra/commit/136c9592fb0eeb0cd212f28629d8a29b7557a2fc), [`4df7cc7`](https://github.com/mastra-ai/mastra/commit/4df7cc79342fd065fe7fdeef93c094db14b12bcd), [`aca3121`](https://github.com/mastra-ai/mastra/commit/aca31211233dac25459f140ea4fcfb3a5af64c18), [`9cdf38e`](https://github.com/mastra-ai/mastra/commit/9cdf38e58506e1109c8b38f97cd7770978a4218e), [`990851e`](https://github.com/mastra-ai/mastra/commit/990851edcb0e30be5c2c18b6532f1a876cc2d335), [`6068a6c`](https://github.com/mastra-ai/mastra/commit/6068a6c42950fad3ebfc92346417896ba60803d2), [`00106be`](https://github.com/mastra-ai/mastra/commit/00106bede59b81e5b0e9cd6aad8d3b5dbc336387), [`e2a079c`](https://github.com/mastra-ai/mastra/commit/e2a079cc3755b1895f7bd5dc36e9be81b11c7c22), [`534a456`](https://github.com/mastra-ai/mastra/commit/534a456a25e4df1e5407e7e632f4cb3b1fa14f9d), [`36bae07`](https://github.com/mastra-ai/mastra/commit/36bae07c0e70b1b3006f2fd20830e8883dcbd066)]:
|
|
10
|
+
- @mastra/core@1.33.0-alpha.7
|
|
11
|
+
|
|
12
|
+
## 1.10.1-alpha.0
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Track `suspendedAt` and `suspendPayload` on background tasks. SQL adapters auto-migrate the new columns via `alterTable`. ([#16260](https://github.com/mastra-ai/mastra/pull/16260))
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [[`9f17410`](https://github.com/mastra-ai/mastra/commit/9f1741080def23d42ee50b39887a385ae316a3c6), [`c6eb39e`](https://github.com/mastra-ai/mastra/commit/c6eb39ea6dca381c6563cb240237fbe608e02f93), [`900d086`](https://github.com/mastra-ai/mastra/commit/900d086bb737b9cf2fcf68f11b0389b801a2738c), [`4c0e286`](https://github.com/mastra-ai/mastra/commit/4c0e28637c9cfb4f416549b55e97ebfa13319dfc), [`25184ff`](https://github.com/mastra-ai/mastra/commit/25184ffaf1293ec95119426eb1a1f8d38831b96c), [`aebde9c`](https://github.com/mastra-ai/mastra/commit/aebde9cfacf56592c6b6350cae721740fe090b8a)]:
|
|
19
|
+
- @mastra/core@1.33.0-alpha.4
|
|
20
|
+
|
|
3
21
|
## 1.10.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -237,4 +237,5 @@ export const memoryAgent = new Agent({
|
|
|
237
237
|
|
|
238
238
|
- [`Memory` reference](https://mastra.ai/reference/memory/memory-class)
|
|
239
239
|
- [Tracing](https://mastra.ai/docs/observability/tracing/overview)
|
|
240
|
-
- [Request Context](https://mastra.ai/docs/server/request-context)
|
|
240
|
+
- [Request Context](https://mastra.ai/docs/server/request-context)
|
|
241
|
+
- [Mastra Code](https://code.mastra.ai/): A coding agent using Mastra's memory system
|
|
@@ -121,26 +121,88 @@ Each vector store page below includes installation instructions, configuration p
|
|
|
121
121
|
|
|
122
122
|
## Recall configuration
|
|
123
123
|
|
|
124
|
-
The
|
|
124
|
+
The following options control semantic recall behavior:
|
|
125
125
|
|
|
126
|
-
1. **topK**:
|
|
127
|
-
2. **messageRange**:
|
|
128
|
-
3. **scope**: Whether to search
|
|
126
|
+
1. **topK**: The number of similar messages to retrieve
|
|
127
|
+
2. **messageRange**: The surrounding messages to include with each match
|
|
128
|
+
3. **scope**: Whether to search the current thread or all threads for a resource
|
|
129
|
+
4. **filter**: Metadata criteria that restrict search results
|
|
129
130
|
|
|
130
131
|
```typescript
|
|
131
132
|
const agent = new Agent({
|
|
132
133
|
memory: new Memory({
|
|
133
134
|
options: {
|
|
134
135
|
semanticRecall: {
|
|
135
|
-
topK: 3, // Retrieve 3
|
|
136
|
+
topK: 3, // Retrieve 3 similar messages
|
|
136
137
|
messageRange: 2, // Include 2 messages before and after each match
|
|
137
|
-
scope: 'resource', // Search
|
|
138
|
+
scope: 'resource', // Search all threads for this resource
|
|
139
|
+
filter: { projectId: { $eq: 'project-a' } },
|
|
138
140
|
},
|
|
139
141
|
},
|
|
140
142
|
}),
|
|
141
143
|
})
|
|
142
144
|
```
|
|
143
145
|
|
|
146
|
+
> **Note:** `scope: 'resource'` is supported by the LibSQL, PostgreSQL, and Upstash storage adapters.
|
|
147
|
+
|
|
148
|
+
### Metadata filtering
|
|
149
|
+
|
|
150
|
+
The `filter` option restricts semantic recall results to messages with matching thread metadata.
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const agent = new Agent({
|
|
154
|
+
memory: new Memory({
|
|
155
|
+
options: {
|
|
156
|
+
semanticRecall: {
|
|
157
|
+
scope: 'resource',
|
|
158
|
+
filter: {
|
|
159
|
+
projectId: { $eq: 'project-a' },
|
|
160
|
+
category: { $in: ['work', 'personal'] },
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
}),
|
|
165
|
+
})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Filters match metadata stored on message embeddings when messages are saved. If thread metadata changes later, existing embeddings keep their previous metadata until those messages are saved or indexed again.
|
|
169
|
+
|
|
170
|
+
Supported filter operators:
|
|
171
|
+
|
|
172
|
+
- `$and`: Logical AND
|
|
173
|
+
- `$eq`: Equal to
|
|
174
|
+
- `$gt`: Greater than
|
|
175
|
+
- `$gte`: Greater than or equal
|
|
176
|
+
- `$in`: In array
|
|
177
|
+
- `$lt`: Less than
|
|
178
|
+
- `$lte`: Less than or equal
|
|
179
|
+
- `$ne`: Not equal to
|
|
180
|
+
- `$nin`: Not in array
|
|
181
|
+
- `$or`: Logical OR
|
|
182
|
+
|
|
183
|
+
The following example demonstrates metadata filters for common use cases:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
// Filter by project
|
|
187
|
+
const options = {
|
|
188
|
+
semanticRecall: { filter: { projectId: { $eq: 'my-project' } } },
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Filter by multiple categories
|
|
192
|
+
const options = {
|
|
193
|
+
semanticRecall: { filter: { category: { $in: ['work', 'research'] } } },
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Filter by project and priority
|
|
197
|
+
const options = {
|
|
198
|
+
semanticRecall: {
|
|
199
|
+
filter: {
|
|
200
|
+
$and: [{ projectId: { $eq: 'project-a' } }, { priority: { $gte: 3 } }],
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
144
206
|
## Embedder configuration
|
|
145
207
|
|
|
146
208
|
Semantic recall relies on an [embedding model](https://mastra.ai/reference/memory/memory-class) to convert messages into embeddings. Mastra supports embedding models through the model router using `provider/model` strings, or you can use any [embedding model](https://sdk.vercel.ai/docs/ai-sdk-core/embeddings) compatible with the AI SDK.
|
package/dist/index.cjs
CHANGED
|
@@ -1172,6 +1172,33 @@ var LibSQLVector = class extends vector.MastraVector {
|
|
|
1172
1172
|
});
|
|
1173
1173
|
}
|
|
1174
1174
|
};
|
|
1175
|
+
var safeStringify = (value) => {
|
|
1176
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
1177
|
+
const sanitize = (val) => {
|
|
1178
|
+
if (val === null || val === void 0) return val;
|
|
1179
|
+
if (typeof val === "function") return void 0;
|
|
1180
|
+
if (typeof val === "symbol") return void 0;
|
|
1181
|
+
if (typeof val === "bigint") return val.toString();
|
|
1182
|
+
if (typeof val !== "object") return val;
|
|
1183
|
+
if (seen.has(val)) return void 0;
|
|
1184
|
+
seen.add(val);
|
|
1185
|
+
if (typeof val.toJSON === "function") {
|
|
1186
|
+
return sanitize(val.toJSON());
|
|
1187
|
+
}
|
|
1188
|
+
if (Array.isArray(val)) {
|
|
1189
|
+
return val.map((item) => sanitize(item));
|
|
1190
|
+
}
|
|
1191
|
+
const result = {};
|
|
1192
|
+
for (const key of Object.keys(val)) {
|
|
1193
|
+
const sanitized = sanitize(val[key]);
|
|
1194
|
+
if (sanitized !== void 0) {
|
|
1195
|
+
result[key] = sanitized;
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
return result;
|
|
1199
|
+
};
|
|
1200
|
+
return JSON.stringify(sanitize(value)) ?? "null";
|
|
1201
|
+
};
|
|
1175
1202
|
function buildSelectColumns(tableName) {
|
|
1176
1203
|
const schema = storage.TABLE_SCHEMAS[tableName];
|
|
1177
1204
|
return Object.keys(schema).map((col) => {
|
|
@@ -1238,12 +1265,12 @@ function prepareStatement({ tableName, record }) {
|
|
|
1238
1265
|
}
|
|
1239
1266
|
const colDef = schema[col];
|
|
1240
1267
|
if (colDef?.type === "jsonb") {
|
|
1241
|
-
return
|
|
1268
|
+
return safeStringify(v);
|
|
1242
1269
|
}
|
|
1243
1270
|
if (v instanceof Date) {
|
|
1244
1271
|
return v.toISOString();
|
|
1245
1272
|
}
|
|
1246
|
-
return typeof v === "object" ?
|
|
1273
|
+
return typeof v === "object" ? safeStringify(v) : v;
|
|
1247
1274
|
});
|
|
1248
1275
|
const placeholders = columnNames.map((col) => {
|
|
1249
1276
|
const colDef = schema[col];
|
|
@@ -1286,12 +1313,12 @@ function transformToSqlValue(value, forceJsonStringify = false) {
|
|
|
1286
1313
|
return null;
|
|
1287
1314
|
}
|
|
1288
1315
|
if (forceJsonStringify) {
|
|
1289
|
-
return
|
|
1316
|
+
return safeStringify(value);
|
|
1290
1317
|
}
|
|
1291
1318
|
if (value instanceof Date) {
|
|
1292
1319
|
return value.toISOString();
|
|
1293
1320
|
}
|
|
1294
|
-
return typeof value === "object" ?
|
|
1321
|
+
return typeof value === "object" ? safeStringify(value) : value;
|
|
1295
1322
|
}
|
|
1296
1323
|
function prepareDeleteStatement({ tableName, keys }) {
|
|
1297
1324
|
const parsedTableName = utils.parseSqlIdentifier(tableName, "table name");
|
|
@@ -2993,11 +3020,13 @@ function rowToTask(row) {
|
|
|
2993
3020
|
runId: String(row.run_id),
|
|
2994
3021
|
result: parseJson(row.result),
|
|
2995
3022
|
error: parseJson(row.error),
|
|
3023
|
+
suspendPayload: parseJson(row.suspend_payload),
|
|
2996
3024
|
retryCount: Number(row.retry_count),
|
|
2997
3025
|
maxRetries: Number(row.max_retries),
|
|
2998
3026
|
timeoutMs: Number(row.timeout_ms),
|
|
2999
3027
|
createdAt: new Date(String(row.createdAt)),
|
|
3000
3028
|
startedAt: row.startedAt ? new Date(String(row.startedAt)) : void 0,
|
|
3029
|
+
suspendedAt: row.suspendedAt ? new Date(String(row.suspendedAt)) : void 0,
|
|
3001
3030
|
completedAt: row.completedAt ? new Date(String(row.completedAt)) : void 0
|
|
3002
3031
|
};
|
|
3003
3032
|
}
|
|
@@ -3015,6 +3044,11 @@ var BackgroundTasksLibSQL = class extends storage.BackgroundTasksStorage {
|
|
|
3015
3044
|
tableName: storage.TABLE_BACKGROUND_TASKS,
|
|
3016
3045
|
schema: storage.TABLE_SCHEMAS[storage.TABLE_BACKGROUND_TASKS]
|
|
3017
3046
|
});
|
|
3047
|
+
await this.#db.alterTable({
|
|
3048
|
+
tableName: storage.TABLE_BACKGROUND_TASKS,
|
|
3049
|
+
schema: storage.TABLE_SCHEMAS[storage.TABLE_BACKGROUND_TASKS],
|
|
3050
|
+
ifNotExists: ["suspend_payload", "suspendedAt"]
|
|
3051
|
+
});
|
|
3018
3052
|
}
|
|
3019
3053
|
async dangerouslyClearAll() {
|
|
3020
3054
|
await this.#db.deleteData({ tableName: storage.TABLE_BACKGROUND_TASKS });
|
|
@@ -3034,11 +3068,13 @@ var BackgroundTasksLibSQL = class extends storage.BackgroundTasksStorage {
|
|
|
3034
3068
|
args: task.args,
|
|
3035
3069
|
result: task.result ?? null,
|
|
3036
3070
|
error: task.error ?? null,
|
|
3071
|
+
suspend_payload: task.suspendPayload ?? null,
|
|
3037
3072
|
retry_count: task.retryCount,
|
|
3038
3073
|
max_retries: task.maxRetries,
|
|
3039
3074
|
timeout_ms: task.timeoutMs,
|
|
3040
3075
|
createdAt: task.createdAt.toISOString(),
|
|
3041
3076
|
startedAt: task.startedAt?.toISOString() ?? null,
|
|
3077
|
+
suspendedAt: task.suspendedAt?.toISOString() ?? null,
|
|
3042
3078
|
completedAt: task.completedAt?.toISOString() ?? null
|
|
3043
3079
|
}
|
|
3044
3080
|
});
|
|
@@ -3058,6 +3094,10 @@ var BackgroundTasksLibSQL = class extends storage.BackgroundTasksStorage {
|
|
|
3058
3094
|
setClauses.push("error = jsonb(?)");
|
|
3059
3095
|
params.push(serializeJson(update.error));
|
|
3060
3096
|
}
|
|
3097
|
+
if ("suspendPayload" in update) {
|
|
3098
|
+
setClauses.push("suspend_payload = jsonb(?)");
|
|
3099
|
+
params.push(serializeJson(update.suspendPayload));
|
|
3100
|
+
}
|
|
3061
3101
|
if ("retryCount" in update) {
|
|
3062
3102
|
setClauses.push("retry_count = ?");
|
|
3063
3103
|
params.push(update.retryCount);
|
|
@@ -3066,6 +3106,10 @@ var BackgroundTasksLibSQL = class extends storage.BackgroundTasksStorage {
|
|
|
3066
3106
|
setClauses.push("startedAt = ?");
|
|
3067
3107
|
params.push(update.startedAt?.toISOString() ?? null);
|
|
3068
3108
|
}
|
|
3109
|
+
if ("suspendedAt" in update) {
|
|
3110
|
+
setClauses.push("suspendedAt = ?");
|
|
3111
|
+
params.push(update.suspendedAt?.toISOString() ?? null);
|
|
3112
|
+
}
|
|
3069
3113
|
if ("completedAt" in update) {
|
|
3070
3114
|
setClauses.push("completedAt = ?");
|
|
3071
3115
|
params.push(update.completedAt?.toISOString() ?? null);
|
|
@@ -3113,7 +3157,11 @@ var BackgroundTasksLibSQL = class extends storage.BackgroundTasksStorage {
|
|
|
3113
3157
|
conditions.push("tool_name = ?");
|
|
3114
3158
|
params.push(filter.toolName);
|
|
3115
3159
|
}
|
|
3116
|
-
|
|
3160
|
+
if (filter.toolCallId) {
|
|
3161
|
+
conditions.push("tool_call_id = ?");
|
|
3162
|
+
params.push(filter.toolCallId);
|
|
3163
|
+
}
|
|
3164
|
+
const dateCol = filter.dateFilterBy === "startedAt" ? "startedAt" : filter.dateFilterBy === "suspendedAt" ? "suspendedAt" : filter.dateFilterBy === "completedAt" ? "completedAt" : "createdAt";
|
|
3117
3165
|
if (filter.fromDate) {
|
|
3118
3166
|
conditions.push(`${dateCol} >= ?`);
|
|
3119
3167
|
params.push(filter.fromDate.toISOString());
|
|
@@ -3128,7 +3176,7 @@ var BackgroundTasksLibSQL = class extends storage.BackgroundTasksStorage {
|
|
|
3128
3176
|
args: [...params]
|
|
3129
3177
|
});
|
|
3130
3178
|
const total = Number(countResult.rows[0]?.count ?? 0);
|
|
3131
|
-
const orderCol = filter.orderBy === "startedAt" ? "startedAt" : filter.orderBy === "completedAt" ? "completedAt" : "createdAt";
|
|
3179
|
+
const orderCol = filter.orderBy === "startedAt" ? "startedAt" : filter.orderBy === "suspendedAt" ? "suspendedAt" : filter.orderBy === "completedAt" ? "completedAt" : "createdAt";
|
|
3132
3180
|
const direction = filter.orderDirection === "desc" ? "DESC" : "ASC";
|
|
3133
3181
|
let sql = `SELECT ${buildSelectColumns(storage.TABLE_BACKGROUND_TASKS)} FROM ${storage.TABLE_BACKGROUND_TASKS} ${where} ORDER BY ${orderCol} ${direction}`;
|
|
3134
3182
|
if (filter.perPage != null) {
|
|
@@ -3156,7 +3204,7 @@ var BackgroundTasksLibSQL = class extends storage.BackgroundTasksStorage {
|
|
|
3156
3204
|
conditions.push(`status IN (${statuses.map(() => "?").join(", ")})`);
|
|
3157
3205
|
params.push(...statuses);
|
|
3158
3206
|
}
|
|
3159
|
-
const dateCol = filter.dateFilterBy === "startedAt" ? "startedAt" : filter.dateFilterBy === "completedAt" ? "completedAt" : "createdAt";
|
|
3207
|
+
const dateCol = filter.dateFilterBy === "startedAt" ? "startedAt" : filter.dateFilterBy === "suspendedAt" ? "suspendedAt" : filter.dateFilterBy === "completedAt" ? "completedAt" : "createdAt";
|
|
3160
3208
|
if (filter.fromDate) {
|
|
3161
3209
|
conditions.push(`${dateCol} >= ?`);
|
|
3162
3210
|
params.push(filter.fromDate.toISOString());
|
|
@@ -10586,7 +10634,7 @@ var WorkflowsLibSQL = class extends storage.WorkflowsStorage {
|
|
|
10586
10634
|
VALUES (?, ?, jsonb(?), ?, ?)
|
|
10587
10635
|
ON CONFLICT(workflow_name, run_id)
|
|
10588
10636
|
DO UPDATE SET snapshot = excluded.snapshot, updatedAt = excluded.updatedAt`,
|
|
10589
|
-
args: [workflowName, runId,
|
|
10637
|
+
args: [workflowName, runId, safeStringify(snapshot), now, now]
|
|
10590
10638
|
});
|
|
10591
10639
|
await tx.commit();
|
|
10592
10640
|
return snapshot.context;
|
|
@@ -10623,7 +10671,7 @@ var WorkflowsLibSQL = class extends storage.WorkflowsStorage {
|
|
|
10623
10671
|
const updatedSnapshot = { ...snapshot, ...opts };
|
|
10624
10672
|
await tx.execute({
|
|
10625
10673
|
sql: `UPDATE ${storage.TABLE_WORKFLOW_SNAPSHOT} SET snapshot = jsonb(?) WHERE workflow_name = ? AND run_id = ?`,
|
|
10626
|
-
args: [
|
|
10674
|
+
args: [safeStringify(updatedSnapshot), workflowName, runId]
|
|
10627
10675
|
});
|
|
10628
10676
|
await tx.commit();
|
|
10629
10677
|
return updatedSnapshot;
|