@mastra/libsql 1.25.2-alpha.1 → 1.26.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/dist/index.cjs CHANGED
@@ -8,6 +8,8 @@ let _mastra_core_vector_filter = require("@mastra/core/vector/filter");
8
8
  let fs_promises = require("fs/promises");
9
9
  let path = require("path");
10
10
  let _mastra_core_base = require("@mastra/core/base");
11
+ let crypto$1 = require("crypto");
12
+ let _mastra_core_features = require("@mastra/core/features");
11
13
  let _mastra_core_agent = require("@mastra/core/agent");
12
14
  let _mastra_core_evals = require("@mastra/core/evals");
13
15
  let _mastra_core_storage_domains_skills = require("@mastra/core/storage/domains/skills");
@@ -1787,7 +1789,7 @@ var LibSQLDB = class extends _mastra_core_base.MastraBase {
1787
1789
  * @param args.tableName - The name of the table to create
1788
1790
  * @param args.schema - The schema definition for the table columns
1789
1791
  */
1790
- async createTable({ tableName, schema, compositePrimaryKey }) {
1792
+ async createTable({ tableName, schema, compositePrimaryKey, executor = this.client }) {
1791
1793
  try {
1792
1794
  const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(tableName, "table name");
1793
1795
  if (compositePrimaryKey) {
@@ -1805,7 +1807,7 @@ var LibSQLDB = class extends _mastra_core_base.MastraBase {
1805
1807
  if (tableName === _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT) tableConstraints.push("UNIQUE (workflow_name, run_id)");
1806
1808
  if (tableName === _mastra_core_storage.TABLE_SPANS) tableConstraints.push("UNIQUE (spanId, traceId)");
1807
1809
  const sql = `CREATE TABLE IF NOT EXISTS ${parsedTableName} (\n ${[...columnDefinitions, ...tableConstraints].join(",\n ")}\n)`;
1808
- await this.client.execute(sql);
1810
+ await executor.execute(sql);
1809
1811
  this.logger.debug(`LibSQLDB: Created table ${tableName}`);
1810
1812
  if (tableName === _mastra_core_storage.TABLE_SPANS) await this.migrateSpansTable();
1811
1813
  } catch (error) {
@@ -6048,20 +6050,678 @@ var HarnessLibSQL = class HarnessLibSQL extends _mastra_core_storage.HarnessStor
6048
6050
  }
6049
6051
  };
6050
6052
  //#endregion
6053
+ //#region ../../packages/_internal-core/dist/knowledge-compat/index.js
6054
+ const KNOWLEDGE_V2_CORE_FEATURE = "knowledge-v2";
6055
+ /** Hard cap on scope nodes returned by one `listScopeNodes` read. */
6056
+ const MAX_KNOWLEDGE_SCOPE_NODES = 1e3;
6057
+ function knowledgeScopeNodeFilterKey(input) {
6058
+ return JSON.stringify([
6059
+ input.withinAddress ?? null,
6060
+ input.addresses ? [...input.addresses].sort() : null,
6061
+ input.ids ? [...input.ids].sort() : null
6062
+ ]);
6063
+ }
6064
+ function createKnowledgeScopeNodeCursor(scope, input) {
6065
+ return encodeURIComponent(JSON.stringify({
6066
+ version: 1,
6067
+ type: "scope",
6068
+ name: scope.name,
6069
+ id: scope.id,
6070
+ filter: knowledgeScopeNodeFilterKey(input)
6071
+ }));
6072
+ }
6073
+ /** Validates the page size and cursor of a `listScopeNodes` query; throws on a cursor from a different query. */
6074
+ function parseListKnowledgeScopeNodesInput(input = {}) {
6075
+ const requested = Number.isFinite(input.limit) ? Math.trunc(input.limit) : MAX_KNOWLEDGE_SCOPE_NODES;
6076
+ const limit = Math.min(Math.max(requested, 1), MAX_KNOWLEDGE_SCOPE_NODES);
6077
+ if (!input.cursor) return {
6078
+ limit,
6079
+ after: null
6080
+ };
6081
+ let value;
6082
+ try {
6083
+ value = JSON.parse(decodeURIComponent(input.cursor));
6084
+ } catch {
6085
+ throw new Error("Invalid Knowledge scope node cursor.");
6086
+ }
6087
+ const parsed = value && typeof value === "object" ? value : {};
6088
+ if (parsed.version !== 1 || parsed.type !== "scope" || typeof parsed.name !== "string" || typeof parsed.id !== "string" || parsed.filter !== knowledgeScopeNodeFilterKey(input)) throw new Error("Knowledge scope node cursor does not match this query.");
6089
+ return {
6090
+ limit,
6091
+ after: {
6092
+ name: parsed.name,
6093
+ id: parsed.id
6094
+ }
6095
+ };
6096
+ }
6097
+ /** Builds a page from up to `limit + 1` name/id-ordered scope nodes. */
6098
+ function pageKnowledgeScopeNodes(rows, limit, input) {
6099
+ const scopes = rows.slice(0, limit);
6100
+ const last = scopes.at(-1);
6101
+ return {
6102
+ scopes,
6103
+ nextCursor: rows.length > limit && last ? createKnowledgeScopeNodeCursor(last, input) : null
6104
+ };
6105
+ }
6106
+ /** Clamps a requested member limit to 1–{@link MAX_KNOWLEDGE_SCOPE_MEMBERS_LIMIT}. */
6107
+ function knowledgeScopeMembersLimit(limit) {
6108
+ if (limit === void 0 || !Number.isFinite(limit)) return 500;
6109
+ return Math.min(Math.max(Math.trunc(limit), 1), 500);
6110
+ }
6111
+ /** Validates the page size and cursor of a `listScopeMembers` query; throws on a cursor from another scope. */
6112
+ function parseListKnowledgeScopeMembersInput(input) {
6113
+ const limit = knowledgeScopeMembersLimit(input.limit);
6114
+ if (!input.cursor) return {
6115
+ limit,
6116
+ after: null
6117
+ };
6118
+ let value;
6119
+ try {
6120
+ value = JSON.parse(decodeURIComponent(input.cursor));
6121
+ } catch {
6122
+ throw new Error("Invalid Knowledge scope member cursor.");
6123
+ }
6124
+ const parsed = value && typeof value === "object" ? value : {};
6125
+ const updatedAt = typeof parsed.updatedAt === "string" ? new Date(parsed.updatedAt) : /* @__PURE__ */ new Date(NaN);
6126
+ if (parsed.version !== 1 || parsed.type !== "scope-member" || parsed.scopeNodeId !== input.scopeNodeId || typeof parsed.name !== "string" || typeof parsed.id !== "string" || Number.isNaN(updatedAt.getTime())) throw new Error("Knowledge scope member cursor does not match this query.");
6127
+ return {
6128
+ limit,
6129
+ after: {
6130
+ updatedAt,
6131
+ name: parsed.name,
6132
+ id: parsed.id
6133
+ }
6134
+ };
6135
+ }
6136
+ /** Builds a page from up to `limit + 1` members in `listScopeMembers` order. */
6137
+ function pageKnowledgeScopeMembers(rows, limit, input) {
6138
+ const members = rows.slice(0, limit);
6139
+ const last = members.at(-1);
6140
+ const hasMore = rows.length > limit;
6141
+ return {
6142
+ members,
6143
+ hasMore,
6144
+ nextCursor: hasMore && last ? encodeURIComponent(JSON.stringify({
6145
+ version: 1,
6146
+ type: "scope-member",
6147
+ scopeNodeId: input.scopeNodeId,
6148
+ updatedAt: last.updatedAt.toISOString(),
6149
+ name: last.name,
6150
+ id: last.id
6151
+ })) : null
6152
+ };
6153
+ }
6154
+ const TABLE_KNOWLEDGE_NODES$1 = "mastra_knowledge_nodes";
6155
+ const TABLE_KNOWLEDGE_RECORDS$1 = "mastra_knowledge_records";
6156
+ const TABLE_KNOWLEDGE_MENTIONS$1 = "mastra_knowledge_mentions";
6157
+ const TABLE_KNOWLEDGE_ACTIVITY$1 = "mastra_knowledge_activity";
6158
+ const TABLE_KNOWLEDGE_SEMANTIC_OUTBOX$1 = "mastra_knowledge_semantic_outbox";
6159
+ const TABLE_KNOWLEDGE_NODE_SCOPES = "mastra_knowledge_node_scopes";
6160
+ const TABLE_KNOWLEDGE_RECORD_SCOPES = "mastra_knowledge_record_scopes";
6161
+ const TABLE_KNOWLEDGE_SCOPE_GRANTS = "mastra_knowledge_scope_grants";
6162
+ const TABLE_KNOWLEDGE_ACCESS_STATE = "mastra_knowledge_access_state";
6163
+ const TABLE_KNOWLEDGE_SCOPE_ADDRESSES = "mastra_knowledge_scope_addresses";
6164
+ const TABLE_KNOWLEDGE_NODE_ADDRESSES = "mastra_knowledge_node_addresses";
6165
+ const TABLE_KNOWLEDGE_IMPORT_STATE = "mastra_knowledge_import_state";
6166
+ const TABLE_KNOWLEDGE_IMPORT_RUNS = "mastra_knowledge_import_runs";
6167
+ const TABLE_KNOWLEDGE_PROPOSALS = "mastra_knowledge_proposals";
6168
+ const KNOWLEDGE_TABLE_NAMES = [
6169
+ TABLE_KNOWLEDGE_NODES$1,
6170
+ TABLE_KNOWLEDGE_RECORDS$1,
6171
+ TABLE_KNOWLEDGE_MENTIONS$1,
6172
+ TABLE_KNOWLEDGE_ACTIVITY$1,
6173
+ TABLE_KNOWLEDGE_SEMANTIC_OUTBOX$1,
6174
+ TABLE_KNOWLEDGE_NODE_SCOPES,
6175
+ TABLE_KNOWLEDGE_RECORD_SCOPES,
6176
+ TABLE_KNOWLEDGE_SCOPE_GRANTS,
6177
+ TABLE_KNOWLEDGE_ACCESS_STATE,
6178
+ TABLE_KNOWLEDGE_SCOPE_ADDRESSES,
6179
+ TABLE_KNOWLEDGE_NODE_ADDRESSES,
6180
+ TABLE_KNOWLEDGE_IMPORT_STATE,
6181
+ TABLE_KNOWLEDGE_IMPORT_RUNS,
6182
+ TABLE_KNOWLEDGE_PROPOSALS
6183
+ ];
6184
+ /** Knowledge v1 tables with no v2 equivalent; an explicit schema reset drops them. */
6185
+ const RETIRED_KNOWLEDGE_TABLE_NAMES = ["mastra_knowledge_cursors"];
6186
+ /** Tables and indexes published v1 adapters created for every app, whether or not it used Knowledge. */
6187
+ const PUBLISHED_KNOWLEDGE_V1_TABLE_NAMES = /* @__PURE__ */ new Set([
6188
+ TABLE_KNOWLEDGE_NODES$1,
6189
+ TABLE_KNOWLEDGE_RECORDS$1,
6190
+ TABLE_KNOWLEDGE_MENTIONS$1,
6191
+ TABLE_KNOWLEDGE_ACTIVITY$1,
6192
+ TABLE_KNOWLEDGE_SEMANTIC_OUTBOX$1,
6193
+ ...RETIRED_KNOWLEDGE_TABLE_NAMES
6194
+ ]);
6195
+ const PUBLISHED_KNOWLEDGE_V1_INDEX_NAMES = /* @__PURE__ */ new Set([
6196
+ "idx_knowledge_nodes_identity",
6197
+ "idx_knowledge_nodes_scope",
6198
+ "idx_knowledge_records_node_latest",
6199
+ "idx_knowledge_records_thread_latest",
6200
+ "idx_knowledge_mentions_record",
6201
+ "idx_knowledge_activity_latest",
6202
+ "idx_knowledge_outbox_idempotency",
6203
+ "idx_knowledge_outbox_claim"
6204
+ ]);
6205
+ const KNOWLEDGE_V2_NODES_SCHEMA = {
6206
+ id: {
6207
+ type: "text",
6208
+ nullable: false,
6209
+ primaryKey: true
6210
+ },
6211
+ name: {
6212
+ type: "text",
6213
+ nullable: false
6214
+ },
6215
+ kind: {
6216
+ type: "text",
6217
+ nullable: true
6218
+ },
6219
+ isScope: {
6220
+ type: "boolean",
6221
+ nullable: false
6222
+ },
6223
+ metadata: {
6224
+ type: "jsonb",
6225
+ nullable: true
6226
+ },
6227
+ version: {
6228
+ type: "integer",
6229
+ nullable: false
6230
+ },
6231
+ createdAt: {
6232
+ type: "timestamp",
6233
+ nullable: false
6234
+ },
6235
+ updatedAt: {
6236
+ type: "timestamp",
6237
+ nullable: false
6238
+ },
6239
+ deletedAt: {
6240
+ type: "timestamp",
6241
+ nullable: true
6242
+ },
6243
+ deletedBy: {
6244
+ type: "text",
6245
+ nullable: true
6246
+ },
6247
+ type: {
6248
+ type: "text",
6249
+ nullable: true
6250
+ },
6251
+ canonicalName: {
6252
+ type: "text",
6253
+ nullable: true
6254
+ },
6255
+ content: {
6256
+ type: "text",
6257
+ nullable: true
6258
+ },
6259
+ description: {
6260
+ type: "text",
6261
+ nullable: true
6262
+ },
6263
+ scope: {
6264
+ type: "jsonb",
6265
+ nullable: true
6266
+ },
6267
+ scopeKey: {
6268
+ type: "text",
6269
+ nullable: true
6270
+ },
6271
+ mergedInto: {
6272
+ type: "text",
6273
+ nullable: true
6274
+ }
6275
+ };
6276
+ const KNOWLEDGE_V2_RECORDS_SCHEMA = {
6277
+ id: {
6278
+ type: "text",
6279
+ nullable: false,
6280
+ primaryKey: true
6281
+ },
6282
+ node: {
6283
+ type: "text",
6284
+ nullable: false,
6285
+ references: {
6286
+ table: TABLE_KNOWLEDGE_NODES$1,
6287
+ column: "id"
6288
+ }
6289
+ },
6290
+ text: {
6291
+ type: "text",
6292
+ nullable: false
6293
+ },
6294
+ metadata: {
6295
+ type: "jsonb",
6296
+ nullable: true
6297
+ },
6298
+ version: {
6299
+ type: "integer",
6300
+ nullable: false
6301
+ },
6302
+ capturedAt: {
6303
+ type: "timestamp",
6304
+ nullable: false
6305
+ },
6306
+ updatedAt: {
6307
+ type: "timestamp",
6308
+ nullable: false
6309
+ },
6310
+ deletedAt: {
6311
+ type: "timestamp",
6312
+ nullable: true
6313
+ },
6314
+ deletedBy: {
6315
+ type: "text",
6316
+ nullable: true
6317
+ },
6318
+ scope: {
6319
+ type: "jsonb",
6320
+ nullable: true
6321
+ },
6322
+ scopeKey: {
6323
+ type: "text",
6324
+ nullable: true
6325
+ },
6326
+ sourceThreadId: {
6327
+ type: "text",
6328
+ nullable: true
6329
+ },
6330
+ when: {
6331
+ type: "timestamp",
6332
+ nullable: true
6333
+ }
6334
+ };
6335
+ const KNOWLEDGE_V2_MENTIONS_SCHEMA = {
6336
+ recordId: {
6337
+ type: "text",
6338
+ nullable: false,
6339
+ references: {
6340
+ table: TABLE_KNOWLEDGE_RECORDS$1,
6341
+ column: "id"
6342
+ }
6343
+ },
6344
+ targetNodeId: {
6345
+ type: "text",
6346
+ nullable: true,
6347
+ references: {
6348
+ table: TABLE_KNOWLEDGE_NODES$1,
6349
+ column: "id"
6350
+ }
6351
+ },
6352
+ sourceType: {
6353
+ type: "text",
6354
+ nullable: true
6355
+ },
6356
+ sourceId: {
6357
+ type: "text",
6358
+ nullable: true
6359
+ }
6360
+ };
6361
+ const KNOWLEDGE_NODE_SCOPES_SCHEMA = {
6362
+ nodeId: {
6363
+ type: "text",
6364
+ nullable: false,
6365
+ references: {
6366
+ table: TABLE_KNOWLEDGE_NODES$1,
6367
+ column: "id"
6368
+ }
6369
+ },
6370
+ scopeNodeId: {
6371
+ type: "text",
6372
+ nullable: false,
6373
+ references: {
6374
+ table: TABLE_KNOWLEDGE_NODES$1,
6375
+ column: "id"
6376
+ }
6377
+ },
6378
+ addedAt: {
6379
+ type: "timestamp",
6380
+ nullable: false
6381
+ }
6382
+ };
6383
+ const KNOWLEDGE_RECORD_SCOPES_SCHEMA = {
6384
+ recordId: {
6385
+ type: "text",
6386
+ nullable: false,
6387
+ references: {
6388
+ table: TABLE_KNOWLEDGE_RECORDS$1,
6389
+ column: "id"
6390
+ }
6391
+ },
6392
+ scopeNodeId: {
6393
+ type: "text",
6394
+ nullable: false,
6395
+ references: {
6396
+ table: TABLE_KNOWLEDGE_NODES$1,
6397
+ column: "id"
6398
+ }
6399
+ },
6400
+ addedAt: {
6401
+ type: "timestamp",
6402
+ nullable: false
6403
+ }
6404
+ };
6405
+ const KNOWLEDGE_SCOPE_GRANTS_SCHEMA = {
6406
+ scopeNodeId: {
6407
+ type: "text",
6408
+ nullable: false,
6409
+ references: {
6410
+ table: TABLE_KNOWLEDGE_NODES$1,
6411
+ column: "id"
6412
+ }
6413
+ },
6414
+ scopeRefId: {
6415
+ type: "text",
6416
+ nullable: false,
6417
+ references: {
6418
+ table: TABLE_KNOWLEDGE_NODES$1,
6419
+ column: "id"
6420
+ }
6421
+ },
6422
+ role: {
6423
+ type: "text",
6424
+ nullable: false
6425
+ },
6426
+ canSuggest: {
6427
+ type: "boolean",
6428
+ nullable: true
6429
+ }
6430
+ };
6431
+ const KNOWLEDGE_ACCESS_STATE_SCHEMA = {
6432
+ id: {
6433
+ type: "text",
6434
+ nullable: false,
6435
+ primaryKey: true
6436
+ },
6437
+ epoch: {
6438
+ type: "integer",
6439
+ nullable: false
6440
+ },
6441
+ schemaVersion: {
6442
+ type: "integer",
6443
+ nullable: false
6444
+ }
6445
+ };
6446
+ const KNOWLEDGE_SCOPE_ADDRESSES_SCHEMA = {
6447
+ address: {
6448
+ type: "text",
6449
+ nullable: false,
6450
+ primaryKey: true
6451
+ },
6452
+ scopeNodeId: {
6453
+ type: "text",
6454
+ nullable: false,
6455
+ references: {
6456
+ table: TABLE_KNOWLEDGE_NODES$1,
6457
+ column: "id"
6458
+ }
6459
+ }
6460
+ };
6461
+ const KNOWLEDGE_NODE_ADDRESSES_SCHEMA = {
6462
+ source: {
6463
+ type: "text",
6464
+ nullable: false
6465
+ },
6466
+ address: {
6467
+ type: "text",
6468
+ nullable: false
6469
+ },
6470
+ nodeId: {
6471
+ type: "text",
6472
+ nullable: false,
6473
+ references: {
6474
+ table: TABLE_KNOWLEDGE_NODES$1,
6475
+ column: "id"
6476
+ }
6477
+ }
6478
+ };
6479
+ const KNOWLEDGE_IMPORT_STATE_SCHEMA = {
6480
+ importerId: {
6481
+ type: "text",
6482
+ nullable: false
6483
+ },
6484
+ binding: {
6485
+ type: "text",
6486
+ nullable: false
6487
+ },
6488
+ key: {
6489
+ type: "text",
6490
+ nullable: false
6491
+ },
6492
+ value: {
6493
+ type: "text",
6494
+ nullable: false
6495
+ }
6496
+ };
6497
+ const KNOWLEDGE_IMPORT_RUNS_SCHEMA = {
6498
+ id: {
6499
+ type: "text",
6500
+ nullable: false,
6501
+ primaryKey: true
6502
+ },
6503
+ importerId: {
6504
+ type: "text",
6505
+ nullable: false
6506
+ },
6507
+ binding: {
6508
+ type: "text",
6509
+ nullable: false
6510
+ },
6511
+ importKind: {
6512
+ type: "text",
6513
+ nullable: false
6514
+ },
6515
+ triggerKind: {
6516
+ type: "text",
6517
+ nullable: false
6518
+ },
6519
+ status: {
6520
+ type: "text",
6521
+ nullable: false
6522
+ },
6523
+ error: {
6524
+ type: "text",
6525
+ nullable: true
6526
+ },
6527
+ transcriptThreadId: {
6528
+ type: "text",
6529
+ nullable: true
6530
+ },
6531
+ traceId: {
6532
+ type: "text",
6533
+ nullable: true
6534
+ },
6535
+ queuedAt: {
6536
+ type: "timestamp",
6537
+ nullable: false
6538
+ },
6539
+ startedAt: {
6540
+ type: "timestamp",
6541
+ nullable: true
6542
+ },
6543
+ completedAt: {
6544
+ type: "timestamp",
6545
+ nullable: true
6546
+ }
6547
+ };
6548
+ const KNOWLEDGE_V2_ACTIVITY_SCHEMA = {
6549
+ id: {
6550
+ type: "text",
6551
+ nullable: false,
6552
+ primaryKey: true
6553
+ },
6554
+ action: {
6555
+ type: "text",
6556
+ nullable: false
6557
+ },
6558
+ targetType: {
6559
+ type: "text",
6560
+ nullable: true
6561
+ },
6562
+ targetId: {
6563
+ type: "text",
6564
+ nullable: true
6565
+ },
6566
+ contextScopeId: {
6567
+ type: "text",
6568
+ nullable: true,
6569
+ references: {
6570
+ table: TABLE_KNOWLEDGE_NODES$1,
6571
+ column: "id"
6572
+ }
6573
+ },
6574
+ importRunId: {
6575
+ type: "text",
6576
+ nullable: true,
6577
+ references: {
6578
+ table: TABLE_KNOWLEDGE_IMPORT_RUNS,
6579
+ column: "id"
6580
+ }
6581
+ },
6582
+ details: {
6583
+ type: "jsonb",
6584
+ nullable: true
6585
+ },
6586
+ createdAt: {
6587
+ type: "timestamp",
6588
+ nullable: false
6589
+ },
6590
+ recordType: {
6591
+ type: "text",
6592
+ nullable: true
6593
+ },
6594
+ recordId: {
6595
+ type: "text",
6596
+ nullable: true
6597
+ },
6598
+ scope: {
6599
+ type: "jsonb",
6600
+ nullable: true
6601
+ },
6602
+ scopeKey: {
6603
+ type: "text",
6604
+ nullable: true
6605
+ },
6606
+ sourceThreadId: {
6607
+ type: "text",
6608
+ nullable: true
6609
+ }
6610
+ };
6611
+ const KNOWLEDGE_PROPOSALS_SCHEMA = {
6612
+ id: {
6613
+ type: "text",
6614
+ nullable: false,
6615
+ primaryKey: true
6616
+ },
6617
+ targetType: {
6618
+ type: "text",
6619
+ nullable: false
6620
+ },
6621
+ targetId: {
6622
+ type: "text",
6623
+ nullable: false
6624
+ },
6625
+ action: {
6626
+ type: "text",
6627
+ nullable: false
6628
+ },
6629
+ changes: {
6630
+ type: "jsonb",
6631
+ nullable: false
6632
+ },
6633
+ reason: {
6634
+ type: "text",
6635
+ nullable: true
6636
+ },
6637
+ proposerContextScopeId: {
6638
+ type: "text",
6639
+ nullable: false
6640
+ },
6641
+ expectedVersion: {
6642
+ type: "integer",
6643
+ nullable: false
6644
+ },
6645
+ status: {
6646
+ type: "text",
6647
+ nullable: false
6648
+ },
6649
+ reviewerContextScopeId: {
6650
+ type: "text",
6651
+ nullable: true
6652
+ },
6653
+ reviewedAt: {
6654
+ type: "timestamp",
6655
+ nullable: true
6656
+ },
6657
+ createdAt: {
6658
+ type: "timestamp",
6659
+ nullable: false
6660
+ }
6661
+ };
6662
+ function assertKnowledgeV2CoreSupport(features) {
6663
+ if (!features.has("knowledge-v2")) throw new Error(`Knowledge v2 requires a @mastra/core release with the "${KNOWLEDGE_V2_CORE_FEATURE}" feature. Upgrade @mastra/core to use Knowledge; other storage domains keep working on this version.`);
6664
+ }
6665
+ function resolveKnowledgeV2Core(storageModule) {
6666
+ if (typeof storageModule !== "object" || storageModule === null) throw new Error("@mastra/core advertises Knowledge v2 without the required storage API");
6667
+ const { assertKnowledgeDescriptionWithinBound: assertDescription, assertKnowledgeRecordTextWithinBound: assertRecordText, assertKnowledgeSchemaCompatible: assertCompatible, inspectKnowledgeSchema: inspectSchema } = storageModule;
6668
+ if (typeof assertDescription !== "function" || typeof assertRecordText !== "function" || typeof assertCompatible !== "function" || typeof inspectSchema !== "function") throw new Error("@mastra/core advertises Knowledge v2 without the required storage API");
6669
+ return {
6670
+ assertKnowledgeDescriptionWithinBound: (description) => assertDescription(description),
6671
+ assertKnowledgeRecordTextWithinBound: (text) => assertRecordText(text),
6672
+ assertKnowledgeSchemaCompatible: (inspection) => assertCompatible(inspection),
6673
+ inspectKnowledgeSchema: (snapshot) => inspectSchema(snapshot)
6674
+ };
6675
+ }
6676
+ function createKnowledgeV2CoreLoader(features, loadStorageModule) {
6677
+ let knowledgeV2Core;
6678
+ return async () => {
6679
+ assertKnowledgeV2CoreSupport(features);
6680
+ knowledgeV2Core ??= loadStorageModule().then(resolveKnowledgeV2Core).catch((error) => {
6681
+ knowledgeV2Core = void 0;
6682
+ throw error;
6683
+ });
6684
+ return knowledgeV2Core;
6685
+ };
6686
+ }
6687
+ //#endregion
6051
6688
  //#region src/storage/domains/knowledge/index.ts
6052
- let assertDescriptionWithinBound;
6689
+ const loadKnowledgeV2Core = createKnowledgeV2CoreLoader(_mastra_core_features.coreFeatures, () => import("@mastra/core/storage"));
6053
6690
  async function assertKnowledgeDescriptionWithinBoundCompat(description) {
6054
- let assertWithinBound = assertDescriptionWithinBound;
6055
- if (!assertWithinBound) {
6056
- const resolvedAssert = (await import("@mastra/core/storage")).assertKnowledgeDescriptionWithinBound ?? ((value) => {
6057
- if (value !== void 0 && value.length > 400) throw new Error("Knowledge node description exceeds the 400 UTF-16 code unit limit");
6058
- });
6059
- assertDescriptionWithinBound = resolvedAssert;
6060
- assertWithinBound = resolvedAssert;
6061
- }
6062
- assertWithinBound(description);
6691
+ const { assertKnowledgeDescriptionWithinBound } = await loadKnowledgeV2Core();
6692
+ assertKnowledgeDescriptionWithinBound(description);
6693
+ }
6694
+ async function assertKnowledgeRecordTextWithinBoundCompat(text) {
6695
+ const { assertKnowledgeRecordTextWithinBound } = await loadKnowledgeV2Core();
6696
+ assertKnowledgeRecordTextWithinBound(text);
6697
+ }
6698
+ const reconcileChains = /* @__PURE__ */ new Map();
6699
+ const unidentifiedClientReconcileKey = {};
6700
+ function withReconcileLock(key, operation) {
6701
+ const lockKey = typeof key === "string" ? key : unidentifiedClientReconcileKey;
6702
+ const result = (reconcileChains.get(lockKey) ?? Promise.resolve()).then(operation, operation);
6703
+ const tail = result.then(() => void 0, () => void 0);
6704
+ reconcileChains.set(lockKey, tail);
6705
+ tail.finally(() => {
6706
+ if (reconcileChains.get(lockKey) === tail) reconcileChains.delete(lockKey);
6707
+ });
6708
+ return result;
6063
6709
  }
6064
- const visibleSql = `(scopeKey = ? OR substr(?, 1, length(scopeKey) + 1) = scopeKey || char(31))`;
6710
+ /**
6711
+ * Scope keys visible to a caller holding `scope`: a row is visible when its scope is a subset of the
6712
+ * caller's (companion entries such as `resource:x:uncurated` make this more than a prefix match).
6713
+ * Matching rows by `scopeKey` keeps visibility filters on an index; a caller scope has only a few
6714
+ * entries, so the list stays small.
6715
+ */
6716
+ function visibleScopeKeys(scope) {
6717
+ const canonical = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(scope);
6718
+ const keys = /* @__PURE__ */ new Set();
6719
+ for (let mask = 1; mask < 1 << canonical.length; mask++) try {
6720
+ keys.add((0, _mastra_core_storage.knowledgeScopeKey)(canonical.filter((_, index) => mask & 1 << index)));
6721
+ } catch {}
6722
+ return [...keys];
6723
+ }
6724
+ const visibleSql = (keys, scopeKeyColumn = "scopeKey") => `${scopeKeyColumn} IN (${keys.map(() => "?").join(",")})`;
6065
6725
  function parseJson$3(value) {
6066
6726
  if (typeof value === "string") return JSON.parse(value);
6067
6727
  if (value instanceof Uint8Array) return JSON.parse(new TextDecoder().decode(value));
@@ -6091,6 +6751,7 @@ function parseNode(row) {
6091
6751
  kind: row.kind == null ? "" : String(row.kind),
6092
6752
  content: row.content == null ? void 0 : String(row.content),
6093
6753
  description: row.description == null ? void 0 : String(row.description),
6754
+ isScope: row.isScope === true || row.isScope === 1 ? true : void 0,
6094
6755
  scope: parseJson$3(row.scopeJson ?? row.scope),
6095
6756
  version: Number(row.version),
6096
6757
  mergedInto: row.mergedInto == null ? void 0 : String(row.mergedInto),
@@ -6107,7 +6768,6 @@ function parseKnowledge(row) {
6107
6768
  sourceThreadId: String(row.sourceThreadId),
6108
6769
  capturedAt: toDate(row.capturedAt),
6109
6770
  when: optionalDate(row.when),
6110
- maxScope: row.maxScope == null ? void 0 : String(row.maxScope),
6111
6771
  metadata: (row.metadataJson ?? row.metadata) == null ? void 0 : parseJson$3(row.metadataJson ?? row.metadata),
6112
6772
  deletedAt: optionalDate(row.deletedAt),
6113
6773
  deletedBy: row.deletedBy == null ? void 0 : String(row.deletedBy)
@@ -6130,100 +6790,458 @@ function parseOutbox(row) {
6130
6790
  completedAt: optionalDate(row.completedAt)
6131
6791
  };
6132
6792
  }
6793
+ const KNOWLEDGE_CURATION_CURSOR_REMOVED_MESSAGE = "Knowledge curation cursors were removed: observation-time curate is the only Knowledge writer and needs no cursor.";
6794
+ const knowledgeV2TableSchemas = /* @__PURE__ */ new Map([
6795
+ [_mastra_core_storage.TABLE_KNOWLEDGE_NODES, KNOWLEDGE_V2_NODES_SCHEMA],
6796
+ [_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS, KNOWLEDGE_V2_RECORDS_SCHEMA],
6797
+ [_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS, KNOWLEDGE_V2_MENTIONS_SCHEMA],
6798
+ [_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY, KNOWLEDGE_V2_ACTIVITY_SCHEMA],
6799
+ [_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX, _mastra_core_storage.KNOWLEDGE_SEMANTIC_OUTBOX_SCHEMA],
6800
+ [TABLE_KNOWLEDGE_NODE_SCOPES, KNOWLEDGE_NODE_SCOPES_SCHEMA],
6801
+ [TABLE_KNOWLEDGE_RECORD_SCOPES, KNOWLEDGE_RECORD_SCOPES_SCHEMA],
6802
+ [TABLE_KNOWLEDGE_SCOPE_GRANTS, KNOWLEDGE_SCOPE_GRANTS_SCHEMA],
6803
+ [TABLE_KNOWLEDGE_ACCESS_STATE, KNOWLEDGE_ACCESS_STATE_SCHEMA],
6804
+ [TABLE_KNOWLEDGE_SCOPE_ADDRESSES, KNOWLEDGE_SCOPE_ADDRESSES_SCHEMA],
6805
+ [TABLE_KNOWLEDGE_NODE_ADDRESSES, KNOWLEDGE_NODE_ADDRESSES_SCHEMA],
6806
+ [TABLE_KNOWLEDGE_IMPORT_STATE, KNOWLEDGE_IMPORT_STATE_SCHEMA],
6807
+ [TABLE_KNOWLEDGE_IMPORT_RUNS, KNOWLEDGE_IMPORT_RUNS_SCHEMA],
6808
+ [TABLE_KNOWLEDGE_PROPOSALS, KNOWLEDGE_PROPOSALS_SCHEMA]
6809
+ ]);
6810
+ function canonicalizeLibSQLUrl(url) {
6811
+ if (url.includes(":memory:")) return /[?&]cache=shared(?:&|$)/.test(url) ? "file::memory:?cache=shared" : void 0;
6812
+ if (url.startsWith("file:")) {
6813
+ const [path$1] = url.slice(5).split("?");
6814
+ if (url.startsWith("file://")) {
6815
+ const parsed = new URL(url);
6816
+ const host = parsed.hostname.toLocaleLowerCase();
6817
+ const filePath = host && host !== "localhost" ? `//${host}${parsed.pathname}` : parsed.pathname;
6818
+ return `file:${(0, path.resolve)(decodeURIComponent(filePath))}`;
6819
+ }
6820
+ return `file:${(0, path.resolve)(decodeURIComponent(path$1))}`;
6821
+ }
6822
+ try {
6823
+ const parsed = new URL(url);
6824
+ const port = parsed.port || (parsed.protocol === "libsql:" || parsed.protocol === "https:" ? "443" : "80");
6825
+ return `${parsed.protocol}//${parsed.hostname.toLocaleLowerCase()}:${port}${parsed.pathname}`;
6826
+ } catch {
6827
+ return url;
6828
+ }
6829
+ }
6830
+ const unidentifiedClientIsolationKey = {};
6831
+ function getLibSQLKnowledgeIsolationKey(config, client) {
6832
+ if (config.storageIsolationKey !== void 0) return config.storageIsolationKey;
6833
+ if (!config.url) return unidentifiedClientIsolationKey;
6834
+ const urlKey = canonicalizeLibSQLUrl(config.url);
6835
+ return urlKey ? `libsql:${urlKey}` : client ?? config.client ?? config;
6836
+ }
6133
6837
  var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6134
6838
  #client;
6135
6839
  #db;
6136
6840
  constructor(config) {
6137
- super();
6138
- this.#client = resolveClient(config);
6841
+ const client = resolveClient(config);
6842
+ const storageIsolationKey = config.storageIsolationKey ?? getLibSQLKnowledgeIsolationKey(config, client);
6843
+ super({ storageIsolationKey });
6844
+ this.#client = client;
6139
6845
  this.#db = new LibSQLDB({
6140
6846
  client: this.#client,
6141
6847
  maxRetries: config.maxRetries,
6142
6848
  initialBackoffMs: config.initialBackoffMs
6143
6849
  });
6144
6850
  }
6851
+ getCapabilities() {
6852
+ return {
6853
+ contractVersion: 2,
6854
+ schemaVersion: 2,
6855
+ supportsV2: true,
6856
+ supportsSchemaInspection: true,
6857
+ supportsExplicitReset: true
6858
+ };
6859
+ }
6860
+ async inspectSchema() {
6861
+ return this.#inspectSchema(this.#client);
6862
+ }
6863
+ async #inspectSchema(executor) {
6864
+ const { inspectKnowledgeSchema } = await loadKnowledgeV2Core();
6865
+ try {
6866
+ const placeholders = KNOWLEDGE_TABLE_NAMES.map(() => "?").join(",");
6867
+ const tableNames = (await executor.execute({
6868
+ sql: `SELECT name FROM sqlite_master WHERE type = 'table' AND name IN (${placeholders})`,
6869
+ args: [...KNOWLEDGE_TABLE_NAMES]
6870
+ })).rows.map((row) => String(row.name));
6871
+ if (tableNames.length === 0) return inspectKnowledgeSchema({
6872
+ available: true,
6873
+ tableNames
6874
+ });
6875
+ const missingTables = KNOWLEDGE_TABLE_NAMES.filter((table) => !tableNames.includes(table));
6876
+ if (missingTables.length > 0) return inspectKnowledgeSchema({
6877
+ available: true,
6878
+ tableNames,
6879
+ reason: `Missing Knowledge v2 tables: ${missingTables.join(", ")}`
6880
+ });
6881
+ for (const [table, schema] of knowledgeV2TableSchemas) {
6882
+ const columns = await executor.execute(`PRAGMA table_info("${table}")`);
6883
+ const actual = new Set(columns.rows.map((row) => String(row.name)));
6884
+ const missing = Object.keys(schema).filter((column) => !actual.has(column));
6885
+ if (missing.length > 0) return inspectKnowledgeSchema({
6886
+ available: true,
6887
+ tableNames,
6888
+ reason: `Knowledge table ${table} is missing v2 columns: ${missing.join(", ")}`
6889
+ });
6890
+ }
6891
+ const accessState = await executor.execute(`SELECT schemaVersion FROM "${TABLE_KNOWLEDGE_ACCESS_STATE}" WHERE id='global'`);
6892
+ if (Number(accessState.rows[0]?.schemaVersion) !== 2) return inspectKnowledgeSchema({
6893
+ available: true,
6894
+ tableNames,
6895
+ reason: "Knowledge schema version marker is missing or incompatible"
6896
+ });
6897
+ return inspectKnowledgeSchema({
6898
+ available: true,
6899
+ tableNames,
6900
+ schemaVersion: 2
6901
+ });
6902
+ } catch (error) {
6903
+ return inspectKnowledgeSchema({
6904
+ available: false,
6905
+ tableNames: [],
6906
+ reason: error instanceof Error ? error.message : String(error)
6907
+ });
6908
+ }
6909
+ }
6145
6910
  async init() {
6146
- await this.#db.createTable({
6147
- tableName: _mastra_core_storage.TABLE_KNOWLEDGE_NODES,
6148
- schema: _mastra_core_storage.KNOWLEDGE_NODES_SCHEMA
6911
+ await this.#transaction((tx) => this.#initializeSchema(tx));
6912
+ }
6913
+ async #initializeSchema(tx) {
6914
+ const { assertKnowledgeSchemaCompatible } = await loadKnowledgeV2Core();
6915
+ let inspection = await this.#inspectSchema(tx);
6916
+ if (inspection.status === "incompatible-reset-required" && await this.#isPublishedV1Layout(tx)) {
6917
+ for (const table of [...RETIRED_KNOWLEDGE_TABLE_NAMES, ...[...KNOWLEDGE_TABLE_NAMES].reverse()]) await tx.execute(`DROP TABLE IF EXISTS "${table}"`);
6918
+ inspection = await this.#inspectSchema(tx);
6919
+ }
6920
+ assertKnowledgeSchemaCompatible(inspection);
6921
+ const createTable = (input) => this.#db.createTable({
6922
+ ...input,
6923
+ executor: tx
6149
6924
  });
6150
- await this.#db.alterTable({
6925
+ await createTable({
6151
6926
  tableName: _mastra_core_storage.TABLE_KNOWLEDGE_NODES,
6152
- schema: _mastra_core_storage.KNOWLEDGE_NODES_SCHEMA,
6153
- ifNotExists: ["description"]
6927
+ schema: KNOWLEDGE_V2_NODES_SCHEMA
6154
6928
  });
6155
- await this.#db.createTable({
6929
+ await createTable({
6156
6930
  tableName: _mastra_core_storage.TABLE_KNOWLEDGE_RECORDS,
6157
- schema: _mastra_core_storage.KNOWLEDGE_RECORDS_SCHEMA
6931
+ schema: KNOWLEDGE_V2_RECORDS_SCHEMA
6158
6932
  });
6159
- await this.#db.createTable({
6933
+ await createTable({
6160
6934
  tableName: _mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS,
6161
- schema: _mastra_core_storage.KNOWLEDGE_MENTIONS_SCHEMA,
6935
+ schema: KNOWLEDGE_V2_MENTIONS_SCHEMA,
6936
+ compositePrimaryKey: ["recordId", "sourceId"]
6937
+ });
6938
+ await createTable({
6939
+ tableName: TABLE_KNOWLEDGE_NODE_SCOPES,
6940
+ schema: KNOWLEDGE_NODE_SCOPES_SCHEMA,
6941
+ compositePrimaryKey: ["nodeId", "scopeNodeId"]
6942
+ });
6943
+ await createTable({
6944
+ tableName: TABLE_KNOWLEDGE_RECORD_SCOPES,
6945
+ schema: KNOWLEDGE_RECORD_SCOPES_SCHEMA,
6946
+ compositePrimaryKey: ["recordId", "scopeNodeId"]
6947
+ });
6948
+ await createTable({
6949
+ tableName: TABLE_KNOWLEDGE_SCOPE_GRANTS,
6950
+ schema: KNOWLEDGE_SCOPE_GRANTS_SCHEMA,
6951
+ compositePrimaryKey: ["scopeNodeId", "scopeRefId"]
6952
+ });
6953
+ await createTable({
6954
+ tableName: TABLE_KNOWLEDGE_ACCESS_STATE,
6955
+ schema: KNOWLEDGE_ACCESS_STATE_SCHEMA
6956
+ });
6957
+ await createTable({
6958
+ tableName: TABLE_KNOWLEDGE_SCOPE_ADDRESSES,
6959
+ schema: KNOWLEDGE_SCOPE_ADDRESSES_SCHEMA
6960
+ });
6961
+ await createTable({
6962
+ tableName: TABLE_KNOWLEDGE_NODE_ADDRESSES,
6963
+ schema: KNOWLEDGE_NODE_ADDRESSES_SCHEMA,
6964
+ compositePrimaryKey: ["source", "address"]
6965
+ });
6966
+ await createTable({
6967
+ tableName: TABLE_KNOWLEDGE_IMPORT_STATE,
6968
+ schema: KNOWLEDGE_IMPORT_STATE_SCHEMA,
6162
6969
  compositePrimaryKey: [
6163
- "sourceType",
6164
- "sourceId",
6165
- "recordId"
6970
+ "importerId",
6971
+ "binding",
6972
+ "key"
6166
6973
  ]
6167
6974
  });
6168
- await this.#db.createTable({
6169
- tableName: _mastra_core_storage.TABLE_KNOWLEDGE_CURSORS,
6170
- schema: _mastra_core_storage.KNOWLEDGE_CURSORS_SCHEMA,
6171
- compositePrimaryKey: ["sourceThreadId", "agent"]
6975
+ await createTable({
6976
+ tableName: TABLE_KNOWLEDGE_IMPORT_RUNS,
6977
+ schema: KNOWLEDGE_IMPORT_RUNS_SCHEMA
6172
6978
  });
6173
- await this.#db.createTable({
6979
+ await createTable({
6980
+ tableName: TABLE_KNOWLEDGE_PROPOSALS,
6981
+ schema: KNOWLEDGE_PROPOSALS_SCHEMA
6982
+ });
6983
+ await createTable({
6174
6984
  tableName: _mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
6175
- schema: _mastra_core_storage.KNOWLEDGE_ACTIVITY_SCHEMA
6985
+ schema: KNOWLEDGE_V2_ACTIVITY_SCHEMA
6176
6986
  });
6177
- await this.#db.createTable({
6987
+ await createTable({
6178
6988
  tableName: _mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX,
6179
6989
  schema: _mastra_core_storage.KNOWLEDGE_SEMANTIC_OUTBOX_SCHEMA
6180
6990
  });
6181
- await this.#client.batch([
6182
- {
6183
- sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_knowledge_nodes_identity ON "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" (type, scopeKey, canonicalName)`,
6184
- args: []
6185
- },
6186
- {
6187
- sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_nodes_scope ON "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" (scopeKey, type)`,
6188
- args: []
6189
- },
6190
- {
6191
- sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_records_node_latest ON "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" (node, id DESC)`,
6192
- args: []
6193
- },
6194
- {
6195
- sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_records_thread_latest ON "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" (sourceThreadId, id DESC)`,
6196
- args: []
6197
- },
6198
- {
6199
- sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_mentions_record ON "${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}" (recordId, sourceType, sourceId)`,
6200
- args: []
6201
- },
6202
- {
6203
- sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_activity_latest ON "${_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY}" (id DESC)`,
6204
- args: []
6205
- },
6206
- {
6207
- sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_knowledge_outbox_idempotency ON "${_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX}" (idempotencyKey)`,
6208
- args: []
6209
- },
6210
- {
6211
- sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_outbox_claim ON "${_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX}" (status, availableAt, createdAt)`,
6212
- args: []
6213
- }
6214
- ], "write");
6991
+ for (const statement of [
6992
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_knowledge_nodes_identity ON "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" (type, scopeKey, canonicalName)`,
6993
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_nodes_scope ON "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" (scopeKey, type)`,
6994
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_nodes_name ON "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" (type, canonicalName)`,
6995
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_records_node_latest ON "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" (node, id DESC)`,
6996
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_records_thread_latest ON "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" (sourceThreadId, id DESC)`,
6997
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_mentions_record ON "${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}" (recordId, sourceType, sourceId)`,
6998
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_activity_latest ON "${_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY}" (id DESC)`,
6999
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_records_scope ON "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" (scopeKey, id)`,
7000
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_activity_scope ON "${_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY}" (scopeKey, id DESC)`,
7001
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_knowledge_outbox_idempotency ON "${_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX}" (idempotencyKey)`,
7002
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_outbox_claim ON "${_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX}" (status, availableAt, createdAt)`,
7003
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_node_scopes_scope ON "${TABLE_KNOWLEDGE_NODE_SCOPES}" (scopeNodeId, nodeId)`,
7004
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_record_scopes_scope ON "${TABLE_KNOWLEDGE_RECORD_SCOPES}" (scopeNodeId, recordId)`,
7005
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_scope_grants_ref ON "${TABLE_KNOWLEDGE_SCOPE_GRANTS}" (scopeRefId, scopeNodeId)`,
7006
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_node_addresses_node ON "${TABLE_KNOWLEDGE_NODE_ADDRESSES}" (nodeId)`,
7007
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_import_runs_lookup ON "${TABLE_KNOWLEDGE_IMPORT_RUNS}" (importerId, binding, queuedAt DESC)`,
7008
+ `CREATE INDEX IF NOT EXISTS idx_knowledge_activity_import_run ON "${_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY}" (importRunId, id DESC)`
7009
+ ]) await tx.execute(statement);
7010
+ await tx.execute({
7011
+ sql: `INSERT OR IGNORE INTO "${TABLE_KNOWLEDGE_ACCESS_STATE}" (id, epoch, schemaVersion) VALUES ('global', 0, ?)`,
7012
+ args: [2]
7013
+ });
7014
+ }
7015
+ /**
7016
+ * True when the only Knowledge objects are the tables and indexes published v1 adapters created,
7017
+ * with or without rows. Anything else (v2 tables, unknown tables, views, triggers) needs an
7018
+ * explicit reset.
7019
+ */
7020
+ async #isPublishedV1Layout(executor) {
7021
+ const objects = await executor.execute("SELECT type, name FROM sqlite_master WHERE name LIKE 'mastra\\_knowledge\\_%' ESCAPE '\\' OR tbl_name LIKE 'mastra\\_knowledge\\_%' ESCAPE '\\' OR sql LIKE '%mastra\\_knowledge\\_%' ESCAPE '\\'");
7022
+ for (const row of objects.rows) {
7023
+ const type = String(row.type);
7024
+ const name = String(row.name);
7025
+ if (type === "table" && PUBLISHED_KNOWLEDGE_V1_TABLE_NAMES.has(name)) continue;
7026
+ const knownIndex = PUBLISHED_KNOWLEDGE_V1_INDEX_NAMES.has(name) || name.startsWith("sqlite_autoindex_");
7027
+ if (type !== "index" || !knownIndex) return false;
7028
+ }
7029
+ return true;
6215
7030
  }
