@mastra/libsql 1.27.0-alpha.1 → 1.27.0-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/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-agents-human-in-the-loop.md +2 -1
- package/dist/docs/references/docs-memory-semantic-recall.md +2 -0
- package/dist/docs/references/reference-core-mastra-class.md +7 -1
- package/dist/index.cjs +78 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +78 -4
- package/dist/index.js.map +1 -1
- package/dist/storage/db/utils.d.ts +5 -0
- package/dist/storage/db/utils.d.ts.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +1 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/skills/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +6 -7
package/dist/docs/SKILL.md
CHANGED
|
@@ -144,7 +144,8 @@ const stream = await agent.stream('Clean up old records', {
|
|
|
144
144
|
},
|
|
145
145
|
})
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
// A refused question has no probability, so it falls back to requiring approval.
|
|
148
|
+
return (result.answers.requiresApproval.probability ?? 1) >= 0.7
|
|
148
149
|
},
|
|
149
150
|
})
|
|
150
151
|
```
|
|
@@ -403,6 +403,8 @@ Memory uses a single embedder for both storing and recalling messages, so pick o
|
|
|
403
403
|
|
|
404
404
|
Multilingual E5 produces 1024-dimensional vectors. Your vector index must be created with matching dimensions, and E5 vectors can't be mixed with vectors from another embedder in the same index.
|
|
405
405
|
|
|
406
|
+
FastEmbed models embed at most 512 tokens per input (roughly 2,000 to 2,500 characters of English text). Longer inputs are truncated, so text past the limit doesn't affect the embedding and can't be found by semantic recall. The AI SDK v3 FastEmbed models return a warning when this happens. The legacy v1 and v2 models don't. If you embed long documents with FastEmbed, chunk them to fit the window, for example with `maxSize: 1500` in `MDocument.chunk()`.
|
|
407
|
+
|
|
406
408
|
## PostgreSQL index optimization
|
|
407
409
|
|
|
408
410
|
When using PostgreSQL as your vector store, you can optimize semantic recall performance by configuring the vector index. This is particularly important for large-scale deployments with thousands of messages.
|
|
@@ -147,6 +147,12 @@ Re-drives every orphaned `running` durable-agent run across all registered durab
|
|
|
147
147
|
|
|
148
148
|
Requires persistent storage. With an in-memory store, there's nothing to recover after a process restart.
|
|
149
149
|
|
|
150
|
+
Agents and their runs are attempted serially. Each built-in `recoverActiveRuns()` attempt waits up to 30 seconds in total for `recover()` setup and settlement of the whole recovered workflow, then traversal can continue to later runs and agents. This isn't an overall recovery deadline: discovery and overridden custom recovery methods aren't bounded by this budget.
|
|
151
|
+
|
|
152
|
+
A timed-out attempt continues in the background. Its outcome is `status: 'skipped'` with `reason: 'recovery-timeout'` and no `retryAt`. It contributes only to `skipped`, not `recovered`, `succeeded`, or `failed`, and Mastra doesn't automatically retry it. Late settlement doesn't change the returned counts.
|
|
153
|
+
|
|
154
|
+
When shutdown begins, recovery stops dispatching new agents and runs. The recovery traversal and original attempts, including timed-out setup or execution, participate in the same shared shutdown drain as active executions. A recovery wait timeout doesn't cancel the attempt or give it a separate shutdown drain window.
|
|
155
|
+
|
|
150
156
|
A run that another execution still drives isn't taken over. It's counted in `skipped` and checked again once that execution's claim could have lapsed, so a run whose process crashed is recovered without another call. `shutdown()` cancels pending re-checks. See [run ownership](https://mastra.ai/docs/harness/durable-agents).
|
|
151
157
|
|
|
152
158
|
```typescript
|
|
@@ -164,4 +170,4 @@ Returns:
|
|
|
164
170
|
|
|
165
171
|
**failed** (`number`): Runs whose restart threw an error.
|
|
166
172
|
|
|
167
|
-
**skipped** (`number`): Runs
|
|
173
|
+
**skipped** (`number`): Runs skipped because they are already active, recovery is already in progress, or the recovery wait timed out. Only ownership skips eligible for re-checks are checked again; recovery timeouts are not automatically retried.
|
package/dist/index.cjs
CHANGED
|
@@ -1645,6 +1645,27 @@ function buildSelectColumnsWithAlias(tableName, alias) {
|
|
|
1645
1645
|
function isLockError(error) {
|
|
1646
1646
|
return error.code === "SQLITE_BUSY" || error.code === "SQLITE_LOCKED" || error.message?.toLowerCase().includes("database is locked") || error.message?.toLowerCase().includes("database table is locked") || error.message?.toLowerCase().includes("table is locked") || error.constructor.name === "SqliteError" && error.message?.toLowerCase().includes("locked");
|
|
1647
1647
|
}
|
|
1648
|
+
const TRANSIENT_NETWORK_PATTERNS = [
|
|
1649
|
+
"fetch failed",
|
|
1650
|
+
"econnreset",
|
|
1651
|
+
"etimedout",
|
|
1652
|
+
"eai_again",
|
|
1653
|
+
"socket hang up",
|
|
1654
|
+
"und_err_"
|
|
1655
|
+
];
|
|
1656
|
+
/**
|
|
1657
|
+
* Checks if an error (or any error in its `cause` chain) is a transient network failure
|
|
1658
|
+
* such as `fetch failed` from a remote libsql client.
|
|
1659
|
+
*/
|
|
1660
|
+
function isTransientNetworkError(error) {
|
|
1661
|
+
let current = error;
|
|
1662
|
+
for (let depth = 0; current && depth < 5; depth++) {
|
|
1663
|
+
const text = `${current.message ?? ""} ${current.code ?? ""}`.toLowerCase();
|
|
1664
|
+
if (TRANSIENT_NETWORK_PATTERNS.some((pattern) => text.includes(pattern))) return true;
|
|
1665
|
+
current = current.cause;
|
|
1666
|
+
}
|
|
1667
|
+
return false;
|
|
1668
|
+
}
|
|
1648
1669
|
function createExecuteWriteOperationWithRetry({ logger, maxRetries, initialBackoffMs }) {
|
|
1649
1670
|
return async function executeWriteOperationWithRetry(operationFn, operationDescription) {
|
|
1650
1671
|
let attempts = 0;
|
|
@@ -14356,7 +14377,7 @@ var SkillsLibSQL = class extends _mastra_core_storage.SkillsStorage {
|
|
|
14356
14377
|
}
|
|
14357
14378
|
async list(args) {
|
|
14358
14379
|
try {
|
|
14359
|
-
const { page = 0, perPage: perPageInput, orderBy, authorId, visibility, status, entityIds, pinFavoritedFor, favoritedOnly } = args || {};
|
|
14380
|
+
const { page = 0, perPage: perPageInput, orderBy, authorId, visibility, status, entityIds, pinFavoritedFor, favoritedOnly, metadata } = args || {};
|
|
14360
14381
|
const { field, direction } = this.parseOrderBy(orderBy);
|
|
14361
14382
|
if (entityIds && entityIds.length === 0) return {
|
|
14362
14383
|
skills: [],
|
|
@@ -14384,6 +14405,28 @@ var SkillsLibSQL = class extends _mastra_core_storage.SkillsStorage {
|
|
|
14384
14405
|
conditions.push(`s_e.id IN (${placeholders})`);
|
|
14385
14406
|
queryParams.push(...entityIds);
|
|
14386
14407
|
}
|
|
14408
|
+
if (metadata && Object.keys(metadata).length > 0) {
|
|
14409
|
+
const latestVersionId = `(SELECT lv.id FROM "${_mastra_core_storage.TABLE_SKILL_VERSIONS}" lv WHERE lv."skillId" = s_e.id ORDER BY lv."versionNumber" DESC LIMIT 1)`;
|
|
14410
|
+
const resolvedVersionId = status === "draft" ? latestVersionId : `COALESCE(s_e."activeVersionId", ${latestVersionId})`;
|
|
14411
|
+
const metadataConditions = [];
|
|
14412
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
14413
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) throw new _mastra_core_error.MastraError({
|
|
14414
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("LIBSQL", "LIST_SKILLS", "INVALID_METADATA_KEY"),
|
|
14415
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
14416
|
+
category: _mastra_core_error.ErrorCategory.USER,
|
|
14417
|
+
text: `Invalid metadata key: ${key}. Keys must be alphanumeric with underscores.`,
|
|
14418
|
+
details: { key }
|
|
14419
|
+
});
|
|
14420
|
+
if (typeof value === "string") {
|
|
14421
|
+
metadataConditions.push(`json_extract(mv.metadata, '$.${key}') = ?`);
|
|
14422
|
+
queryParams.push(value);
|
|
14423
|
+
} else {
|
|
14424
|
+
metadataConditions.push(`json_extract(mv.metadata, '$.${key}') = json_extract(?, '$')`);
|
|
14425
|
+
queryParams.push(JSON.stringify(value));
|
|
14426
|
+
}
|
|
14427
|
+
}
|
|
14428
|
+
conditions.push(`EXISTS (SELECT 1 FROM "${_mastra_core_storage.TABLE_SKILL_VERSIONS}" mv WHERE mv."skillId" = s_e.id AND mv.id = ${resolvedVersionId} AND ${metadataConditions.join(" AND ")})`);
|
|
14429
|
+
}
|
|
14387
14430
|
const joinUserId = pinFavoritedFor;
|
|
14388
14431
|
const useJoin = Boolean(joinUserId);
|
|
14389
14432
|
let joinClause = "";
|
|
@@ -16584,6 +16627,8 @@ var LibSQLFactoryStorage = class extends _mastra_core_storage.FactoryStorage {
|
|
|
16584
16627
|
};
|
|
16585
16628
|
//#endregion
|
|
16586
16629
|
//#region src/storage/index.ts
|
|
16630
|
+
const REMOTE_INIT_CONCURRENCY = 5;
|
|
16631
|
+
const REMOTE_INIT_MAX_ATTEMPTS = 3;
|
|
16587
16632
|
const DEFAULT_LOCAL_CACHE_SIZE = -16e3;
|
|
16588
16633
|
const DEFAULT_LOCAL_MMAP_SIZE = 134217728;
|
|
16589
16634
|
/**
|
|
@@ -16730,8 +16775,31 @@ var LibSQLStore = class extends _mastra_core_storage.MastraCompositeStore {
|
|
|
16730
16775
|
for (const store of this.getStoresToInit()) await store.init();
|
|
16731
16776
|
return true;
|
|
16732
16777
|
}
|
|
16778
|
+
async initStoreWithRetry(store) {
|
|
16779
|
+
for (let attempt = 1;; attempt++) try {
|
|
16780
|
+
await store.init();
|
|
16781
|
+
return;
|
|
16782
|
+
} catch (error) {
|
|
16783
|
+
if (attempt >= REMOTE_INIT_MAX_ATTEMPTS || !isTransientNetworkError(error)) throw error;
|
|
16784
|
+
const backoff = this.initialBackoffMs * 2 ** (attempt - 1);
|
|
16785
|
+
this.logger.warn(`LibSQLStore: Transient network error during domain init, retrying in ${backoff}ms (attempt ${attempt}/${REMOTE_INIT_MAX_ATTEMPTS}).`, error);
|
|
16786
|
+
await new Promise((resolve) => setTimeout(resolve, backoff));
|
|
16787
|
+
}
|
|
16788
|
+
}
|
|
16733
16789
|
async initDomainsInParallel() {
|
|
16734
|
-
|
|
16790
|
+
const stores = this.getStoresToInit();
|
|
16791
|
+
let next = 0;
|
|
16792
|
+
let failed = false;
|
|
16793
|
+
const worker = async () => {
|
|
16794
|
+
while (!failed && next < stores.length) try {
|
|
16795
|
+
await this.initStoreWithRetry(stores[next++]);
|
|
16796
|
+
} catch (error) {
|
|
16797
|
+
failed = true;
|
|
16798
|
+
throw error;
|
|
16799
|
+
}
|
|
16800
|
+
};
|
|
16801
|
+
const rejected = (await Promise.allSettled(Array.from({ length: Math.min(REMOTE_INIT_CONCURRENCY, stores.length) }, worker))).find((r) => r.status === "rejected");
|
|
16802
|
+
if (rejected) throw rejected.reason;
|
|
16735
16803
|
return true;
|
|
16736
16804
|
}
|
|
16737
16805
|
async init() {
|
|
@@ -16742,7 +16810,10 @@ var LibSQLStore = class extends _mastra_core_storage.MastraCompositeStore {
|
|
|
16742
16810
|
await this.hasInitialized;
|
|
16743
16811
|
return;
|
|
16744
16812
|
}
|
|
16745
|
-
this.hasInitialized = this.initDomainsInParallel()
|
|
16813
|
+
this.hasInitialized = this.initDomainsInParallel().catch((error) => {
|
|
16814
|
+
this.hasInitialized = null;
|
|
16815
|
+
throw error;
|
|
16816
|
+
});
|
|
16746
16817
|
await this.hasInitialized;
|
|
16747
16818
|
return;
|
|
16748
16819
|
}
|
|
@@ -16754,7 +16825,10 @@ var LibSQLStore = class extends _mastra_core_storage.MastraCompositeStore {
|
|
|
16754
16825
|
await this.hasInitialized;
|
|
16755
16826
|
return;
|
|
16756
16827
|
}
|
|
16757
|
-
this.hasInitialized = this.initDomainsSequentially()
|
|
16828
|
+
this.hasInitialized = this.initDomainsSequentially().catch((error) => {
|
|
16829
|
+
this.hasInitialized = null;
|
|
16830
|
+
throw error;
|
|
16831
|
+
});
|
|
16758
16832
|
await this.hasInitialized;
|
|
16759
16833
|
return;
|
|
16760
16834
|
}
|