@mastra/mongodb 1.22.1-alpha.0 → 1.23.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/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { v4 } from "@lukeed/uuid";
2
2
  import { ErrorCategory, ErrorDomain, MastraError } from "@mastra/core/error";
3
- import { AgentsStorage, BackgroundTasksStorage, BlobStore, DatasetsStorage, ExperimentsStorage, KnowledgeConflictError, KnowledgeNotFoundError, KnowledgeStorage, MCPClientsStorage, MCPServersStorage, MastraCompositeStore, MemoryStorage, NotificationsStorage, ObservabilityStorage, PromptBlocksStorage, SchedulesStorage, ScorerDefinitionsStorage, ScoresStorage, SkillsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_BACKGROUND_TASKS, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, TABLE_KNOWLEDGE_ACTIVITY, TABLE_KNOWLEDGE_CURSORS, TABLE_KNOWLEDGE_MENTIONS, TABLE_KNOWLEDGE_NODES, TABLE_KNOWLEDGE_RECORDS, TABLE_KNOWLEDGE_SEMANTIC_OUTBOX, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, TABLE_MESSAGES, TABLE_NOTIFICATIONS, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCORERS, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SKILLS, TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SPANS, TABLE_THREADS, TABLE_WORKFLOW_DEFINITIONS, TABLE_WORKFLOW_SNAPSHOT, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, TraceStatus, WorkflowDefinitionsStorage, WorkflowsStorage, WorkspacesStorage, assertKnowledgeCeilingRaised, assertKnowledgeScopeWithinCeiling, calculatePagination, canonicalizeKnowledgeScope, createKnowledgeUlid, createStorageErrorId, createVectorErrorId, ensureDate, hasErrorCode, isKnowledgeScopeVisible, knowledgeScopeKey, knowledgeSemanticDocumentId, knowledgeSemanticIdempotencyKey, listTracesArgsSchema, normalizePerPage, normalizeScheduleTarget, parseDuration, parseKnowledgeNodeCursor, parseKnowledgeWikilinks, resolveListOrderBy, safelyParseJSON, storageMessageMatchesMetadataFilter, toTraceSpans, transformScoreRow, validateStorageMetadataFilter } from "@mastra/core/storage";
3
+ import { AgentsStorage, BackgroundTasksStorage, BlobStore, DatasetsStorage, ExperimentsStorage, KnowledgeConflictError, KnowledgeNotFoundError, KnowledgeStorage, MCPClientsStorage, MCPServersStorage, MastraCompositeStore, MemoryStorage, NotificationsStorage, ObservabilityStorage, PromptBlocksStorage, SchedulesStorage, ScorerDefinitionsStorage, ScoresStorage, SkillsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_BACKGROUND_TASKS, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, TABLE_KNOWLEDGE_ACTIVITY, TABLE_KNOWLEDGE_MENTIONS, TABLE_KNOWLEDGE_NODES, TABLE_KNOWLEDGE_RECORDS, TABLE_KNOWLEDGE_SEMANTIC_OUTBOX, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, TABLE_MESSAGES, TABLE_NOTIFICATIONS, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCORERS, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SKILLS, TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SPANS, TABLE_THREADS, TABLE_WORKFLOW_DEFINITIONS, TABLE_WORKFLOW_SNAPSHOT, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, TraceStatus, WorkflowDefinitionsStorage, WorkflowsStorage, WorkspacesStorage, calculatePagination, canonicalizeKnowledgeScope, createKnowledgeUlid, createStorageErrorId, createVectorErrorId, ensureDate, hasErrorCode, isKnowledgeScopeVisible, knowledgeScopeKey, knowledgeSemanticDocumentId, knowledgeSemanticIdempotencyKey, listTracesArgsSchema, normalizePerPage, normalizeScheduleTarget, parseDuration, parseKnowledgeNodeCursor, parseKnowledgeWikilinks, resolveListOrderBy, safelyParseJSON, storageMessageMatchesMetadataFilter, toTraceSpans, transformScoreRow, validateStorageMetadataFilter } from "@mastra/core/storage";
4
4
  import { MastraVector, validateUpsertInput, validateVectorValues } from "@mastra/core/vector";
5
5
  import { MongoBulkWriteError, MongoClient, ObjectId } from "mongodb";
6
6
  import { BaseFilterTranslator } from "@mastra/core/vector/filter";
@@ -8,7 +8,7 @@ import { MessageList } from "@mastra/core/agent";
8
8
  import { saveScorePayloadSchema } from "@mastra/core/evals";
9
9
  import { skillSnapshotFieldValuesEqual } from "@mastra/core/storage/domains/skills";
10
10
  //#region package.json
