@mastra/pg 1.31.0-alpha.2 → 1.31.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_types/@internal_core/dist/knowledge-compat/index.d.ts +594 -0
- package/dist/_types/@internal_core/package.json +1 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +1350 -217
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1353 -220
- package/dist/index.js.map +1 -1
- package/dist/shared/config.d.ts +6 -0
- package/dist/shared/config.d.ts.map +1 -1
- package/dist/storage/db/index.d.ts +8 -5
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/domains/knowledge/index.d.ts +38 -9
- package/dist/storage/domains/knowledge/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -35,8 +35,8 @@ let pg_connection_string = require("pg-connection-string");
|
|
|
35
35
|
let _mastra_core_vector_filter = require("@mastra/core/vector/filter");
|
|
36
36
|
let _mastra_core_base = require("@mastra/core/base");
|
|
37
37
|
let crypto$1 = require("crypto");
|
|
38
|
-
let _mastra_core_agent = require("@mastra/core/agent");
|
|
39
38
|
let _mastra_core_features = require("@mastra/core/features");
|
|
39
|
+
let _mastra_core_agent = require("@mastra/core/agent");
|
|
40
40
|
let _mastra_core_evals = require("@mastra/core/evals");
|
|
41
41
|
let _mastra_core_storage_domains_skills = require("@mastra/core/storage/domains/skills");
|
|
42
42
|
let util = require("util");
|
|
@@ -8301,18 +8301,650 @@ var FavoritesPG = class FavoritesPG extends _mastra_core_storage.FavoritesStorag
|
|
|
8301
8301
|
}
|
|
8302
8302
|
};
|
|
8303
8303
|
//#endregion
|
|
8304
|
+
//#region ../../packages/_internal-core/dist/knowledge-compat/index.js
|
|
8305
|
+
const KNOWLEDGE_V2_CORE_FEATURE = "knowledge-v2";
|
|
8306
|
+
/** Hard cap on scope nodes returned by one `listScopeNodes` read. */
|
|
8307
|
+
const MAX_KNOWLEDGE_SCOPE_NODES = 1e3;
|
|
8308
|
+
function knowledgeScopeNodeFilterKey(input) {
|
|
8309
|
+
return JSON.stringify([
|
|
8310
|
+
input.withinAddress ?? null,
|
|
8311
|
+
input.addresses ? [...input.addresses].sort() : null,
|
|
8312
|
+
input.ids ? [...input.ids].sort() : null
|
|
8313
|
+
]);
|
|
8314
|
+
}
|
|
8315
|
+
function createKnowledgeScopeNodeCursor(scope, input) {
|
|
8316
|
+
return encodeURIComponent(JSON.stringify({
|
|
8317
|
+
version: 1,
|
|
8318
|
+
type: "scope",
|
|
8319
|
+
name: scope.name,
|
|
8320
|
+
id: scope.id,
|
|
8321
|
+
filter: knowledgeScopeNodeFilterKey(input)
|
|
8322
|
+
}));
|
|
8323
|
+
}
|
|
8324
|
+
/** Validates the page size and cursor of a `listScopeNodes` query; throws on a cursor from a different query. */
|
|
8325
|
+
function parseListKnowledgeScopeNodesInput(input = {}) {
|
|
8326
|
+
const requested = Number.isFinite(input.limit) ? Math.trunc(input.limit) : MAX_KNOWLEDGE_SCOPE_NODES;
|
|
8327
|
+
const limit = Math.min(Math.max(requested, 1), MAX_KNOWLEDGE_SCOPE_NODES);
|
|
8328
|
+
if (!input.cursor) return {
|
|
8329
|
+
limit,
|
|
8330
|
+
after: null
|
|
8331
|
+
};
|
|
8332
|
+
let value;
|
|
8333
|
+
try {
|
|
8334
|
+
value = JSON.parse(decodeURIComponent(input.cursor));
|
|
8335
|
+
} catch {
|
|
8336
|
+
throw new Error("Invalid Knowledge scope node cursor.");
|
|
8337
|
+
}
|
|
8338
|
+
const parsed = value && typeof value === "object" ? value : {};
|
|
8339
|
+
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.");
|
|
8340
|
+
return {
|
|
8341
|
+
limit,
|
|
8342
|
+
after: {
|
|
8343
|
+
name: parsed.name,
|
|
8344
|
+
id: parsed.id
|
|
8345
|
+
}
|
|
8346
|
+
};
|
|
8347
|
+
}
|
|
8348
|
+
/** Builds a page from up to `limit + 1` name/id-ordered scope nodes. */
|
|
8349
|
+
function pageKnowledgeScopeNodes(rows, limit, input) {
|
|
8350
|
+
const scopes = rows.slice(0, limit);
|
|
8351
|
+
const last = scopes.at(-1);
|
|
8352
|
+
return {
|
|
8353
|
+
scopes,
|
|
8354
|
+
nextCursor: rows.length > limit && last ? createKnowledgeScopeNodeCursor(last, input) : null
|
|
8355
|
+
};
|
|
8356
|
+
}
|
|
8357
|
+
/** Clamps a requested member limit to 1–{@link MAX_KNOWLEDGE_SCOPE_MEMBERS_LIMIT}. */
|
|
8358
|
+
function knowledgeScopeMembersLimit(limit) {
|
|
8359
|
+
if (limit === void 0 || !Number.isFinite(limit)) return 500;
|
|
8360
|
+
return Math.min(Math.max(Math.trunc(limit), 1), 500);
|
|
8361
|
+
}
|
|
8362
|
+
/** Validates the page size and cursor of a `listScopeMembers` query; throws on a cursor from another scope. */
|
|
8363
|
+
function parseListKnowledgeScopeMembersInput(input) {
|
|
8364
|
+
const limit = knowledgeScopeMembersLimit(input.limit);
|
|
8365
|
+
if (!input.cursor) return {
|
|
8366
|
+
limit,
|
|
8367
|
+
after: null
|
|
8368
|
+
};
|
|
8369
|
+
let value;
|
|
8370
|
+
try {
|
|
8371
|
+
value = JSON.parse(decodeURIComponent(input.cursor));
|
|
8372
|
+
} catch {
|
|
8373
|
+
throw new Error("Invalid Knowledge scope member cursor.");
|
|
8374
|
+
}
|
|
8375
|
+
const parsed = value && typeof value === "object" ? value : {};
|
|
8376
|
+
const updatedAt = typeof parsed.updatedAt === "string" ? new Date(parsed.updatedAt) : /* @__PURE__ */ new Date(NaN);
|
|
8377
|
+
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.");
|
|
8378
|
+
return {
|
|
8379
|
+
limit,
|
|
8380
|
+
after: {
|
|
8381
|
+
updatedAt,
|
|
8382
|
+
name: parsed.name,
|
|
8383
|
+
id: parsed.id
|
|
8384
|
+
}
|
|
8385
|
+
};
|
|
8386
|
+
}
|
|
8387
|
+
/** Builds a page from up to `limit + 1` members in `listScopeMembers` order. */
|
|
8388
|
+
function pageKnowledgeScopeMembers(rows, limit, input) {
|
|
8389
|
+
const members = rows.slice(0, limit);
|
|
8390
|
+
const last = members.at(-1);
|
|
8391
|
+
const hasMore = rows.length > limit;
|
|
8392
|
+
return {
|
|
8393
|
+
members,
|
|
8394
|
+
hasMore,
|
|
8395
|
+
nextCursor: hasMore && last ? encodeURIComponent(JSON.stringify({
|
|
8396
|
+
version: 1,
|
|
8397
|
+
type: "scope-member",
|
|
8398
|
+
scopeNodeId: input.scopeNodeId,
|
|
8399
|
+
updatedAt: last.updatedAt.toISOString(),
|
|
8400
|
+
name: last.name,
|
|
8401
|
+
id: last.id
|
|
8402
|
+
})) : null
|
|
8403
|
+
};
|
|
8404
|
+
}
|
|
8405
|
+
const TABLE_KNOWLEDGE_NODES$1 = "mastra_knowledge_nodes";
|
|
8406
|
+
const TABLE_KNOWLEDGE_RECORDS$1 = "mastra_knowledge_records";
|
|
8407
|
+
const TABLE_KNOWLEDGE_MENTIONS$1 = "mastra_knowledge_mentions";
|
|
8408
|
+
const TABLE_KNOWLEDGE_ACTIVITY$1 = "mastra_knowledge_activity";
|
|
8409
|
+
const TABLE_KNOWLEDGE_SEMANTIC_OUTBOX$1 = "mastra_knowledge_semantic_outbox";
|
|
8410
|
+
const TABLE_KNOWLEDGE_NODE_SCOPES = "mastra_knowledge_node_scopes";
|
|
8411
|
+
const TABLE_KNOWLEDGE_RECORD_SCOPES = "mastra_knowledge_record_scopes";
|
|
8412
|
+
const TABLE_KNOWLEDGE_SCOPE_GRANTS = "mastra_knowledge_scope_grants";
|
|
8413
|
+
const TABLE_KNOWLEDGE_ACCESS_STATE = "mastra_knowledge_access_state";
|
|
8414
|
+
const TABLE_KNOWLEDGE_SCOPE_ADDRESSES = "mastra_knowledge_scope_addresses";
|
|
8415
|
+
const TABLE_KNOWLEDGE_NODE_ADDRESSES = "mastra_knowledge_node_addresses";
|
|
8416
|
+
const TABLE_KNOWLEDGE_IMPORT_STATE = "mastra_knowledge_import_state";
|
|
8417
|
+
const TABLE_KNOWLEDGE_IMPORT_RUNS = "mastra_knowledge_import_runs";
|
|
8418
|
+
const TABLE_KNOWLEDGE_PROPOSALS = "mastra_knowledge_proposals";
|
|
8419
|
+
const KNOWLEDGE_TABLE_NAMES = [
|
|
8420
|
+
TABLE_KNOWLEDGE_NODES$1,
|
|
8421
|
+
TABLE_KNOWLEDGE_RECORDS$1,
|
|
8422
|
+
TABLE_KNOWLEDGE_MENTIONS$1,
|
|
8423
|
+
TABLE_KNOWLEDGE_ACTIVITY$1,
|
|
8424
|
+
TABLE_KNOWLEDGE_SEMANTIC_OUTBOX$1,
|
|
8425
|
+
TABLE_KNOWLEDGE_NODE_SCOPES,
|
|
8426
|
+
TABLE_KNOWLEDGE_RECORD_SCOPES,
|
|
8427
|
+
TABLE_KNOWLEDGE_SCOPE_GRANTS,
|
|
8428
|
+
TABLE_KNOWLEDGE_ACCESS_STATE,
|
|
8429
|
+
TABLE_KNOWLEDGE_SCOPE_ADDRESSES,
|
|
8430
|
+
TABLE_KNOWLEDGE_NODE_ADDRESSES,
|
|
8431
|
+
TABLE_KNOWLEDGE_IMPORT_STATE,
|
|
8432
|
+
TABLE_KNOWLEDGE_IMPORT_RUNS,
|
|
8433
|
+
TABLE_KNOWLEDGE_PROPOSALS
|
|
8434
|
+
];
|
|
8435
|
+
/** Knowledge v1 tables with no v2 equivalent; an explicit schema reset drops them. */
|
|
8436
|
+
const RETIRED_KNOWLEDGE_TABLE_NAMES = ["mastra_knowledge_cursors"];
|
|
8437
|
+
/** Tables and indexes published v1 adapters created for every app, whether or not it used Knowledge. */
|
|
8438
|
+
const PUBLISHED_KNOWLEDGE_V1_TABLE_NAMES = /* @__PURE__ */ new Set([
|
|
8439
|
+
TABLE_KNOWLEDGE_NODES$1,
|
|
8440
|
+
TABLE_KNOWLEDGE_RECORDS$1,
|
|
8441
|
+
TABLE_KNOWLEDGE_MENTIONS$1,
|
|
8442
|
+
TABLE_KNOWLEDGE_ACTIVITY$1,
|
|
8443
|
+
TABLE_KNOWLEDGE_SEMANTIC_OUTBOX$1,
|
|
8444
|
+
...RETIRED_KNOWLEDGE_TABLE_NAMES
|
|
8445
|
+
]);
|
|
8446
|
+
const PUBLISHED_KNOWLEDGE_V1_INDEX_NAMES = /* @__PURE__ */ new Set([
|
|
8447
|
+
"idx_knowledge_nodes_identity",
|
|
8448
|
+
"idx_knowledge_nodes_scope",
|
|
8449
|
+
"idx_knowledge_records_node_latest",
|
|
8450
|
+
"idx_knowledge_records_thread_latest",
|
|
8451
|
+
"idx_knowledge_mentions_record",
|
|
8452
|
+
"idx_knowledge_activity_latest",
|
|
8453
|
+
"idx_knowledge_outbox_idempotency",
|
|
8454
|
+
"idx_knowledge_outbox_claim"
|
|
8455
|
+
]);
|
|
8456
|
+
const KNOWLEDGE_V2_NODES_SCHEMA = {
|
|
8457
|
+
id: {
|
|
8458
|
+
type: "text",
|
|
8459
|
+
nullable: false,
|
|
8460
|
+
primaryKey: true
|
|
8461
|
+
},
|
|
8462
|
+
name: {
|
|
8463
|
+
type: "text",
|
|
8464
|
+
nullable: false
|
|
8465
|
+
},
|
|
8466
|
+
kind: {
|
|
8467
|
+
type: "text",
|
|
8468
|
+
nullable: true
|
|
8469
|
+
},
|
|
8470
|
+
isScope: {
|
|
8471
|
+
type: "boolean",
|
|
8472
|
+
nullable: false
|
|
8473
|
+
},
|
|
8474
|
+
metadata: {
|
|
8475
|
+
type: "jsonb",
|
|
8476
|
+
nullable: true
|
|
8477
|
+
},
|
|
8478
|
+
version: {
|
|
8479
|
+
type: "integer",
|
|
8480
|
+
nullable: false
|
|
8481
|
+
},
|
|
8482
|
+
createdAt: {
|
|
8483
|
+
type: "timestamp",
|
|
8484
|
+
nullable: false
|
|
8485
|
+
},
|
|
8486
|
+
updatedAt: {
|
|
8487
|
+
type: "timestamp",
|
|
8488
|
+
nullable: false
|
|
8489
|
+
},
|
|
8490
|
+
deletedAt: {
|
|
8491
|
+
type: "timestamp",
|
|
8492
|
+
nullable: true
|
|
8493
|
+
},
|
|
8494
|
+
deletedBy: {
|
|
8495
|
+
type: "text",
|
|
8496
|
+
nullable: true
|
|
8497
|
+
},
|
|
8498
|
+
type: {
|
|
8499
|
+
type: "text",
|
|
8500
|
+
nullable: true
|
|
8501
|
+
},
|
|
8502
|
+
canonicalName: {
|
|
8503
|
+
type: "text",
|
|
8504
|
+
nullable: true
|
|
8505
|
+
},
|
|
8506
|
+
content: {
|
|
8507
|
+
type: "text",
|
|
8508
|
+
nullable: true
|
|
8509
|
+
},
|
|
8510
|
+
description: {
|
|
8511
|
+
type: "text",
|
|
8512
|
+
nullable: true
|
|
8513
|
+
},
|
|
8514
|
+
scope: {
|
|
8515
|
+
type: "jsonb",
|
|
8516
|
+
nullable: true
|
|
8517
|
+
},
|
|
8518
|
+
scopeKey: {
|
|
8519
|
+
type: "text",
|
|
8520
|
+
nullable: true
|
|
8521
|
+
},
|
|
8522
|
+
mergedInto: {
|
|
8523
|
+
type: "text",
|
|
8524
|
+
nullable: true
|
|
8525
|
+
}
|
|
8526
|
+
};
|
|
8527
|
+
const KNOWLEDGE_V2_RECORDS_SCHEMA = {
|
|
8528
|
+
id: {
|
|
8529
|
+
type: "text",
|
|
8530
|
+
nullable: false,
|
|
8531
|
+
primaryKey: true
|
|
8532
|
+
},
|
|
8533
|
+
node: {
|
|
8534
|
+
type: "text",
|
|
8535
|
+
nullable: false,
|
|
8536
|
+
references: {
|
|
8537
|
+
table: TABLE_KNOWLEDGE_NODES$1,
|
|
8538
|
+
column: "id"
|
|
8539
|
+
}
|
|
8540
|
+
},
|
|
8541
|
+
text: {
|
|
8542
|
+
type: "text",
|
|
8543
|
+
nullable: false
|
|
8544
|
+
},
|
|
8545
|
+
metadata: {
|
|
8546
|
+
type: "jsonb",
|
|
8547
|
+
nullable: true
|
|
8548
|
+
},
|
|
8549
|
+
version: {
|
|
8550
|
+
type: "integer",
|
|
8551
|
+
nullable: false
|
|
8552
|
+
},
|
|
8553
|
+
capturedAt: {
|
|
8554
|
+
type: "timestamp",
|
|
8555
|
+
nullable: false
|
|
8556
|
+
},
|
|
8557
|
+
updatedAt: {
|
|
8558
|
+
type: "timestamp",
|
|
8559
|
+
nullable: false
|
|
8560
|
+
},
|
|
8561
|
+
deletedAt: {
|
|
8562
|
+
type: "timestamp",
|
|
8563
|
+
nullable: true
|
|
8564
|
+
},
|
|
8565
|
+
deletedBy: {
|
|
8566
|
+
type: "text",
|
|
8567
|
+
nullable: true
|
|
8568
|
+
},
|
|
8569
|
+
scope: {
|
|
8570
|
+
type: "jsonb",
|
|
8571
|
+
nullable: true
|
|
8572
|
+
},
|
|
8573
|
+
scopeKey: {
|
|
8574
|
+
type: "text",
|
|
8575
|
+
nullable: true
|
|
8576
|
+
},
|
|
8577
|
+
sourceThreadId: {
|
|
8578
|
+
type: "text",
|
|
8579
|
+
nullable: true
|
|
8580
|
+
},
|
|
8581
|
+
when: {
|
|
8582
|
+
type: "timestamp",
|
|
8583
|
+
nullable: true
|
|
8584
|
+
}
|
|
8585
|
+
};
|
|
8586
|
+
const KNOWLEDGE_V2_MENTIONS_SCHEMA = {
|
|
8587
|
+
recordId: {
|
|
8588
|
+
type: "text",
|
|
8589
|
+
nullable: false,
|
|
8590
|
+
references: {
|
|
8591
|
+
table: TABLE_KNOWLEDGE_RECORDS$1,
|
|
8592
|
+
column: "id"
|
|
8593
|
+
}
|
|
8594
|
+
},
|
|
8595
|
+
targetNodeId: {
|
|
8596
|
+
type: "text",
|
|
8597
|
+
nullable: true,
|
|
8598
|
+
references: {
|
|
8599
|
+
table: TABLE_KNOWLEDGE_NODES$1,
|
|
8600
|
+
column: "id"
|
|
8601
|
+
}
|
|
8602
|
+
},
|
|
8603
|
+
sourceType: {
|
|
8604
|
+
type: "text",
|
|
8605
|
+
nullable: true
|
|
8606
|
+
},
|
|
8607
|
+
sourceId: {
|
|
8608
|
+
type: "text",
|
|
8609
|
+
nullable: true
|
|
8610
|
+
}
|
|
8611
|
+
};
|
|
8612
|
+
const KNOWLEDGE_NODE_SCOPES_SCHEMA = {
|
|
8613
|
+
nodeId: {
|
|
8614
|
+
type: "text",
|
|
8615
|
+
nullable: false,
|
|
8616
|
+
references: {
|
|
8617
|
+
table: TABLE_KNOWLEDGE_NODES$1,
|
|
8618
|
+
column: "id"
|
|
8619
|
+
}
|
|
8620
|
+
},
|
|
8621
|
+
scopeNodeId: {
|
|
8622
|
+
type: "text",
|
|
8623
|
+
nullable: false,
|
|
8624
|
+
references: {
|
|
8625
|
+
table: TABLE_KNOWLEDGE_NODES$1,
|
|
8626
|
+
column: "id"
|
|
8627
|
+
}
|
|
8628
|
+
},
|
|
8629
|
+
addedAt: {
|
|
8630
|
+
type: "timestamp",
|
|
8631
|
+
nullable: false
|
|
8632
|
+
}
|
|
8633
|
+
};
|
|
8634
|
+
const KNOWLEDGE_RECORD_SCOPES_SCHEMA = {
|
|
8635
|
+
recordId: {
|
|
8636
|
+
type: "text",
|
|
8637
|
+
nullable: false,
|
|
8638
|
+
references: {
|
|
8639
|
+
table: TABLE_KNOWLEDGE_RECORDS$1,
|
|
8640
|
+
column: "id"
|
|
8641
|
+
}
|
|
8642
|
+
},
|
|
8643
|
+
scopeNodeId: {
|
|
8644
|
+
type: "text",
|
|
8645
|
+
nullable: false,
|
|
8646
|
+
references: {
|
|
8647
|
+
table: TABLE_KNOWLEDGE_NODES$1,
|
|
8648
|
+
column: "id"
|
|
8649
|
+
}
|
|
8650
|
+
},
|
|
8651
|
+
addedAt: {
|
|
8652
|
+
type: "timestamp",
|
|
8653
|
+
nullable: false
|
|
8654
|
+
}
|
|
8655
|
+
};
|
|
8656
|
+
const KNOWLEDGE_SCOPE_GRANTS_SCHEMA = {
|
|
8657
|
+
scopeNodeId: {
|
|
8658
|
+
type: "text",
|
|
8659
|
+
nullable: false,
|
|
8660
|
+
references: {
|
|
8661
|
+
table: TABLE_KNOWLEDGE_NODES$1,
|
|
8662
|
+
column: "id"
|
|
8663
|
+
}
|
|
8664
|
+
},
|
|
8665
|
+
scopeRefId: {
|
|
8666
|
+
type: "text",
|
|
8667
|
+
nullable: false,
|
|
8668
|
+
references: {
|
|
8669
|
+
table: TABLE_KNOWLEDGE_NODES$1,
|
|
8670
|
+
column: "id"
|
|
8671
|
+
}
|
|
8672
|
+
},
|
|
8673
|
+
role: {
|
|
8674
|
+
type: "text",
|
|
8675
|
+
nullable: false
|
|
8676
|
+
},
|
|
8677
|
+
canSuggest: {
|
|
8678
|
+
type: "boolean",
|
|
8679
|
+
nullable: true
|
|
8680
|
+
}
|
|
8681
|
+
};
|
|
8682
|
+
const KNOWLEDGE_ACCESS_STATE_SCHEMA = {
|
|
8683
|
+
id: {
|
|
8684
|
+
type: "text",
|
|
8685
|
+
nullable: false,
|
|
8686
|
+
primaryKey: true
|
|
8687
|
+
},
|
|
8688
|
+
epoch: {
|
|
8689
|
+
type: "integer",
|
|
8690
|
+
nullable: false
|
|
8691
|
+
},
|
|
8692
|
+
schemaVersion: {
|
|
8693
|
+
type: "integer",
|
|
8694
|
+
nullable: false
|
|
8695
|
+
}
|
|
8696
|
+
};
|
|
8697
|
+
const KNOWLEDGE_SCOPE_ADDRESSES_SCHEMA = {
|
|
8698
|
+
address: {
|
|
8699
|
+
type: "text",
|
|
8700
|
+
nullable: false,
|
|
8701
|
+
primaryKey: true
|
|
8702
|
+
},
|
|
8703
|
+
scopeNodeId: {
|
|
8704
|
+
type: "text",
|
|
8705
|
+
nullable: false,
|
|
8706
|
+
references: {
|
|
8707
|
+
table: TABLE_KNOWLEDGE_NODES$1,
|
|
8708
|
+
column: "id"
|
|
8709
|
+
}
|
|
8710
|
+
}
|
|
8711
|
+
};
|
|
8712
|
+
const KNOWLEDGE_NODE_ADDRESSES_SCHEMA = {
|
|
8713
|
+
source: {
|
|
8714
|
+
type: "text",
|
|
8715
|
+
nullable: false
|
|
8716
|
+
},
|
|
8717
|
+
address: {
|
|
8718
|
+
type: "text",
|
|
8719
|
+
nullable: false
|
|
8720
|
+
},
|
|
8721
|
+
nodeId: {
|
|
8722
|
+
type: "text",
|
|
8723
|
+
nullable: false,
|
|
8724
|
+
references: {
|
|
8725
|
+
table: TABLE_KNOWLEDGE_NODES$1,
|
|
8726
|
+
column: "id"
|
|
8727
|
+
}
|
|
8728
|
+
}
|
|
8729
|
+
};
|
|
8730
|
+
const KNOWLEDGE_IMPORT_STATE_SCHEMA = {
|
|
8731
|
+
importerId: {
|
|
8732
|
+
type: "text",
|
|
8733
|
+
nullable: false
|
|
8734
|
+
},
|
|
8735
|
+
binding: {
|
|
8736
|
+
type: "text",
|
|
8737
|
+
nullable: false
|
|
8738
|
+
},
|
|
8739
|
+
key: {
|
|
8740
|
+
type: "text",
|
|
8741
|
+
nullable: false
|
|
8742
|
+
},
|
|
8743
|
+
value: {
|
|
8744
|
+
type: "text",
|
|
8745
|
+
nullable: false
|
|
8746
|
+
}
|
|
8747
|
+
};
|
|
8748
|
+
const KNOWLEDGE_IMPORT_RUNS_SCHEMA = {
|
|
8749
|
+
id: {
|
|
8750
|
+
type: "text",
|
|
8751
|
+
nullable: false,
|
|
8752
|
+
primaryKey: true
|
|
8753
|
+
},
|
|
8754
|
+
importerId: {
|
|
8755
|
+
type: "text",
|
|
8756
|
+
nullable: false
|
|
8757
|
+
},
|
|
8758
|
+
binding: {
|
|
8759
|
+
type: "text",
|
|
8760
|
+
nullable: false
|
|
8761
|
+
},
|
|
8762
|
+
importKind: {
|
|
8763
|
+
type: "text",
|
|
8764
|
+
nullable: false
|
|
8765
|
+
},
|
|
8766
|
+
triggerKind: {
|
|
8767
|
+
type: "text",
|
|
8768
|
+
nullable: false
|
|
8769
|
+
},
|
|
8770
|
+
status: {
|
|
8771
|
+
type: "text",
|
|
8772
|
+
nullable: false
|
|
8773
|
+
},
|
|
8774
|
+
error: {
|
|
8775
|
+
type: "text",
|
|
8776
|
+
nullable: true
|
|
8777
|
+
},
|
|
8778
|
+
transcriptThreadId: {
|
|
8779
|
+
type: "text",
|
|
8780
|
+
nullable: true
|
|
8781
|
+
},
|
|
8782
|
+
traceId: {
|
|
8783
|
+
type: "text",
|
|
8784
|
+
nullable: true
|
|
8785
|
+
},
|
|
8786
|
+
queuedAt: {
|
|
8787
|
+
type: "timestamp",
|
|
8788
|
+
nullable: false
|
|
8789
|
+
},
|
|
8790
|
+
startedAt: {
|
|
8791
|
+
type: "timestamp",
|
|
8792
|
+
nullable: true
|
|
8793
|
+
},
|
|
8794
|
+
completedAt: {
|
|
8795
|
+
type: "timestamp",
|
|
8796
|
+
nullable: true
|
|
8797
|
+
}
|
|
8798
|
+
};
|
|
8799
|
+
const KNOWLEDGE_V2_ACTIVITY_SCHEMA = {
|
|
8800
|
+
id: {
|
|
8801
|
+
type: "text",
|
|
8802
|
+
nullable: false,
|
|
8803
|
+
primaryKey: true
|
|
8804
|
+
},
|
|
8805
|
+
action: {
|
|
8806
|
+
type: "text",
|
|
8807
|
+
nullable: false
|
|
8808
|
+
},
|
|
8809
|
+
targetType: {
|
|
8810
|
+
type: "text",
|
|
8811
|
+
nullable: true
|
|
8812
|
+
},
|
|
8813
|
+
targetId: {
|
|
8814
|
+
type: "text",
|
|
8815
|
+
nullable: true
|
|
8816
|
+
},
|
|
8817
|
+
contextScopeId: {
|
|
8818
|
+
type: "text",
|
|
8819
|
+
nullable: true,
|
|
8820
|
+
references: {
|
|
8821
|
+
table: TABLE_KNOWLEDGE_NODES$1,
|
|
8822
|
+
column: "id"
|
|
8823
|
+
}
|
|
8824
|
+
},
|
|
8825
|
+
importRunId: {
|
|
8826
|
+
type: "text",
|
|
8827
|
+
nullable: true,
|
|
8828
|
+
references: {
|
|
8829
|
+
table: TABLE_KNOWLEDGE_IMPORT_RUNS,
|
|
8830
|
+
column: "id"
|
|
8831
|
+
}
|
|
8832
|
+
},
|
|
8833
|
+
details: {
|
|
8834
|
+
type: "jsonb",
|
|
8835
|
+
nullable: true
|
|
8836
|
+
},
|
|
8837
|
+
createdAt: {
|
|
8838
|
+
type: "timestamp",
|
|
8839
|
+
nullable: false
|
|
8840
|
+
},
|
|
8841
|
+
recordType: {
|
|
8842
|
+
type: "text",
|
|
8843
|
+
nullable: true
|
|
8844
|
+
},
|
|
8845
|
+
recordId: {
|
|
8846
|
+
type: "text",
|
|
8847
|
+
nullable: true
|
|
8848
|
+
},
|
|
8849
|
+
scope: {
|
|
8850
|
+
type: "jsonb",
|
|
8851
|
+
nullable: true
|
|
8852
|
+
},
|
|
8853
|
+
scopeKey: {
|
|
8854
|
+
type: "text",
|
|
8855
|
+
nullable: true
|
|
8856
|
+
},
|
|
8857
|
+
sourceThreadId: {
|
|
8858
|
+
type: "text",
|
|
8859
|
+
nullable: true
|
|
8860
|
+
}
|
|
8861
|
+
};
|
|
8862
|
+
const KNOWLEDGE_PROPOSALS_SCHEMA = {
|
|
8863
|
+
id: {
|
|
8864
|
+
type: "text",
|
|
8865
|
+
nullable: false,
|
|
8866
|
+
primaryKey: true
|
|
8867
|
+
},
|
|
8868
|
+
targetType: {
|
|
8869
|
+
type: "text",
|
|
8870
|
+
nullable: false
|
|
8871
|
+
},
|
|
8872
|
+
targetId: {
|
|
8873
|
+
type: "text",
|
|
8874
|
+
nullable: false
|
|
8875
|
+
},
|
|
8876
|
+
action: {
|
|
8877
|
+
type: "text",
|
|
8878
|
+
nullable: false
|
|
8879
|
+
},
|
|
8880
|
+
changes: {
|
|
8881
|
+
type: "jsonb",
|
|
8882
|
+
nullable: false
|
|
8883
|
+
},
|
|
8884
|
+
reason: {
|
|
8885
|
+
type: "text",
|
|
8886
|
+
nullable: true
|
|
8887
|
+
},
|
|
8888
|
+
proposerContextScopeId: {
|
|
8889
|
+
type: "text",
|
|
8890
|
+
nullable: false
|
|
8891
|
+
},
|
|
8892
|
+
expectedVersion: {
|
|
8893
|
+
type: "integer",
|
|
8894
|
+
nullable: false
|
|
8895
|
+
},
|
|
8896
|
+
status: {
|
|
8897
|
+
type: "text",
|
|
8898
|
+
nullable: false
|
|
8899
|
+
},
|
|
8900
|
+
reviewerContextScopeId: {
|
|
8901
|
+
type: "text",
|
|
8902
|
+
nullable: true
|
|
8903
|
+
},
|
|
8904
|
+
reviewedAt: {
|
|
8905
|
+
type: "timestamp",
|
|
8906
|
+
nullable: true
|
|
8907
|
+
},
|
|
8908
|
+
createdAt: {
|
|
8909
|
+
type: "timestamp",
|
|
8910
|
+
nullable: false
|
|
8911
|
+
}
|
|
8912
|
+
};
|
|
8913
|
+
function assertKnowledgeV2CoreSupport(features) {
|
|
8914
|
+
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.`);
|
|
8915
|
+
}
|
|
8916
|
+
function resolveKnowledgeV2Core(storageModule) {
|
|
8917
|
+
if (typeof storageModule !== "object" || storageModule === null) throw new Error("@mastra/core advertises Knowledge v2 without the required storage API");
|
|
8918
|
+
const { assertKnowledgeDescriptionWithinBound: assertDescription, assertKnowledgeRecordTextWithinBound: assertRecordText, assertKnowledgeSchemaCompatible: assertCompatible, inspectKnowledgeSchema: inspectSchema } = storageModule;
|
|
8919
|
+
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");
|
|
8920
|
+
return {
|
|
8921
|
+
assertKnowledgeDescriptionWithinBound: (description) => assertDescription(description),
|
|
8922
|
+
assertKnowledgeRecordTextWithinBound: (text) => assertRecordText(text),
|
|
8923
|
+
assertKnowledgeSchemaCompatible: (inspection) => assertCompatible(inspection),
|
|
8924
|
+
inspectKnowledgeSchema: (snapshot) => inspectSchema(snapshot)
|
|
8925
|
+
};
|
|
8926
|
+
}
|
|
8927
|
+
function createKnowledgeV2CoreLoader(features, loadStorageModule) {
|
|
8928
|
+
let knowledgeV2Core;
|
|
8929
|
+
return async () => {
|
|
8930
|
+
assertKnowledgeV2CoreSupport(features);
|
|
8931
|
+
knowledgeV2Core ??= loadStorageModule().then(resolveKnowledgeV2Core).catch((error) => {
|
|
8932
|
+
knowledgeV2Core = void 0;
|
|
8933
|
+
throw error;
|
|
8934
|
+
});
|
|
8935
|
+
return knowledgeV2Core;
|
|
8936
|
+
};
|
|
8937
|
+
}
|
|
8938
|
+
//#endregion
|
|
8304
8939
|
//#region src/storage/domains/knowledge/index.ts
|
|
8305
|
-
|
|
8940
|
+
const loadKnowledgeV2Core = createKnowledgeV2CoreLoader(_mastra_core_features.coreFeatures, () => import("@mastra/core/storage"));
|
|
8306
8941
|
async function assertKnowledgeDescriptionWithinBoundCompat(description) {
|
|
8307
|
-
|
|
8308
|
-
|
|
8309
|
-
|
|
8310
|
-
|
|
8311
|
-
|
|
8312
|
-
|
|
8313
|
-
assertWithinBound = resolvedAssert;
|
|
8314
|
-
}
|
|
8315
|
-
assertWithinBound(description);
|
|
8942
|
+
const { assertKnowledgeDescriptionWithinBound } = await loadKnowledgeV2Core();
|
|
8943
|
+
assertKnowledgeDescriptionWithinBound(description);
|
|
8944
|
+
}
|
|
8945
|
+
async function assertKnowledgeRecordTextWithinBoundCompat(text) {
|
|
8946
|
+
const { assertKnowledgeRecordTextWithinBound } = await loadKnowledgeV2Core();
|
|
8947
|
+
assertKnowledgeRecordTextWithinBound(text);
|
|
8316
8948
|
}
|
|
8317
8949
|
const camelCaseColumns = [
|
|
8318
8950
|
"canonicalName",
|
|
@@ -8323,7 +8955,6 @@ const camelCaseColumns = [
|
|
|
8323
8955
|
"node",
|
|
8324
8956
|
"sourceThreadId",
|
|
8325
8957
|
"capturedAt",
|
|
8326
|
-
"maxScope",
|
|
8327
8958
|
"deletedAt",
|
|
8328
8959
|
"deletedBy",
|
|
8329
8960
|
"sourceType",
|
|
@@ -8337,7 +8968,30 @@ const camelCaseColumns = [
|
|
|
8337
8968
|
"availableAt",
|
|
8338
8969
|
"claimedAt",
|
|
8339
8970
|
"claimedBy",
|
|
8340
|
-
"completedAt"
|
|
8971
|
+
"completedAt",
|
|
8972
|
+
"isScope",
|
|
8973
|
+
"nodeId",
|
|
8974
|
+
"targetNodeId",
|
|
8975
|
+
"scopeNodeId",
|
|
8976
|
+
"scopeRefId",
|
|
8977
|
+
"canSuggest",
|
|
8978
|
+
"schemaVersion",
|
|
8979
|
+
"importerId",
|
|
8980
|
+
"importKind",
|
|
8981
|
+
"triggerKind",
|
|
8982
|
+
"transcriptThreadId",
|
|
8983
|
+
"traceId",
|
|
8984
|
+
"queuedAt",
|
|
8985
|
+
"startedAt",
|
|
8986
|
+
"targetType",
|
|
8987
|
+
"targetId",
|
|
8988
|
+
"contextScopeId",
|
|
8989
|
+
"importRunId",
|
|
8990
|
+
"proposerContextScopeId",
|
|
8991
|
+
"expectedVersion",
|
|
8992
|
+
"reviewerContextScopeId",
|
|
8993
|
+
"reviewedAt",
|
|
8994
|
+
"addedAt"
|
|
8341
8995
|
];
|
|
8342
8996
|
function transformSqlCode(sql, transform) {
|
|
8343
8997
|
return sql.split(/('(?:''|[^'])*')/g).map((part, index) => index % 2 === 0 ? transform(part) : part).join("");
|
|
@@ -8352,14 +9006,7 @@ function postgresSql(sql, schemaName) {
|
|
|
8352
9006
|
const quotedSchema = `"${parseSchemaName(schemaName)}"`;
|
|
8353
9007
|
normalized = transformSqlCode(normalized, (code) => {
|
|
8354
9008
|
let transformed = code;
|
|
8355
|
-
for (const table of [
|
|
8356
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_NODES,
|
|
8357
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS,
|
|
8358
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS,
|
|
8359
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_CURSORS,
|
|
8360
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
|
|
8361
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX
|
|
8362
|
-
]) transformed = transformed.replaceAll(`"${table}"`, `${quotedSchema}."${table}"`);
|
|
9009
|
+
for (const table of [...KNOWLEDGE_TABLE_NAMES, ...RETIRED_KNOWLEDGE_TABLE_NAMES]) transformed = transformed.replaceAll(`"${table}"`, `${quotedSchema}."${table}"`);
|
|
8363
9010
|
return transformed;
|
|
8364
9011
|
});
|
|
8365
9012
|
}
|
|
@@ -8367,17 +9014,35 @@ function postgresSql(sql, schemaName) {
|
|
|
8367
9014
|
return transformSqlCode(normalized, (code) => code.replace(/\?/g, () => `$${++index}`));
|
|
8368
9015
|
}
|
|
8369
9016
|
function createExecutor(client, schemaName) {
|
|
8370
|
-
|
|
9017
|
+
const execute = async (statement, qualifyWithSchema) => {
|
|
8371
9018
|
const sql = typeof statement === "string" ? statement : statement.sql;
|
|
8372
9019
|
const args = typeof statement === "string" ? [] : statement.args ?? [];
|
|
8373
|
-
const result = await client.query(postgresSql(sql, schemaName), args);
|
|
9020
|
+
const result = await client.query(postgresSql(sql, qualifyWithSchema ? schemaName : void 0), args);
|
|
8374
9021
|
return {
|
|
8375
9022
|
rows: result.rows,
|
|
8376
9023
|
rowsAffected: result.rowCount ?? 0
|
|
8377
9024
|
};
|
|
8378
|
-
}
|
|
9025
|
+
};
|
|
9026
|
+
return {
|
|
9027
|
+
execute: (statement) => execute(statement, true),
|
|
9028
|
+
executeRaw: (statement) => execute(statement, false)
|
|
9029
|
+
};
|
|
9030
|
+
}
|
|
9031
|
+
/**
|
|
9032
|
+
* Scope keys visible to a caller holding `scope`: a row is visible when its scope is a subset of the
|
|
9033
|
+
* caller's (companion entries such as `resource:x:uncurated` make this more than a prefix match).
|
|
9034
|
+
* Matching rows by `scopeKey` keeps visibility filters on an index; a caller scope has only a few
|
|
9035
|
+
* entries, so the list stays small.
|
|
9036
|
+
*/
|
|
9037
|
+
function visibleScopeKeys(scope) {
|
|
9038
|
+
const canonical = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(scope);
|
|
9039
|
+
const keys = /* @__PURE__ */ new Set();
|
|
9040
|
+
for (let mask = 1; mask < 1 << canonical.length; mask++) try {
|
|
9041
|
+
keys.add((0, _mastra_core_storage.knowledgeScopeKey)(canonical.filter((_, index) => mask & 1 << index)));
|
|
9042
|
+
} catch {}
|
|
9043
|
+
return [...keys];
|
|
8379
9044
|
}
|
|
8380
|
-
const visibleSql =
|
|
9045
|
+
const visibleSql = (keys, scopeKeyColumn = "scopeKey") => `${scopeKeyColumn} IN (${keys.map(() => "?").join(",")})`;
|
|
8381
9046
|
function parseJson$1(value) {
|
|
8382
9047
|
if (typeof value === "string") return JSON.parse(value);
|
|
8383
9048
|
if (value instanceof Uint8Array) return JSON.parse(new TextDecoder().decode(value));
|
|
@@ -8417,9 +9082,10 @@ function parseNode(row) {
|
|
|
8417
9082
|
id: String(row.id),
|
|
8418
9083
|
type: "node",
|
|
8419
9084
|
name: String(row.name),
|
|
8420
|
-
kind: String(row.kind),
|
|
9085
|
+
kind: row.kind == null ? "" : String(row.kind),
|
|
8421
9086
|
content: row.content == null ? void 0 : String(row.content),
|
|
8422
9087
|
description: row.description == null ? void 0 : String(row.description),
|
|
9088
|
+
isScope: row.isScope === true || row.isScope === 1 ? true : void 0,
|
|
8423
9089
|
scope: parseJson$1(row.scopeJson ?? row.scope),
|
|
8424
9090
|
version: Number(row.version),
|
|
8425
9091
|
mergedInto: row.mergedInto == null ? void 0 : String(row.mergedInto),
|
|
@@ -8436,7 +9102,6 @@ function parseKnowledge(row) {
|
|
|
8436
9102
|
sourceThreadId: String(row.sourceThreadId),
|
|
8437
9103
|
capturedAt: toDate$1(row.capturedAt),
|
|
8438
9104
|
when: optionalDate(row.when),
|
|
8439
|
-
maxScope: row.maxScope == null ? void 0 : String(row.maxScope),
|
|
8440
9105
|
metadata: row.metadata == null ? void 0 : parseJson$1(row.metadata),
|
|
8441
9106
|
deletedAt: optionalDate(row.deletedAt),
|
|
8442
9107
|
deletedBy: row.deletedBy == null ? void 0 : String(row.deletedBy)
|
|
@@ -8473,6 +9138,10 @@ function knowledgeIndexes(schemaName) {
|
|
|
8473
9138
|
name: "idx_knowledge_nodes_scope",
|
|
8474
9139
|
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_nodes_scope ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_NODES)} ("scopeKey", "type");`
|
|
8475
9140
|
},
|
|
9141
|
+
{
|
|
9142
|
+
name: "idx_knowledge_nodes_name",
|
|
9143
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_nodes_name ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_NODES)} ("type", "canonicalName");`
|
|
9144
|
+
},
|
|
8476
9145
|
{
|
|
8477
9146
|
name: "idx_knowledge_records_node_latest",
|
|
8478
9147
|
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_records_node_latest ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS)} ("node", "id" DESC);`
|
|
@@ -8489,6 +9158,14 @@ function knowledgeIndexes(schemaName) {
|
|
|
8489
9158
|
name: "idx_knowledge_activity_latest",
|
|
8490
9159
|
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_activity_latest ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY)} ("id" DESC);`
|
|
8491
9160
|
},
|
|
9161
|
+
{
|
|
9162
|
+
name: "idx_knowledge_records_scope",
|
|
9163
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_records_scope ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS)} ("scopeKey", "id");`
|
|
9164
|
+
},
|
|
9165
|
+
{
|
|
9166
|
+
name: "idx_knowledge_activity_scope",
|
|
9167
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_activity_scope ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY)} ("scopeKey", "id" DESC);`
|
|
9168
|
+
},
|
|
8492
9169
|
{
|
|
8493
9170
|
name: "idx_knowledge_outbox_idempotency",
|
|
8494
9171
|
sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_knowledge_outbox_idempotency ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX)} ("idempotencyKey");`
|
|
@@ -8496,67 +9173,152 @@ function knowledgeIndexes(schemaName) {
|
|
|
8496
9173
|
{
|
|
8497
9174
|
name: "idx_knowledge_outbox_claim",
|
|
8498
9175
|
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_outbox_claim ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX)} ("status", "availableAt", "createdAt");`
|
|
9176
|
+
},
|
|
9177
|
+
{
|
|
9178
|
+
name: "idx_knowledge_node_scopes_scope",
|
|
9179
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_node_scopes_scope ON ${table(TABLE_KNOWLEDGE_NODE_SCOPES)} ("scopeNodeId", "nodeId");`
|
|
9180
|
+
},
|
|
9181
|
+
{
|
|
9182
|
+
name: "idx_knowledge_record_scopes_scope",
|
|
9183
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_record_scopes_scope ON ${table(TABLE_KNOWLEDGE_RECORD_SCOPES)} ("scopeNodeId", "recordId");`
|
|
9184
|
+
},
|
|
9185
|
+
{
|
|
9186
|
+
name: "idx_knowledge_scope_grants_ref",
|
|
9187
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_scope_grants_ref ON ${table(TABLE_KNOWLEDGE_SCOPE_GRANTS)} ("scopeRefId", "scopeNodeId");`
|
|
9188
|
+
},
|
|
9189
|
+
{
|
|
9190
|
+
name: "idx_knowledge_node_addresses_node",
|
|
9191
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_node_addresses_node ON ${table(TABLE_KNOWLEDGE_NODE_ADDRESSES)} ("nodeId");`
|
|
9192
|
+
},
|
|
9193
|
+
{
|
|
9194
|
+
name: "idx_knowledge_import_runs_lookup",
|
|
9195
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_import_runs_lookup ON ${table(TABLE_KNOWLEDGE_IMPORT_RUNS)} ("importerId", "binding", "queuedAt" DESC);`
|
|
9196
|
+
},
|
|
9197
|
+
{
|
|
9198
|
+
name: "idx_knowledge_activity_import_run",
|
|
9199
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_activity_import_run ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY)} ("importRunId", "id" DESC);`
|
|
8499
9200
|
}
|
|
8500
9201
|
];
|
|
8501
9202
|
}
|
|
8502
9203
|
function knowledgeIndexDDL(schemaName) {
|
|
8503
9204
|
return knowledgeIndexes(schemaName).map((index) => index.sql);
|
|
8504
9205
|
}
|
|
9206
|
+
const KNOWLEDGE_CURATION_CURSOR_REMOVED_MESSAGE = "Knowledge curation cursors were removed: observation-time curate is the only Knowledge writer and needs no cursor.";
|
|
9207
|
+
const knowledgeTableDefinitions = [
|
|
9208
|
+
{
|
|
9209
|
+
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_NODES,
|
|
9210
|
+
schema: KNOWLEDGE_V2_NODES_SCHEMA
|
|
9211
|
+
},
|
|
9212
|
+
{
|
|
9213
|
+
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_RECORDS,
|
|
9214
|
+
schema: KNOWLEDGE_V2_RECORDS_SCHEMA
|
|
9215
|
+
},
|
|
9216
|
+
{
|
|
9217
|
+
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS,
|
|
9218
|
+
schema: KNOWLEDGE_V2_MENTIONS_SCHEMA,
|
|
9219
|
+
compositePrimaryKey: ["recordId", "sourceId"]
|
|
9220
|
+
},
|
|
9221
|
+
{
|
|
9222
|
+
tableName: TABLE_KNOWLEDGE_NODE_SCOPES,
|
|
9223
|
+
schema: KNOWLEDGE_NODE_SCOPES_SCHEMA,
|
|
9224
|
+
compositePrimaryKey: ["nodeId", "scopeNodeId"]
|
|
9225
|
+
},
|
|
9226
|
+
{
|
|
9227
|
+
tableName: TABLE_KNOWLEDGE_RECORD_SCOPES,
|
|
9228
|
+
schema: KNOWLEDGE_RECORD_SCOPES_SCHEMA,
|
|
9229
|
+
compositePrimaryKey: ["recordId", "scopeNodeId"]
|
|
9230
|
+
},
|
|
9231
|
+
{
|
|
9232
|
+
tableName: TABLE_KNOWLEDGE_SCOPE_GRANTS,
|
|
9233
|
+
schema: KNOWLEDGE_SCOPE_GRANTS_SCHEMA,
|
|
9234
|
+
compositePrimaryKey: ["scopeNodeId", "scopeRefId"]
|
|
9235
|
+
},
|
|
9236
|
+
{
|
|
9237
|
+
tableName: TABLE_KNOWLEDGE_ACCESS_STATE,
|
|
9238
|
+
schema: KNOWLEDGE_ACCESS_STATE_SCHEMA
|
|
9239
|
+
},
|
|
9240
|
+
{
|
|
9241
|
+
tableName: TABLE_KNOWLEDGE_SCOPE_ADDRESSES,
|
|
9242
|
+
schema: KNOWLEDGE_SCOPE_ADDRESSES_SCHEMA
|
|
9243
|
+
},
|
|
9244
|
+
{
|
|
9245
|
+
tableName: TABLE_KNOWLEDGE_NODE_ADDRESSES,
|
|
9246
|
+
schema: KNOWLEDGE_NODE_ADDRESSES_SCHEMA,
|
|
9247
|
+
compositePrimaryKey: ["source", "address"]
|
|
9248
|
+
},
|
|
9249
|
+
{
|
|
9250
|
+
tableName: TABLE_KNOWLEDGE_IMPORT_STATE,
|
|
9251
|
+
schema: KNOWLEDGE_IMPORT_STATE_SCHEMA,
|
|
9252
|
+
compositePrimaryKey: [
|
|
9253
|
+
"importerId",
|
|
9254
|
+
"binding",
|
|
9255
|
+
"key"
|
|
9256
|
+
]
|
|
9257
|
+
},
|
|
9258
|
+
{
|
|
9259
|
+
tableName: TABLE_KNOWLEDGE_IMPORT_RUNS,
|
|
9260
|
+
schema: KNOWLEDGE_IMPORT_RUNS_SCHEMA
|
|
9261
|
+
},
|
|
9262
|
+
{
|
|
9263
|
+
tableName: TABLE_KNOWLEDGE_PROPOSALS,
|
|
9264
|
+
schema: KNOWLEDGE_PROPOSALS_SCHEMA
|
|
9265
|
+
},
|
|
9266
|
+
{
|
|
9267
|
+
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
|
|
9268
|
+
schema: KNOWLEDGE_V2_ACTIVITY_SCHEMA
|
|
9269
|
+
},
|
|
9270
|
+
{
|
|
9271
|
+
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX,
|
|
9272
|
+
schema: _mastra_core_storage.KNOWLEDGE_SEMANTIC_OUTBOX_SCHEMA
|
|
9273
|
+
}
|
|
9274
|
+
];
|
|
9275
|
+
function pgSetting(config, key) {
|
|
9276
|
+
const value = config[key] || process.env[`PG${key.toUpperCase()}`] || pg.defaults[key];
|
|
9277
|
+
return value === void 0 || value === null || value === "" ? void 0 : String(value);
|
|
9278
|
+
}
|
|
9279
|
+
function effectivePgTarget(config) {
|
|
9280
|
+
const host = pgSetting(config, "host");
|
|
9281
|
+
const database = pgSetting(config, "database") ?? pgSetting(config, "user");
|
|
9282
|
+
if (!host || !database) return void 0;
|
|
9283
|
+
return `${host.startsWith("/") ? host : host.toLocaleLowerCase()}:${pgSetting(config, "port") ?? "5432"}/${database}`;
|
|
9284
|
+
}
|
|
9285
|
+
function canonicalPgTarget(config) {
|
|
9286
|
+
if (config.connectionString) try {
|
|
9287
|
+
const parsed = new URL(config.connectionString);
|
|
9288
|
+
return effectivePgTarget({
|
|
9289
|
+
host: decodeURIComponent(parsed.hostname) || config.host,
|
|
9290
|
+
port: parsed.port || config.port,
|
|
9291
|
+
database: decodeURIComponent(parsed.pathname.slice(1)) || config.database,
|
|
9292
|
+
user: decodeURIComponent(parsed.username) || config.user
|
|
9293
|
+
});
|
|
9294
|
+
} catch {
|
|
9295
|
+
return config.connectionString;
|
|
9296
|
+
}
|
|
9297
|
+
return effectivePgTarget(config);
|
|
9298
|
+
}
|
|
9299
|
+
function pgSourceConfig(source) {
|
|
9300
|
+
if (!source || !("options" in source)) return void 0;
|
|
9301
|
+
return source.options;
|
|
9302
|
+
}
|
|
9303
|
+
function pgClientPool(client) {
|
|
9304
|
+
if (!client || !("$pool" in client)) return void 0;
|
|
9305
|
+
return client.$pool;
|
|
9306
|
+
}
|
|
9307
|
+
function getPgKnowledgeIsolationKey(config) {
|
|
9308
|
+
const schema = config.schemaName ?? "public";
|
|
9309
|
+
const poolConfig = pgSourceConfig(config.pool ?? pgClientPool(config.client));
|
|
9310
|
+
const target = Boolean(config.connectionString || config.host || config.database) ? canonicalPgTarget(config) : poolConfig ? canonicalPgTarget(poolConfig) : void 0;
|
|
9311
|
+
if (target) return `pg:${target}:schema:${schema}`;
|
|
9312
|
+
return `pg:unidentified:schema:${schema}`;
|
|
9313
|
+
}
|
|
8505
9314
|
var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
8506
|
-
static MANAGED_TABLES =
|
|
8507
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_NODES,
|
|
8508
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS,
|
|
8509
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS,
|
|
8510
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_CURSORS,
|
|
8511
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
|
|
8512
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX
|
|
8513
|
-
];
|
|
9315
|
+
static MANAGED_TABLES = KNOWLEDGE_TABLE_NAMES;
|
|
8514
9316
|
static getExportDDL(schemaName) {
|
|
8515
|
-
return [
|
|
8516
|
-
|
|
8517
|
-
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
includeAllConstraints: true
|
|
8521
|
-
}),
|
|
8522
|
-
generateTableSQL({
|
|
8523
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_RECORDS,
|
|
8524
|
-
schema: _mastra_core_storage.KNOWLEDGE_RECORDS_SCHEMA,
|
|
8525
|
-
schemaName,
|
|
8526
|
-
includeAllConstraints: true
|
|
8527
|
-
}),
|
|
8528
|
-
generateTableSQL({
|
|
8529
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS,
|
|
8530
|
-
schema: _mastra_core_storage.KNOWLEDGE_MENTIONS_SCHEMA,
|
|
8531
|
-
schemaName,
|
|
8532
|
-
compositePrimaryKey: [
|
|
8533
|
-
"sourceType",
|
|
8534
|
-
"sourceId",
|
|
8535
|
-
"recordId"
|
|
8536
|
-
],
|
|
8537
|
-
includeAllConstraints: true
|
|
8538
|
-
}),
|
|
8539
|
-
generateTableSQL({
|
|
8540
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_CURSORS,
|
|
8541
|
-
schema: _mastra_core_storage.KNOWLEDGE_CURSORS_SCHEMA,
|
|
8542
|
-
schemaName,
|
|
8543
|
-
compositePrimaryKey: ["sourceThreadId", "agent"],
|
|
8544
|
-
includeAllConstraints: true
|
|
8545
|
-
}),
|
|
8546
|
-
generateTableSQL({
|
|
8547
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
|
|
8548
|
-
schema: _mastra_core_storage.KNOWLEDGE_ACTIVITY_SCHEMA,
|
|
8549
|
-
schemaName,
|
|
8550
|
-
includeAllConstraints: true
|
|
8551
|
-
}),
|
|
8552
|
-
generateTableSQL({
|
|
8553
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX,
|
|
8554
|
-
schema: _mastra_core_storage.KNOWLEDGE_SEMANTIC_OUTBOX_SCHEMA,
|
|
8555
|
-
schemaName,
|
|
8556
|
-
includeAllConstraints: true
|
|
8557
|
-
}),
|
|
8558
|
-
...knowledgeIndexDDL(schemaName)
|
|
8559
|
-
];
|
|
9317
|
+
return [...knowledgeTableDefinitions.map((definition) => generateTableSQL({
|
|
9318
|
+
...definition,
|
|
9319
|
+
schemaName,
|
|
9320
|
+
includeAllConstraints: true
|
|
9321
|
+
})), ...knowledgeIndexDDL(schemaName)];
|
|
8560
9322
|
}
|
|
8561
9323
|
#client;
|
|
8562
9324
|
#executor;
|
|
@@ -8565,7 +9327,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8565
9327
|
#db;
|
|
8566
9328
|
#schemaName;
|
|
8567
9329
|
constructor(config) {
|
|
8568
|
-
super();
|
|
9330
|
+
super({ storageIsolationKey: config.storageIsolationKey ?? getPgKnowledgeIsolationKey(config) });
|
|
8569
9331
|
const { client, readClient, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
|
|
8570
9332
|
this.#client = client;
|
|
8571
9333
|
this.#schemaName = schemaName;
|
|
@@ -8578,56 +9340,359 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8578
9340
|
skipDefaultIndexes
|
|
8579
9341
|
});
|
|
8580
9342
|
}
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
|
|
8584
|
-
|
|
8585
|
-
|
|
8586
|
-
|
|
8587
|
-
|
|
8588
|
-
|
|
8589
|
-
|
|
9343
|
+
getCapabilities() {
|
|
9344
|
+
return {
|
|
9345
|
+
contractVersion: 2,
|
|
9346
|
+
schemaVersion: 2,
|
|
9347
|
+
supportsV2: true,
|
|
9348
|
+
supportsSchemaInspection: true,
|
|
9349
|
+
supportsExplicitReset: true
|
|
9350
|
+
};
|
|
9351
|
+
}
|
|
9352
|
+
async inspectSchema() {
|
|
9353
|
+
const { inspectKnowledgeSchema } = await loadKnowledgeV2Core();
|
|
9354
|
+
try {
|
|
9355
|
+
const snapshot = getSchemaSnapshot(this.#client, this.#schemaName);
|
|
9356
|
+
if (snapshot) {
|
|
9357
|
+
const tableNames = KNOWLEDGE_TABLE_NAMES.filter((table) => snapshot.tables.has(table));
|
|
9358
|
+
return this.#classifySchema(this.#executor, tableNames, snapshot.columns);
|
|
9359
|
+
}
|
|
9360
|
+
return this.#inspectSchemaWithExecutor(this.#executor);
|
|
9361
|
+
} catch (error) {
|
|
9362
|
+
return inspectKnowledgeSchema({
|
|
9363
|
+
available: false,
|
|
9364
|
+
tableNames: [],
|
|
9365
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
9366
|
+
});
|
|
9367
|
+
}
|
|
9368
|
+
}
|
|
9369
|
+
async #inspectSchemaWithExecutor(executor) {
|
|
9370
|
+
const tableNames = (await executor.execute({
|
|
9371
|
+
sql: `SELECT table_name FROM information_schema.tables WHERE table_schema = COALESCE(?, current_schema()) AND table_name = ANY(?::text[])`,
|
|
9372
|
+
args: [this.#schemaName ?? null, [...KNOWLEDGE_TABLE_NAMES]]
|
|
9373
|
+
})).rows.map((row) => String(row.table_name));
|
|
9374
|
+
const columnResult = await executor.execute({
|
|
9375
|
+
sql: `SELECT table_name, column_name FROM information_schema.columns WHERE table_schema = COALESCE(?, current_schema()) AND table_name = ANY(?::text[])`,
|
|
9376
|
+
args: [this.#schemaName ?? null, [...KNOWLEDGE_TABLE_NAMES]]
|
|
9377
|
+
});
|
|
9378
|
+
const columns = /* @__PURE__ */ new Map();
|
|
9379
|
+
for (const row of columnResult.rows) {
|
|
9380
|
+
const table = String(row.table_name);
|
|
9381
|
+
const names = columns.get(table) ?? /* @__PURE__ */ new Set();
|
|
9382
|
+
names.add(String(row.column_name));
|
|
9383
|
+
columns.set(table, names);
|
|
9384
|
+
}
|
|
9385
|
+
return this.#classifySchema(executor, tableNames, columns);
|
|
9386
|
+
}
|
|
9387
|
+
async #classifySchema(executor, tableNames, columns) {
|
|
9388
|
+
const { inspectKnowledgeSchema } = await loadKnowledgeV2Core();
|
|
9389
|
+
if (tableNames.length === 0) return inspectKnowledgeSchema({
|
|
9390
|
+
available: true,
|
|
9391
|
+
tableNames
|
|
9392
|
+
});
|
|
9393
|
+
const missingTables = KNOWLEDGE_TABLE_NAMES.filter((table) => !tableNames.includes(table));
|
|
9394
|
+
if (missingTables.length > 0) return inspectKnowledgeSchema({
|
|
9395
|
+
available: true,
|
|
9396
|
+
tableNames,
|
|
9397
|
+
reason: `Missing Knowledge v2 tables: ${missingTables.join(", ")}`
|
|
9398
|
+
});
|
|
9399
|
+
for (const { tableName: table, schema } of knowledgeTableDefinitions) {
|
|
9400
|
+
const actual = columns.get(table) ?? /* @__PURE__ */ new Set();
|
|
9401
|
+
const missing = Object.keys(schema).filter((column) => !actual.has(column));
|
|
9402
|
+
if (missing.length > 0) return inspectKnowledgeSchema({
|
|
9403
|
+
available: true,
|
|
9404
|
+
tableNames,
|
|
9405
|
+
reason: `Knowledge table ${table} is missing v2 columns: ${missing.join(", ")}`
|
|
9406
|
+
});
|
|
9407
|
+
}
|
|
9408
|
+
const accessState = await executor.execute(`SELECT schemaVersion FROM "${TABLE_KNOWLEDGE_ACCESS_STATE}" WHERE id='global'`);
|
|
9409
|
+
if (Number(accessState.rows[0]?.schemaVersion) !== 2) return inspectKnowledgeSchema({
|
|
9410
|
+
available: true,
|
|
9411
|
+
tableNames,
|
|
9412
|
+
reason: "Knowledge schema version marker is missing or incompatible"
|
|
9413
|
+
});
|
|
9414
|
+
return inspectKnowledgeSchema({
|
|
9415
|
+
available: true,
|
|
9416
|
+
tableNames,
|
|
9417
|
+
schemaVersion: 2
|
|
8590
9418
|
});
|
|
8591
|
-
|
|
8592
|
-
|
|
8593
|
-
|
|
9419
|
+
}
|
|
9420
|
+
async init() {
|
|
9421
|
+
await this.#transaction(async (tx) => {
|
|
9422
|
+
await tx.execute({
|
|
9423
|
+
sql: "SELECT pg_advisory_xact_lock(hashtext(?))",
|
|
9424
|
+
args: [`mastra-knowledge-v2:${this.#schemaName ?? "current_schema"}`]
|
|
9425
|
+
});
|
|
9426
|
+
const { assertKnowledgeSchemaCompatible } = await loadKnowledgeV2Core();
|
|
9427
|
+
let inspection = await this.#inspectSchemaWithExecutor(tx);
|
|
9428
|
+
if (inspection.status === "incompatible-reset-required" && await this.#isPublishedV1Layout(tx)) {
|
|
9429
|
+
const tables = [...RETIRED_KNOWLEDGE_TABLE_NAMES, ...[...KNOWLEDGE_TABLE_NAMES].reverse()].map((table) => `"${table}"`).join(", ");
|
|
9430
|
+
await tx.execute(`DROP TABLE IF EXISTS ${tables}`);
|
|
9431
|
+
inspection = await this.#inspectSchemaWithExecutor(tx);
|
|
9432
|
+
}
|
|
9433
|
+
assertKnowledgeSchemaCompatible(inspection);
|
|
9434
|
+
for (const definition of knowledgeTableDefinitions) await tx.executeRaw(generateTableSQL({
|
|
9435
|
+
...definition,
|
|
9436
|
+
schemaName: this.#schemaName,
|
|
9437
|
+
includeAllConstraints: true
|
|
9438
|
+
}));
|
|
9439
|
+
for (const index of knowledgeIndexes(this.#schemaName)) await tx.executeRaw(index.sql);
|
|
9440
|
+
await tx.execute({
|
|
9441
|
+
sql: `INSERT INTO "${TABLE_KNOWLEDGE_ACCESS_STATE}" (id, epoch, schemaVersion) VALUES ('global', 0, ?) ON CONFLICT (id) DO NOTHING`,
|
|
9442
|
+
args: [2]
|
|
9443
|
+
});
|
|
8594
9444
|
});
|
|
8595
|
-
|
|
8596
|
-
|
|
8597
|
-
|
|
8598
|
-
|
|
8599
|
-
|
|
8600
|
-
|
|
8601
|
-
|
|
9445
|
+
}
|
|
9446
|
+
/**
|
|
9447
|
+
* True when the only Knowledge objects are the tables and indexes published v1 adapters created,
|
|
9448
|
+
* with or without rows. Anything else (v2 tables, unknown tables, views, triggers, extra indexes)
|
|
9449
|
+
* needs an explicit reset.
|
|
9450
|
+
*/
|
|
9451
|
+
async #isPublishedV1Layout(executor) {
|
|
9452
|
+
const schema = this.#schemaName ?? null;
|
|
9453
|
+
const relations = await executor.execute({
|
|
9454
|
+
sql: `SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = COALESCE(?, current_schema()) AND table_name LIKE 'mastra\\_knowledge\\_%'`,
|
|
9455
|
+
args: [schema]
|
|
9456
|
+
});
|
|
9457
|
+
const tables = [];
|
|
9458
|
+
for (const row of relations.rows) {
|
|
9459
|
+
const name = String(row.table_name);
|
|
9460
|
+
if (row.table_type !== "BASE TABLE" || !PUBLISHED_KNOWLEDGE_V1_TABLE_NAMES.has(name)) return false;
|
|
9461
|
+
tables.push(name);
|
|
9462
|
+
}
|
|
9463
|
+
const indexes = await executor.execute({
|
|
9464
|
+
sql: `SELECT indexname FROM pg_indexes WHERE schemaname = COALESCE(?, current_schema()) AND tablename = ANY(?::text[])`,
|
|
9465
|
+
args: [schema, tables]
|
|
9466
|
+
});
|
|
9467
|
+
for (const row of indexes.rows) {
|
|
9468
|
+
const name = String(row.indexname);
|
|
9469
|
+
if (!PUBLISHED_KNOWLEDGE_V1_INDEX_NAMES.has(name) && !name.endsWith("_pkey")) return false;
|
|
9470
|
+
}
|
|
9471
|
+
if ((await executor.execute({
|
|
9472
|
+
sql: `SELECT 1 FROM information_schema.view_table_usage WHERE table_schema = COALESCE(?, current_schema()) AND table_name = ANY(?::text[]) UNION ALL SELECT 1 FROM information_schema.triggers WHERE event_object_schema = COALESCE(?, current_schema()) AND event_object_table = ANY(?::text[]) LIMIT 1`,
|
|
9473
|
+
args: [
|
|
9474
|
+
schema,
|
|
9475
|
+
tables,
|
|
9476
|
+
schema,
|
|
9477
|
+
tables
|
|
8602
9478
|
]
|
|
8603
|
-
});
|
|
8604
|
-
|
|
8605
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_CURSORS,
|
|
8606
|
-
schema: _mastra_core_storage.KNOWLEDGE_CURSORS_SCHEMA,
|
|
8607
|
-
compositePrimaryKey: ["sourceThreadId", "agent"]
|
|
8608
|
-
});
|
|
8609
|
-
await this.#db.createTable({
|
|
8610
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
|
|
8611
|
-
schema: _mastra_core_storage.KNOWLEDGE_ACTIVITY_SCHEMA
|
|
8612
|
-
});
|
|
8613
|
-
await this.#db.createTable({
|
|
8614
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX,
|
|
8615
|
-
schema: _mastra_core_storage.KNOWLEDGE_SEMANTIC_OUTBOX_SCHEMA
|
|
8616
|
-
});
|
|
8617
|
-
await Promise.all(knowledgeIndexes(this.#schemaName).map((index) => this.#db.createIndexFromStatement(index.name, index.sql)));
|
|
9479
|
+
})).rows.length > 0) return false;
|
|
9480
|
+
return true;
|
|
8618
9481
|
}
|
|
8619
9482
|
async dangerouslyClearAll() {
|
|
8620
9483
|
await this.#transaction(async (tx) => {
|
|
8621
9484
|
for (const table of [
|
|
9485
|
+
TABLE_KNOWLEDGE_RECORD_SCOPES,
|
|
9486
|
+
TABLE_KNOWLEDGE_NODE_SCOPES,
|
|
9487
|
+
TABLE_KNOWLEDGE_SCOPE_GRANTS,
|
|
9488
|
+
TABLE_KNOWLEDGE_SCOPE_ADDRESSES,
|
|
9489
|
+
TABLE_KNOWLEDGE_NODE_ADDRESSES,
|
|
8622
9490
|
_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS,
|
|
8623
|
-
|
|
8624
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_NODES,
|
|
8625
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_CURSORS,
|
|
9491
|
+
TABLE_KNOWLEDGE_PROPOSALS,
|
|
8626
9492
|
_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
|
|
8627
|
-
|
|
9493
|
+
TABLE_KNOWLEDGE_IMPORT_STATE,
|
|
9494
|
+
TABLE_KNOWLEDGE_IMPORT_RUNS,
|
|
9495
|
+
_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX,
|
|
9496
|
+
_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS,
|
|
9497
|
+
_mastra_core_storage.TABLE_KNOWLEDGE_NODES
|
|
8628
9498
|
]) await tx.execute(`DELETE FROM "${table}"`);
|
|
9499
|
+
await tx.execute(`UPDATE "${TABLE_KNOWLEDGE_ACCESS_STATE}" SET epoch = 0 WHERE id = 'global'`);
|
|
9500
|
+
});
|
|
9501
|
+
}
|
|
9502
|
+
async dangerouslyReset() {
|
|
9503
|
+
const tables = [...RETIRED_KNOWLEDGE_TABLE_NAMES, ...[...KNOWLEDGE_TABLE_NAMES].reverse()].map((table) => `"${table}"`).join(", ");
|
|
9504
|
+
await this.#executor.execute(`DROP TABLE IF EXISTS ${tables}`);
|
|
9505
|
+
await this.init();
|
|
9506
|
+
}
|
|
9507
|
+
async reconcileStructure(plan) {
|
|
9508
|
+
return this.#transaction(async (tx) => {
|
|
9509
|
+
await tx.execute({
|
|
9510
|
+
sql: `SELECT pg_advisory_xact_lock(hashtext(?))`,
|
|
9511
|
+
args: [`mastra-knowledge-reconcile:${this.#schemaName}`]
|
|
9512
|
+
});
|
|
9513
|
+
const scopes = {};
|
|
9514
|
+
const createdScopeIds = [];
|
|
9515
|
+
const createdAddresses = /* @__PURE__ */ new Set();
|
|
9516
|
+
const retrofit = plan.retrofit ?? true;
|
|
9517
|
+
let structureChanged = false;
|
|
9518
|
+
const deletedScopeAddresses = /* @__PURE__ */ new Set();
|
|
9519
|
+
const resolveAddress = async (address) => {
|
|
9520
|
+
if (scopes[address]) return scopes[address];
|
|
9521
|
+
const row = (await tx.execute({
|
|
9522
|
+
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=?`,
|
|
9523
|
+
args: [address]
|
|
9524
|
+
})).rows[0];
|
|
9525
|
+
if (!row) return void 0;
|
|
9526
|
+
if (!row.isScope) throw new Error(`Knowledge address ${address} does not reference a scope`);
|
|
9527
|
+
if (row.deletedAt) deletedScopeAddresses.add(address);
|
|
9528
|
+
scopes[address] = String(row.scopeNodeId);
|
|
9529
|
+
return scopes[address];
|
|
9530
|
+
};
|
|
9531
|
+
for (const scope of plan.scopes) {
|
|
9532
|
+
if (await resolveAddress(scope.address)) continue;
|
|
9533
|
+
const id = (0, crypto$1.randomUUID)();
|
|
9534
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9535
|
+
await tx.execute({
|
|
9536
|
+
sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" (id,type,name,"canonicalName",kind,description,"isScope",metadata,version,"createdAt","updatedAt") VALUES (?,'node',?,?,?,?,TRUE,?,1,?,?)`,
|
|
9537
|
+
args: [
|
|
9538
|
+
id,
|
|
9539
|
+
scope.name,
|
|
9540
|
+
canonicalName(scope.name),
|
|
9541
|
+
scope.kind ?? null,
|
|
9542
|
+
scope.description ?? null,
|
|
9543
|
+
scope.metadata ?? null,
|
|
9544
|
+
now,
|
|
9545
|
+
now
|
|
9546
|
+
]
|
|
9547
|
+
});
|
|
9548
|
+
await tx.execute({
|
|
9549
|
+
sql: `INSERT INTO "${TABLE_KNOWLEDGE_SCOPE_ADDRESSES}" (address,"scopeNodeId") VALUES (?,?)`,
|
|
9550
|
+
args: [scope.address, id]
|
|
9551
|
+
});
|
|
9552
|
+
scopes[scope.address] = id;
|
|
9553
|
+
createdAddresses.add(scope.address);
|
|
9554
|
+
createdScopeIds.push(id);
|
|
9555
|
+
structureChanged = true;
|
|
9556
|
+
}
|
|
9557
|
+
for (const scope of plan.scopes) {
|
|
9558
|
+
if (!createdAddresses.has(scope.address) && (!retrofit || deletedScopeAddresses.has(scope.address))) continue;
|
|
9559
|
+
const scopeNodeId = scopes[scope.address];
|
|
9560
|
+
for (const parentAddress of scope.parentAddresses ?? []) {
|
|
9561
|
+
const parentId = await resolveAddress(parentAddress);
|
|
9562
|
+
if (!parentId || deletedScopeAddresses.has(parentAddress)) {
|
|
9563
|
+
const deletedParentId = scopes[parentAddress];
|
|
9564
|
+
if ((deletedParentId ? await tx.execute({
|
|
9565
|
+
sql: `SELECT 1 FROM "mastra_knowledge_node_scopes" WHERE "nodeId"=? AND "scopeNodeId"=?`,
|
|
9566
|
+
args: [scopeNodeId, deletedParentId]
|
|
9567
|
+
}) : void 0)?.rows.length) continue;
|
|
9568
|
+
throw new Error(`Knowledge parent scope does not exist: ${parentAddress}`);
|
|
9569
|
+
}
|
|
9570
|
+
if ((await tx.execute({
|
|
9571
|
+
sql: `SELECT 1 FROM "mastra_knowledge_node_scopes" WHERE "nodeId"=? AND "scopeNodeId"=?`,
|
|
9572
|
+
args: [scopeNodeId, parentId]
|
|
9573
|
+
})).rows.length) continue;
|
|
9574
|
+
if ((await tx.execute({
|
|
9575
|
+
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`,
|
|
9576
|
+
args: [
|
|
9577
|
+
parentId,
|
|
9578
|
+
canonicalName(scope.name),
|
|
9579
|
+
scopeNodeId
|
|
9580
|
+
]
|
|
9581
|
+
})).rows.length) throw new Error(`Knowledge scope name ${scope.name} already exists under ${parentAddress}`);
|
|
9582
|
+
const inserted = await tx.execute({
|
|
9583
|
+
sql: `INSERT INTO "${TABLE_KNOWLEDGE_NODE_SCOPES}" ("nodeId","scopeNodeId","addedAt") VALUES (?,?,?) ON CONFLICT DO NOTHING`,
|
|
9584
|
+
args: [
|
|
9585
|
+
scopeNodeId,
|
|
9586
|
+
parentId,
|
|
9587
|
+
(/* @__PURE__ */ new Date()).toISOString()
|
|
9588
|
+
]
|
|
9589
|
+
});
|
|
9590
|
+
structureChanged ||= inserted.rowsAffected > 0;
|
|
9591
|
+
}
|
|
9592
|
+
for (const grant of scope.grants ?? []) {
|
|
9593
|
+
const scopeRefId = await resolveAddress(grant.scopeRefAddress);
|
|
9594
|
+
if (!scopeRefId || deletedScopeAddresses.has(grant.scopeRefAddress)) {
|
|
9595
|
+
const deletedScopeRefId = scopes[grant.scopeRefAddress];
|
|
9596
|
+
if ((deletedScopeRefId ? await tx.execute({
|
|
9597
|
+
sql: `SELECT 1 FROM "mastra_knowledge_scope_grants" WHERE "scopeNodeId"=? AND "scopeRefId"=?`,
|
|
9598
|
+
args: [scopeNodeId, deletedScopeRefId]
|
|
9599
|
+
}) : void 0)?.rows.length) continue;
|
|
9600
|
+
throw new Error(`Knowledge grant scope does not exist: ${grant.scopeRefAddress}`);
|
|
9601
|
+
}
|
|
9602
|
+
const inserted = await tx.execute({
|
|
9603
|
+
sql: `INSERT INTO "${TABLE_KNOWLEDGE_SCOPE_GRANTS}" ("scopeNodeId","scopeRefId",role,"canSuggest") VALUES (?,?,?,?) ON CONFLICT DO NOTHING`,
|
|
9604
|
+
args: [
|
|
9605
|
+
scopeNodeId,
|
|
9606
|
+
scopeRefId,
|
|
9607
|
+
grant.role,
|
|
9608
|
+
grant.canSuggest ?? null
|
|
9609
|
+
]
|
|
9610
|
+
});
|
|
9611
|
+
structureChanged ||= inserted.rowsAffected > 0;
|
|
9612
|
+
}
|
|
9613
|
+
}
|
|
9614
|
+
if (structureChanged) await tx.execute(`UPDATE "${TABLE_KNOWLEDGE_ACCESS_STATE}" SET epoch=epoch+1 WHERE id='global'`);
|
|
9615
|
+
const state = await tx.execute(`SELECT epoch FROM "${TABLE_KNOWLEDGE_ACCESS_STATE}" WHERE id='global'`);
|
|
9616
|
+
return {
|
|
9617
|
+
scopes,
|
|
9618
|
+
createdScopeIds,
|
|
9619
|
+
deletedScopeAddresses: [...deletedScopeAddresses],
|
|
9620
|
+
changed: structureChanged,
|
|
9621
|
+
accessEpoch: Number(state.rows[0]?.epoch ?? 0)
|
|
9622
|
+
};
|
|
8629
9623
|
});
|
|
8630
9624
|
}
|
|
9625
|
+
async listScopeNodes(input = {}) {
|
|
9626
|
+
const { limit, after } = parseListKnowledgeScopeNodesInput(input);
|
|
9627
|
+
if (input.addresses?.length === 0 || input.ids?.length === 0) return {
|
|
9628
|
+
scopes: [],
|
|
9629
|
+
nextCursor: null
|
|
9630
|
+
};
|
|
9631
|
+
const args = [];
|
|
9632
|
+
const where = [`n."isScope"`, `n."deletedAt" IS NULL`];
|
|
9633
|
+
let within = "";
|
|
9634
|
+
if (input.withinAddress !== void 0) {
|
|
9635
|
+
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) `;
|
|
9636
|
+
args.push(input.withinAddress);
|
|
9637
|
+
where.push("n.id IN (SELECT id FROM within_scope)");
|
|
9638
|
+
}
|
|
9639
|
+
if (input.addresses) {
|
|
9640
|
+
where.push(`a.address IN (${input.addresses.map(() => "?").join(",")})`);
|
|
9641
|
+
args.push(...input.addresses);
|
|
9642
|
+
}
|
|
9643
|
+
if (input.ids) {
|
|
9644
|
+
where.push(`n.id IN (${input.ids.map(() => "?").join(",")})`);
|
|
9645
|
+
args.push(...input.ids);
|
|
9646
|
+
}
|
|
9647
|
+
if (after) {
|
|
9648
|
+
where.push("(n.name COLLATE \"C\" > ? OR (n.name = ? AND n.id > ?))");
|
|
9649
|
+
args.push(after.name, after.name, after.id);
|
|
9650
|
+
}
|
|
9651
|
+
args.push(limit + 1);
|
|
9652
|
+
const rows = (await this.#readExecutor.execute({
|
|
9653
|
+
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 COLLATE "C", n.id LIMIT ?`,
|
|
9654
|
+
args
|
|
9655
|
+
})).rows;
|
|
9656
|
+
if (rows.length === 0) return {
|
|
9657
|
+
scopes: [],
|
|
9658
|
+
nextCursor: null
|
|
9659
|
+
};
|
|
9660
|
+
const parents = await this.#readExecutor.execute({
|
|
9661
|
+
sql: `SELECT ns."nodeId",ns."scopeNodeId" FROM "${TABLE_KNOWLEDGE_NODE_SCOPES}" ns WHERE ns."nodeId" IN (${rows.map(() => "?").join(",")}) ORDER BY ns."scopeNodeId" COLLATE "C"`,
|
|
9662
|
+
args: rows.map((row) => String(row.id))
|
|
9663
|
+
});
|
|
9664
|
+
const parentsByScopeId = /* @__PURE__ */ new Map();
|
|
9665
|
+
for (const row of parents.rows) {
|
|
9666
|
+
const scopeId = String(row.nodeId);
|
|
9667
|
+
const parentId = String(row.scopeNodeId);
|
|
9668
|
+
const existing = parentsByScopeId.get(scopeId);
|
|
9669
|
+
if (existing) existing.push(parentId);
|
|
9670
|
+
else parentsByScopeId.set(scopeId, [parentId]);
|
|
9671
|
+
}
|
|
9672
|
+
return pageKnowledgeScopeNodes(rows.map((row) => ({
|
|
9673
|
+
id: String(row.id),
|
|
9674
|
+
address: String(row.address),
|
|
9675
|
+
name: String(row.name),
|
|
9676
|
+
...row.kind == null ? {} : { kind: String(row.kind) },
|
|
9677
|
+
...row.description == null ? {} : { description: String(row.description) },
|
|
9678
|
+
parentIds: parentsByScopeId.get(String(row.id)) ?? []
|
|
9679
|
+
})), limit, input);
|
|
9680
|
+
}
|
|
9681
|
+
async listScopeMembers(input) {
|
|
9682
|
+
const { limit, after } = parseListKnowledgeScopeMembersInput(input);
|
|
9683
|
+
const args = [input.scopeNodeId];
|
|
9684
|
+
let keyset = "";
|
|
9685
|
+
if (after) {
|
|
9686
|
+
const updatedAt = postgresTimestamp(after.updatedAt);
|
|
9687
|
+
keyset = ` AND (n."updatedAt" < ? OR (n."updatedAt" = ? AND (n.name > ? OR (n.name = ? AND n.id > ?))))`;
|
|
9688
|
+
args.push(updatedAt, updatedAt, after.name, after.name, after.id);
|
|
9689
|
+
}
|
|
9690
|
+
args.push(limit + 1);
|
|
9691
|
+
return pageKnowledgeScopeMembers((await this.#readExecutor.execute({
|
|
9692
|
+
sql: `SELECT *, 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 ?`,
|
|
9693
|
+
args
|
|
9694
|
+
})).rows.map(parseNode), limit, input);
|
|
9695
|
+
}
|
|
8631
9696
|
async createNode(input) {
|
|
8632
9697
|
await assertKnowledgeDescriptionWithinBoundCompat(input.description);
|
|
8633
9698
|
const scope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope);
|
|
@@ -8636,6 +9701,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8636
9701
|
if (existing) {
|
|
8637
9702
|
const terminal = await this.#resolveTerminalNode(tx, existing.id);
|
|
8638
9703
|
if (!(0, _mastra_core_storage.isKnowledgeScopeVisible)(terminal.scope, scope)) throw new Error(`Merged knowledge node is not visible from scope: ${input.name}`);
|
|
9704
|
+
await this.#placeNodeInScopes(tx, terminal.id, input.scopeAddresses, /* @__PURE__ */ new Date());
|
|
8639
9705
|
return terminal;
|
|
8640
9706
|
}
|
|
8641
9707
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -8652,7 +9718,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8652
9718
|
updatedAt: now
|
|
8653
9719
|
};
|
|
8654
9720
|
await tx.execute({
|
|
8655
|
-
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,?,?)`,
|
|
9721
|
+
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,?,?)`,
|
|
8656
9722
|
args: [
|
|
8657
9723
|
node.id,
|
|
8658
9724
|
"node",
|
|
@@ -8668,6 +9734,8 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8668
9734
|
now.toISOString()
|
|
8669
9735
|
]
|
|
8670
9736
|
});
|
|
9737
|
+
await this.#replaceNodeScopes(tx, node.id, scope, now);
|
|
9738
|
+
await this.#placeNodeInScopes(tx, node.id, input.scopeAddresses, now);
|
|
8671
9739
|
await this.#replaceMentions(tx, "node", node.id, node.content ?? "", input.resolutionScope ?? scope, scope);
|
|
8672
9740
|
await this.#activity(tx, "node-created", "node", node.id, scope);
|
|
8673
9741
|
await this.#outbox(tx, "node", node.id, "upsert", node.version, scope);
|
|
@@ -8684,13 +9752,13 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8684
9752
|
return this.#resolveNode(this.#readExecutor, input.name, (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
|
|
8685
9753
|
}
|
|
8686
9754
|
async listNodes(input) {
|
|
8687
|
-
const
|
|
9755
|
+
const keys = visibleScopeKeys((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
|
|
8688
9756
|
const clauses = [
|
|
8689
9757
|
`type = 'node'`,
|
|
8690
9758
|
"mergedInto IS NULL",
|
|
8691
|
-
visibleSql
|
|
9759
|
+
visibleSql(keys)
|
|
8692
9760
|
];
|
|
8693
|
-
const args = [
|
|
9761
|
+
const args = [...keys];
|
|
8694
9762
|
if (input.namePrefix) {
|
|
8695
9763
|
clauses.push("canonicalName LIKE ? ESCAPE '='");
|
|
8696
9764
|
args.push(`${escapeLikePattern(canonicalName(input.namePrefix))}%`);
|
|
@@ -8742,6 +9810,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8742
9810
|
input.version
|
|
8743
9811
|
]
|
|
8744
9812
|
})).rowsAffected === 0) throw new _mastra_core_storage.KnowledgeConflictError(input.id);
|
|
9813
|
+
if ((0, _mastra_core_storage.knowledgeScopeKey)(existing.scope) !== (0, _mastra_core_storage.knowledgeScopeKey)(scope)) await this.#swapIdentityScopes(tx, input.id, existing.scope, scope, now);
|
|
8745
9814
|
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);
|
|
8746
9815
|
await this.#activity(tx, "node-updated", "node", input.id, scope);
|
|
8747
9816
|
if ((0, _mastra_core_storage.knowledgeScopeKey)(existing.scope) !== (0, _mastra_core_storage.knowledgeScopeKey)(scope)) {
|
|
@@ -8796,8 +9865,12 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8796
9865
|
]
|
|
8797
9866
|
})).rowsAffected === 0) throw new _mastra_core_storage.KnowledgeConflictError(source.id);
|
|
8798
9867
|
await tx.execute({
|
|
8799
|
-
sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET node=? WHERE node=?`,
|
|
8800
|
-
args: [
|
|
9868
|
+
sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET node=?,version=version+1,updatedAt=? WHERE node=?`,
|
|
9869
|
+
args: [
|
|
9870
|
+
target.id,
|
|
9871
|
+
(/* @__PURE__ */ new Date()).toISOString(),
|
|
9872
|
+
source.id
|
|
9873
|
+
]
|
|
8801
9874
|
});
|
|
8802
9875
|
await tx.execute({
|
|
8803
9876
|
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=?)`,
|
|
@@ -8837,10 +9910,10 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8837
9910
|
});
|
|
8838
9911
|
}
|
|
8839
9912
|
async appendKnowledge(input) {
|
|
9913
|
+
await assertKnowledgeRecordTextWithinBoundCompat(input.text);
|
|
8840
9914
|
const scope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope);
|
|
8841
9915
|
const resolutionScope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.resolutionScope);
|
|
8842
9916
|
const defaultScope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.defaultScope);
|
|
8843
|
-
(0, _mastra_core_storage.assertKnowledgeScopeWithinCeiling)(scope, input.maxScope);
|
|
8844
9917
|
return this.#transaction(async (tx) => {
|
|
8845
9918
|
const parent = await this.#resolveTerminalNode(tx, nodeReferenceId(input.node));
|
|
8846
9919
|
if (!parent) throw new _mastra_core_storage.KnowledgeNotFoundError("node", nodeReferenceId(input.node));
|
|
@@ -8853,11 +9926,10 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8853
9926
|
sourceThreadId: input.sourceThreadId,
|
|
8854
9927
|
capturedAt: /* @__PURE__ */ new Date(),
|
|
8855
9928
|
when: input.when ? new Date(input.when) : void 0,
|
|
8856
|
-
maxScope: input.maxScope,
|
|
8857
9929
|
metadata: input.metadata
|
|
8858
9930
|
};
|
|
8859
9931
|
await tx.execute({
|
|
8860
|
-
sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" (id,node,text,scope,scopeKey,sourceThreadId,capturedAt,"when",
|
|
9932
|
+
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)`,
|
|
8861
9933
|
args: [
|
|
8862
9934
|
record.id,
|
|
8863
9935
|
record.node,
|
|
@@ -8867,10 +9939,12 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8867
9939
|
record.sourceThreadId,
|
|
8868
9940
|
record.capturedAt.toISOString(),
|
|
8869
9941
|
record.when?.toISOString() ?? null,
|
|
8870
|
-
|
|
8871
|
-
|
|
9942
|
+
metadataJson,
|
|
9943
|
+
1,
|
|
9944
|
+
record.capturedAt.toISOString()
|
|
8872
9945
|
]
|
|
8873
9946
|
});
|
|
9947
|
+
await this.#replaceRecordScopes(tx, record.id, scope, record.capturedAt);
|
|
8874
9948
|
await this.#replaceMentions(tx, "record", record.id, record.text, resolutionScope, defaultScope);
|
|
8875
9949
|
await this.#activity(tx, "record-created", "record", record.id, scope, record.sourceThreadId);
|
|
8876
9950
|
await this.#outbox(tx, "record", record.id, "upsert", record.id, scope);
|
|
@@ -8897,17 +9971,13 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8897
9971
|
return this.#queryKnowledge(input, "related");
|
|
8898
9972
|
}
|
|
8899
9973
|
async knowledgeBySource(input) {
|
|
8900
|
-
const
|
|
8901
|
-
const args = [
|
|
8902
|
-
input.sourceThreadId,
|
|
8903
|
-
key,
|
|
8904
|
-
key
|
|
8905
|
-
];
|
|
9974
|
+
const keys = visibleScopeKeys((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
|
|
9975
|
+
const args = [input.sourceThreadId, ...keys];
|
|
8906
9976
|
if (input.after) args.push(input.after);
|
|
8907
9977
|
const limit = input.limit ?? 100;
|
|
8908
9978
|
args.push(limit + 1);
|
|
8909
9979
|
const records = (await this.#readExecutor.execute({
|
|
8910
|
-
sql: `SELECT *,scope AS "scopeJson" 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 ?`,
|
|
9980
|
+
sql: `SELECT *,scope AS "scopeJson" 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 ?`,
|
|
8911
9981
|
args
|
|
8912
9982
|
})).rows.map(parseKnowledge);
|
|
8913
9983
|
return {
|
|
@@ -8922,10 +9992,11 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8922
9992
|
if (record.deletedAt) return record;
|
|
8923
9993
|
const deletedAt = /* @__PURE__ */ new Date();
|
|
8924
9994
|
await tx.execute({
|
|
8925
|
-
sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET deletedAt=?,deletedBy=? WHERE id=? AND deletedAt IS NULL`,
|
|
9995
|
+
sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET deletedAt=?,deletedBy=?,version=version+1,updatedAt=? WHERE id=? AND deletedAt IS NULL`,
|
|
8926
9996
|
args: [
|
|
8927
9997
|
deletedAt.toISOString(),
|
|
8928
9998
|
input.deletedBy,
|
|
9999
|
+
deletedAt.toISOString(),
|
|
8929
10000
|
input.id
|
|
8930
10001
|
]
|
|
8931
10002
|
});
|
|
@@ -8944,8 +10015,8 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8944
10015
|
if (!record) throw new _mastra_core_storage.KnowledgeNotFoundError("record", input.id);
|
|
8945
10016
|
if (!record.deletedAt) return record;
|
|
8946
10017
|
await tx.execute({
|
|
8947
|
-
sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET deletedAt=NULL,deletedBy=NULL WHERE id=?`,
|
|
8948
|
-
args: [input.id]
|
|
10018
|
+
sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET deletedAt=NULL,deletedBy=NULL,version=version+1,updatedAt=? WHERE id=?`,
|
|
10019
|
+
args: [(/* @__PURE__ */ new Date()).toISOString(), input.id]
|
|
8949
10020
|
});
|
|
8950
10021
|
await this.#activity(tx, "record-restored", "record", input.id, record.scope, record.sourceThreadId);
|
|
8951
10022
|
await this.#outbox(tx, "record", input.id, "upsert", (0, _mastra_core_storage.createKnowledgeUlid)(), record.scope);
|
|
@@ -8961,15 +10032,17 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8961
10032
|
return this.#transaction(async (tx) => {
|
|
8962
10033
|
const record = await this.#getKnowledge(tx, input.id, true);
|
|
8963
10034
|
if (!record) throw new _mastra_core_storage.KnowledgeNotFoundError("record", input.id);
|
|
8964
|
-
|
|
10035
|
+
const updatedAt = /* @__PURE__ */ new Date();
|
|
8965
10036
|
await tx.execute({
|
|
8966
|
-
sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET scope=jsonb(?),scopeKey=? WHERE id=?`,
|
|
10037
|
+
sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET scope=jsonb(?),scopeKey=?,version=version+1,updatedAt=? WHERE id=?`,
|
|
8967
10038
|
args: [
|
|
8968
10039
|
JSON.stringify(scope),
|
|
8969
10040
|
(0, _mastra_core_storage.knowledgeScopeKey)(scope),
|
|
10041
|
+
updatedAt.toISOString(),
|
|
8970
10042
|
input.id
|
|
8971
10043
|
]
|
|
8972
10044
|
});
|
|
10045
|
+
await this.#replaceRecordScopes(tx, input.id, scope, updatedAt);
|
|
8973
10046
|
await this.#activity(tx, "record-rescoped", "record", input.id, scope, record.sourceThreadId);
|
|
8974
10047
|
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);
|
|
8975
10048
|
if (!record.deletedAt) await this.#outbox(tx, "record", input.id, "upsert", (0, _mastra_core_storage.createKnowledgeUlid)(), scope);
|
|
@@ -8979,33 +10052,16 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8979
10052
|
};
|
|
8980
10053
|
});
|
|
8981
10054
|
}
|
|
8982
|
-
async raiseKnowledgeCeiling(input) {
|
|
8983
|
-
return this.#transaction(async (tx) => {
|
|
8984
|
-
const record = await this.#getKnowledge(tx, input.id, true);
|
|
8985
|
-
if (!record) throw new _mastra_core_storage.KnowledgeNotFoundError("record", input.id);
|
|
8986
|
-
(0, _mastra_core_storage.assertKnowledgeScopeWithinCeiling)(record.scope, input.maxScope);
|
|
8987
|
-
(0, _mastra_core_storage.assertKnowledgeCeilingRaised)(record.maxScope, input.maxScope);
|
|
8988
|
-
await tx.execute({
|
|
8989
|
-
sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET maxScope=? WHERE id=?`,
|
|
8990
|
-
args: [input.maxScope ?? null, input.id]
|
|
8991
|
-
});
|
|
8992
|
-
return {
|
|
8993
|
-
...record,
|
|
8994
|
-
maxScope: input.maxScope
|
|
8995
|
-
};
|
|
8996
|
-
});
|
|
8997
|
-
}
|
|
8998
10055
|
async search(input) {
|
|
8999
10056
|
const scope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope);
|
|
9000
|
-
const
|
|
10057
|
+
const keys = visibleScopeKeys(scope);
|
|
9001
10058
|
const normalizedQuery = input.query.trim().toLocaleLowerCase();
|
|
9002
10059
|
if (!normalizedQuery) return [];
|
|
9003
10060
|
const query = `%${escapeLikePattern(normalizedQuery)}%`;
|
|
9004
10061
|
const results = (await this.#readExecutor.execute({
|
|
9005
|
-
sql: `SELECT *,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 ?`,
|
|
10062
|
+
sql: `SELECT *,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 ?`,
|
|
9006
10063
|
args: [
|
|
9007
|
-
|
|
9008
|
-
key,
|
|
10064
|
+
...keys,
|
|
9009
10065
|
query,
|
|
9010
10066
|
query,
|
|
9011
10067
|
query,
|
|
@@ -9026,10 +10082,9 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9026
10082
|
}));
|
|
9027
10083
|
if (results.length < (input.limit ?? 20)) {
|
|
9028
10084
|
const records = await this.#readExecutor.execute({
|
|
9029
|
-
sql: `SELECT f.*,f.scope AS "scopeJson",r.name,r.scope AS "parentScopeJson" FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" f JOIN "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" r ON r.id=f.node AND r.type='node' AND r.mergedInto IS NULL WHERE f.deletedAt IS NULL AND ${visibleSql
|
|
10085
|
+
sql: `SELECT f.*,f.scope AS "scopeJson",r.name,r.scope AS "parentScopeJson" FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" f JOIN "${_mastra_core_storage.TABLE_KNOWLEDGE_NODES}" r ON r.id=f.node AND r.type='node' AND r.mergedInto IS NULL WHERE f.deletedAt IS NULL AND ${visibleSql(keys, "f.scopeKey")} AND lower(f.text) LIKE ? ESCAPE '=' ORDER BY f.id DESC LIMIT ?`,
|
|
9030
10086
|
args: [
|
|
9031
|
-
|
|
9032
|
-
key,
|
|
10087
|
+
...keys,
|
|
9033
10088
|
query,
|
|
9034
10089
|
(input.limit ?? 20) - results.length
|
|
9035
10090
|
]
|
|
@@ -9039,7 +10094,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9039
10094
|
return {
|
|
9040
10095
|
type: "record",
|
|
9041
10096
|
id: String(row.id),
|
|
9042
|
-
recordId: String(row.node),
|
|
10097
|
+
recordId: parentVisible ? String(row.node) : String(row.id),
|
|
9043
10098
|
name: parentVisible ? String(row.name) : "(private node)",
|
|
9044
10099
|
text: String(row.text),
|
|
9045
10100
|
scope: parseJson$1(row.scopeJson)
|
|
@@ -9048,41 +10103,26 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9048
10103
|
}
|
|
9049
10104
|
return results;
|
|
9050
10105
|
}
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
const updatedAt = /* @__PURE__ */ new Date();
|
|
9065
|
-
if ((await this.#executor.execute({
|
|
9066
|
-
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`,
|
|
9067
|
-
args: [
|
|
9068
|
-
input.sourceThreadId,
|
|
9069
|
-
input.agent,
|
|
9070
|
-
input.lastKnowledgeId,
|
|
9071
|
-
updatedAt.toISOString()
|
|
9072
|
-
]
|
|
9073
|
-
})).rowsAffected === 0) throw new Error("Knowledge curation cursor cannot move backwards");
|
|
9074
|
-
return {
|
|
9075
|
-
...input,
|
|
9076
|
-
updatedAt
|
|
9077
|
-
};
|
|
10106
|
+
/**
|
|
10107
|
+
* @deprecated Curation cursors were removed. Observation-time curate is the only Knowledge writer and needs no
|
|
10108
|
+
* cursor. Always throws.
|
|
10109
|
+
*/
|
|
10110
|
+
async getCurationCursor(_input) {
|
|
10111
|
+
throw new Error(KNOWLEDGE_CURATION_CURSOR_REMOVED_MESSAGE);
|
|
10112
|
+
}
|
|
10113
|
+
/**
|
|
10114
|
+
* @deprecated Curation cursors were removed. Observation-time curate is the only Knowledge writer and needs no
|
|
10115
|
+
* cursor. Always throws.
|
|
10116
|
+
*/
|
|
10117
|
+
async advanceCurationCursor(_input) {
|
|
10118
|
+
throw new Error(KNOWLEDGE_CURATION_CURSOR_REMOVED_MESSAGE);
|
|
9078
10119
|
}
|
|
9079
10120
|
async listActivity(input) {
|
|
9080
|
-
const
|
|
10121
|
+
const keys = visibleScopeKeys((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
|
|
9081
10122
|
return (await this.#readExecutor.execute({
|
|
9082
|
-
sql: `SELECT *,scope AS "scopeJson" FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY}" WHERE ${visibleSql}${input.after ? " AND id < ?" : ""} ORDER BY id DESC LIMIT ?`,
|
|
10123
|
+
sql: `SELECT *,scope AS "scopeJson" FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY}" WHERE ${visibleSql(keys)}${input.after ? " AND id < ?" : ""} ORDER BY id DESC LIMIT ?`,
|
|
9083
10124
|
args: [
|
|
9084
|
-
|
|
9085
|
-
key,
|
|
10125
|
+
...keys,
|
|
9086
10126
|
...input.after ? [input.after] : [],
|
|
9087
10127
|
input.limit ?? 100
|
|
9088
10128
|
]
|
|
@@ -9104,9 +10144,9 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9104
10144
|
args.push(input.status);
|
|
9105
10145
|
}
|
|
9106
10146
|
if (input.scope) {
|
|
9107
|
-
const
|
|
9108
|
-
clauses.push(visibleSql);
|
|
9109
|
-
args.push(
|
|
10147
|
+
const keys = visibleScopeKeys(input.scope);
|
|
10148
|
+
clauses.push(visibleSql(keys));
|
|
10149
|
+
args.push(...keys);
|
|
9110
10150
|
}
|
|
9111
10151
|
args.push(input.limit ?? 100);
|
|
9112
10152
|
return (await this.#executor.execute({
|
|
@@ -9125,9 +10165,9 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9125
10165
|
];
|
|
9126
10166
|
const args = [now.toISOString(), stale.toISOString()];
|
|
9127
10167
|
if (input.scope) {
|
|
9128
|
-
const
|
|
9129
|
-
clauses.push(visibleSql);
|
|
9130
|
-
args.push(
|
|
10168
|
+
const keys = visibleScopeKeys(input.scope);
|
|
10169
|
+
clauses.push(visibleSql(keys));
|
|
10170
|
+
args.push(...keys);
|
|
9131
10171
|
}
|
|
9132
10172
|
args.push(input.limit ?? 100);
|
|
9133
10173
|
const ids = (await tx.execute({
|
|
@@ -9194,12 +10234,14 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9194
10234
|
return result.rows[0] ? parseNode(result.rows[0]) : null;
|
|
9195
10235
|
}
|
|
9196
10236
|
async #resolveNode(executor, name, scope) {
|
|
9197
|
-
|
|
9198
|
-
|
|
9199
|
-
|
|
9200
|
-
|
|
9201
|
-
|
|
9202
|
-
|
|
10237
|
+
const keys = visibleScopeKeys(scope);
|
|
10238
|
+
const candidates = (await executor.execute({
|
|
10239
|
+
sql: `SELECT *,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)`,
|
|
10240
|
+
args: [canonicalName(name), ...keys]
|
|
10241
|
+
})).rows.map(parseNode).sort((left, right) => right.scope.length - left.scope.length);
|
|
10242
|
+
for (const candidate of candidates) {
|
|
10243
|
+
const terminal = await this.#resolveTerminalNode(executor, candidate.id);
|
|
10244
|
+
if (terminal && (0, _mastra_core_storage.isKnowledgeScopeVisible)(terminal.scope, scope)) return terminal;
|
|
9203
10245
|
}
|
|
9204
10246
|
return null;
|
|
9205
10247
|
}
|
|
@@ -9224,17 +10266,16 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9224
10266
|
const scope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope);
|
|
9225
10267
|
const node = await this.#resolveTerminalNode(this.#readExecutor, nodeReferenceId(input.node));
|
|
9226
10268
|
if (!node) return { records: [] };
|
|
9227
|
-
const
|
|
10269
|
+
const keys = visibleScopeKeys(scope);
|
|
9228
10270
|
const args = [
|
|
9229
10271
|
node.id,
|
|
9230
10272
|
...relationship === "related" ? [node.id] : [],
|
|
9231
|
-
|
|
9232
|
-
key
|
|
10273
|
+
...keys
|
|
9233
10274
|
];
|
|
9234
10275
|
if (input.after) args.push(input.after);
|
|
9235
10276
|
args.push((input.limit ?? 100) + 1);
|
|
9236
10277
|
const records = (await this.#readExecutor.execute({
|
|
9237
|
-
sql: `SELECT DISTINCT f.*,f.scope AS "scopeJson" FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" f${relationship === "about" ? "" : ` LEFT JOIN "${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}" m ON m.sourceType='record' AND m.sourceId=f.id`} WHERE ${relationship === "about" ? "f.node=?" : relationship === "mentioning" ? "m.recordId=?" : "(f.node=? OR m.recordId=?)"} AND ${visibleSql
|
|
10278
|
+
sql: `SELECT DISTINCT f.*,f.scope AS "scopeJson" FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" f${relationship === "about" ? "" : ` LEFT JOIN "${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}" m ON m.sourceType='record' AND m.sourceId=f.id`} WHERE ${relationship === "about" ? "f.node=?" : relationship === "mentioning" ? "m.recordId=?" : "(f.node=? OR m.recordId=?)"} AND ${visibleSql(keys, "f.scopeKey")}${input.includeDeleted ? "" : " AND f.deletedAt IS NULL"}${input.after ? " AND f.id < ?" : ""} ORDER BY f.id DESC LIMIT ?`,
|
|
9238
10279
|
args
|
|
9239
10280
|
})).rows.map(parseKnowledge);
|
|
9240
10281
|
const limit = input.limit ?? 100;
|
|
@@ -9243,6 +10284,90 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9243
10284
|
nextCursor: records.length > limit ? records[limit - 1]?.id : void 0
|
|
9244
10285
|
};
|
|
9245
10286
|
}
|
|
10287
|
+
async #resolveScopeNodeIds(executor, addresses) {
|
|
10288
|
+
const scopeNodeIds = /* @__PURE__ */ new Set();
|
|
10289
|
+
for (const address of addresses) {
|
|
10290
|
+
const result = await executor.execute({
|
|
10291
|
+
sql: `SELECT scopeNodeId FROM "${TABLE_KNOWLEDGE_SCOPE_ADDRESSES}" WHERE address=?`,
|
|
10292
|
+
args: [address]
|
|
10293
|
+
});
|
|
10294
|
+
if (result.rows[0]?.scopeNodeId != null) scopeNodeIds.add(String(result.rows[0].scopeNodeId));
|
|
10295
|
+
}
|
|
10296
|
+
return [...scopeNodeIds];
|
|
10297
|
+
}
|
|
10298
|
+
async #replaceNodeScopes(executor, nodeId, addresses, addedAt) {
|
|
10299
|
+
await executor.execute({
|
|
10300
|
+
sql: `DELETE FROM "${TABLE_KNOWLEDGE_NODE_SCOPES}" WHERE nodeId=?`,
|
|
10301
|
+
args: [nodeId]
|
|
10302
|
+
});
|
|
10303
|
+
for (const scopeNodeId of await this.#resolveScopeNodeIds(executor, addresses)) await executor.execute({
|
|
10304
|
+
sql: `INSERT INTO "${TABLE_KNOWLEDGE_NODE_SCOPES}" (nodeId,scopeNodeId,addedAt) VALUES (?,?,?) ON CONFLICT DO NOTHING`,
|
|
10305
|
+
args: [
|
|
10306
|
+
nodeId,
|
|
10307
|
+
scopeNodeId,
|
|
10308
|
+
addedAt.toISOString()
|
|
10309
|
+
]
|
|
10310
|
+
});
|
|
10311
|
+
}
|
|
10312
|
+
/**
|
|
10313
|
+
* Move a node's identity memberships from `from` to `to` without touching structural
|
|
10314
|
+
* placements added by `#placeNodeInScopes`, which a scope change must not erase.
|
|
10315
|
+
*/
|
|
10316
|
+
async #swapIdentityScopes(executor, nodeId, from, to, addedAt) {
|
|
10317
|
+
const next = await this.#resolveScopeNodeIds(executor, to);
|
|
10318
|
+
for (const scopeNodeId of await this.#resolveScopeNodeIds(executor, from)) {
|
|
10319
|
+
if (next.includes(scopeNodeId)) continue;
|
|
10320
|
+
await executor.execute({
|
|
10321
|
+
sql: `DELETE FROM "${TABLE_KNOWLEDGE_NODE_SCOPES}" WHERE nodeId=? AND scopeNodeId=?`,
|
|
10322
|
+
args: [nodeId, scopeNodeId]
|
|
10323
|
+
});
|
|
10324
|
+
}
|
|
10325
|
+
for (const scopeNodeId of next) await executor.execute({
|
|
10326
|
+
sql: `INSERT INTO "${TABLE_KNOWLEDGE_NODE_SCOPES}" (nodeId,scopeNodeId,addedAt) VALUES (?,?,?) ON CONFLICT DO NOTHING`,
|
|
10327
|
+
args: [
|
|
10328
|
+
nodeId,
|
|
10329
|
+
scopeNodeId,
|
|
10330
|
+
addedAt.toISOString()
|
|
10331
|
+
]
|
|
10332
|
+
});
|
|
10333
|
+
}
|
|
10334
|
+
/**
|
|
10335
|
+
* Additive structural placement: every address must resolve to a live scope node
|
|
10336
|
+
* (unlike identity membership, an unknown address is a caller error, not a lazy
|
|
10337
|
+
* materialization miss). Runs inside the caller's transaction, so a throw aborts
|
|
10338
|
+
* the whole mutation.
|
|
10339
|
+
*/
|
|
10340
|
+
async #placeNodeInScopes(executor, nodeId, addresses, addedAt) {
|
|
10341
|
+
for (const address of addresses ?? []) {
|
|
10342
|
+
const scopeNodeId = (await executor.execute({
|
|
10343
|
+
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`,
|
|
10344
|
+
args: [address]
|
|
10345
|
+
})).rows[0]?.scopeNodeId;
|
|
10346
|
+
if (scopeNodeId == null) throw new _mastra_core_storage.KnowledgeNotFoundError("scope", address);
|
|
10347
|
+
await executor.execute({
|
|
10348
|
+
sql: `INSERT INTO "${TABLE_KNOWLEDGE_NODE_SCOPES}" ("nodeId","scopeNodeId","addedAt") VALUES (?,?,?) ON CONFLICT DO NOTHING`,
|
|
10349
|
+
args: [
|
|
10350
|
+
nodeId,
|
|
10351
|
+
String(scopeNodeId),
|
|
10352
|
+
addedAt.toISOString()
|
|
10353
|
+
]
|
|
10354
|
+
});
|
|
10355
|
+
}
|
|
10356
|
+
}
|
|
10357
|
+
async #replaceRecordScopes(executor, recordId, addresses, addedAt) {
|
|
10358
|
+
await executor.execute({
|
|
10359
|
+
sql: `DELETE FROM "${TABLE_KNOWLEDGE_RECORD_SCOPES}" WHERE recordId=?`,
|
|
10360
|
+
args: [recordId]
|
|
10361
|
+
});
|
|
10362
|
+
for (const scopeNodeId of await this.#resolveScopeNodeIds(executor, addresses)) await executor.execute({
|
|
10363
|
+
sql: `INSERT INTO "${TABLE_KNOWLEDGE_RECORD_SCOPES}" (recordId,scopeNodeId,addedAt) VALUES (?,?,?) ON CONFLICT DO NOTHING`,
|
|
10364
|
+
args: [
|
|
10365
|
+
recordId,
|
|
10366
|
+
scopeNodeId,
|
|
10367
|
+
addedAt.toISOString()
|
|
10368
|
+
]
|
|
10369
|
+
});
|
|
10370
|
+
}
|
|
9246
10371
|
async #replaceMentions(tx, sourceType, sourceId, text, resolutionScope, defaultScope) {
|
|
9247
10372
|
await tx.execute({
|
|
9248
10373
|
sql: `DELETE FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}" WHERE sourceType=? AND sourceId=?`,
|
|
@@ -9266,7 +10391,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9266
10391
|
updatedAt: now
|
|
9267
10392
|
};
|
|
9268
10393
|
await tx.execute({
|
|
9269
|
-
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,?,?)`,
|
|
10394
|
+
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,?,?)`,
|
|
9270
10395
|
args: [
|
|
9271
10396
|
node.id,
|
|
9272
10397
|
"node",
|
|
@@ -9280,6 +10405,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9280
10405
|
now.toISOString()
|
|
9281
10406
|
]
|
|
9282
10407
|
});
|
|
10408
|
+
await this.#replaceNodeScopes(tx, node.id, defaultScope, now);
|
|
9283
10409
|
await this.#activity(tx, "node-created", "node", node.id, defaultScope);
|
|
9284
10410
|
await this.#outbox(tx, "node", node.id, "upsert", 1, defaultScope);
|
|
9285
10411
|
}
|
|
@@ -9296,13 +10422,17 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9296
10422
|
}
|
|
9297
10423
|
async #activity(executor, action, recordType, recordId, scope, sourceThreadId) {
|
|
9298
10424
|
const now = /* @__PURE__ */ new Date();
|
|
10425
|
+
const [contextScopeId] = await this.#resolveScopeNodeIds(executor, scope);
|
|
9299
10426
|
await executor.execute({
|
|
9300
|
-
sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY}" (id,action,recordType,recordId,scope,scopeKey,sourceThreadId,createdAt) VALUES (
|
|
10427
|
+
sql: `INSERT INTO "${_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY}" (id,action,targetType,targetId,contextScopeId,recordType,recordId,scope,scopeKey,sourceThreadId,createdAt) VALUES (?,?,?,?,?,?,?,jsonb(?),?,?,?)`,
|
|
9301
10428
|
args: [
|
|
9302
10429
|
(0, _mastra_core_storage.createKnowledgeUlid)(),
|
|
9303
10430
|
action,
|
|
9304
10431
|
recordType,
|
|
9305
10432
|
recordId,
|
|
10433
|
+
contextScopeId ?? null,
|
|
10434
|
+
recordType,
|
|
10435
|
+
recordId,
|
|
9306
10436
|
JSON.stringify(scope),
|
|
9307
10437
|
(0, _mastra_core_storage.knowledgeScopeKey)(scope),
|
|
9308
10438
|
sourceThreadId ?? null,
|
|
@@ -25062,7 +26192,10 @@ var PostgresStore = class extends _mastra_core_storage.MastraCompositeStore {
|
|
|
25062
26192
|
workflows: new WorkflowsPG(domainConfig),
|
|
25063
26193
|
workflowDefinitions: new WorkflowDefinitionsPG(domainConfig),
|
|
25064
26194
|
memory: new MemoryPG(domainConfig),
|
|
25065
|
-
knowledge: new KnowledgePG(
|
|
26195
|
+
knowledge: new KnowledgePG({
|
|
26196
|
+
...domainConfig,
|
|
26197
|
+
storageIsolationKey: config.storageIsolationKey ?? getPgKnowledgeIsolationKey(config)
|
|
26198
|
+
}),
|
|
25066
26199
|
notifications: new NotificationsPG(domainConfig),
|
|
25067
26200
|
observability: new ObservabilityPG(domainConfig),
|
|
25068
26201
|
agents: new AgentsPG(domainConfig),
|
|
@@ -25116,7 +26249,7 @@ var PostgresStore = class extends _mastra_core_storage.MastraCompositeStore {
|
|
|
25116
26249
|
const pinned = new PinnedClientAdapter(this.#writePool, pinnedClient);
|
|
25117
26250
|
this.#db.pin(pinned);
|
|
25118
26251
|
this.#db.setSchemaSnapshot(await loadSchemaSnapshot(pinned, this.schema));
|
|
25119
|
-
await
|
|
26252
|
+
await Promise.all(Object.entries(this.stores).filter(([name, store]) => name !== "knowledge" && store).map(([, store]) => store.init()));
|
|
25120
26253
|
this.isInitialized = true;
|
|
25121
26254
|
} catch (error) {
|
|
25122
26255
|
this.#initPromise = null;
|