6216
7031
  async dangerouslyClearAll() {
6217
7032
  await this.#transaction(async (tx) => {
6218
7033
  for (const table of [
7034
+ TABLE_KNOWLEDGE_RECORD_SCOPES,
7035
+ TABLE_KNOWLEDGE_NODE_SCOPES,
7036
+ TABLE_KNOWLEDGE_SCOPE_GRANTS,
7037
+ TABLE_KNOWLEDGE_SCOPE_ADDRESSES,
7038
+ TABLE_KNOWLEDGE_NODE_ADDRESSES,
6219
7039
  _mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS,
6220
- _mastra_core_storage.TABLE_KNOWLEDGE_RECORDS,
6221
- _mastra_core_storage.TABLE_KNOWLEDGE_NODES,
6222
- _mastra_core_storage.TABLE_KNOWLEDGE_CURSORS,
7040
+ TABLE_KNOWLEDGE_PROPOSALS,
6223
7041
  _mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
6224
- _mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX
7042
+ TABLE_KNOWLEDGE_IMPORT_STATE,
7043
+ TABLE_KNOWLEDGE_IMPORT_RUNS,
7044
+ _mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX,
7045
+ _mastra_core_storage.TABLE_KNOWLEDGE_RECORDS,
7046
+ _mastra_core_storage.TABLE_KNOWLEDGE_NODES
6225
7047
  ]) await tx.execute(`DELETE FROM "${table}"`);
7048
+ await tx.execute(`UPDATE "${TABLE_KNOWLEDGE_ACCESS_STATE}" SET epoch = 0 WHERE id = 'global'`);
7049
+ });
7050
+ }
7051
+ async dangerouslyReset() {
7052
+ await withClientWriteLock(this.#client, async () => {
7053
+ await this.#client.batch([...RETIRED_KNOWLEDGE_TABLE_NAMES, ...[...KNOWLEDGE_TABLE_NAMES].reverse()].map((table) => ({
7054
+ sql: `DROP TABLE IF EXISTS "${table}"`,
7055
+ args: []
7056
+ })), "write");
6226
7057
  });