11
- var version = "1.22.1-alpha.0";
11
+ var version = "1.23.0";
12
12
  //#endregion
13
13
  //#region src/vector/filter.ts
14
14
  /**
@@ -4763,13 +4763,26 @@ async function assertKnowledgeDescriptionWithinBoundCompat(description) {
4763
4763
  }
4764
4764
  assertWithinBound(description);
4765
4765
  }
4766
+ let assertRecordTextWithinBound;
4767
+ async function assertKnowledgeRecordTextWithinBoundCompat(text) {
4768
+ if (!assertRecordTextWithinBound) assertRecordTextWithinBound = (await import("@mastra/core/storage")).assertKnowledgeRecordTextWithinBound ?? ((value) => {
4769
+ if (value.length > 1e3) throw new Error("Knowledge record text exceeds the 1000 UTF-16 code unit limit; split it into separate facts or summarize it");
4770
+ });
4771
+ assertRecordTextWithinBound(text);
4772
+ }
4766
4773
  const cloneScope = (scope) => [...scope];
4767
4774
  const canonicalName = (name) => name.trim().toLocaleLowerCase();
4768
4775
  const nodeReferenceId = (node) => typeof node === "string" ? node : node.id;
4769
4776
  const sessionOptions = (session) => session ? { session } : {};
4770
4777
  function visibleScopeKeys(scope) {
4771
4778
  const canonical = canonicalizeKnowledgeScope(scope);
4772
- return canonical.map((_, index) => knowledgeScopeKey(canonical.slice(0, index + 1)));
4779
+ const subsets = [[]];
4780
+ for (const entry of canonical) subsets.push(...subsets.map((subset) => [...subset, entry]));
4781
+ const keys = /* @__PURE__ */ new Set();
4782
+ for (const subset of subsets.slice(1)) try {
4783
+ keys.add(knowledgeScopeKey(subset));
4784
+ } catch {}
4785
+ return [...keys];
4773
4786
  }
4774
4787
  function recordCursorFilter(cursor, expected) {
4775
4788
  const parsed = parseKnowledgeNodeCursor(cursor, expected);
@@ -4805,7 +4818,6 @@ function recordFromDocument(row) {
4805
4818
  sourceThreadId: String(row.sourceThreadId),
4806
4819
  capturedAt: new Date(row.capturedAt),
4807
4820
  when: row.when ? new Date(row.when) : void 0,
4808
- maxScope: row.maxScope ?? void 0,
4809
4821
  metadata: row.metadata ?? void 0,
4810
4822
  deletedAt: row.deletedAt ? new Date(row.deletedAt) : void 0,
4811
4823
  deletedBy: row.deletedBy ?? void 0
@@ -4828,12 +4840,12 @@ function outboxFromDocument(row) {
4828
4840
  completedAt: row.completedAt ? new Date(row.completedAt) : void 0
4829
4841
  };
4830
4842
  }
4843
+ const KNOWLEDGE_CURATION_CURSOR_REMOVED_MESSAGE = "Knowledge curation cursors were removed: observation-time curate is the only Knowledge writer and needs no cursor.";
4831
4844
  var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
4832
4845
  static MANAGED_COLLECTIONS = [
4833
4846
  TABLE_KNOWLEDGE_NODES,
4834
4847
  TABLE_KNOWLEDGE_RECORDS,
4835
4848
  TABLE_KNOWLEDGE_MENTIONS,
4836
- TABLE_KNOWLEDGE_CURSORS,
4837
4849
  TABLE_KNOWLEDGE_ACTIVITY,
4838
4850
  TABLE_KNOWLEDGE_SEMANTIC_OUTBOX
4839
4851
  ];
@@ -4846,7 +4858,6 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
4846
4858
  const nodes = await this.#collection(TABLE_KNOWLEDGE_NODES);
4847
4859
  const knowledge = await this.#collection(TABLE_KNOWLEDGE_RECORDS);
4848
4860
  const mentions = await this.#collection(TABLE_KNOWLEDGE_MENTIONS);
4849
- const cursors = await this.#collection(TABLE_KNOWLEDGE_CURSORS);
4850
4861
  const activity = await this.#collection(TABLE_KNOWLEDGE_ACTIVITY);
4851
4862
  const outbox = await this.#collection(TABLE_KNOWLEDGE_SEMANTIC_OUTBOX);
4852
4863
  await Promise.all([
@@ -4859,6 +4870,10 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
4859
4870
  scopeKey: 1,
4860
4871
  type: 1
4861
4872
  }),
4873
+ nodes.createIndex({
4874
+ type: 1,
4875
+ canonicalName: 1
4876
+ }),
4862
4877
  knowledge.createIndex({
4863
4878
  node: 1,
4864
4879
  id: -1
@@ -4867,6 +4882,10 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
4867
4882
  sourceThreadId: 1,
4868
4883
  id: -1
4869
4884
  }),
4885
+ knowledge.createIndex({
4886
+ scopeKey: 1,
4887
+ id: -1
4888
+ }),
4870
4889
  mentions.createIndex({
4871
4890
  sourceType: 1,
4872
4891
  sourceId: 1,
@@ -4877,11 +4896,11 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
4877
4896
  sourceType: 1,
4878
4897
  sourceId: 1
4879
4898
  }),
4880
- cursors.createIndex({
4881
- sourceThreadId: 1,
4882
- agent: 1
4883
- }, { unique: true }),
4884
4899
  activity.createIndex({ id: -1 }),
4900
+ activity.createIndex({
4901
+ scopeKey: 1,
4902
+ id: -1
4903
+ }),
4885
4904
  outbox.createIndex({ idempotencyKey: 1 }, { unique: true }),
4886
4905
  outbox.createIndex({
4887
4906
  status: 1,
@@ -4897,6 +4916,11 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
4897
4916
  }
4898
4917
  async createNode(input) {
4899
4918
  await assertKnowledgeDescriptionWithinBoundCompat(input.description);
4919
+ if (input.scopeAddresses?.length) {
4920
+ const error = /* @__PURE__ */ new Error("This Knowledge storage adapter does not expose structural scope placement.");
4921
+ error.name = "KnowledgeUnsupportedCapabilityError";
4922
+ throw error;
4923
+ }
4900
4924
  const scope = canonicalizeKnowledgeScope(input.scope);
4901
4925
  return this.#connector.withTransaction(async (session) => {
4902
4926
  const existing = await this.#getNodeByName(input.name, scope, session);
@@ -5089,9 +5113,9 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
5089
5113
  });
5090
5114
  }
