@mastra/libsql 1.27.1-alpha.0 → 1.27.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/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-semantic-recall.md +4 -2
- package/dist/docs/references/reference-memory-memory-class.md +8 -6
- package/dist/index.cjs +97 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +97 -22
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +12 -0
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +2 -1
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +9 -3
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/vector/sql-builder.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/docs/SKILL.md
CHANGED
|
@@ -456,8 +456,10 @@ const agent = new Agent({
|
|
|
456
456
|
indexConfig: {
|
|
457
457
|
type: 'hnsw', // Use HNSW for better performance
|
|
458
458
|
metric: 'dotproduct', // Best for OpenAI embeddings
|
|
459
|
-
|
|
460
|
-
|
|
459
|
+
hnsw: {
|
|
460
|
+
m: 16, // Number of bi-directional links (default: 16)
|
|
461
|
+
efConstruction: 64, // Size of candidate list during construction (default: 64)
|
|
462
|
+
},
|
|
461
463
|
},
|
|
462
464
|
},
|
|
463
465
|
},
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# Memory class
|
|
6
6
|
|
|
7
|
-
The `Memory` class provides a reliable system for managing conversation history and thread-based message storage in Mastra. It enables persistent storage of conversations, semantic search capabilities, and efficient message retrieval. You must configure a storage provider for conversation history, and if you enable semantic recall you will also need to provide a vector store and embedder.
|
|
7
|
+
The `Memory` class provides a reliable system for managing conversation history and thread-based message storage in Mastra. It enables persistent storage of conversations, semantic search capabilities, and efficient message retrieval. You must configure a storage provider for conversation history, and if you enable semantic recall you will also need to provide a vector store and, unless that vector store embeds text itself, an embedder.
|
|
8
8
|
|
|
9
9
|
## Usage example
|
|
10
10
|
|
|
@@ -31,11 +31,11 @@ export const agent = new Agent({
|
|
|
31
31
|
|
|
32
32
|
## Constructor parameters
|
|
33
33
|
|
|
34
|
-
**storage** (`MastraCompositeStore`): Storage implementation for persisting memory data.
|
|
34
|
+
**storage** (`MastraCompositeStore`): Storage implementation for persisting memory data. Optional: when omitted, an agent uses the storage of the Mastra instance it belongs to. If neither is configured, accessing memory.storage throws Memory requires a storage provider to function.
|
|
35
35
|
|
|
36
36
|
**vector** (`MastraVector | false`): Vector store for semantic search capabilities. Set to false to disable vector operations.
|
|
37
37
|
|
|
38
|
-
**embedder** (`EmbeddingModel<string> | EmbeddingModelV2<string>`): Embedder
|
|
38
|
+
**embedder** (`string | EmbeddingModel<string> | EmbeddingModelV2<string>`): Embedder for vector embeddings, as a model-router ID string (for example "openai/text-embedding-3-small"), an EmbeddingModel, or an EmbeddingModelV2. Required when semantic recall is enabled and the vector store doesn't generate embeddings itself (vector.isSelfEmbedding is false).
|
|
39
39
|
|
|
40
40
|
**embeddingDimension** (`number`): Output dimension of the embedder, as a positive integer. When set, Memory uses it to name the semantic recall index instead of embedding a probe string on first use. It must match the vectors the embedder returns: a mismatch throws a MASTRA_MEMORY_EMBEDDING_DIMENSION_MISMATCH error before any index is created. See Setting the embedding dimension.
|
|
41
41
|
|
|
@@ -49,7 +49,7 @@ export const agent = new Agent({
|
|
|
49
49
|
|
|
50
50
|
**options.retainFullInput** (`boolean`): When true, the request input is processed exactly as supplied instead of being filtered against stored history. Use this when you assemble the input yourself and need the message sequence preserved. Stored history is still loaded underneath, and every input message that isn't already stored is saved to the thread, including few-shot examples. Can be set per call on memory.options or agent-wide in the memory constructor options.
|
|
51
51
|
|
|
52
|
-
**options.semanticRecall** (`boolean | { topK: number; messageRange: number | { before: number; after: number }; scope?: 'thread' | 'resource' }`): Enable semantic search in message history. Can be a boolean or an object with configuration options. When enabled, requires
|
|
52
|
+
**options.semanticRecall** (`boolean | { topK: number; messageRange: number | { before: number; after: number }; scope?: 'thread' | 'resource' }`): Enable semantic search in message history. Can be a boolean or an object with configuration options. When enabled, requires a vector store, and an embedder unless the vector store embeds text itself (isSelfEmbedding). Default topK is 4, default messageRange is {before: 1, after: 1}.
|
|
53
53
|
|
|
54
54
|
**options.workingMemory** (`WorkingMemory`): Configuration for working memory feature. Can be { enabled: boolean; template?: string; schema?: ZodObject\<any> | JSONSchema7; scope?: 'thread' | 'resource' } or { enabled: boolean } to disable.
|
|
55
55
|
|
|
@@ -128,8 +128,10 @@ export const agent = new Agent({
|
|
|
128
128
|
indexConfig: {
|
|
129
129
|
type: 'hnsw', // Use HNSW for better performance
|
|
130
130
|
metric: 'dotproduct', // Optimal for OpenAI embeddings
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
hnsw: {
|
|
132
|
+
m: 16, // Number of bi-directional links
|
|
133
|
+
efConstruction: 64, // Construction-time candidate list size
|
|
134
|
+
},
|
|
133
135
|
},
|
|
134
136
|
},
|
|
135
137
|
workingMemory: {
|
package/dist/index.cjs
CHANGED
|
@@ -501,7 +501,7 @@ const createNumericOperator = (symbol) => {
|
|
|
501
501
|
sql: `CAST(json_extract(metadata, ${jsonPath}) AS NUMERIC) ${symbol} ?`,
|
|
502
502
|
needsValue: true
|
|
503
503
|
};
|
|
504
|
-
|
|
504
|
+
return {
|
|
505
505
|
sql: `CAST(json_extract(metadata, ${jsonPath}) AS TEXT) ${symbol} ?`,
|
|
506
506
|
needsValue: true
|
|
507
507
|
};
|
|
@@ -528,7 +528,8 @@ function buildElemMatchConditions(value) {
|
|
|
528
528
|
sql: sql.replace(pattern, `json_extract(elem.value, '$.${jsonPath}')`),
|
|
529
529
|
values
|
|
530
530
|
};
|
|
531
|
-
}
|
|
531
|
+
}
|
|
532
|
+
return {
|
|
532
533
|
sql: `json_extract(elem.value, '$.${parseJsonPathKey(field)}') = ?`,
|
|
533
534
|
values: [fieldValue]
|
|
534
535
|
};
|
|
@@ -2059,6 +2060,41 @@ var LibSQLDB = class extends _mastra_core_base.MastraBase {
|
|
|
2059
2060
|
});
|
|
2060
2061
|
}
|
|
2061
2062
|
/**
|
|
2063
|
+
* Updates multiple records in one write batch, with the same retry behavior as
|
|
2064
|
+
* {@link batchUpdate}. Returns, in input order, whether each update changed a row,
|
|
2065
|
+
* so callers can put extra conditions in `keys` (for example `{ endedAt: null }`).
|
|
2066
|
+
*/
|
|
2067
|
+
async batchUpdateReportingChanges({ tableName, updates }) {
|
|
2068
|
+
return this.executeWriteOperationWithRetry(async () => {
|
|
2069
|
+
const changed = updates.map(() => false);
|
|
2070
|
+
const statements = [];
|
|
2071
|
+
const statementIndexes = [];
|
|
2072
|
+
for (const [index, { keys, data }] of updates.entries()) {
|
|
2073
|
+
const filteredData = await this.filterRecordToKnownColumns(tableName, data);
|
|
2074
|
+
if (Object.keys(filteredData).length === 0) continue;
|
|
2075
|
+
statements.push(prepareUpdateStatement({
|
|
2076
|
+
tableName,
|
|
2077
|
+
updates: filteredData,
|
|
2078
|
+
keys
|
|
2079
|
+
}));
|
|
2080
|
+
statementIndexes.push(index);
|
|
2081
|
+
}
|
|
2082
|
+
if (statements.length === 0) return changed;
|
|
2083
|
+
(await withClientWriteLock(this.client, () => this.client.batch(statements, "write"))).forEach((result, i) => {
|
|
2084
|
+
const index = statementIndexes[i];
|
|
2085
|
+
if (index !== void 0) changed[index] = result.rowsAffected > 0;
|
|
2086
|
+
});
|
|
2087
|
+
return changed;
|
|
2088
|
+
}, `batch update in table ${tableName}`).catch((error) => {
|
|
2089
|
+
throw new _mastra_core_error.MastraError({
|
|
2090
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("LIBSQL", "BATCH_UPDATE_REPORTING_CHANGES", "FAILED"),
|
|
2091
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
2092
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
2093
|
+
details: { tableName }
|
|
2094
|
+
}, error);
|
|
2095
|
+
});
|
|
2096
|
+
}
|
|
2097
|
+
/**
|
|
2062
2098
|
* Internal batch delete implementation without retry logic.
|
|
2063
2099
|
* Each record can be deleted based on single or composite keys.
|
|
2064
2100
|
*/
|
|
@@ -2191,7 +2227,7 @@ var LibSQLDB = class extends _mastra_core_base.MastraBase {
|
|
|
2191
2227
|
* @returns The total count of matching records
|
|
2192
2228
|
*/
|
|
2193
2229
|
async selectTotalCount({ tableName, whereClause }) {
|
|
2194
|
-
const statement = `SELECT COUNT(*) as count FROM ${(0, _mastra_core_utils.parseSqlIdentifier)(tableName, "table name")} ${whereClause ?
|
|
2230
|
+
const statement = `SELECT COUNT(*) as count FROM ${(0, _mastra_core_utils.parseSqlIdentifier)(tableName, "table name")} ${whereClause ? whereClause.sql : ""}`;
|
|
2195
2231
|
const result = await this.client.execute({
|
|
2196
2232
|
sql: statement,
|
|
2197
2233
|
args: whereClause?.args ?? []
|
|
@@ -12563,24 +12599,27 @@ var ObservabilityLibSQL = class ObservabilityLibSQL extends _mastra_core_storage
|
|
|
12563
12599
|
}, error);
|
|
12564
12600
|
}
|
|
12565
12601
|
}
|
|
12566
|
-
|
|
12602
|
+
#toSpanUpdates(records) {
|
|
12567
12603
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
12604
|
+
return records.map((record) => {
|
|
12605
|
+
const data = { ...record.updates };
|
|
12606
|
+
if (data.endedAt instanceof Date) data.endedAt = data.endedAt.toISOString();
|
|
12607
|
+
if (data.startedAt instanceof Date) data.startedAt = data.startedAt.toISOString();
|
|
12608
|
+
data.updatedAt = now;
|
|
12609
|
+
return {
|
|
12610
|
+
keys: {
|
|
12611
|
+
spanId: record.spanId,
|
|
12612
|
+
traceId: record.traceId
|
|
12613
|
+
},
|
|
12614
|
+
data
|
|
12615
|
+
};
|
|
12616
|
+
});
|
|
12617
|
+
}
|
|
12618
|
+
async batchUpdateSpans(args) {
|
|
12568
12619
|
try {
|
|
12569
12620
|
return this.#db.batchUpdate({
|
|
12570
12621
|
tableName: _mastra_core_storage.TABLE_SPANS,
|
|
12571
|
-
updates: args.records
|
|
12572
|
-
const data = { ...record.updates };
|
|
12573
|
-
if (data.endedAt instanceof Date) data.endedAt = data.endedAt.toISOString();
|
|
12574
|
-
if (data.startedAt instanceof Date) data.startedAt = data.startedAt.toISOString();
|
|
12575
|
-
data.updatedAt = now;
|
|
12576
|
-
return {
|
|
12577
|
-
keys: {
|
|
12578
|
-
spanId: record.spanId,
|
|
12579
|
-
traceId: record.traceId
|
|
12580
|
-
},
|
|
12581
|
-
data
|
|
12582
|
-
};
|
|
12583
|
-
})
|
|
12622
|
+
updates: this.#toSpanUpdates(args.records)
|
|
12584
12623
|
});
|
|
12585
12624
|
} catch (error) {
|
|
12586
12625
|
throw new _mastra_core_error.MastraError({
|
|
@@ -12590,6 +12629,30 @@ var ObservabilityLibSQL = class ObservabilityLibSQL extends _mastra_core_storage
|
|
|
12590
12629
|
}, error);
|
|
12591
12630
|
}
|
|
12592
12631
|
}
|
|
12632
|
+
async batchUpdateUnendedSpans(args) {
|
|
12633
|
+
try {
|
|
12634
|
+
const changed = await this.#db.batchUpdateReportingChanges({
|
|
12635
|
+
tableName: _mastra_core_storage.TABLE_SPANS,
|
|
12636
|
+
updates: this.#toSpanUpdates(args.records).map((update) => ({
|
|
12637
|
+
...update,
|
|
12638
|
+
keys: {
|
|
12639
|
+
...update.keys,
|
|
12640
|
+
endedAt: null
|
|
12641
|
+
}
|
|
12642
|
+
}))
|
|
12643
|
+
});
|
|
12644
|
+
return { updated: args.records.filter((_, index) => changed[index]).map(({ traceId, spanId }) => ({
|
|
12645
|
+
traceId,
|
|
12646
|
+
spanId
|
|
12647
|
+
})) };
|
|
12648
|
+
} catch (error) {
|
|
12649
|
+
throw new _mastra_core_error.MastraError({
|
|
12650
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("LIBSQL", "BATCH_UPDATE_UNENDED_SPANS", "FAILED"),
|
|
12651
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
12652
|
+
category: _mastra_core_error.ErrorCategory.USER
|
|
12653
|
+
}, error);
|
|
12654
|
+
}
|
|
12655
|
+
}
|
|
12593
12656
|
async batchDeleteTraces(args) {
|
|
12594
12657
|
this.assertUnscopedBatchDeleteTraces(args);
|
|
12595
12658
|
try {
|
|
@@ -15278,6 +15341,9 @@ var WorkflowsLibSQL = class WorkflowsLibSQL extends _mastra_core_storage.Workflo
|
|
|
15278
15341
|
supportsConcurrentUpdates() {
|
|
15279
15342
|
return true;
|
|
15280
15343
|
}
|
|
15344
|
+
supportsGuardedSnapshotWrites() {
|
|
15345
|
+
return true;
|
|
15346
|
+
}
|
|
15281
15347
|
parseWorkflowRun(row) {
|
|
15282
15348
|
let parsedSnapshot = row.snapshot;
|
|
15283
15349
|
if (typeof parsedSnapshot === "string") try {
|
|
@@ -15551,7 +15617,7 @@ var WorkflowsLibSQL = class WorkflowsLibSQL extends _mastra_core_storage.Workflo
|
|
|
15551
15617
|
}
|
|
15552
15618
|
}), "updateWorkflowState");
|
|
15553
15619
|
}
|
|
15554
|
-
async persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot, createdAt, updatedAt, fence }) {
|
|
15620
|
+
async persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot, createdAt, updatedAt, fence, expectedStatus }) {
|
|
15555
15621
|
const now = /* @__PURE__ */ new Date();
|
|
15556
15622
|
const createdAtValue = (createdAt ?? now).toISOString();
|
|
15557
15623
|
const updatedAtValue = (updatedAt ?? now).toISOString();
|
|
@@ -15559,21 +15625,30 @@ var WorkflowsLibSQL = class WorkflowsLibSQL extends _mastra_core_storage.Workflo
|
|
|
15559
15625
|
workflowName,
|
|
15560
15626
|
runId
|
|
15561
15627
|
});
|
|
15628
|
+
const expected = expectedStatus === void 0 ? [] : Array.isArray(expectedStatus) ? expectedStatus : [expectedStatus];
|
|
15629
|
+
const guard = expectedStatus === void 0 ? "" : expected.length ? ` WHERE json_extract(${_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT}.snapshot, '$.status') IN (${expected.map(() => "?").join(", ")})` : " WHERE 0";
|
|
15562
15630
|
const check = this.#runFenceCheck(fence, runId, "persistWorkflowSnapshot");
|
|
15563
|
-
await this.executeWithRetry(() => withRunFence(this.#client, check, (writer) => writer.execute({
|
|
15631
|
+
return (await this.executeWithRetry(() => withRunFence(this.#client, check, (writer) => writer.execute({
|
|
15564
15632
|
sql: `INSERT INTO ${_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT} (workflow_name, run_id, resourceId, snapshot, createdAt, updatedAt)
|
|
15565
15633
|
VALUES (?, ?, ?, jsonb(?), ?, ?)
|
|
15566
15634
|
ON CONFLICT(workflow_name, run_id)
|
|
15567
|
-
DO UPDATE SET resourceId = COALESCE(excluded.resourceId, ${_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT}.resourceId), snapshot = excluded.snapshot, updatedAt = excluded.updatedAt`,
|
|
15635
|
+
DO UPDATE SET resourceId = COALESCE(excluded.resourceId, ${_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT}.resourceId), snapshot = excluded.snapshot, updatedAt = excluded.updatedAt${guard}`,
|
|
15568
15636
|
args: [
|
|
15569
15637
|
workflowName,
|
|
15570
15638
|
runId,
|
|
15571
15639
|
resourceId ?? null,
|
|
15572
15640
|
safeStringify(snapshot),
|
|
15573
15641
|
createdAtValue,
|
|
15574
|
-
updatedAtValue
|
|
15642
|
+
updatedAtValue,
|
|
15643
|
+
...expected
|
|
15575
15644
|
]
|
|
15576
|
-
})), "persistWorkflowSnapshot");
|
|
15645
|
+
})), "persistWorkflowSnapshot")).rowsAffected > 0;
|
|
15646
|
+
}
|
|
15647
|
+
async loadWorkflowRunStatus({ workflowName, runId }) {
|
|
15648
|
+
return (await this.#client.execute({
|
|
15649
|
+
sql: `SELECT json_extract(snapshot, '$.status') AS status FROM ${_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
|
|
15650
|
+
args: [workflowName, runId]
|
|
15651
|
+
})).rows?.[0]?.status ?? null;
|
|
15577
15652
|
}
|
|
15578
15653
|
async loadWorkflowSnapshot({ workflowName, runId }) {
|
|
15579
15654
|
this.logger.debug("Loading workflow snapshot", {
|