7058
+ await this.init();
7059
+ }
7060
+ async reconcileStructure(plan) {
7061
+ return withReconcileLock(this.getStorageIsolationKey(), () => this.#transaction(async (tx) => {
7062
+ await tx.execute(`UPDATE "${TABLE_KNOWLEDGE_ACCESS_STATE}" SET epoch=epoch WHERE id='global'`);
7063
+ const scopes = {};
7064
+ const createdScopeIds = [];
7065
+ const createdAddresses = /* @__PURE__ */ new Set();
7066
+ const retrofit = plan.retrofit ?? true;
7067
+ let structureChanged = false;
7068
+ const deletedScopeAddresses = /* @__PURE__ */ new Set();
7069
+ const resolveAddress = async (address) => {
7070
+ if (scopes[address]) return scopes[address];
7071
+ const row = (await tx.execute({
7072
+ sql: `SELECT a.scopeNodeId,n.isScope,n.deletedAt FROM "${TABLE_KNOWLEDGE_SCOPE_ADDRESSES}" a JOIN "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" n ON n.id=a.scopeNodeId WHERE a.address=?`,
7073
+ args: [address]
7074
+ })).rows[0];
7075
+ if (!row) return void 0;
7076
+ if (!row.isScope) throw new Error(`Knowledge address ${address} does not reference a scope`);
7077
+ if (row.deletedAt) deletedScopeAddresses.add(address);
7078
+ scopes[address] = String(row.scopeNodeId);
7079
+ return scopes[address];
7080
+ };
7081
+ for (const scope of plan.scopes) {
7082
+ if (await resolveAddress(scope.address)) continue;
7083
+ const id = (0, crypto$1.randomUUID)();
7084
+ const now = (/* @__PURE__ */ new Date()).toISOString();
7085
+ await tx.execute({
7086
+ sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" (id,type,name,canonicalName,kind,description,isScope,metadata,version,createdAt,updatedAt) VALUES (?,'node',?,?,?,?,TRUE,jsonb(?),1,?,?)`,
7087
+ args: [
7088
+ id,
7089
+ scope.name,
7090
+ canonicalName(scope.name),
7091
+ scope.kind ?? null,
7092
+ scope.description ?? null,
7093
+ scope.metadata ? JSON.stringify(scope.metadata) : null,
7094
+ now,
7095
+ now
7096
+ ]
7097
+ });
7098
+ await tx.execute({
7099
+ sql: `INSERT INTO "${TABLE_KNOWLEDGE_SCOPE_ADDRESSES}" (address,scopeNodeId) VALUES (?,?)`,
7100
+ args: [scope.address, id]
7101
+ });
7102
+ scopes[scope.address] = id;
7103
+ createdAddresses.add(scope.address);
7104
+ createdScopeIds.push(id);
7105
+ structureChanged = true;
7106
+ }
7107
+ for (const scope of plan.scopes) {
7108
+ if (!createdAddresses.has(scope.address) && (!retrofit || deletedScopeAddresses.has(scope.address))) continue;
7109
+ const scopeNodeId = scopes[scope.address];
7110
+ for (const parentAddress of scope.parentAddresses ?? []) {
7111
+ const parentId = await resolveAddress(parentAddress);
7112
+ if (!parentId || deletedScopeAddresses.has(parentAddress)) {
7113
+ const deletedParentId = scopes[parentAddress];
7114
+ if ((deletedParentId ? await tx.execute({
7115
+ sql: `SELECT 1 FROM "mastra_knowledge_node_scopes" WHERE nodeId=? AND scopeNodeId=?`,
7116
+ args: [scopeNodeId, deletedParentId]
7117
+ }) : void 0)?.rows.length) continue;
7118
+ throw new Error(`Knowledge parent scope does not exist: ${parentAddress}`);
7119
+ }
7120
+ if ((await tx.execute({
7121
+ sql: `SELECT 1 FROM "mastra_knowledge_node_scopes" WHERE nodeId=? AND scopeNodeId=?`,
7122
+ args: [scopeNodeId, parentId]
7123
+ })).rows.length) continue;
7124
+ if ((await tx.execute({
7125
+ sql: `SELECT n.id FROM "mastra_knowledge_node_scopes" ns JOIN "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" n ON n.id=ns.nodeId WHERE ns.scopeNodeId=? AND n.isScope AND n.canonicalName=? AND n.deletedAt IS NULL AND n.id<>? LIMIT 1`,
7126
+ args: [
7127
+ parentId,
7128
+ canonicalName(scope.name),
7129
+ scopeNodeId
7130
+ ]
7131
+ })).rows.length) throw new Error(`Knowledge scope name ${scope.name} already exists under ${parentAddress}`);
7132
+ const inserted = await tx.execute({
7133
+ sql: `INSERT OR IGNORE INTO "${TABLE_KNOWLEDGE_NODE_SCOPES}" (nodeId,scopeNodeId,addedAt) VALUES (?,?,?)`,
7134
+ args: [
7135
+ scopeNodeId,
7136
+ parentId,
7137
+ (/* @__PURE__ */ new Date()).toISOString()
7138
+ ]
7139
+ });
7140
+ structureChanged ||= inserted.rowsAffected > 0;
7141
+ }
7142
+ for (const grant of scope.grants ?? []) {
7143
+ const scopeRefId = await resolveAddress(grant.scopeRefAddress);
7144
+ if (!scopeRefId || deletedScopeAddresses.has(grant.scopeRefAddress)) {
7145
+ const deletedScopeRefId = scopes[grant.scopeRefAddress];
7146
+ if ((deletedScopeRefId ? await tx.execute({
7147
+ sql: `SELECT 1 FROM "mastra_knowledge_scope_grants" WHERE scopeNodeId=? AND scopeRefId=?`,
7148
+ args: [scopeNodeId, deletedScopeRefId]
7149
+ }) : void 0)?.rows.length) continue;
7150
+ throw new Error(`Knowledge grant scope does not exist: ${grant.scopeRefAddress}`);
7151
+ }
7152
+ const inserted = await tx.execute({
7153
+ sql: `INSERT OR IGNORE INTO "${TABLE_KNOWLEDGE_SCOPE_GRANTS}" (scopeNodeId,scopeRefId,role,canSuggest) VALUES (?,?,?,?)`,
7154
+ args: [
7155
+ scopeNodeId,
7156
+ scopeRefId,
7157
+ grant.role,
7158
+ grant.canSuggest ?? null
7159
+ ]
7160
+ });
7161
+ structureChanged ||= inserted.rowsAffected > 0;
7162
+ }
7163
+ }
7164
+ if (structureChanged) await tx.execute(`UPDATE "${TABLE_KNOWLEDGE_ACCESS_STATE}" SET epoch=epoch+1 WHERE id='global'`);
7165
+ const state = await tx.execute(`SELECT epoch FROM "${TABLE_KNOWLEDGE_ACCESS_STATE}" WHERE id='global'`);
7166
+ return {
7167
+ scopes,
7168
+ createdScopeIds,
7169
+ deletedScopeAddresses: [...deletedScopeAddresses],
7170
+ changed: structureChanged,
7171
+ accessEpoch: Number(state.rows[0]?.epoch ?? 0)
7172
+ };
7173
+ }));
7174
+ }
7175
+ async listScopeNodes(input = {}) {
7176
+ const { limit, after } = parseListKnowledgeScopeNodesInput(input);
7177
+ if (input.addresses?.length === 0 || input.ids?.length === 0) return {
7178
+ scopes: [],
7179
+ nextCursor: null
7180
+ };
7181
+ const args = [];
7182
+ const where = [`n.isScope`, `n.deletedAt IS NULL`];
7183
+ let within = "";
7184
+ if (input.withinAddress !== void 0) {
7185
+ within = `WITH RECURSIVE within_scope(id) AS (SELECT r.id FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" r JOIN "${TABLE_KNOWLEDGE_SCOPE_ADDRESSES}" ra ON ra.scopeNodeId=r.id WHERE ra.address=? AND r.isScope AND r.deletedAt IS NULL UNION SELECT ns.nodeId FROM "${TABLE_KNOWLEDGE_NODE_SCOPES}" ns JOIN within_scope w ON ns.scopeNodeId=w.id JOIN "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" c ON c.id=ns.nodeId WHERE c.isScope AND c.deletedAt IS NULL) `;
7186
+ args.push(input.withinAddress);
7187
+ where.push("n.id IN (SELECT id FROM within_scope)");
7188
+ }
7189
+ if (input.addresses) {
7190
+ where.push(`a.address IN (${input.addresses.map(() => "?").join(",")})`);
7191
+ args.push(...input.addresses);
7192
+ }
7193
+ if (input.ids) {
7194
+ where.push(`n.id IN (${input.ids.map(() => "?").join(",")})`);
7195
+ args.push(...input.ids);
7196
+ }
7197
+ if (after) {
7198
+ where.push("(n.name > ? OR (n.name = ? AND n.id > ?))");
7199
+ args.push(after.name, after.name, after.id);
7200
+ }
7201
+ args.push(limit + 1);
7202
+ const rows = (await this.#client.execute({
7203
+ sql: `${within}SELECT n.id,n.name,n.kind,n.description,a.address FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" n LEFT JOIN "${TABLE_KNOWLEDGE_SCOPE_ADDRESSES}" a ON a.scopeNodeId=n.id WHERE ${where.join(" AND ")} ORDER BY n.name, n.id LIMIT ?`,
7204
+ args
7205
+ })).rows;
7206
+ if (rows.length === 0) return {
7207
+ scopes: [],
7208
+ nextCursor: null
7209
+ };
7210
+ const parents = await this.#client.execute({
7211
+ sql: `SELECT ns.nodeId,ns.scopeNodeId FROM "${TABLE_KNOWLEDGE_NODE_SCOPES}" ns WHERE ns.nodeId IN (${rows.map(() => "?").join(",")}) ORDER BY ns.scopeNodeId`,
7212
+ args: rows.map((row) => String(row.id))
7213
+ });
7214
+ const parentsByScopeId = /* @__PURE__ */ new Map();
7215
+ for (const row of parents.rows) {
7216
+ const scopeId = String(row.nodeId);
7217
+ const parentId = String(row.scopeNodeId);
7218
+ const existing = parentsByScopeId.get(scopeId);
7219
+ if (existing) existing.push(parentId);
7220
+ else parentsByScopeId.set(scopeId, [parentId]);
7221
+ }
7222
+ return pageKnowledgeScopeNodes(rows.map((row) => ({
7223
+ id: String(row.id),
7224
+ address: String(row.address),
7225
+ name: String(row.name),
7226
+ ...row.kind == null ? {} : { kind: String(row.kind) },
7227
+ ...row.description == null ? {} : { description: String(row.description) },
7228
+ parentIds: parentsByScopeId.get(String(row.id)) ?? []
7229
+ })), limit, input);
7230
+ }
7231
+ async listScopeMembers(input) {
7232
+ const { limit, after } = parseListKnowledgeScopeMembersInput(input);
7233
+ const args = [input.scopeNodeId];
7234
+ let keyset = "";
7235
+ if (after) {
7236
+ const updatedAt = after.updatedAt.toISOString();
7237
+ keyset = ` AND (n.updatedAt < ? OR (n.updatedAt = ? AND (n.name > ? OR (n.name = ? AND n.id > ?))))`;
7238
+ args.push(updatedAt, updatedAt, after.name, after.name, after.id);
7239
+ }
7240
+ args.push(limit + 1);
7241
+ return pageKnowledgeScopeMembers((await this.#client.execute({
7242
+ sql: `SELECT *, json(scope) AS scopeJson FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" n WHERE EXISTS (SELECT 1 FROM "${TABLE_KNOWLEDGE_NODE_SCOPES}" ns WHERE ns.nodeId=n.id AND ns.scopeNodeId=?) AND n.deletedAt IS NULL AND n.mergedInto IS NULL${keyset} ORDER BY n.updatedAt DESC, n.name ASC, n.id ASC LIMIT ?`,
7243
+ args
7244
+ })).rows.map(parseNode), limit, input);
6227
7245
  }