5091
5115
  async appendKnowledge(input) {
5116
+ await assertKnowledgeRecordTextWithinBoundCompat(input.text);
5092
5117
  const scope = canonicalizeKnowledgeScope(input.scope);
5093
5118
  const defaultScope = canonicalizeKnowledgeScope(input.defaultScope);
5094
- assertKnowledgeScopeWithinCeiling(scope, input.maxScope);
5095
5119
  return this.#connector.withTransaction(async (session) => {
5096
5120
  const parent = await this.#resolveTerminalNode(nodeReferenceId(input.node), session);
5097
5121
  if (!parent) throw new KnowledgeNotFoundError("node", nodeReferenceId(input.node));
@@ -5106,14 +5130,12 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
5106
5130
  sourceThreadId: input.sourceThreadId,
5107
5131
  capturedAt: /* @__PURE__ */ new Date(),
5108
5132
  when: input.when,
5109
- maxScope: input.maxScope,
5110
5133
  metadata: input.metadata
5111
5134
  };
5112
5135
  await (await this.#knowledge()).insertOne({
5113
5136
  ...record,
5114
5137
  scopeKey: knowledgeScopeKey(scope),
5115
5138
  when: record.when ?? null,
5116
- maxScope: record.maxScope ?? null,
5117
5139
  deletedAt: null,
5118
5140
  deletedBy: null
5119
5141
  }, sessionOptions(session));
@@ -5198,7 +5220,6 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
5198
5220
  return this.#connector.withTransaction(async (session) => {
5199
5221
  const record = await this.#getKnowledge(input.id, true, session);
5200
5222
  if (!record) throw new KnowledgeNotFoundError("record", input.id);
5201
- assertKnowledgeScopeWithinCeiling(scope, record.maxScope);
5202
5223
  await (await this.#knowledge()).updateOne({ id: input.id }, { $set: {
5203
5224
  scope,
5204
5225
  scopeKey: knowledgeScopeKey(scope)
@@ -5212,17 +5233,6 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
5212
5233
  };
5213
5234
  });
5214
5235
  }
