@mastra/mongodb 1.11.1 → 1.12.0-alpha.0
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 +27 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-working-memory.md +2 -0
- package/dist/docs/references/docs-rag-retrieval.md +2 -0
- package/dist/docs/references/docs-rag-vector-databases.md +2 -0
- package/dist/docs/references/reference-storage-mongodb.md +2 -0
- package/dist/docs/references/reference-vectors-mongodb.md +2 -0
- package/dist/index.cjs +302 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +303 -3
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/background-tasks/index.d.ts +13 -0
- package/dist/storage/domains/background-tasks/index.d.ts.map +1 -1
- package/dist/storage/domains/experiments/index.d.ts +22 -1
- package/dist/storage/domains/experiments/index.d.ts.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +14 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/notifications/index.d.ts +5 -1
- package/dist/storage/domains/notifications/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +5 -1
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/dist/storage/domains/schedules/index.d.ts +11 -1
- package/dist/storage/domains/schedules/index.d.ts.map +1 -1
- package/dist/storage/domains/scores/index.d.ts +5 -1
- package/dist/storage/domains/scores/index.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +8 -1
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/retention.d.ts +121 -0
- package/dist/storage/retention.d.ts.map +1 -0
- package/dist/storage/types.d.ts +21 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { v4 } from '@lukeed/uuid';
|
|
2
2
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
3
|
-
import { createVectorErrorId, AgentsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, createStorageErrorId, normalizePerPage, calculatePagination, BackgroundTasksStorage, TABLE_BACKGROUND_TASKS, BlobStore, TABLE_SKILL_BLOBS, DatasetsStorage, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, ensureDate, safelyParseJSON, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, ExperimentsStorage, MCPClientsStorage, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, MCPServersStorage, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, NotificationsStorage, TABLE_NOTIFICATIONS, ObservabilityStorage, TABLE_SPANS, listTracesArgsSchema, toTraceSpans, PromptBlocksStorage, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, SchedulesStorage, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, ScorerDefinitionsStorage, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, ScoresStorage, TABLE_SCORERS, SkillsStorage, TABLE_SKILLS, TABLE_SKILL_VERSIONS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, WorkspacesStorage, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, MastraCompositeStore, TraceStatus, transformScoreRow as transformScoreRow$1 } from '@mastra/core/storage';
|
|
3
|
+
import { createVectorErrorId, AgentsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, createStorageErrorId, normalizePerPage, calculatePagination, BackgroundTasksStorage, TABLE_BACKGROUND_TASKS, BlobStore, TABLE_SKILL_BLOBS, DatasetsStorage, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, ensureDate, safelyParseJSON, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, ExperimentsStorage, MCPClientsStorage, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, MCPServersStorage, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, NotificationsStorage, TABLE_NOTIFICATIONS, ObservabilityStorage, TABLE_SPANS, listTracesArgsSchema, toTraceSpans, PromptBlocksStorage, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, SchedulesStorage, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, ScorerDefinitionsStorage, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, ScoresStorage, TABLE_SCORERS, SkillsStorage, TABLE_SKILLS, TABLE_SKILL_VERSIONS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, WorkspacesStorage, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, MastraCompositeStore, TraceStatus, parseDuration, transformScoreRow as transformScoreRow$1 } from '@mastra/core/storage';
|
|
4
4
|
import { MastraVector, validateUpsertInput, validateVectorValues } from '@mastra/core/vector';
|
|
5
5
|
import { MongoClient, MongoBulkWriteError } from 'mongodb';
|
|
6
6
|
import { BaseFilterTranslator } from '@mastra/core/vector/filter';
|
|
@@ -13,7 +13,7 @@ import { skillSnapshotFieldValuesEqual } from '@mastra/core/storage/domains/skil
|
|
|
13
13
|
|
|
14
14
|
// package.json
|
|
15
15
|
var package_default = {
|
|
16
|
-
version: "1.
|
|
16
|
+
version: "1.12.0-alpha.0"};
|
|
17
17
|
var MongoDBFilterTranslator = class extends BaseFilterTranslator {
|
|
18
18
|
getSupportedOperators() {
|
|
19
19
|
return {
|
|
@@ -1619,6 +1619,126 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
|
|
|
1619
1619
|
return result;
|
|
1620
1620
|
}
|
|
1621
1621
|
};
|
|
1622
|
+
var DEFAULT_PRUNE_BATCH_SIZE = 1e3;
|
|
1623
|
+
async function ensureAnchorIndex(connector, target, logger) {
|
|
1624
|
+
if (!target.indexed) return;
|
|
1625
|
+
try {
|
|
1626
|
+
const collection = await connector.getCollection(target.table);
|
|
1627
|
+
await collection.createIndex({ [target.column]: -1 });
|
|
1628
|
+
} catch (error) {
|
|
1629
|
+
logger?.warn?.(`Failed to ensure retention index on ${target.table}(${target.column}):`, error);
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
async function sleep(ms, signal) {
|
|
1633
|
+
if (ms <= 0 || signal?.aborted) return;
|
|
1634
|
+
await new Promise((resolve) => {
|
|
1635
|
+
const timer = setTimeout(() => {
|
|
1636
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1637
|
+
resolve();
|
|
1638
|
+
}, ms);
|
|
1639
|
+
const onAbort = () => {
|
|
1640
|
+
clearTimeout(timer);
|
|
1641
|
+
resolve();
|
|
1642
|
+
};
|
|
1643
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1644
|
+
});
|
|
1645
|
+
}
|
|
1646
|
+
function cutoffFor(policy, encoding, now = Date.now()) {
|
|
1647
|
+
const cutoffMs = now - parseDuration(policy.maxAge);
|
|
1648
|
+
if (encoding === "epoch-ms") return cutoffMs;
|
|
1649
|
+
if (encoding === "iso") return new Date(cutoffMs).toISOString();
|
|
1650
|
+
return new Date(cutoffMs);
|
|
1651
|
+
}
|
|
1652
|
+
async function pruneCollectionBatch({
|
|
1653
|
+
connector,
|
|
1654
|
+
table,
|
|
1655
|
+
column,
|
|
1656
|
+
cutoff,
|
|
1657
|
+
limit
|
|
1658
|
+
}) {
|
|
1659
|
+
const collection = await connector.getCollection(table);
|
|
1660
|
+
const docs = await collection.find({ [column]: { $lt: cutoff } }).project({ _id: 1 }).limit(limit).toArray();
|
|
1661
|
+
if (docs.length === 0) return 0;
|
|
1662
|
+
const result = await collection.deleteMany({ _id: { $in: docs.map((doc) => doc._id) } });
|
|
1663
|
+
return result.deletedCount;
|
|
1664
|
+
}
|
|
1665
|
+
async function runBatchedDelete({
|
|
1666
|
+
deleteBatch,
|
|
1667
|
+
batchSize,
|
|
1668
|
+
options
|
|
1669
|
+
}) {
|
|
1670
|
+
if (!Number.isSafeInteger(batchSize) || batchSize <= 0) {
|
|
1671
|
+
throw new Error(`retention batchSize must be a positive integer; received ${batchSize}`);
|
|
1672
|
+
}
|
|
1673
|
+
let deleted = 0;
|
|
1674
|
+
let batches = 0;
|
|
1675
|
+
while (true) {
|
|
1676
|
+
if (options?.signal?.aborted) return { deleted, done: false };
|
|
1677
|
+
if (options?.maxBatches !== void 0 && batches >= options.maxBatches) return { deleted, done: false };
|
|
1678
|
+
let limit = batchSize;
|
|
1679
|
+
if (options?.maxRows !== void 0) {
|
|
1680
|
+
const remaining = options.maxRows - deleted;
|
|
1681
|
+
if (remaining <= 0) return { deleted, done: false };
|
|
1682
|
+
limit = Math.min(limit, remaining);
|
|
1683
|
+
}
|
|
1684
|
+
const affected = await deleteBatch(limit);
|
|
1685
|
+
deleted += affected;
|
|
1686
|
+
batches += 1;
|
|
1687
|
+
if (affected < limit) return { deleted, done: true };
|
|
1688
|
+
if (options?.pauseMs) {
|
|
1689
|
+
await sleep(options.pauseMs, options.signal);
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
async function runPrune({
|
|
1694
|
+
connector,
|
|
1695
|
+
domain,
|
|
1696
|
+
targets,
|
|
1697
|
+
options,
|
|
1698
|
+
logger
|
|
1699
|
+
}) {
|
|
1700
|
+
const results = [];
|
|
1701
|
+
const now = Date.now();
|
|
1702
|
+
for (const target of targets) {
|
|
1703
|
+
if (options?.signal?.aborted) {
|
|
1704
|
+
results.push({ domain, table: target.table, deleted: 0, done: false });
|
|
1705
|
+
continue;
|
|
1706
|
+
}
|
|
1707
|
+
await ensureAnchorIndex(connector, target, logger);
|
|
1708
|
+
const cutoff = cutoffFor(target.policy, target.encoding, now);
|
|
1709
|
+
const batchSize = target.policy.batchSize ?? DEFAULT_PRUNE_BATCH_SIZE;
|
|
1710
|
+
const { deleted, done } = await runBatchedDelete({
|
|
1711
|
+
deleteBatch: (limit) => pruneCollectionBatch({ connector, table: target.table, column: target.column, cutoff, limit }),
|
|
1712
|
+
batchSize,
|
|
1713
|
+
options
|
|
1714
|
+
});
|
|
1715
|
+
results.push({ domain, table: target.table, deleted, done });
|
|
1716
|
+
}
|
|
1717
|
+
return results;
|
|
1718
|
+
}
|
|
1719
|
+
function resolveTargets({
|
|
1720
|
+
policies,
|
|
1721
|
+
descriptor,
|
|
1722
|
+
order,
|
|
1723
|
+
encodings
|
|
1724
|
+
}) {
|
|
1725
|
+
const targets = [];
|
|
1726
|
+
for (const key of order) {
|
|
1727
|
+
const policy = policies[key];
|
|
1728
|
+
const entry = descriptor[key];
|
|
1729
|
+
if (!policy || !entry) continue;
|
|
1730
|
+
targets.push({
|
|
1731
|
+
table: entry.table,
|
|
1732
|
+
column: entry.column,
|
|
1733
|
+
encoding: encodings?.[key] ?? (entry.anchorType === "epoch-ms" ? "epoch-ms" : "date"),
|
|
1734
|
+
indexed: entry.indexed ?? true,
|
|
1735
|
+
policy
|
|
1736
|
+
});
|
|
1737
|
+
}
|
|
1738
|
+
return targets;
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
// src/storage/domains/background-tasks/index.ts
|
|
1622
1742
|
function toDoc(task) {
|
|
1623
1743
|
return {
|
|
1624
1744
|
id: task.id,
|
|
@@ -1670,6 +1790,14 @@ var BackgroundTasksStorageMongoDB = class _BackgroundTasksStorageMongoDB extends
|
|
|
1670
1790
|
#skipDefaultIndexes;
|
|
1671
1791
|
#indexes;
|
|
1672
1792
|
static MANAGED_COLLECTIONS = [TABLE_BACKGROUND_TASKS];
|
|
1793
|
+
/**
|
|
1794
|
+
* Anchor is `completedAt`, so age is measured from task completion; it stays
|
|
1795
|
+
* `null` while a task is in-flight, and `null $lt cutoff` never matches, so
|
|
1796
|
+
* pending/running tasks are never pruned regardless of age.
|
|
1797
|
+
*/
|
|
1798
|
+
static retentionTables = {
|
|
1799
|
+
backgroundTasks: { table: TABLE_BACKGROUND_TASKS, column: "completedAt", indexed: true }
|
|
1800
|
+
};
|
|
1673
1801
|
constructor(config) {
|
|
1674
1802
|
super();
|
|
1675
1803
|
this.#connector = resolveMongoDBConfig(config);
|
|
@@ -1681,6 +1809,20 @@ var BackgroundTasksStorageMongoDB = class _BackgroundTasksStorageMongoDB extends
|
|
|
1681
1809
|
async getCollection() {
|
|
1682
1810
|
return this.#connector.getCollection(TABLE_BACKGROUND_TASKS);
|
|
1683
1811
|
}
|
|
1812
|
+
/**
|
|
1813
|
+
* Delete tasks completed longer ago than the policy's `maxAge`, batched.
|
|
1814
|
+
* `completedAt` is stored as an ISO-8601 string (see `toDoc`), so the cutoff
|
|
1815
|
+
* uses the `iso` encoding — lexicographic `$lt` on ISO strings is time-ordered.
|
|
1816
|
+
*/
|
|
1817
|
+
async prune(policies, options) {
|
|
1818
|
+
const targets = resolveTargets({
|
|
1819
|
+
policies,
|
|
1820
|
+
descriptor: _BackgroundTasksStorageMongoDB.retentionTables,
|
|
1821
|
+
order: ["backgroundTasks"],
|
|
1822
|
+
encodings: { backgroundTasks: "iso" }
|
|
1823
|
+
});
|
|
1824
|
+
return runPrune({ connector: this.#connector, domain: "backgroundTasks", targets, options, logger: this.logger });
|
|
1825
|
+
}
|
|
1684
1826
|
getDefaultIndexDefinitions() {
|
|
1685
1827
|
return [
|
|
1686
1828
|
{ collection: TABLE_BACKGROUND_TASKS, keys: { id: 1 }, options: { unique: true } },
|
|
@@ -3081,6 +3223,15 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends Experim
|
|
|
3081
3223
|
#skipDefaultIndexes;
|
|
3082
3224
|
#indexes;
|
|
3083
3225
|
static MANAGED_COLLECTIONS = [TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS];
|
|
3226
|
+
/**
|
|
3227
|
+
* Experiments prune as whole units: an experiment and its results are only
|
|
3228
|
+
* deleted together, once the experiment itself is old (anchored on the
|
|
3229
|
+
* parent's `completedAt`, a BSON date that stays `null` while running).
|
|
3230
|
+
* `results` is intentionally not an independent retention key.
|
|
3231
|
+
*/
|
|
3232
|
+
static retentionTables = {
|
|
3233
|
+
experiments: { table: TABLE_EXPERIMENTS, column: "completedAt", indexed: true }
|
|
3234
|
+
};
|
|
3084
3235
|
constructor(config) {
|
|
3085
3236
|
super();
|
|
3086
3237
|
this.#connector = resolveMongoDBConfig(config);
|
|
@@ -3092,6 +3243,57 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends Experim
|
|
|
3092
3243
|
async getCollection(name) {
|
|
3093
3244
|
return this.#connector.getCollection(name);
|
|
3094
3245
|
}
|
|
3246
|
+
/**
|
|
3247
|
+
* Prune whole experiments older than the `experiments` policy's `maxAge`.
|
|
3248
|
+
*
|
|
3249
|
+
* Each batch collects up to `batchSize` aged experiment ids
|
|
3250
|
+
* (`completedAt < cutoff`; BSON type bracketing means `null` — still
|
|
3251
|
+
* running — never matches), then deletes their `experiment_results` rows and
|
|
3252
|
+
* the experiment rows for exactly that id set inside
|
|
3253
|
+
* `connector.withTransaction()` — atomic on replica sets, sequential
|
|
3254
|
+
* children-first on standalone — mirroring `deleteExperiment`. Hitting
|
|
3255
|
+
* `maxBatches`/`maxRows` or the abort signal between batches therefore never
|
|
3256
|
+
* leaves a run hollow (parent kept, results gone). Bounds count whole
|
|
3257
|
+
* experiments, not rows.
|
|
3258
|
+
*/
|
|
3259
|
+
async prune(policies, options) {
|
|
3260
|
+
const policy = policies["experiments"];
|
|
3261
|
+
if (!policy || options?.signal?.aborted) {
|
|
3262
|
+
return policy ? [
|
|
3263
|
+
{ domain: "experiments", table: TABLE_EXPERIMENT_RESULTS, deleted: 0, done: false },
|
|
3264
|
+
{ domain: "experiments", table: TABLE_EXPERIMENTS, deleted: 0, done: false }
|
|
3265
|
+
] : [];
|
|
3266
|
+
}
|
|
3267
|
+
await ensureAnchorIndex(
|
|
3268
|
+
this.#connector,
|
|
3269
|
+
{ table: TABLE_EXPERIMENTS, column: "completedAt", indexed: true },
|
|
3270
|
+
this.logger
|
|
3271
|
+
);
|
|
3272
|
+
const cutoff = cutoffFor(policy, "date");
|
|
3273
|
+
const batchSize = policy.batchSize ?? DEFAULT_PRUNE_BATCH_SIZE;
|
|
3274
|
+
const experimentsCollection = await this.getCollection(TABLE_EXPERIMENTS);
|
|
3275
|
+
const resultsCollection = await this.getCollection(TABLE_EXPERIMENT_RESULTS);
|
|
3276
|
+
let childDeleted = 0;
|
|
3277
|
+
const parent = await runBatchedDelete({
|
|
3278
|
+
deleteBatch: async (limit) => {
|
|
3279
|
+
const docs = await experimentsCollection.find({ completedAt: { $lt: cutoff } }).project({ id: 1 }).limit(limit).toArray();
|
|
3280
|
+
if (docs.length === 0) return 0;
|
|
3281
|
+
const ids = docs.map((doc) => doc.id);
|
|
3282
|
+
return this.#connector.withTransaction(async (session) => {
|
|
3283
|
+
const children = await resultsCollection.deleteMany({ experimentId: { $in: ids } }, { session });
|
|
3284
|
+
childDeleted += children.deletedCount;
|
|
3285
|
+
const parents = await experimentsCollection.deleteMany({ id: { $in: ids } }, { session });
|
|
3286
|
+
return parents.deletedCount;
|
|
3287
|
+
});
|
|
3288
|
+
},
|
|
3289
|
+
batchSize,
|
|
3290
|
+
options
|
|
3291
|
+
});
|
|
3292
|
+
return [
|
|
3293
|
+
{ domain: "experiments", table: TABLE_EXPERIMENT_RESULTS, deleted: childDeleted, done: parent.done },
|
|
3294
|
+
{ domain: "experiments", table: TABLE_EXPERIMENTS, deleted: parent.deleted, done: parent.done }
|
|
3295
|
+
];
|
|
3296
|
+
}
|
|
3095
3297
|
// -------------------------------------------------------------------------
|
|
3096
3298
|
// Index Management
|
|
3097
3299
|
// -------------------------------------------------------------------------
|
|
@@ -4689,6 +4891,15 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends MemoryStorage {
|
|
|
4689
4891
|
#indexes;
|
|
4690
4892
|
/** Collections managed by this domain */
|
|
4691
4893
|
static MANAGED_COLLECTIONS = [TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, OM_TABLE];
|
|
4894
|
+
/**
|
|
4895
|
+
* Retention-eligible collections. The observational-memory collection is
|
|
4896
|
+
* excluded: it has no timestamp anchor to age on. All anchors are BSON dates.
|
|
4897
|
+
*/
|
|
4898
|
+
static retentionTables = {
|
|
4899
|
+
messages: { table: TABLE_MESSAGES, column: "createdAt", indexed: true },
|
|
4900
|
+
resources: { table: TABLE_RESOURCES, column: "createdAt", indexed: true },
|
|
4901
|
+
threads: { table: TABLE_THREADS, column: "createdAt", indexed: true }
|
|
4902
|
+
};
|
|
4692
4903
|
constructor(config) {
|
|
4693
4904
|
super();
|
|
4694
4905
|
this.#connector = resolveMongoDBConfig(config);
|
|
@@ -4704,6 +4915,21 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends MemoryStorage {
|
|
|
4704
4915
|
await this.createDefaultIndexes();
|
|
4705
4916
|
await this.createCustomIndexes();
|
|
4706
4917
|
}
|
|
4918
|
+
/**
|
|
4919
|
+
* Delete memory rows older than each table's `maxAge`, batched. Order is
|
|
4920
|
+
* messages → resources → threads so child rows never outlive the delete of
|
|
4921
|
+
* their thread. Like `deleteThread()`, this does not sweep vector-store
|
|
4922
|
+
* embeddings — semantic-recall vectors live in a separate vector store the
|
|
4923
|
+
* memory domain cannot reach; cleaning those up is the operator's concern.
|
|
4924
|
+
*/
|
|
4925
|
+
async prune(policies, options) {
|
|
4926
|
+
const targets = resolveTargets({
|
|
4927
|
+
policies,
|
|
4928
|
+
descriptor: _MemoryStorageMongoDB.retentionTables,
|
|
4929
|
+
order: ["messages", "resources", "threads"]
|
|
4930
|
+
});
|
|
4931
|
+
return runPrune({ connector: this.#connector, domain: "memory", targets, options, logger: this.logger });
|
|
4932
|
+
}
|
|
4707
4933
|
/**
|
|
4708
4934
|
* Returns default index definitions for the memory domain collections.
|
|
4709
4935
|
*/
|
|
@@ -6657,6 +6883,10 @@ var NotificationsMongoDB = class _NotificationsMongoDB extends NotificationsStor
|
|
|
6657
6883
|
#skipDefaultIndexes;
|
|
6658
6884
|
#indexes;
|
|
6659
6885
|
static MANAGED_COLLECTIONS = [TABLE_NOTIFICATIONS];
|
|
6886
|
+
/** Anchor is the notification's creation time, stored as a BSON date. */
|
|
6887
|
+
static retentionTables = {
|
|
6888
|
+
notifications: { table: TABLE_NOTIFICATIONS, column: "createdAt", indexed: true }
|
|
6889
|
+
};
|
|
6660
6890
|
constructor(config) {
|
|
6661
6891
|
super();
|
|
6662
6892
|
this.#connector = resolveMongoDBConfig(config);
|
|
@@ -6668,6 +6898,15 @@ var NotificationsMongoDB = class _NotificationsMongoDB extends NotificationsStor
|
|
|
6668
6898
|
async getCollection() {
|
|
6669
6899
|
return this.#connector.getCollection(TABLE_NOTIFICATIONS);
|
|
6670
6900
|
}
|
|
6901
|
+
/** Delete notifications older than the policy's `maxAge`, batched. */
|
|
6902
|
+
async prune(policies, options) {
|
|
6903
|
+
const targets = resolveTargets({
|
|
6904
|
+
policies,
|
|
6905
|
+
descriptor: _NotificationsMongoDB.retentionTables,
|
|
6906
|
+
order: ["notifications"]
|
|
6907
|
+
});
|
|
6908
|
+
return runPrune({ connector: this.#connector, domain: "notifications", targets, options, logger: this.logger });
|
|
6909
|
+
}
|
|
6671
6910
|
async init() {
|
|
6672
6911
|
await this.createDefaultIndexes();
|
|
6673
6912
|
await this.createCustomIndexes();
|
|
@@ -6860,6 +7099,10 @@ var ObservabilityMongoDB = class _ObservabilityMongoDB extends ObservabilityStor
|
|
|
6860
7099
|
#indexes;
|
|
6861
7100
|
/** Collections managed by this domain */
|
|
6862
7101
|
static MANAGED_COLLECTIONS = [TABLE_SPANS];
|
|
7102
|
+
/** Anchor is the span's start time, stored as a BSON date. */
|
|
7103
|
+
static retentionTables = {
|
|
7104
|
+
spans: { table: TABLE_SPANS, column: "startedAt", indexed: true }
|
|
7105
|
+
};
|
|
6863
7106
|
constructor(config) {
|
|
6864
7107
|
super();
|
|
6865
7108
|
this.#connector = resolveMongoDBConfig(config);
|
|
@@ -6871,6 +7114,15 @@ var ObservabilityMongoDB = class _ObservabilityMongoDB extends ObservabilityStor
|
|
|
6871
7114
|
async getCollection(name) {
|
|
6872
7115
|
return this.#connector.getCollection(name);
|
|
6873
7116
|
}
|
|
7117
|
+
/** Delete spans older than the `spans` policy's `maxAge`, batched. */
|
|
7118
|
+
async prune(policies, options) {
|
|
7119
|
+
const targets = resolveTargets({
|
|
7120
|
+
policies,
|
|
7121
|
+
descriptor: _ObservabilityMongoDB.retentionTables,
|
|
7122
|
+
order: ["spans"]
|
|
7123
|
+
});
|
|
7124
|
+
return runPrune({ connector: this.#connector, domain: "observability", targets, options, logger: this.logger });
|
|
7125
|
+
}
|
|
6874
7126
|
/**
|
|
6875
7127
|
* Returns default index definitions for the observability domain collections.
|
|
6876
7128
|
* These indexes optimize common query patterns for span and trace lookups.
|
|
@@ -8285,6 +8537,16 @@ var SchedulesMongoDB = class _SchedulesMongoDB extends SchedulesStorage {
|
|
|
8285
8537
|
#skipDefaultIndexes;
|
|
8286
8538
|
#indexes;
|
|
8287
8539
|
static MANAGED_COLLECTIONS = [TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS];
|
|
8540
|
+
/**
|
|
8541
|
+
* Only trigger (fire-history) rows are retention-eligible — schedule
|
|
8542
|
+
* definitions are config, not growth. Anchor `actual_fire_at` is stored as a
|
|
8543
|
+
* raw epoch-ms number, so `anchorType: 'epoch-ms'` keeps the cutoff numeric.
|
|
8544
|
+
* The default composite index `(schedule_id, actual_fire_at)` can't serve a
|
|
8545
|
+
* bare `actual_fire_at` range scan, hence the lazy single-field anchor index.
|
|
8546
|
+
*/
|
|
8547
|
+
static retentionTables = {
|
|
8548
|
+
triggers: { table: TABLE_SCHEDULE_TRIGGERS, column: "actual_fire_at", anchorType: "epoch-ms", indexed: true }
|
|
8549
|
+
};
|
|
8288
8550
|
constructor(config) {
|
|
8289
8551
|
super();
|
|
8290
8552
|
this.#connector = resolveMongoDBConfig(config);
|
|
@@ -8299,6 +8561,15 @@ var SchedulesMongoDB = class _SchedulesMongoDB extends SchedulesStorage {
|
|
|
8299
8561
|
getTriggersCollection() {
|
|
8300
8562
|
return this.#connector.getCollection(TABLE_SCHEDULE_TRIGGERS);
|
|
8301
8563
|
}
|
|
8564
|
+
/** Delete trigger (fire-history) rows older than the `triggers` policy's `maxAge`, batched. */
|
|
8565
|
+
async prune(policies, options) {
|
|
8566
|
+
const targets = resolveTargets({
|
|
8567
|
+
policies,
|
|
8568
|
+
descriptor: _SchedulesMongoDB.retentionTables,
|
|
8569
|
+
order: ["triggers"]
|
|
8570
|
+
});
|
|
8571
|
+
return runPrune({ connector: this.#connector, domain: "schedules", targets, options, logger: this.logger });
|
|
8572
|
+
}
|
|
8302
8573
|
getDefaultIndexDefinitions() {
|
|
8303
8574
|
return [
|
|
8304
8575
|
{ collection: TABLE_SCHEDULES, keys: { id: 1 }, options: { unique: true } },
|
|
@@ -9002,6 +9273,10 @@ var ScoresStorageMongoDB = class _ScoresStorageMongoDB extends ScoresStorage {
|
|
|
9002
9273
|
#indexes;
|
|
9003
9274
|
/** Collections managed by this domain */
|
|
9004
9275
|
static MANAGED_COLLECTIONS = [TABLE_SCORERS];
|
|
9276
|
+
/** Anchor is the score row's creation time, stored as a BSON date. */
|
|
9277
|
+
static retentionTables = {
|
|
9278
|
+
scorers: { table: TABLE_SCORERS, column: "createdAt", indexed: true }
|
|
9279
|
+
};
|
|
9005
9280
|
constructor(config) {
|
|
9006
9281
|
super();
|
|
9007
9282
|
this.#connector = resolveMongoDBConfig(config);
|
|
@@ -9013,6 +9288,15 @@ var ScoresStorageMongoDB = class _ScoresStorageMongoDB extends ScoresStorage {
|
|
|
9013
9288
|
async getCollection(name) {
|
|
9014
9289
|
return this.#connector.getCollection(name);
|
|
9015
9290
|
}
|
|
9291
|
+
/** Delete scorer results older than the `scorers` policy's `maxAge`, batched. */
|
|
9292
|
+
async prune(policies, options) {
|
|
9293
|
+
const targets = resolveTargets({
|
|
9294
|
+
policies,
|
|
9295
|
+
descriptor: _ScoresStorageMongoDB.retentionTables,
|
|
9296
|
+
order: ["scorers"]
|
|
9297
|
+
});
|
|
9298
|
+
return runPrune({ connector: this.#connector, domain: "scores", targets, options, logger: this.logger });
|
|
9299
|
+
}
|
|
9016
9300
|
/**
|
|
9017
9301
|
* Returns default index definitions for the scores domain collections.
|
|
9018
9302
|
* These indexes optimize common query patterns for score lookups.
|
|
@@ -9980,6 +10264,13 @@ var WorkflowsStorageMongoDB = class _WorkflowsStorageMongoDB extends WorkflowsSt
|
|
|
9980
10264
|
#indexes;
|
|
9981
10265
|
/** Collections managed by this domain */
|
|
9982
10266
|
static MANAGED_COLLECTIONS = [TABLE_WORKFLOW_SNAPSHOT];
|
|
10267
|
+
/**
|
|
10268
|
+
* Anchor is `updatedAt` (BSON date), so the policy reads as inactivity:
|
|
10269
|
+
* a run is pruned only after its snapshot has not been touched for `maxAge`.
|
|
10270
|
+
*/
|
|
10271
|
+
static retentionTables = {
|
|
10272
|
+
workflowSnapshot: { table: TABLE_WORKFLOW_SNAPSHOT, column: "updatedAt", indexed: true }
|
|
10273
|
+
};
|
|
9983
10274
|
constructor(config) {
|
|
9984
10275
|
super();
|
|
9985
10276
|
this.#connector = resolveMongoDBConfig(config);
|
|
@@ -9988,6 +10279,15 @@ var WorkflowsStorageMongoDB = class _WorkflowsStorageMongoDB extends WorkflowsSt
|
|
|
9988
10279
|
(idx) => _WorkflowsStorageMongoDB.MANAGED_COLLECTIONS.includes(idx.collection)
|
|
9989
10280
|
);
|
|
9990
10281
|
}
|
|
10282
|
+
/** Delete workflow snapshots idle for longer than the policy's `maxAge`, batched. */
|
|
10283
|
+
async prune(policies, options) {
|
|
10284
|
+
const targets = resolveTargets({
|
|
10285
|
+
policies,
|
|
10286
|
+
descriptor: _WorkflowsStorageMongoDB.retentionTables,
|
|
10287
|
+
order: ["workflowSnapshot"]
|
|
10288
|
+
});
|
|
10289
|
+
return runPrune({ connector: this.#connector, domain: "workflows", targets, options, logger: this.logger });
|
|
10290
|
+
}
|
|
9991
10291
|
supportsConcurrentUpdates() {
|
|
9992
10292
|
return true;
|
|
9993
10293
|
}
|
|
@@ -10995,7 +11295,7 @@ var MongoDBStore = class extends MastraCompositeStore {
|
|
|
10995
11295
|
#connector;
|
|
10996
11296
|
stores;
|
|
10997
11297
|
constructor(config) {
|
|
10998
|
-
super({ id: config.id, name: "MongoDBStore", disableInit: config.disableInit });
|
|
11298
|
+
super({ id: config.id, name: "MongoDBStore", disableInit: config.disableInit, retention: config.retention });
|
|
10999
11299
|
this.#connector = resolveMongoDBConfig(config);
|
|
11000
11300
|
const domainConfig = {
|
|
11001
11301
|
connector: this.#connector,
|