6228
7246
  async createNode(input) {
6229
7247
  await assertKnowledgeDescriptionWithinBoundCompat(input.description);
@@ -6233,6 +7251,7 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6233
7251
  if (existing) {
6234
7252
  const terminal = await this.#resolveTerminalNode(tx, existing.id);
6235
7253
  if (!(0, _mastra_core_storage.isKnowledgeScopeVisible)(terminal.scope, scope)) throw new Error(`Merged knowledge node is not visible from scope: ${input.name}`);
7254
+ await this.#placeNodeInScopes(tx, terminal.id, input.scopeAddresses, /* @__PURE__ */ new Date());
6236
7255
  return terminal;
6237
7256
  }
6238
7257
  const now = /* @__PURE__ */ new Date();
@@ -6249,7 +7268,7 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6249
7268
  updatedAt: now
6250
7269
  };
6251
7270
  await tx.execute({
6252
- sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" (id,type,name,canonicalName,kind,content,description,scope,scopeKey,version,mergedInto,createdAt,updatedAt) VALUES (?,?,?,?,?,?,?,jsonb(?),?,?,NULL,?,?)`,
7271
+ sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" (id,type,name,canonicalName,kind,content,description,isScope,scope,scopeKey,version,mergedInto,createdAt,updatedAt) VALUES (?,?,?,?,?,?,?,FALSE,jsonb(?),?,?,NULL,?,?)`,
6253
7272
  args: [
6254
7273
  node.id,
6255
7274
  "node",
@@ -6265,6 +7284,8 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6265
7284
  now.toISOString()
6266
7285
  ]
6267
7286
  });
