@mastra/mongodb 1.16.0-alpha.0 → 1.16.0-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/CHANGELOG.md +69 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-vectors-mongodb.md +13 -13
- package/dist/index.cjs +145 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +146 -5
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/workflow-definitions/index.d.ts +20 -0
- package/dist/storage/domains/workflow-definitions/index.d.ts.map +1 -0
- package/dist/storage/index.d.ts +2 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,74 @@
|
|
|
1
1
|
# @mastra/mongodb
|
|
2
2
|
|
|
3
|
+
## 1.16.0-alpha.2
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Stored workflow definitions now persist across restarts on every major database backend. ([#20471](https://github.com/mastra-ai/mastra/pull/20471))
|
|
8
|
+
|
|
9
|
+
Implement the `workflowDefinitions` storage domain for libsql, pg, mysql, mssql, mongodb, and spanner. Previously the stored-workflow persistence path (`POST /stored/workflows`, `Mastra.addStoredWorkflow`) only worked against `@mastra/core`'s in-memory store. Persistent adapters returned `undefined` from `storage.getStore('workflowDefinitions')` and threw when the HTTP handler tried to read/write a workflow.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
const workflowDefinitions = await storage.getStore('workflowDefinitions');
|
|
13
|
+
if (!workflowDefinitions) {
|
|
14
|
+
throw new Error('This storage adapter does not support the workflowDefinitions domain');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
await workflowDefinitions.upsert({
|
|
18
|
+
id: 'greeting-workflow',
|
|
19
|
+
inputSchema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },
|
|
20
|
+
outputSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'] },
|
|
21
|
+
graph: [{ type: 'agent', id: 'greet', agentId: 'greeter-agent' }],
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const { definitions, total } = await workflowDefinitions.list({ status: 'active' });
|
|
25
|
+
const definition = await workflowDefinitions.get('greeting-workflow');
|
|
26
|
+
await workflowDefinitions.delete('greeting-workflow');
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Each adapter now ships a `WorkflowDefinitions*` domain that:
|
|
30
|
+
|
|
31
|
+
- Creates the shared `mastra_workflow_definitions` table (or Mongo collection) from `WORKFLOW_DEFINITIONS_SCHEMA` during `init()`, plus a default index on `status`.
|
|
32
|
+
- Implements `upsert` / `get` / `list` / `delete` matching `WorkflowDefinitionsStorage` semantics (`list` supports `status` and `authorId` filters and orders by `updatedAt` desc). Partial upserts preserve unspecified fields, including `authorId` updates and `createdAt` / `updatedAt` semantics.
|
|
33
|
+
- Handles concurrent first-writes race-safely: if two callers upsert the same new id simultaneously, the losing insert detects the duplicate key, re-reads the row, and applies the partial-update path instead of failing.
|
|
34
|
+
- Round-trips the JSON columns (`inputSchema`, `outputSchema`, `stateSchema`, `requestContextSchema`, `metadata`, `graph`) through each adapter's JSON handling, so declarative workflow graphs rehydrate identically no matter which backend they were stored in. Malformed persisted JSON surfaces as an actionable error naming the row and column instead of hydrating raw strings.
|
|
35
|
+
|
|
36
|
+
Exported class names by adapter: `WorkflowDefinitionsLibSQL`, `WorkflowDefinitionsPG`, `WorkflowDefinitionsMySQL`, `WorkflowDefinitionsMSSQL`, `MongoDBWorkflowDefinitionsStore`, `WorkflowDefinitionsSpanner`. The composite stores (`LibSQLStore`, `PostgresStore`, `MySQLStore`, `MSSQLStore`, `MongoDBStore`, `SpannerStore`) auto-wire the new domain, so callers do not need to construct it manually — `storage.getStore('workflowDefinitions')` now returns a live handle.
|
|
37
|
+
|
|
38
|
+
The pg adapter reads `createdAt` / `updatedAt` from the auto-added `createdAtZ` / `updatedAtZ` `timestamptz` companion columns to avoid the naive-timestamp / local-TZ drift that a plain `TIMESTAMP` read exhibits under node-pg.
|
|
39
|
+
|
|
40
|
+
`@mastra/clickhouse` and `@mastra/cloudflare` register the new `mastra_workflow_definitions` table in their table/type maps so shared table constants stay exhaustive (no workflow-definitions domain implementation yet).
|
|
41
|
+
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- Updated dependencies [[`4844167`](https://github.com/mastra-ai/mastra/commit/4844167cff2d5ec5004e94edd34970833040fa3f), [`5faf93f`](https://github.com/mastra-ai/mastra/commit/5faf93f03e19daea394b9e2a923f2e4f833407f2), [`80ad891`](https://github.com/mastra-ai/mastra/commit/80ad891f8cd10379aa5b5af7510c763783b2ab56), [`a1cb98d`](https://github.com/mastra-ai/mastra/commit/a1cb98d11990b560b98482292a1f34aa1a2d9092), [`598ad82`](https://github.com/mastra-ai/mastra/commit/598ad82d41c41389a686338a1d0e50b7400e1938), [`1fd6aad`](https://github.com/mastra-ai/mastra/commit/1fd6aad1ea4a9d32f65efa832307c35e981a4c0a)]:
|
|
45
|
+
- @mastra/core@1.56.0-alpha.4
|
|
46
|
+
|
|
47
|
+
## 1.16.0-alpha.1
|
|
48
|
+
|
|
49
|
+
### Patch Changes
|
|
50
|
+
|
|
51
|
+
- When MongoDB storage initialization fails because an existing non-unique index conflicts with Mastra's required unique index, the error now includes step-by-step migration commands instead of a generic failure message. ([#20486](https://github.com/mastra-ai/mastra/pull/20486))
|
|
52
|
+
|
|
53
|
+
**Before:** `Failed to create default index on collection "mastra_threads". Set skipDefaultIndexes to manage indexes yourself.`
|
|
54
|
+
|
|
55
|
+
**After:**
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
Index conflict on collection "mastra_threads": an existing non-unique index on { id: 1 }
|
|
59
|
+
conflicts with Mastra's required unique index.
|
|
60
|
+
|
|
61
|
+
To migrate:
|
|
62
|
+
1. Check for duplicates: db.mastra_threads.aggregate([{ $group: { _id: "$id", n: { $sum: 1 } } }, { $match: { n: { $gt: 1 } } }])
|
|
63
|
+
2. Drop the old index: db.mastra_threads.dropIndex("id_1")
|
|
64
|
+
3. Recreate as unique: db.mastra_threads.createIndex({ id: 1 }, { unique: true })
|
|
65
|
+
|
|
66
|
+
Alternatively, set skipDefaultIndexes: true to manage indexes yourself.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- Updated dependencies [[`594f7b2`](https://github.com/mastra-ai/mastra/commit/594f7b28f5263fb9982fd50d95c471fb971ea984), [`311f943`](https://github.com/mastra-ai/mastra/commit/311f943bee60e8fdf5c84499ea50e884276c936c), [`0c89896`](https://github.com/mastra-ai/mastra/commit/0c8989673fb7d106837098398131e570c6023b68), [`23b4238`](https://github.com/mastra-ai/mastra/commit/23b423844ad0bcf2a502a68dd62866d6160f9f6d), [`e320a76`](https://github.com/mastra-ai/mastra/commit/e320a763feaf65c6be3cebecf746defcbde161b3), [`03b4918`](https://github.com/mastra-ai/mastra/commit/03b4918c80d188ce375334c393e131c6e94bd7eb), [`14ef73a`](https://github.com/mastra-ai/mastra/commit/14ef73a4bbd73e7808414816eb0628ce1d80b5d7), [`1d677d5`](https://github.com/mastra-ai/mastra/commit/1d677d5f99d7db403f7828585e8c25f299f72628), [`93e28ec`](https://github.com/mastra-ai/mastra/commit/93e28ecce9031c02397e0ae8406593e5c7a95883), [`729dab4`](https://github.com/mastra-ai/mastra/commit/729dab408faccfaef0cbb048e5a4338f9172847e), [`484003d`](https://github.com/mastra-ai/mastra/commit/484003d33ff59330c86b19863e4a38732d7e4155), [`933d291`](https://github.com/mastra-ai/mastra/commit/933d291146b789c19442ad206f94da3e4be90c64)]:
|
|
70
|
+
- @mastra/core@1.56.0-alpha.3
|
|
71
|
+
|
|
3
72
|
## 1.16.0-alpha.0
|
|
4
73
|
|
|
5
74
|
### Minor Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: mastra-mongodb
|
|
|
3
3
|
description: Documentation for @mastra/mongodb. Use when working with @mastra/mongodb APIs, configuration, or implementation.
|
|
4
4
|
metadata:
|
|
5
5
|
package: "@mastra/mongodb"
|
|
6
|
-
version: "1.16.0-alpha.
|
|
6
|
+
version: "1.16.0-alpha.2"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## When to use
|
|
@@ -109,7 +109,7 @@ Waits for an index to become ready after creation. Useful when you need to ensur
|
|
|
109
109
|
|
|
110
110
|
### `upsert()`
|
|
111
111
|
|
|
112
|
-
Adds or updates vectors and their metadata in the collection. On a bring-your-own index this requires `allowWrites: true` at `createIndex()` time
|
|
112
|
+
Adds or updates vectors and their metadata in the collection. On a bring-your-own index, this requires `allowWrites: true` at `createIndex()` time because BYO collections are read-only by default.
|
|
113
113
|
|
|
114
114
|
**indexName** (`string`): Name of the collection to insert into
|
|
115
115
|
|
|
@@ -148,12 +148,12 @@ Provisions an Atlas Search (BM25/full-text) index on the collection backing an i
|
|
|
148
148
|
**Managed vs. bring-your-own collections:**
|
|
149
149
|
|
|
150
150
|
- For a **managed** index (created without `collectionName`), `createIndex()` already provisions a _dynamic_ full-text index named `${collectionName}_search_index` (covering all string fields). `createSearchIndex()` is therefore only needed when you want a **field-restricted** mapping or a **custom index name**.
|
|
151
|
-
- For a **bring-your-own** index (created with `collectionName`), `createIndex()`
|
|
151
|
+
- For a **bring-your-own** index (created with `collectionName`), `createIndex()` doesn't auto-create any full-text index. Enabling `textQuery()`/`hybridQuery()` on a caller-owned operational collection is opt-in. Call `createSearchIndex()` explicitly to provision the (billable) text index. Until you do, `textQuery()`/`hybridQuery()` throw a clear error rather than querying a non-existent index.
|
|
152
152
|
|
|
153
153
|
Naming:
|
|
154
154
|
|
|
155
|
-
- When `fields` is provided **without** an explicit `searchIndexName`, the field-mapped index is created under a **distinct** default name (`${collectionName}_${indexName}_search_fields_index`, unique per logical index) so it
|
|
156
|
-
- When `searchIndexName` is provided, that exact name is used and persisted. `textQuery()`/`hybridQuery()` resolve the persisted name automatically
|
|
155
|
+
- When `fields` is provided **without** an explicit `searchIndexName`, the field-mapped index is created under a **distinct** default name (`${collectionName}_${indexName}_search_fields_index`, unique per logical index) so it doesn't collide with a managed collection's auto-created dynamic index and get silently ignored. This distinct index is persisted as the text-search index, so `textQuery()`/`hybridQuery()` use the restricted mapping automatically.
|
|
156
|
+
- When `searchIndexName` is provided, that exact name is used and persisted. `textQuery()`/`hybridQuery()` resolve the persisted name automatically. You can also override the name per call via their `searchIndexName` / `textSearchIndexName` parameters.
|
|
157
157
|
|
|
158
158
|
**indexName** (`string`): Name of the Mastra index whose collection will have the search index
|
|
159
159
|
|
|
@@ -170,7 +170,7 @@ await store.createSearchIndex({
|
|
|
170
170
|
})
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
-
|
|
173
|
+
The field-mapped index name includes the logical `indexName`, so two logical indexes on the same collection get distinct text indexes. Recreating the _same_ logical index with different `fields` still requires dropping the existing index first (`IndexAlreadyExists`).
|
|
174
174
|
|
|
175
175
|
### `waitForSearchIndexReady()`
|
|
176
176
|
|
|
@@ -193,7 +193,7 @@ await store.waitForSearchIndexReady({ indexName: 'precedents' })
|
|
|
193
193
|
|
|
194
194
|
Runs a full-text (BM25) search against an Atlas Search index. By default it targets the text-search index recorded for this index (set by `createSearchIndex()`, or the dynamic `${collectionName}_search_index` auto-created by `createIndex()`). Pass `searchIndexName` to target a specific index for this call.
|
|
195
195
|
|
|
196
|
-
|
|
196
|
+
Metadata filters here (like `hybridQuery()`) are applied via a `$match` stage. For the vector branch of `hybridQuery()`, filters on fields not declared via `filterFields` at index creation are transparently materialised as candidate `_id`s (the same fallback `query()` uses), so undeclared-field filters don't error.
|
|
197
197
|
|
|
198
198
|
**indexName** (`string`): Name of the Mastra index to search
|
|
199
199
|
|
|
@@ -220,7 +220,7 @@ const results = await store.textQuery({
|
|
|
220
220
|
|
|
221
221
|
### `hybridQuery()`
|
|
222
222
|
|
|
223
|
-
Runs a hybrid search that fuses vector similarity and full-text results using MongoDB's server-side `$rankFusion
|
|
223
|
+
Runs a hybrid search that fuses vector similarity and full-text results using MongoDB's server-side `$rankFusion`. It requires MongoDB >= 8.0 and is generally available from 8.1. On 8.0.x, it may need a MongoDB support case to enable, and it runs where enabled, such as Atlas 8.0.x. A full-text search index must exist: it's auto-created for managed indexes, but for a bring-your-own collection you must call `createSearchIndex()` first (opt-in).
|
|
224
224
|
|
|
225
225
|
**indexName** (`string`): Name of the Mastra index to search
|
|
226
226
|
|
|
@@ -253,7 +253,7 @@ const results = await store.hybridQuery({
|
|
|
253
253
|
})
|
|
254
254
|
```
|
|
255
255
|
|
|
256
|
-
|
|
256
|
+
`hybridQuery()` requires MongoDB >= 8.0 for the `$rankFusion` stage. The stage is generally available from 8.1. On 8.0.x, it may need a MongoDB support case to enable and runs where enabled, such as Atlas 8.0.x. If you're running an older version, or `$rankFusion` isn't enabled on your 8.0.x deployment, use `query()` and `textQuery()` separately and merge the results client-side.
|
|
257
257
|
|
|
258
258
|
### `describeIndex()`
|
|
259
259
|
|
|
@@ -276,15 +276,15 @@ interface IndexStats {
|
|
|
276
276
|
Deletes a vector index. Behavior depends on how the index was created:
|
|
277
277
|
|
|
278
278
|
- **Managed index** (created without `collectionName`): drops the entire collection and all its data.
|
|
279
|
-
- **Bring-your-own index** (created with `collectionName`): drops the Atlas vectorSearch index
|
|
279
|
+
- **Bring-your-own index** (created with `collectionName`): drops the Atlas vectorSearch index and, if one was provisioned via `createSearchIndex()`, the companion full-text search index. The caller's operational collection and its documents are preserved. This store never drops a collection it didn't create.
|
|
280
280
|
|
|
281
|
-
The BYO classification is recorded durably when the index is created, so it
|
|
281
|
+
The BYO classification is recorded durably when the index is created, so it's applied correctly even by a different process (e.g. an index created by a setup job and later deleted by a long-lived service). Always pass the **logical index name** (the `indexName` used at `createIndex`), not the physical collection name.
|
|
282
282
|
|
|
283
283
|
**indexName** (`string`): Logical name of the index to delete
|
|
284
284
|
|
|
285
285
|
### `listIndexes()`
|
|
286
286
|
|
|
287
|
-
Lists the **logical** Mastra index names (the `indexName` values passed to `createIndex`), not physical collection names. For a bring-your-own index whose data lives in an operational collection, the logical index name is returned
|
|
287
|
+
Lists the **logical** Mastra index names (the `indexName` values passed to `createIndex`), not physical collection names. For a bring-your-own index whose data lives in an operational collection, the logical index name is returned instead of the physical collection name. The value can be passed straight back into `deleteIndex()` / `describeIndex()`. Managed indexes created before durable metadata was introduced are still discovered via their `${name}_vector_index` search index. The internal registry collection is never listed.
|
|
288
288
|
|
|
289
289
|
Returns: `Promise<string[]>`
|
|
290
290
|
|
|
@@ -408,12 +408,12 @@ await store.createSearchIndex({ indexName: 'precedents', fields: ['note'] })
|
|
|
408
408
|
|
|
409
409
|
- The collection must already exist and contain documents with an `embedding` field (or the custom `embeddingFieldPath` you configured)
|
|
410
410
|
- The collection is never created or dropped when using `collectionName`
|
|
411
|
-
- **A BYO index is read-only by default.** `upsert()`, `updateVector()`, `deleteVector()`, and `deleteVectors()` throw a clear error rather than mutating caller-owned operational documents. To let the store write embeddings into (or delete documents from) your collection, opt in explicitly with `createIndex({ ..., allowWrites: true })`. The policy is persisted and survives restarts
|
|
411
|
+
- **A BYO index is read-only by default.** `upsert()`, `updateVector()`, `deleteVector()`, and `deleteVectors()` throw a clear error rather than mutating caller-owned operational documents. To let the store write embeddings into (or delete documents from) your collection, opt in explicitly with `createIndex({ ..., allowWrites: true })`. The policy is persisted and survives restarts. Entries written by older versions without the flag are treated as read-only (fail closed).
|
|
412
412
|
- Use `metadataMode: 'document'` when querying to retrieve the full source document as `metadata`
|
|
413
413
|
- In `'document'` mode the embedding is omitted from `metadata` by default; pass `includeVector: true` to retain it (and also expose it as a top-level `vector`)
|
|
414
414
|
- **Filtering in `'document'` mode operates on root document fields**, not a nested `metadata.` subdocument. `filter: { lane: 'fraud' }` matches the top-level `lane` field of your operational documents (in the default `'field'` mode, bare fields are rewritten to `metadata.<field>` for managed collections). Both the pushdown and `$match` fallback paths honor this.
|
|
415
415
|
- **Native `ObjectId` `_id`s are supported.** Operational collections commonly key on `ObjectId`; query results coerce `_id` to a string (the `QueryResult.id` contract), and `deleteVector()`/`updateVector()`/`deleteVectors()` accept that string and match the underlying `ObjectId` document. Managed collections (string `_id`s) are unaffected.
|
|
416
|
-
- Full-text and hybrid search on a BYO collection are **opt-in**: no full-text index is auto-created, so call `createSearchIndex()` before `textQuery()`/`hybridQuery()`. The full-text index builds asynchronously
|
|
416
|
+
- Full-text and hybrid search on a BYO collection are **opt-in**: no full-text index is auto-created, so call `createSearchIndex()` before `textQuery()`/`hybridQuery()`. The full-text index builds asynchronously. Call `waitForSearchIndexReady()` (or pass `waitUntilReady: true`) before an immediate text/hybrid query.
|
|
417
417
|
- `deleteIndex()` on a BYO index drops the vector index (and the text index if one was created) but **preserves** the collection and its documents
|
|
418
418
|
|
|
419
419
|
## Best practices
|
package/dist/index.cjs
CHANGED
|
@@ -10,7 +10,7 @@ let _mastra_core_agent = require("@mastra/core/agent");
|
|
|
10
10
|
let _mastra_core_evals = require("@mastra/core/evals");
|
|
11
11
|
let _mastra_core_storage_domains_skills = require("@mastra/core/storage/domains/skills");
|
|
12
12
|
//#region package.json
|
|
13
|
-
var version = "1.16.0-alpha.
|
|
13
|
+
var version = "1.16.0-alpha.2";
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/vector/filter.ts
|
|
16
16
|
/**
|
|
@@ -5329,11 +5329,15 @@ var MemoryStorageMongoDB = class MemoryStorageMongoDB extends _mastra_core_stora
|
|
|
5329
5329
|
for (const indexDef of this.getDefaultIndexDefinitions()) try {
|
|
5330
5330
|
await (await this.getCollection(indexDef.collection)).createIndex(indexDef.keys, indexDef.options);
|
|
5331
5331
|
} catch (error) {
|
|
5332
|
+
const isUniqueConflict = error?.code === 85 && indexDef.options?.unique === true;
|
|
5333
|
+
const field = Object.keys(indexDef.keys)[0] ?? "id";
|
|
5334
|
+
const indexName = Object.entries(indexDef.keys).map(([k, v]) => `${k}_${v}`).join("_");
|
|
5335
|
+
const text = isUniqueConflict ? `Index conflict on collection "${indexDef.collection}": an existing non-unique index on { ${field}: 1 } conflicts with Mastra's required unique index.\n\nTo migrate:\n 1. Check for duplicates: db.${indexDef.collection}.aggregate([{ $group: { _id: "$${field}", n: { $sum: 1 } } }, { $match: { n: { $gt: 1 } } }])\n 2. Drop the old index: db.${indexDef.collection}.dropIndex("${indexName}")\n 3. Recreate as unique: db.${indexDef.collection}.createIndex({ ${field}: 1 }, { unique: true })\n\nAlternatively, set skipDefaultIndexes: true to manage indexes yourself.` : `Failed to create default index on collection "${indexDef.collection}". Set skipDefaultIndexes to manage indexes yourself.`;
|
|
5332
5336
|
throw new _mastra_core_error.MastraError({
|
|
5333
5337
|
id: (0, _mastra_core_storage.createStorageErrorId)("MONGODB", "CREATE_DEFAULT_INDEXES", "FAILED"),
|
|
5334
5338
|
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
5335
5339
|
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
5336
|
-
text
|
|
5340
|
+
text,
|
|
5337
5341
|
details: { collection: indexDef.collection }
|
|
5338
5342
|
}, error);
|
|
5339
5343
|
}
|
|
@@ -9932,6 +9936,141 @@ var MongoDBSkillsStorage = class MongoDBSkillsStorage extends _mastra_core_stora
|
|
|
9932
9936
|
}
|
|
9933
9937
|
};
|
|
9934
9938
|
//#endregion
|
|
9939
|
+
//#region src/storage/domains/workflow-definitions/index.ts
|
|
9940
|
+
function docToDefinition(doc) {
|
|
9941
|
+
const def = {
|
|
9942
|
+
id: String(doc.id),
|
|
9943
|
+
inputSchema: doc.inputSchema,
|
|
9944
|
+
outputSchema: doc.outputSchema,
|
|
9945
|
+
graph: doc.graph,
|
|
9946
|
+
status: doc.status,
|
|
9947
|
+
source: doc.source,
|
|
9948
|
+
createdAt: doc.createdAt instanceof Date ? doc.createdAt : new Date(doc.createdAt),
|
|
9949
|
+
updatedAt: doc.updatedAt instanceof Date ? doc.updatedAt : new Date(doc.updatedAt)
|
|
9950
|
+
};
|
|
9951
|
+
if (doc.description != null) def.description = doc.description;
|
|
9952
|
+
if (doc.metadata != null) def.metadata = doc.metadata;
|
|
9953
|
+
if (doc.stateSchema != null) def.stateSchema = doc.stateSchema;
|
|
9954
|
+
if (doc.requestContextSchema != null) def.requestContextSchema = doc.requestContextSchema;
|
|
9955
|
+
if (doc.authorId != null) def.authorId = doc.authorId;
|
|
9956
|
+
return def;
|
|
9957
|
+
}
|
|
9958
|
+
var MongoDBWorkflowDefinitionsStore = class MongoDBWorkflowDefinitionsStore extends _mastra_core_storage.WorkflowDefinitionsStorage {
|
|
9959
|
+
#connector;
|
|
9960
|
+
#skipDefaultIndexes;
|
|
9961
|
+
#indexes;
|
|
9962
|
+
static MANAGED_COLLECTIONS = [_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS];
|
|
9963
|
+
constructor(config) {
|
|
9964
|
+
super();
|
|
9965
|
+
this.#connector = resolveMongoDBConfig(config);
|
|
9966
|
+
this.#skipDefaultIndexes = config.skipDefaultIndexes;
|
|
9967
|
+
this.#indexes = config.indexes?.filter((idx) => MongoDBWorkflowDefinitionsStore.MANAGED_COLLECTIONS.includes(idx.collection));
|
|
9968
|
+
}
|
|
9969
|
+
async getCollection(name) {
|
|
9970
|
+
return this.#connector.getCollection(name);
|
|
9971
|
+
}
|
|
9972
|
+
getDefaultIndexDefinitions() {
|
|
9973
|
+
return [{
|
|
9974
|
+
collection: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
|
|
9975
|
+
keys: { id: 1 },
|
|
9976
|
+
options: { unique: true }
|
|
9977
|
+
}, {
|
|
9978
|
+
collection: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
|
|
9979
|
+
keys: { status: 1 }
|
|
9980
|
+
}];
|
|
9981
|
+
}
|
|
9982
|
+
async createDefaultIndexes() {
|
|
9983
|
+
if (this.#skipDefaultIndexes) return;
|
|
9984
|
+
for (const indexDef of this.getDefaultIndexDefinitions()) try {
|
|
9985
|
+
await (await this.getCollection(indexDef.collection)).createIndex(indexDef.keys, indexDef.options);
|
|
9986
|
+
} catch (error) {
|
|
9987
|
+
this.logger?.warn?.(`Failed to create index on ${indexDef.collection}:`, error);
|
|
9988
|
+
}
|
|
9989
|
+
}
|
|
9990
|
+
async createCustomIndexes() {
|
|
9991
|
+
if (!this.#indexes || this.#indexes.length === 0) return;
|
|
9992
|
+
for (const indexDef of this.#indexes) try {
|
|
9993
|
+
await (await this.getCollection(indexDef.collection)).createIndex(indexDef.keys, indexDef.options);
|
|
9994
|
+
} catch (error) {
|
|
9995
|
+
this.logger?.warn?.(`Failed to create custom index on ${indexDef.collection}:`, error);
|
|
9996
|
+
}
|
|
9997
|
+
}
|
|
9998
|
+
async init() {
|
|
9999
|
+
await this.createDefaultIndexes();
|
|
10000
|
+
await this.createCustomIndexes();
|
|
10001
|
+
}
|
|
10002
|
+
async dangerouslyClearAll() {
|
|
10003
|
+
await (await this.getCollection(_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS)).deleteMany({});
|
|
10004
|
+
}
|
|
10005
|
+
async upsert(input) {
|
|
10006
|
+
const now = /* @__PURE__ */ new Date();
|
|
10007
|
+
const collection = await this.getCollection(_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS);
|
|
10008
|
+
if (!await collection.findOne({ id: input.id })) {
|
|
10009
|
+
if (!("inputSchema" in input) || input.inputSchema === void 0) throw new Error(`Cannot create workflow definition "${input.id}": inputSchema is required.`);
|
|
10010
|
+
if (!("outputSchema" in input) || input.outputSchema === void 0) throw new Error(`Cannot create workflow definition "${input.id}": outputSchema is required.`);
|
|
10011
|
+
if (!("graph" in input) || input.graph === void 0) throw new Error(`Cannot create workflow definition "${input.id}": graph is required.`);
|
|
10012
|
+
const doc = {
|
|
10013
|
+
id: input.id,
|
|
10014
|
+
description: input.description ?? null,
|
|
10015
|
+
metadata: input.metadata ?? null,
|
|
10016
|
+
inputSchema: input.inputSchema,
|
|
10017
|
+
outputSchema: input.outputSchema,
|
|
10018
|
+
stateSchema: input.stateSchema ?? null,
|
|
10019
|
+
requestContextSchema: input.requestContextSchema ?? null,
|
|
10020
|
+
graph: input.graph,
|
|
10021
|
+
status: "active",
|
|
10022
|
+
source: "storage",
|
|
10023
|
+
authorId: "authorId" in input ? input.authorId ?? null : null,
|
|
10024
|
+
createdAt: now,
|
|
10025
|
+
updatedAt: now
|
|
10026
|
+
};
|
|
10027
|
+
try {
|
|
10028
|
+
await collection.insertOne(doc);
|
|
10029
|
+
} catch (error) {
|
|
10030
|
+
if (!(error?.code === 11e3) || !await collection.findOne({ id: input.id })) throw error;
|
|
10031
|
+
return this.applyUpdate(input, now);
|
|
10032
|
+
}
|
|
10033
|
+
return docToDefinition(doc);
|
|
10034
|
+
}
|
|
10035
|
+
return this.applyUpdate(input, now);
|
|
10036
|
+
}
|
|
10037
|
+
async applyUpdate(input, now) {
|
|
10038
|
+
const collection = await this.getCollection(_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS);
|
|
10039
|
+
const update = { updatedAt: now };
|
|
10040
|
+
if ("description" in input && input.description !== void 0) update.description = input.description;
|
|
10041
|
+
if ("metadata" in input && input.metadata !== void 0) update.metadata = input.metadata;
|
|
10042
|
+
if ("inputSchema" in input && input.inputSchema !== void 0) update.inputSchema = input.inputSchema;
|
|
10043
|
+
if ("outputSchema" in input && input.outputSchema !== void 0) update.outputSchema = input.outputSchema;
|
|
10044
|
+
if ("stateSchema" in input && input.stateSchema !== void 0) update.stateSchema = input.stateSchema;
|
|
10045
|
+
if ("requestContextSchema" in input && input.requestContextSchema !== void 0) update.requestContextSchema = input.requestContextSchema;
|
|
10046
|
+
if ("graph" in input && input.graph !== void 0) update.graph = input.graph;
|
|
10047
|
+
if ("status" in input && input.status !== void 0) update.status = input.status;
|
|
10048
|
+
if ("authorId" in input && input.authorId !== void 0) update.authorId = input.authorId;
|
|
10049
|
+
await collection.updateOne({ id: input.id }, { $set: update });
|
|
10050
|
+
const updated = await collection.findOne({ id: input.id });
|
|
10051
|
+
if (!updated) throw new Error(`Failed to update workflow definition "${input.id}".`);
|
|
10052
|
+
return docToDefinition(updated);
|
|
10053
|
+
}
|
|
10054
|
+
async get(id) {
|
|
10055
|
+
const doc = await (await this.getCollection(_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS)).findOne({ id });
|
|
10056
|
+
return doc ? docToDefinition(doc) : null;
|
|
10057
|
+
}
|
|
10058
|
+
async list(args) {
|
|
10059
|
+
const collection = await this.getCollection(_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS);
|
|
10060
|
+
const filter = {};
|
|
10061
|
+
if (args?.status) filter.status = args.status;
|
|
10062
|
+
if (args?.authorId !== void 0) filter.authorId = args.authorId;
|
|
10063
|
+
const definitions = (await collection.find(filter).sort({ updatedAt: -1 }).toArray()).map(docToDefinition);
|
|
10064
|
+
return {
|
|
10065
|
+
definitions,
|
|
10066
|
+
total: definitions.length
|
|
10067
|
+
};
|
|
10068
|
+
}
|
|
10069
|
+
async delete(id) {
|
|
10070
|
+
await (await this.getCollection(_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS)).deleteOne({ id });
|
|
10071
|
+
}
|
|
10072
|
+
};
|
|
10073
|
+
//#endregion
|
|
9935
10074
|
//#region src/storage/domains/workflows/index.ts
|
|
9936
10075
|
var WorkflowsStorageMongoDB = class WorkflowsStorageMongoDB extends _mastra_core_storage.WorkflowsStorage {
|
|
9937
10076
|
#connector;
|
|
@@ -10820,6 +10959,7 @@ var MongoDBStore = class extends _mastra_core_storage.MastraCompositeStore {
|
|
|
10820
10959
|
const experiments = new MongoDBExperimentsStorage(domainConfig);
|
|
10821
10960
|
const backgroundTasks = new BackgroundTasksStorageMongoDB(domainConfig);
|
|
10822
10961
|
const schedules = new SchedulesMongoDB(domainConfig);
|
|
10962
|
+
const workflowDefinitions = new MongoDBWorkflowDefinitionsStore(domainConfig);
|
|
10823
10963
|
this.stores = {
|
|
10824
10964
|
memory,
|
|
10825
10965
|
notifications,
|
|
@@ -10837,7 +10977,8 @@ var MongoDBStore = class extends _mastra_core_storage.MastraCompositeStore {
|
|
|
10837
10977
|
backgroundTasks,
|
|
10838
10978
|
datasets,
|
|
10839
10979
|
experiments,
|
|
10840
|
-
schedules
|
|
10980
|
+
schedules,
|
|
10981
|
+
workflowDefinitions
|
|
10841
10982
|
};
|
|
10842
10983
|
}
|
|
10843
10984
|
/**
|
|
@@ -10971,6 +11112,7 @@ exports.MongoDBScorerDefinitionsStorage = MongoDBScorerDefinitionsStorage;
|
|
|
10971
11112
|
exports.MongoDBSkillsStorage = MongoDBSkillsStorage;
|
|
10972
11113
|
exports.MongoDBStore = MongoDBStore;
|
|
10973
11114
|
exports.MongoDBVector = MongoDBVector;
|
|
11115
|
+
exports.MongoDBWorkflowDefinitionsStore = MongoDBWorkflowDefinitionsStore;
|
|
10974
11116
|
exports.MongoDBWorkspacesStorage = MongoDBWorkspacesStorage;
|
|
10975
11117
|
exports.NotificationsMongoDB = NotificationsMongoDB;
|
|
10976
11118
|
exports.ObservabilityMongoDB = ObservabilityMongoDB;
|