5215
- async raiseKnowledgeCeiling(input) {
5216
- const record = await this.#getKnowledge(input.id, true);
5217
- if (!record) throw new KnowledgeNotFoundError("record", input.id);
5218
- assertKnowledgeScopeWithinCeiling(record.scope, input.maxScope);
5219
- assertKnowledgeCeilingRaised(record.maxScope, input.maxScope);
5220
- await (await this.#knowledge()).updateOne({ id: input.id }, { $set: { maxScope: input.maxScope ?? null } });
5221
- return {
5222
- ...record,
5223
- maxScope: input.maxScope
5224
- };
5225
- }
5226
5236
  async search(input) {
5227
5237
  const scope = canonicalizeKnowledgeScope(input.scope);
5228
5238
  const query = input.query.trim();
@@ -5262,7 +5272,7 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
5262
5272
  results.push({
5263
5273
  type: "record",
5264
5274
  id: record.id,
5265
- recordId: record.node,
5275
+ recordId: parentVisible ? record.node : record.id,
5266
5276
  name: parentVisible ? parent.name : "(private node)",
5267
5277
  text: record.text,
5268
5278
  scope: cloneScope(record.scope)
@@ -5271,36 +5281,19 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
5271
5281
  }
5272
5282
  return results.slice(0, limit);
5273
5283
  }
5274
- async getCurationCursor(input) {
5275
- const row = await (await this.#cursors()).findOne(input);
5276
- return row ? {
5277
- sourceThreadId: row.sourceThreadId,
5278
- agent: row.agent,
5279
- lastKnowledgeId: row.lastKnowledgeId,
5280
- updatedAt: new Date(row.updatedAt)
5281
- } : null;
5282
- }
5283
- async advanceCurationCursor(input) {
5284
- const row = await (await this.#cursors()).findOneAndUpdate({
5285
- sourceThreadId: input.sourceThreadId,
5286
- agent: input.agent
5287
- }, {
5288
- $max: { lastKnowledgeId: input.lastKnowledgeId },
5289
- $set: { updatedAt: /* @__PURE__ */ new Date() },
5290
- $setOnInsert: {
5291
- sourceThreadId: input.sourceThreadId,
5292
- agent: input.agent
5293
- }
5294
- }, {
5295
- upsert: true,
5296
- returnDocument: "after"
5297
- });
5298
- return {
5299
- sourceThreadId: row.sourceThreadId,
5300
- agent: row.agent,
5301
- lastKnowledgeId: row.lastKnowledgeId,
5302
- updatedAt: new Date(row.updatedAt)
5303
- };
5284
+ /**
5285
+ * @deprecated Curation cursors were removed. Observation-time curate is the only Knowledge writer and needs no
5286
+ * cursor. Always throws.
5287
+ */
5288
+ async getCurationCursor(_input) {
5289
+ throw new Error(KNOWLEDGE_CURATION_CURSOR_REMOVED_MESSAGE);
5290
+ }
5291
+ /**
5292
+ * @deprecated Curation cursors were removed. Observation-time curate is the only Knowledge writer and needs no
5293
+ * cursor. Always throws.
5294
+ */
5295
+ async advanceCurationCursor(_input) {
5296
+ throw new Error(KNOWLEDGE_CURATION_CURSOR_REMOVED_MESSAGE);
5304
5297
  }
5305
5298
  async listActivity(input) {
5306
5299
  const scope = canonicalizeKnowledgeScope(input.scope);
@@ -5421,9 +5414,6 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
5421
5414
  #mentions() {
5422
5415
  return this.#collection(TABLE_KNOWLEDGE_MENTIONS);
5423
5416
  }
5424
- #cursors() {
5425
- return this.#collection(TABLE_KNOWLEDGE_CURSORS);
5426
- }
5427
5417
  #activityCollection() {
5428
5418
  return this.#collection(TABLE_KNOWLEDGE_ACTIVITY);
5429
5419
  }
@@ -5446,12 +5436,14 @@ var KnowledgeMongoDB = class KnowledgeMongoDB extends KnowledgeStorage {
5446
5436
  return row ? nodeFromDocument(row) : null;
5447
5437
  }
5448
5438
  async #resolveNode(name, scope, session) {
5449
- for (let length = scope.length; length > 0; length--) {
5450
- const node = await this.#getNodeByName(name, scope.slice(0, length), session);
5451
- if (node) {
5452
- const terminal = await this.#resolveTerminalNode(node.id, session);
5453
- if (terminal && isKnowledgeScopeVisible(terminal.scope, scope)) return terminal;
5454
- }
5439
+ const candidates = (await (await this.#nodes()).find({
5440
+ type: "node",
5441
+ canonicalName: canonicalName(name),
5442
+ $or: [{ scopeKey: { $in: visibleScopeKeys(scope) } }, { mergedInto: { $ne: null } }]
5443
+ }, sessionOptions(session)).toArray()).map(nodeFromDocument).sort((left, right) => right.scope.length - left.scope.length);
5444
+ for (const candidate of candidates) {
5445
+ const terminal = await this.#resolveTerminalNode(candidate.id, session);
5446
+ if (terminal && isKnowledgeScopeVisible(terminal.scope, scope)) return terminal;
5455
5447
  }
5456
5448
  return null;
5457
5449
  }