7287
+ await this.#replaceNodeScopes(tx, node.id, scope, now);
7288
+ await this.#placeNodeInScopes(tx, node.id, input.scopeAddresses, now);
6268
7289
  await this.#replaceMentions(tx, "node", node.id, node.content ?? "", input.resolutionScope ?? scope, scope);
6269
7290
  await this.#activity(tx, "node-created", "node", node.id, scope);
6270
7291
  await this.#outbox(tx, "node", node.id, "upsert", node.version, scope);
@@ -6281,13 +7302,13 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6281
7302
  return this.#resolveNode(this.#client, input.name, (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
6282
7303
  }
6283
7304
  async listNodes(input) {
6284
- const key = (0, _mastra_core_storage.knowledgeScopeKey)((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
7305
+ const keys = visibleScopeKeys((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
6285
7306
  const clauses = [
6286
7307
  `type = 'node'`,
6287
7308
  "mergedInto IS NULL",
6288
- visibleSql
7309
+ visibleSql(keys)
6289
7310
  ];
6290
- const args = [key, key];
7311
+ const args = [...keys];
6291
7312
  if (input.namePrefix) {
6292
7313
  clauses.push("canonicalName LIKE ? ESCAPE '='");
6293
7314
  args.push(`${escapeLikePattern(canonicalName(input.namePrefix))}%`);
@@ -6339,6 +7360,7 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6339
7360
  input.version
6340
7361
  ]
6341
7362
  })).rowsAffected === 0) throw new _mastra_core_storage.KnowledgeConflictError(input.id);
7363
+ if ((0, _mastra_core_storage.knowledgeScopeKey)(existing.scope) !== (0, _mastra_core_storage.knowledgeScopeKey)(scope)) await this.#swapIdentityScopes(tx, input.id, existing.scope, scope, now);
6342
7364
  if (input.content !== void 0 || input.name !== void 0 || input.scope !== void 0) await this.#replaceMentions(tx, "node", input.id, content ?? "", input.resolutionScope ?? scope, scope);
6343
7365
  await this.#activity(tx, "node-updated", "node", input.id, scope);
6344
7366
  if ((0, _mastra_core_storage.knowledgeScopeKey)(existing.scope) !== (0, _mastra_core_storage.knowledgeScopeKey)(scope)) {
@@ -6393,8 +7415,12 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6393
7415
  ]
6394
7416
  })).rowsAffected === 0) throw new _mastra_core_storage.KnowledgeConflictError(source.id);
6395
7417
  await tx.execute({
6396
- sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET node=? WHERE node=?`,
6397
- args: [target.id, source.id]
7418
+ sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET node=?,version=version+1,updatedAt=? WHERE node=?`,
7419
+ args: [
7420
+ target.id,
7421
+ (/* @__PURE__ */ new Date()).toISOString(),
7422
+ source.id
7423
+ ]
6398
7424
  });
6399
7425
  await tx.execute({
6400
7426
  sql: `DELETE FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}" WHERE recordId=? AND EXISTS (SELECT 1 FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}" target WHERE target.sourceType="${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}".sourceType AND target.sourceId="${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}".sourceId AND target.recordId=?)`,
@@ -6434,10 +7460,10 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6434
7460
  });
6435
7461
  }
6436
7462
  async appendKnowledge(input) {
7463
+ await assertKnowledgeRecordTextWithinBoundCompat(input.text);
6437
7464
  const scope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope);
6438
7465
  const resolutionScope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.resolutionScope);
6439
7466
  const defaultScope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.defaultScope);
6440
- (0, _mastra_core_storage.assertKnowledgeScopeWithinCeiling)(scope, input.maxScope);
6441
7467
  return this.#transaction(async (tx) => {
6442
7468
  const node = nodeReferenceId(input.node);
6443
7469
  const parent = await this.#resolveTerminalNode(tx, node);
@@ -6450,11 +7476,10 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6450
7476
  sourceThreadId: input.sourceThreadId,
6451
7477
  capturedAt: /* @__PURE__ */ new Date(),
6452
7478
  when: input.when ? new Date(input.when) : void 0,
6453
- maxScope: input.maxScope,
6454
7479
  metadata: input.metadata
6455
7480
  };
6456
7481
  await tx.execute({
6457
- sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" (id,node,text,scope,scopeKey,sourceThreadId,capturedAt,"when",maxScope,metadata,deletedAt,deletedBy) VALUES (?,?,?,jsonb(?),?,?,?,?,?,jsonb(?),NULL,NULL)`,
7482
+ sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" (id,node,text,scope,scopeKey,sourceThreadId,capturedAt,"when",metadata,version,updatedAt,deletedAt,deletedBy) VALUES (?,?,?,jsonb(?),?,?,?,?,jsonb(?),?,?,NULL,NULL)`,
6458
7483
  args: [
6459
7484
  record.id,
6460
7485
  record.node,
@@ -6464,10 +7489,12 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6464
7489
  record.sourceThreadId,
6465
7490
  record.capturedAt.toISOString(),
6466
7491
  record.when?.toISOString() ?? null,
6467
- record.maxScope ?? null,
6468
- record.metadata ? JSON.stringify(record.metadata) : null
7492
+ record.metadata ? JSON.stringify(record.metadata) : null,
7493
+ 1,
7494
+ record.capturedAt.toISOString()
6469
7495
  ]
6470
7496
  });
7497
+ await this.#replaceRecordScopes(tx, record.id, scope, record.capturedAt);
6471
7498
  await this.#replaceMentions(tx, "record", record.id, record.text, resolutionScope, defaultScope);
6472
7499
  await this.#activity(tx, "record-created", "record", record.id, scope, record.sourceThreadId);
6473
7500
  await this.#outbox(tx, "record", record.id, "upsert", record.id, scope);
@@ -6491,17 +7518,13 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6491
7518
  return this.#queryKnowledge(input, "related");
6492
7519
  }
6493
7520
  async knowledgeBySource(input) {
6494
- const key = (0, _mastra_core_storage.knowledgeScopeKey)((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
6495
- const args = [
6496
- input.sourceThreadId,
6497
- key,
6498
- key
6499
- ];
7521
+ const keys = visibleScopeKeys((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
7522
+ const args = [input.sourceThreadId, ...keys];
6500
7523
  if (input.after) args.push(input.after);
6501
7524
  const limit = input.limit ?? 100;
6502
7525
  args.push(limit + 1);
6503
7526
  const records = (await this.#client.execute({
6504
- sql: `SELECT *,json(scope) AS scopeJson,json(metadata) AS metadataJson FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" WHERE sourceThreadId=? AND ${visibleSql}${input.includeDeleted ? "" : " AND deletedAt IS NULL"}${input.after ? " AND id > ?" : ""} ORDER BY id ASC LIMIT ?`,
7527
+ sql: `SELECT *,json(scope) AS scopeJson,json(metadata) AS metadataJson FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" WHERE sourceThreadId=? AND ${visibleSql(keys)}${input.includeDeleted ? "" : " AND deletedAt IS NULL"}${input.after ? " AND id > ?" : ""} ORDER BY id ASC LIMIT ?`,
6505
7528
  args
6506
7529
  })).rows.map(parseKnowledge);
6507
7530
  return {
@@ -6516,10 +7539,11 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6516
7539
  if (record.deletedAt) return record;
6517
7540
  const deletedAt = /* @__PURE__ */ new Date();
6518
7541
  await tx.execute({
6519
- sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET deletedAt=?,deletedBy=? WHERE id=? AND deletedAt IS NULL`,
7542
+ sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET deletedAt=?,deletedBy=?,version=version+1,updatedAt=? WHERE id=? AND deletedAt IS NULL`,
6520
7543
  args: [
6521
7544
  deletedAt.toISOString(),
6522
7545
  input.deletedBy,
7546
+ deletedAt.toISOString(),
6523
7547
  input.id
6524
7548
  ]
6525
7549
  });
@@ -6538,8 +7562,8 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6538
7562
  if (!record) throw new _mastra_core_storage.KnowledgeNotFoundError("record", input.id);
6539
7563
  if (!record.deletedAt) return record;
6540
7564
  await tx.execute({
6541
- sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET deletedAt=NULL,deletedBy=NULL WHERE id=?`,
6542
- args: [input.id]
7565
+ sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET deletedAt=NULL,deletedBy=NULL,version=version+1,updatedAt=? WHERE id=?`,
7566
+ args: [(/* @__PURE__ */ new Date()).toISOString(), input.id]
6543
7567
  });
6544
7568
  await this.#activity(tx, "record-restored", "record", input.id, record.scope, record.sourceThreadId);
6545
7569
  await this.#outbox(tx, "record", input.id, "upsert", (0, _mastra_core_storage.createKnowledgeUlid)(), record.scope);
@@ -6555,15 +7579,17 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6555
7579
  return this.#transaction(async (tx) => {
6556
7580
  const record = await this.#getKnowledge(tx, input.id, true);
6557
7581
  if (!record) throw new _mastra_core_storage.KnowledgeNotFoundError("record", input.id);
6558
- (0, _mastra_core_storage.assertKnowledgeScopeWithinCeiling)(scope, record.maxScope);
7582
+ const updatedAt = /* @__PURE__ */ new Date();
6559
7583
  await tx.execute({
6560
- sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET scope=jsonb(?),scopeKey=? WHERE id=?`,
7584
+ sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET scope=jsonb(?),scopeKey=?,version=version+1,updatedAt=? WHERE id=?`,
6561
7585
  args: [
6562
7586
  JSON.stringify(scope),
6563
7587
  (0, _mastra_core_storage.knowledgeScopeKey)(scope),
7588
+ updatedAt.toISOString(),
6564
7589
  input.id
6565
7590
  ]
6566
7591
  });
7592
+ await this.#replaceRecordScopes(tx, input.id, scope, updatedAt);
6567
7593
  await this.#activity(tx, "record-rescoped", "record", input.id, scope, record.sourceThreadId);
6568
7594
  if ((0, _mastra_core_storage.knowledgeScopeKey)(record.scope) !== (0, _mastra_core_storage.knowledgeScopeKey)(scope)) await this.#outbox(tx, "record", input.id, "delete", (0, _mastra_core_storage.createKnowledgeUlid)(), record.scope);
6569
7595
  if (!record.deletedAt) await this.#outbox(tx, "record", input.id, "upsert", (0, _mastra_core_storage.createKnowledgeUlid)(), scope);
@@ -6573,32 +7599,16 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6573
7599
  };
6574
7600
  });
6575
7601
  }
6576
- async raiseKnowledgeCeiling(input) {
6577
- return this.#transaction(async (tx) => {
6578
- const record = await this.#getKnowledge(tx, input.id, true);
6579
- if (!record) throw new _mastra_core_storage.KnowledgeNotFoundError("record", input.id);
6580
- (0, _mastra_core_storage.assertKnowledgeScopeWithinCeiling)(record.scope, input.maxScope);
6581
- (0, _mastra_core_storage.assertKnowledgeCeilingRaised)(record.maxScope, input.maxScope);
6582
- await tx.execute({
6583
- sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET maxScope=? WHERE id=?`,
6584
- args: [input.maxScope ?? null, input.id]
6585
- });
6586
- return {
6587
- ...record,
6588
- maxScope: input.maxScope
6589
- };
6590
- });
6591
- }
6592
7602
  async search(input) {
6593
- const key = (0, _mastra_core_storage.knowledgeScopeKey)((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
7603
+ const scope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope);
7604
+ const keys = visibleScopeKeys(scope);
6594
7605
  const normalizedQuery = input.query.trim().toLocaleLowerCase();
6595
7606
  if (!normalizedQuery) return [];
6596
7607
  const query = `%${escapeLikePattern(normalizedQuery)}%`;
6597
7608
  const results = (await this.#client.execute({
6598
- sql: `SELECT *,json(scope) AS scopeJson FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" WHERE mergedInto IS NULL AND ${visibleSql} AND (canonicalName LIKE ? ESCAPE '=' OR lower(COALESCE(kind,'')) LIKE ? ESCAPE '=' OR lower(COALESCE(content,'')) LIKE ? ESCAPE '=' OR lower(COALESCE(description,'')) LIKE ? ESCAPE '=') ORDER BY updatedAt DESC LIMIT ?`,
7609
+ sql: `SELECT *,json(scope) AS scopeJson FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" WHERE mergedInto IS NULL AND ${visibleSql(keys)} AND (canonicalName LIKE ? ESCAPE '=' OR lower(COALESCE(kind,'')) LIKE ? ESCAPE '=' OR lower(COALESCE(content,'')) LIKE ? ESCAPE '=' OR lower(COALESCE(description,'')) LIKE ? ESCAPE '=') ORDER BY updatedAt DESC LIMIT ?`,
6599
7610
  args: [
6600
- key,
6601
- key,
7611
+ ...keys,
6602
7612
  query,
6603
7613
  query,
6604
7614
  query,
@@ -6619,60 +7629,47 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6619
7629
  }));
6620
7630
  if (results.length < (input.limit ?? 20)) {
6621
7631
  const knowledge = await this.#client.execute({
6622
- sql: `SELECT k.*,json(k.scope) AS scopeJson,json(k.metadata) AS metadataJson,n.name FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" k JOIN "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" n ON n.id=k.node AND n.type='node' AND n.mergedInto IS NULL WHERE k.deletedAt IS NULL AND ${visibleSql.replaceAll("scopeKey", "k.scopeKey")} AND lower(k.text) LIKE ? ESCAPE '=' ORDER BY k.id DESC LIMIT ?`,
7632
+ sql: `SELECT k.*,json(k.scope) AS scopeJson,json(k.metadata) AS metadataJson,n.name,json(n.scope) AS parentScopeJson FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" k CROSS JOIN "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" n ON n.id=k.node AND n.type='node' AND n.mergedInto IS NULL WHERE k.deletedAt IS NULL AND ${visibleSql(keys, "k.scopeKey")} AND lower(k.text) LIKE ? ESCAPE '=' ORDER BY k.id DESC LIMIT ?`,
6623
7633
  args: [
6624
- key,
6625
- key,
7634
+ ...keys,
6626
7635
  query,
6627
7636
  (input.limit ?? 20) - results.length
6628
7637
  ]
6629
7638
  });
6630
- results.push(...knowledge.rows.map((row) => ({
6631
- type: "record",
6632
- id: String(row.id),
6633
- recordId: String(row.node),
6634
- name: String(row.name),
6635
- text: String(row.text),
6636
- scope: parseJson$3(row.scopeJson)
6637
- })));
7639
+ results.push(...knowledge.rows.map((row) => {
7640
+ const parentVisible = (0, _mastra_core_storage.isKnowledgeScopeVisible)(parseJson$3(row.parentScopeJson), scope);
7641
+ return {
7642
+ type: "record",
7643
+ id: String(row.id),
7644
+ recordId: parentVisible ? String(row.node) : String(row.id),
7645
+ name: parentVisible ? String(row.name) : "(private node)",
7646
+ text: String(row.text),
7647
+ scope: parseJson$3(row.scopeJson)
7648
+ };
7649
+ }));
6638
7650
  }
6639
7651
  return results;
6640
7652
  }
6641
- async getCurationCursor(input) {
6642
- const row = (await this.#client.execute({
6643
- sql: `SELECT * FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_CURSORS}" WHERE sourceThreadId=? AND agent=?`,
6644
- args: [input.sourceThreadId, input.agent]
6645
- })).rows[0];
6646
- return row ? {
6647
- sourceThreadId: String(row.sourceThreadId),
6648
- agent: String(row.agent),
6649
- lastKnowledgeId: String(row.lastKnowledgeId),
6650
- updatedAt: toDate(row.updatedAt)
6651
- } : null;
6652
- }
6653
- async advanceCurationCursor(input) {
6654
- const updatedAt = /* @__PURE__ */ new Date();
6655
- if ((await this.#db.executeWriteOperationWithRetry(() => withClientWriteLock(this.#client, () => this.#client.execute({
6656
- sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_CURSORS}" (sourceThreadId,agent,lastKnowledgeId,updatedAt) VALUES (?,?,?,?) ON CONFLICT(sourceThreadId,agent) DO UPDATE SET lastKnowledgeId=excluded.lastKnowledgeId,updatedAt=excluded.updatedAt WHERE excluded.lastKnowledgeId >= "${_mastra_core_storage.TABLE_KNOWLEDGE_CURSORS}".lastKnowledgeId`,
6657
- args: [
6658
- input.sourceThreadId,
6659
- input.agent,
6660
- input.lastKnowledgeId,
6661
- updatedAt.toISOString()
6662
- ]
6663
- })), "advance knowledge curation cursor")).rowsAffected === 0) throw new Error("Knowledge curation cursor cannot move backwards");
6664
- return {
6665
- ...input,
6666
- updatedAt
6667
- };
7653
+ /**
7654
+ * @deprecated Curation cursors were removed. Observation-time curate is the only Knowledge writer and needs no
7655
+ * cursor. Always throws.
7656
+ */
7657
+ async getCurationCursor(_input) {
7658
+ throw new Error(KNOWLEDGE_CURATION_CURSOR_REMOVED_MESSAGE);
7659
+ }
7660
+ /**
7661
+ * @deprecated Curation cursors were removed. Observation-time curate is the only Knowledge writer and needs no
7662
+ * cursor. Always throws.
7663
+ */
7664
+ async advanceCurationCursor(_input) {
7665
+ throw new Error(KNOWLEDGE_CURATION_CURSOR_REMOVED_MESSAGE);
6668
7666
  }
6669
7667
  async listActivity(input) {
6670
- const key = (0, _mastra_core_storage.knowledgeScopeKey)((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
7668
+ const keys = visibleScopeKeys((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
6671
7669
  return (await this.#client.execute({
6672
- sql: `SELECT *,json(scope) AS scopeJson FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY}" WHERE ${visibleSql}${input.after ? " AND id < ?" : ""} ORDER BY id DESC LIMIT ?`,
7670
+ sql: `SELECT *,json(scope) AS scopeJson FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY}" WHERE ${visibleSql(keys)}${input.after ? " AND id < ?" : ""} ORDER BY id DESC LIMIT ?`,
6673
7671
  args: [
6674
- key,
6675
- key,
7672
+ ...keys,
6676
7673
  ...input.after ? [input.after] : [],
6677
7674
  input.limit ?? 100
6678
7675
  ]
@@ -6694,9 +7691,9 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6694
7691
  args.push(input.status);
6695
7692
  }
6696
7693
  if (input.scope) {
6697
- const key = (0, _mastra_core_storage.knowledgeScopeKey)((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
6698
- clauses.push(visibleSql);
6699
- args.push(key, key);
7694
+ const keys = visibleScopeKeys(input.scope);
7695
+ clauses.push(visibleSql(keys));
7696
+ args.push(...keys);
6700
7697
  }
6701
7698
  args.push(input.limit ?? 100);
6702
7699
  return (await this.#client.execute({
@@ -6715,9 +7712,9 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6715
7712
  ];
6716
7713
  const args = [now.toISOString(), stale.toISOString()];
6717
7714
  if (input.scope) {
6718
- const key = (0, _mastra_core_storage.knowledgeScopeKey)((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
6719
- clauses.push(visibleSql);
6720
- args.push(key, key);
7715
+ const keys = visibleScopeKeys(input.scope);
7716
+ clauses.push(visibleSql(keys));
7717
+ args.push(...keys);
6721
7718
  }
6722
7719
  args.push(input.limit ?? 100);
6723
7720
  const ids = (await tx.execute({
@@ -6794,12 +7791,14 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6794
7791
  return result.rows[0] ? parseNode(result.rows[0]) : null;
6795
7792
  }
6796
7793
  async #resolveNode(executor, name, scope) {
6797
- for (let length = scope.length; length > 0; length--) {
6798
- const node = await this.#getNodeByName(executor, name, scope.slice(0, length));
6799
- if (node) {
6800
- const terminal = await this.#resolveTerminalNode(executor, node.id);
6801
- if (terminal && (0, _mastra_core_storage.isKnowledgeScopeVisible)(terminal.scope, scope)) return terminal;
6802
- }
7794
+ const keys = visibleScopeKeys(scope);
7795
+ const candidates = (await executor.execute({
7796
+ sql: `SELECT *,json(scope) AS scopeJson FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" WHERE type='node' AND canonicalName=? AND (scopeKey IN (${keys.map(() => "?").join(",")}) OR mergedInto IS NOT NULL)`,
7797
+ args: [canonicalName(name), ...keys]
7798
+ })).rows.map(parseNode).sort((left, right) => right.scope.length - left.scope.length);
7799
+ for (const candidate of candidates) {
7800
+ const terminal = await this.#resolveTerminalNode(executor, candidate.id);
7801
+ if (terminal && (0, _mastra_core_storage.isKnowledgeScopeVisible)(terminal.scope, scope)) return terminal;
6803
7802
  }
6804
7803
  return null;
6805
7804
  }
@@ -6824,19 +7823,18 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6824
7823
  const scope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope);
6825
7824
  const node = await this.#resolveTerminalNode(this.#client, nodeReferenceId(input.node));
6826
7825
  if (!node) return { records: [] };
6827
- const key = (0, _mastra_core_storage.knowledgeScopeKey)(scope);
7826
+ const keys = visibleScopeKeys(scope);
6828
7827
  const includesMentions = relationship !== "about";
6829
7828
  const relationSql = relationship === "about" ? "k.node=?" : relationship === "mentioning" ? "m.recordId=?" : "(k.node=? OR m.recordId=?)";
6830
7829
  const args = [
6831
7830
  node.id,
6832
7831
  ...relationship === "related" ? [node.id] : [],
6833
- key,
6834
- key
7832
+ ...keys
6835
7833
  ];
6836
7834
  if (input.after) args.push(input.after);
6837
7835
  args.push((input.limit ?? 100) + 1);
6838
7836
  const result = await this.#client.execute({
6839
- sql: `SELECT DISTINCT k.*,json(k.scope) AS scopeJson,json(k.metadata) AS metadataJson FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" k${includesMentions ? ` LEFT JOIN "${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}" m ON m.sourceType='record' AND m.sourceId=k.id` : ""} WHERE ${relationSql} AND ${visibleSql.replaceAll("scopeKey", "k.scopeKey")}${input.includeDeleted ? "" : " AND k.deletedAt IS NULL"}${input.after ? " AND k.id < ?" : ""} ORDER BY k.id DESC LIMIT ?`,
7837
+ sql: `SELECT DISTINCT k.*,json(k.scope) AS scopeJson,json(k.metadata) AS metadataJson FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" k${includesMentions ? ` LEFT JOIN "${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}" m ON m.sourceType='record' AND m.sourceId=k.id` : ""} WHERE ${relationSql} AND ${visibleSql(keys, "k.scopeKey")}${input.includeDeleted ? "" : " AND k.deletedAt IS NULL"}${input.after ? " AND k.id < ?" : ""} ORDER BY k.id DESC LIMIT ?`,
6840
7838
  args
6841
7839
  });
6842
7840
  const limit = input.limit ?? 100;
@@ -6846,6 +7844,90 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6846
7844
  nextCursor: result.rows.length > limit ? String(rows.at(-1)?.id) : void 0
6847
7845
  };
6848
7846
  }
7847
+ async #resolveScopeNodeIds(executor, addresses) {
7848
+ const scopeNodeIds = /* @__PURE__ */ new Set();
7849
+ for (const address of addresses) {
7850
+ const result = await executor.execute({
7851
+ sql: `SELECT scopeNodeId FROM "${TABLE_KNOWLEDGE_SCOPE_ADDRESSES}" WHERE address=?`,
7852
+ args: [address]
7853
+ });
7854
+ if (result.rows[0]?.scopeNodeId != null) scopeNodeIds.add(String(result.rows[0].scopeNodeId));
7855
+ }
7856
+ return [...scopeNodeIds];
7857
+ }
7858
+ async #replaceNodeScopes(executor, nodeId, addresses, addedAt) {
7859
+ await executor.execute({
7860
+ sql: `DELETE FROM "${TABLE_KNOWLEDGE_NODE_SCOPES}" WHERE nodeId=?`,
7861
+ args: [nodeId]
7862
+ });
7863
+ for (const scopeNodeId of await this.#resolveScopeNodeIds(executor, addresses)) await executor.execute({
7864
+ sql: `INSERT OR IGNORE INTO "${TABLE_KNOWLEDGE_NODE_SCOPES}" (nodeId,scopeNodeId,addedAt) VALUES (?,?,?)`,
7865
+ args: [
7866
+ nodeId,
7867
+ scopeNodeId,
7868
+ addedAt.toISOString()
7869
+ ]
7870
+ });
7871
+ }
7872
+ /**
7873
+ * Move a node's identity memberships from `from` to `to` without touching structural
7874
+ * placements added by `#placeNodeInScopes`, which a scope change must not erase.
7875
+ */
7876
+ async #swapIdentityScopes(executor, nodeId, from, to, addedAt) {
7877
+ const next = await this.#resolveScopeNodeIds(executor, to);
7878
+ for (const scopeNodeId of await this.#resolveScopeNodeIds(executor, from)) {
7879
+ if (next.includes(scopeNodeId)) continue;
7880
+ await executor.execute({
7881
+ sql: `DELETE FROM "${TABLE_KNOWLEDGE_NODE_SCOPES}" WHERE nodeId=? AND scopeNodeId=?`,
7882
+ args: [nodeId, scopeNodeId]
7883
+ });
7884
+ }
7885
+ for (const scopeNodeId of next) await executor.execute({
7886
+ sql: `INSERT OR IGNORE INTO "${TABLE_KNOWLEDGE_NODE_SCOPES}" (nodeId,scopeNodeId,addedAt) VALUES (?,?,?)`,
7887
+ args: [
7888
+ nodeId,
7889
+ scopeNodeId,
7890
+ addedAt.toISOString()
7891
+ ]
7892
+ });
7893
+ }
7894
+ /**
7895
+ * Additive structural placement: every address must resolve to a live scope node
7896
+ * (unlike identity membership, an unknown address is a caller error, not a lazy
7897
+ * materialization miss). Runs inside the caller's transaction, so a throw aborts
7898
+ * the whole mutation.
7899
+ */
7900
+ async #placeNodeInScopes(executor, nodeId, addresses, addedAt) {
7901
+ for (const address of addresses ?? []) {
7902
+ const scopeNodeId = (await executor.execute({
7903
+ sql: `SELECT sa.scopeNodeId AS scopeNodeId FROM "${TABLE_KNOWLEDGE_SCOPE_ADDRESSES}" sa JOIN "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" n ON n.id=sa.scopeNodeId WHERE sa.address=? AND n.isScope AND n.deletedAt IS NULL`,
7904
+ args: [address]
7905
+ })).rows[0]?.scopeNodeId;
7906
+ if (scopeNodeId == null) throw new _mastra_core_storage.KnowledgeNotFoundError("scope", address);
7907
+ await executor.execute({
7908
+ sql: `INSERT OR IGNORE INTO "${TABLE_KNOWLEDGE_NODE_SCOPES}" (nodeId,scopeNodeId,addedAt) VALUES (?,?,?)`,
7909
+ args: [
7910
+ nodeId,
7911
+ String(scopeNodeId),
7912
+ addedAt.toISOString()
7913
+ ]
7914
+ });
7915
+ }
7916
+ }
7917
+ async #replaceRecordScopes(executor, recordId, addresses, addedAt) {
7918
+ await executor.execute({
7919
+ sql: `DELETE FROM "${TABLE_KNOWLEDGE_RECORD_SCOPES}" WHERE recordId=?`,
7920
+ args: [recordId]
7921
+ });
7922
+ for (const scopeNodeId of await this.#resolveScopeNodeIds(executor, addresses)) await executor.execute({
7923
+ sql: `INSERT OR IGNORE INTO "${TABLE_KNOWLEDGE_RECORD_SCOPES}" (recordId,scopeNodeId,addedAt) VALUES (?,?,?)`,
7924
+ args: [
7925
+ recordId,
7926
+ scopeNodeId,
7927
+ addedAt.toISOString()
7928
+ ]
7929
+ });
7930
+ }
6849
7931
  async #replaceMentions(tx, sourceType, sourceId, text, resolutionScope, defaultScope) {
6850
7932
  await tx.execute({
6851
7933
  sql: `DELETE FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}" WHERE sourceType=? AND sourceId=?`,
@@ -6869,7 +7951,7 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6869
7951
  updatedAt: now
6870
7952
  };
6871
7953
  await tx.execute({
6872
- sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" (id,type,name,canonicalName,kind,content,scope,scopeKey,version,mergedInto,createdAt,updatedAt) VALUES (?,?,?,?,?,NULL,jsonb(?),?,?,NULL,?,?)`,
7954
+ sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" (id,type,name,canonicalName,kind,content,isScope,scope,scopeKey,version,mergedInto,createdAt,updatedAt) VALUES (?,?,?,?,?,NULL,FALSE,jsonb(?),?,?,NULL,?,?)`,
6873
7955
  args: [
6874
7956
  node.id,
6875
7957
  "node",
@@ -6883,6 +7965,7 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6883
7965
  now.toISOString()
6884
7966
  ]
6885
7967
  });
7968
+ await this.#replaceNodeScopes(tx, node.id, defaultScope, now);
6886
7969
  await this.#activity(tx, "node-created", "node", node.id, defaultScope);
6887
7970
  await this.#outbox(tx, "node", node.id, "upsert", 1, defaultScope);
6888
7971
  }
@@ -6899,13 +7982,17 @@ var KnowledgeLibSQL = class extends _mastra_core_storage.KnowledgeStorage {
6899
7982
  }
6900
7983
  async #activity(executor, action, recordType, recordId, scope, sourceThreadId) {
6901
7984
  const now = /* @__PURE__ */ new Date();
7985
+ const [contextScopeId] = await this.#resolveScopeNodeIds(executor, scope);
6902
7986
  await executor.execute({
6903
- sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY}" (id,action,recordType,recordId,scope,scopeKey,sourceThreadId,createdAt) VALUES (?,?,?,?,jsonb(?),?,?,?)`,
7987
+ sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY}" (id,action,targetType,targetId,contextScopeId,recordType,recordId,scope,scopeKey,sourceThreadId,createdAt) VALUES (?,?,?,?,?,?,?,jsonb(?),?,?,?)`,
6904
7988
  args: [
6905
7989
  (0, _mastra_core_storage.createKnowledgeUlid)(),
6906
7990
  action,
6907
7991
  recordType,
6908
7992
  recordId,
7993
+ contextScopeId ?? null,
7994
+ recordType,
7995
+ recordId,
6909
7996
  JSON.stringify(scope),
6910
7997
  (0, _mastra_core_storage.knowledgeScopeKey)(scope),
6911
7998
  sourceThreadId ?? null,
@@ -14683,7 +15770,10 @@ var LibSQLStore = class extends _mastra_core_storage.MastraCompositeStore {
14683
15770
  const workflows = new WorkflowsLibSQL(domainConfig);
14684
15771
  const workflowDefinitions = new WorkflowDefinitionsLibSQL(domainConfig);
14685
15772
  const memory = new MemoryLibSQL(domainConfig);
14686
- const knowledge = new KnowledgeLibSQL(domainConfig);
15773
+ const knowledge = new KnowledgeLibSQL({
15774
+ ...domainConfig,
15775
+ storageIsolationKey: config.storageIsolationKey ?? getLibSQLKnowledgeIsolationKey(config, this.client)
15776
+ });
14687
15777
  const observability = new ObservabilityLibSQL(domainConfig);
14688
15778
  const agents = new AgentsLibSQL(domainConfig);
14689
15779
  const channels = new ChannelsLibSQL(domainConfig);
@@ -14747,7 +15837,7 @@ var LibSQLStore = class extends _mastra_core_storage.MastraCompositeStore {
14747
15837
  }
14748
15838
  }
14749
15839
  getStoresToInit() {
14750
- return Object.values(this.stores).filter(Boolean);
15840
+ return Object.entries(this.stores).filter(([name]) => name !== "knowledge").map(([, store]) => store).filter(Boolean);
14751
15841
  }
14752
15842
  async initDomainsSequentially() {
14753
15843
  for (const store of this.getStoresToInit()) await store.init();