@mastra/pg 1.31.0-alpha.1 → 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/docs/references/reference-rag-chunking-and-embedding.md +1 -1
- package/dist/docs/references/reference-rag-retrieval.md +7 -5
- package/dist/index.cjs +1396 -220
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1399 -223
- 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 +17 -5
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/db/schema-snapshot.d.ts +2 -0
- package/dist/storage/db/schema-snapshot.d.ts.map +1 -1
- package/dist/storage/domains/experiments/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/domains/workflows/index.d.ts +2 -1
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +3 -2
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");
|
|
@@ -2499,7 +2499,8 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2499
2499
|
const schema = schemaName || "public";
|
|
2500
2500
|
const [tableRows, columnRows, indexRows] = await Promise.all([
|
|
2501
2501
|
client.manyOrNone(`SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = $1`, [schema]),
|
|
2502
|
-
client.manyOrNone(`SELECT c.relname AS table_name, a.attname AS column_name, format_type(a.atttypid, a.atttypmod) AS data_type
|
|
2502
|
+
client.manyOrNone(`SELECT c.relname AS table_name, a.attname AS column_name, format_type(a.atttypid, a.atttypmod) AS data_type,
|
|
2503
|
+
a.attnotnull AS not_null
|
|
2503
2504
|
FROM pg_catalog.pg_class c
|
|
2504
2505
|
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
2505
2506
|
JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
|
|
@@ -2515,6 +2516,7 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2515
2516
|
]);
|
|
2516
2517
|
const columns = /* @__PURE__ */ new Map();
|
|
2517
2518
|
const columnTypes = /* @__PURE__ */ new Map();
|
|
2519
|
+
const notNullColumns = /* @__PURE__ */ new Map();
|
|
2518
2520
|
for (const row of columnRows) {
|
|
2519
2521
|
let set = columns.get(row.table_name);
|
|
2520
2522
|
if (!set) {
|
|
@@ -2528,6 +2530,14 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2528
2530
|
columnTypes.set(row.table_name, types);
|
|
2529
2531
|
}
|
|
2530
2532
|
types.set(row.column_name, row.data_type);
|
|
2533
|
+
if (row.not_null) {
|
|
2534
|
+
let notNull = notNullColumns.get(row.table_name);
|
|
2535
|
+
if (!notNull) {
|
|
2536
|
+
notNull = /* @__PURE__ */ new Set();
|
|
2537
|
+
notNullColumns.set(row.table_name, notNull);
|
|
2538
|
+
}
|
|
2539
|
+
notNull.add(row.column_name);
|
|
2540
|
+
}
|
|
2531
2541
|
}
|
|
2532
2542
|
const indexes = /* @__PURE__ */ new Set();
|
|
2533
2543
|
const replicaIdentityIndexes = /* @__PURE__ */ new Set();
|
|
@@ -2544,6 +2554,7 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2544
2554
|
tables: new Set(tableRows.map((r) => r.tablename)),
|
|
2545
2555
|
columns,
|
|
2546
2556
|
columnTypes,
|
|
2557
|
+
notNullColumns,
|
|
2547
2558
|
indexes,
|
|
2548
2559
|
replicaIdentityIndexes,
|
|
2549
2560
|
primaryKeyIndexes,
|
|
@@ -3622,6 +3633,33 @@ MIGRATION REQUIRED: Duplicate spans detected in ${duplicateInfo.tableName}\n====
|
|
|
3622
3633
|
this.columnTypeCache.delete(tableName);
|
|
3623
3634
|
}
|
|
3624
3635
|
}
|
|
3636
|
+
/**
|
|
3637
|
+
* Drops NOT NULL from `columns` on `tableName` where it is still set. Answered
|
|
3638
|
+
* from the init snapshot when one is installed, so a converged schema issues
|
|
3639
|
+
* no query and never takes the ACCESS EXCLUSIVE lock.
|
|
3640
|
+
*/
|
|
3641
|
+
async dropNotNull({ tableName, columns }) {
|
|
3642
|
+
const parsedColumns = columns.map((c) => (0, _mastra_core_utils.parseSqlIdentifier)(c, "column name"));
|
|
3643
|
+
const snapshot = this.schemaSnapshot;
|
|
3644
|
+
let toAlter;
|
|
3645
|
+
if (snapshot) {
|
|
3646
|
+
const notNull = snapshot.notNullColumns.get(tableName);
|
|
3647
|
+
toAlter = parsedColumns.filter((c) => notNull?.has(c));
|
|
3648
|
+
} else toAlter = (await this.client.any(`SELECT column_name FROM information_schema.columns
|
|
3649
|
+
WHERE table_schema = $1 AND table_name = $2 AND column_name = ANY($3) AND is_nullable = 'NO'`, [
|
|
3650
|
+
this.schemaName || "public",
|
|
3651
|
+
tableName,
|
|
3652
|
+
parsedColumns
|
|
3653
|
+
])).map((r) => r.column_name);
|
|
3654
|
+
if (toAlter.length === 0) return;
|
|
3655
|
+
const fullTableName = getTableName$6({
|
|
3656
|
+
indexName: tableName,
|
|
3657
|
+
schemaName: getSchemaName$6(this.schemaName)
|
|
3658
|
+
});
|
|
3659
|
+
await this.client.none(`ALTER TABLE ${fullTableName} ${toAlter.map((c) => `ALTER COLUMN "${c}" DROP NOT NULL`).join(", ")}`);
|
|
3660
|
+
const notNull = snapshot?.notNullColumns.get(tableName);
|
|
3661
|
+
for (const c of toAlter) notNull?.delete(c);
|
|
3662
|
+
}
|
|
3625
3663
|
async load({ tableName, keys }) {
|
|
3626
3664
|
try {
|
|
3627
3665
|
const keyEntries = Object.entries(keys).map(([key, value]) => [(0, _mastra_core_utils.parseSqlIdentifier)(key, "column name"), value]);
|
|
@@ -7112,6 +7150,10 @@ var ExperimentsPG = class ExperimentsPG extends _mastra_core_storage.Experiments
|
|
|
7112
7150
|
"scorerIds"
|
|
7113
7151
|
]
|
|
7114
7152
|
});
|
|
7153
|
+
await this.#db.dropNotNull({
|
|
7154
|
+
tableName: _mastra_core_storage.TABLE_EXPERIMENTS,
|
|
7155
|
+
columns: ["targetType", "targetId"]
|
|
7156
|
+
});
|
|
7115
7157
|
await this.#db.alterTable({
|
|
7116
7158
|
tableName: _mastra_core_storage.TABLE_EXPERIMENT_RESULTS,
|
|
7117
7159
|
schema: _mastra_core_storage.EXPERIMENT_RESULTS_SCHEMA,
|
|
@@ -8259,18 +8301,650 @@ var FavoritesPG = class FavoritesPG extends _mastra_core_storage.FavoritesStorag
|
|
|
8259
8301
|
}
|
|
8260
8302
|
};
|
|
8261
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
|
|
8262
8939
|
//#region src/storage/domains/knowledge/index.ts
|
|
8263
|
-
|
|
8940
|
+
const loadKnowledgeV2Core = createKnowledgeV2CoreLoader(_mastra_core_features.coreFeatures, () => import("@mastra/core/storage"));
|
|
8264
8941
|
async function assertKnowledgeDescriptionWithinBoundCompat(description) {
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
assertWithinBound = resolvedAssert;
|
|
8272
|
-
}
|
|
8273
|
-
assertWithinBound(description);
|
|
8942
|
+
const { assertKnowledgeDescriptionWithinBound } = await loadKnowledgeV2Core();
|
|
8943
|
+
assertKnowledgeDescriptionWithinBound(description);
|
|
8944
|
+
}
|
|
8945
|
+
async function assertKnowledgeRecordTextWithinBoundCompat(text) {
|
|
8946
|
+
const { assertKnowledgeRecordTextWithinBound } = await loadKnowledgeV2Core();
|
|
8947
|
+
assertKnowledgeRecordTextWithinBound(text);
|
|
8274
8948
|
}
|
|
8275
8949
|
const camelCaseColumns = [
|
|
8276
8950
|
"canonicalName",
|
|
@@ -8281,7 +8955,6 @@ const camelCaseColumns = [
|
|
|
8281
8955
|
"node",
|
|
8282
8956
|
"sourceThreadId",
|
|
8283
8957
|
"capturedAt",
|
|
8284
|
-
"maxScope",
|
|
8285
8958
|
"deletedAt",
|
|
8286
8959
|
"deletedBy",
|
|
8287
8960
|
"sourceType",
|
|
@@ -8295,7 +8968,30 @@ const camelCaseColumns = [
|
|
|
8295
8968
|
"availableAt",
|
|
8296
8969
|
"claimedAt",
|
|
8297
8970
|
"claimedBy",
|
|
8298
|
-
"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"
|
|
8299
8995
|
];
|
|
8300
8996
|
function transformSqlCode(sql, transform) {
|
|
8301
8997
|
return sql.split(/('(?:''|[^'])*')/g).map((part, index) => index % 2 === 0 ? transform(part) : part).join("");
|
|
@@ -8310,14 +9006,7 @@ function postgresSql(sql, schemaName) {
|
|
|
8310
9006
|
const quotedSchema = `"${parseSchemaName(schemaName)}"`;
|
|
8311
9007
|
normalized = transformSqlCode(normalized, (code) => {
|
|
8312
9008
|
let transformed = code;
|
|
8313
|
-
for (const table of [
|
|
8314
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_NODES,
|
|
8315
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS,
|
|
8316
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS,
|
|
8317
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_CURSORS,
|
|
8318
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
|
|
8319
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX
|
|
8320
|
-
]) transformed = transformed.replaceAll(`"${table}"`, `${quotedSchema}."${table}"`);
|
|
9009
|
+
for (const table of [...KNOWLEDGE_TABLE_NAMES, ...RETIRED_KNOWLEDGE_TABLE_NAMES]) transformed = transformed.replaceAll(`"${table}"`, `${quotedSchema}."${table}"`);
|
|
8321
9010
|
return transformed;
|
|
8322
9011
|
});
|
|
8323
9012
|
}
|
|
@@ -8325,17 +9014,35 @@ function postgresSql(sql, schemaName) {
|
|
|
8325
9014
|
return transformSqlCode(normalized, (code) => code.replace(/\?/g, () => `$${++index}`));
|
|
8326
9015
|
}
|
|
8327
9016
|
function createExecutor(client, schemaName) {
|
|
8328
|
-
|
|
9017
|
+
const execute = async (statement, qualifyWithSchema) => {
|
|
8329
9018
|
const sql = typeof statement === "string" ? statement : statement.sql;
|
|
8330
9019
|
const args = typeof statement === "string" ? [] : statement.args ?? [];
|
|
8331
|
-
const result = await client.query(postgresSql(sql, schemaName), args);
|
|
9020
|
+
const result = await client.query(postgresSql(sql, qualifyWithSchema ? schemaName : void 0), args);
|
|
8332
9021
|
return {
|
|
8333
9022
|
rows: result.rows,
|
|
8334
9023
|
rowsAffected: result.rowCount ?? 0
|
|
8335
9024
|
};
|
|
8336
|
-
}
|
|
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];
|
|
8337
9044
|
}
|
|
8338
|
-
const visibleSql =
|
|
9045
|
+
const visibleSql = (keys, scopeKeyColumn = "scopeKey") => `${scopeKeyColumn} IN (${keys.map(() => "?").join(",")})`;
|
|
8339
9046
|
function parseJson$1(value) {
|
|
8340
9047
|
if (typeof value === "string") return JSON.parse(value);
|
|
8341
9048
|
if (value instanceof Uint8Array) return JSON.parse(new TextDecoder().decode(value));
|
|
@@ -8375,9 +9082,10 @@ function parseNode(row) {
|
|
|
8375
9082
|
id: String(row.id),
|
|
8376
9083
|
type: "node",
|
|
8377
9084
|
name: String(row.name),
|
|
8378
|
-
kind: String(row.kind),
|
|
9085
|
+
kind: row.kind == null ? "" : String(row.kind),
|
|
8379
9086
|
content: row.content == null ? void 0 : String(row.content),
|
|
8380
9087
|
description: row.description == null ? void 0 : String(row.description),
|
|
9088
|
+
isScope: row.isScope === true || row.isScope === 1 ? true : void 0,
|
|
8381
9089
|
scope: parseJson$1(row.scopeJson ?? row.scope),
|
|
8382
9090
|
version: Number(row.version),
|
|
8383
9091
|
mergedInto: row.mergedInto == null ? void 0 : String(row.mergedInto),
|
|
@@ -8394,7 +9102,6 @@ function parseKnowledge(row) {
|
|
|
8394
9102
|
sourceThreadId: String(row.sourceThreadId),
|
|
8395
9103
|
capturedAt: toDate$1(row.capturedAt),
|
|
8396
9104
|
when: optionalDate(row.when),
|
|
8397
|
-
maxScope: row.maxScope == null ? void 0 : String(row.maxScope),
|
|
8398
9105
|
metadata: row.metadata == null ? void 0 : parseJson$1(row.metadata),
|
|
8399
9106
|
deletedAt: optionalDate(row.deletedAt),
|
|
8400
9107
|
deletedBy: row.deletedBy == null ? void 0 : String(row.deletedBy)
|
|
@@ -8431,6 +9138,10 @@ function knowledgeIndexes(schemaName) {
|
|
|
8431
9138
|
name: "idx_knowledge_nodes_scope",
|
|
8432
9139
|
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_nodes_scope ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_NODES)} ("scopeKey", "type");`
|
|
8433
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
|
+
},
|
|
8434
9145
|
{
|
|
8435
9146
|
name: "idx_knowledge_records_node_latest",
|
|
8436
9147
|
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_records_node_latest ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS)} ("node", "id" DESC);`
|
|
@@ -8447,6 +9158,14 @@ function knowledgeIndexes(schemaName) {
|
|
|
8447
9158
|
name: "idx_knowledge_activity_latest",
|
|
8448
9159
|
sql: `CREATE INDEX IF NOT EXISTS idx_knowledge_activity_latest ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY)} ("id" DESC);`
|
|
8449
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
|
+
},
|
|
8450
9169
|
{
|
|
8451
9170
|
name: "idx_knowledge_outbox_idempotency",
|
|
8452
9171
|
sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_knowledge_outbox_idempotency ON ${table(_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX)} ("idempotencyKey");`
|
|
@@ -8454,67 +9173,152 @@ function knowledgeIndexes(schemaName) {
|
|
|
8454
9173
|
{
|
|
8455
9174
|
name: "idx_knowledge_outbox_claim",
|
|
8456
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);`
|
|
8457
9200
|
}
|
|
8458
9201
|
];
|
|
8459
9202
|
}
|
|
8460
9203
|
function knowledgeIndexDDL(schemaName) {
|
|
8461
9204
|
return knowledgeIndexes(schemaName).map((index) => index.sql);
|
|
8462
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
|
+
}
|
|
8463
9314
|
var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
8464
|
-
static MANAGED_TABLES =
|
|
8465
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_NODES,
|
|
8466
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS,
|
|
8467
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS,
|
|
8468
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_CURSORS,
|
|
8469
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
|
|
8470
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX
|
|
8471
|
-
];
|
|
9315
|
+
static MANAGED_TABLES = KNOWLEDGE_TABLE_NAMES;
|
|
8472
9316
|
static getExportDDL(schemaName) {
|
|
8473
|
-
return [
|
|
8474
|
-
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
includeAllConstraints: true
|
|
8479
|
-
}),
|
|
8480
|
-
generateTableSQL({
|
|
8481
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_RECORDS,
|
|
8482
|
-
schema: _mastra_core_storage.KNOWLEDGE_RECORDS_SCHEMA,
|
|
8483
|
-
schemaName,
|
|
8484
|
-
includeAllConstraints: true
|
|
8485
|
-
}),
|
|
8486
|
-
generateTableSQL({
|
|
8487
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS,
|
|
8488
|
-
schema: _mastra_core_storage.KNOWLEDGE_MENTIONS_SCHEMA,
|
|
8489
|
-
schemaName,
|
|
8490
|
-
compositePrimaryKey: [
|
|
8491
|
-
"sourceType",
|
|
8492
|
-
"sourceId",
|
|
8493
|
-
"recordId"
|
|
8494
|
-
],
|
|
8495
|
-
includeAllConstraints: true
|
|
8496
|
-
}),
|
|
8497
|
-
generateTableSQL({
|
|
8498
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_CURSORS,
|
|
8499
|
-
schema: _mastra_core_storage.KNOWLEDGE_CURSORS_SCHEMA,
|
|
8500
|
-
schemaName,
|
|
8501
|
-
compositePrimaryKey: ["sourceThreadId", "agent"],
|
|
8502
|
-
includeAllConstraints: true
|
|
8503
|
-
}),
|
|
8504
|
-
generateTableSQL({
|
|
8505
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
|
|
8506
|
-
schema: _mastra_core_storage.KNOWLEDGE_ACTIVITY_SCHEMA,
|
|
8507
|
-
schemaName,
|
|
8508
|
-
includeAllConstraints: true
|
|
8509
|
-
}),
|
|
8510
|
-
generateTableSQL({
|
|
8511
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX,
|
|
8512
|
-
schema: _mastra_core_storage.KNOWLEDGE_SEMANTIC_OUTBOX_SCHEMA,
|
|
8513
|
-
schemaName,
|
|
8514
|
-
includeAllConstraints: true
|
|
8515
|
-
}),
|
|
8516
|
-
...knowledgeIndexDDL(schemaName)
|
|
8517
|
-
];
|
|
9317
|
+
return [...knowledgeTableDefinitions.map((definition) => generateTableSQL({
|
|
9318
|
+
...definition,
|
|
9319
|
+
schemaName,
|
|
9320
|
+
includeAllConstraints: true
|
|
9321
|
+
})), ...knowledgeIndexDDL(schemaName)];
|
|
8518
9322
|
}
|
|
8519
9323
|
#client;
|
|
8520
9324
|
#executor;
|
|
@@ -8523,7 +9327,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8523
9327
|
#db;
|
|
8524
9328
|
#schemaName;
|
|
8525
9329
|
constructor(config) {
|
|
8526
|
-
super();
|
|
9330
|
+
super({ storageIsolationKey: config.storageIsolationKey ?? getPgKnowledgeIsolationKey(config) });
|
|
8527
9331
|
const { client, readClient, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
|
|
8528
9332
|
this.#client = client;
|
|
8529
9333
|
this.#schemaName = schemaName;
|
|
@@ -8536,56 +9340,359 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8536
9340
|
skipDefaultIndexes
|
|
8537
9341
|
});
|
|
8538
9342
|
}
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
|
|
8547
|
-
|
|
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
|
|
8548
9418
|
});
|
|
8549
|
-
|
|
8550
|
-
|
|
8551
|
-
|
|
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
|
+
});
|
|
8552
9444
|
});
|
|
8553
|
-
|
|
8554
|
-
|
|
8555
|
-
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
|
|
8559
|
-
|
|
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
|
|
8560
9478
|
]
|
|
8561
|
-
});
|
|
8562
|
-
|
|
8563
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_CURSORS,
|
|
8564
|
-
schema: _mastra_core_storage.KNOWLEDGE_CURSORS_SCHEMA,
|
|
8565
|
-
compositePrimaryKey: ["sourceThreadId", "agent"]
|
|
8566
|
-
});
|
|
8567
|
-
await this.#db.createTable({
|
|
8568
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
|
|
8569
|
-
schema: _mastra_core_storage.KNOWLEDGE_ACTIVITY_SCHEMA
|
|
8570
|
-
});
|
|
8571
|
-
await this.#db.createTable({
|
|
8572
|
-
tableName: _mastra_core_storage.TABLE_KNOWLEDGE_SEMANTIC_OUTBOX,
|
|
8573
|
-
schema: _mastra_core_storage.KNOWLEDGE_SEMANTIC_OUTBOX_SCHEMA
|
|
8574
|
-
});
|
|
8575
|
-
await Promise.all(knowledgeIndexes(this.#schemaName).map((index) => this.#db.createIndexFromStatement(index.name, index.sql)));
|
|
9479
|
+
})).rows.length > 0) return false;
|
|
9480
|
+
return true;
|
|
8576
9481
|
}
|
|
8577
9482
|
async dangerouslyClearAll() {
|
|
8578
9483
|
await this.#transaction(async (tx) => {
|
|
8579
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,
|
|
8580
9490
|
_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS,
|
|
8581
|
-
|
|
8582
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_NODES,
|
|
8583
|
-
_mastra_core_storage.TABLE_KNOWLEDGE_CURSORS,
|
|
9491
|
+
TABLE_KNOWLEDGE_PROPOSALS,
|
|
8584
9492
|
_mastra_core_storage.TABLE_KNOWLEDGE_ACTIVITY,
|
|
8585
|
-
|
|
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
|
|
8586
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
|
+
};
|
|
8587
9623
|
});
|
|
8588
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
|
+
}
|
|
8589
9696
|
async createNode(input) {
|
|
8590
9697
|
await assertKnowledgeDescriptionWithinBoundCompat(input.description);
|
|
8591
9698
|
const scope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope);
|
|
@@ -8594,6 +9701,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8594
9701
|
if (existing) {
|
|
8595
9702
|
const terminal = await this.#resolveTerminalNode(tx, existing.id);
|
|
8596
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());
|
|
8597
9705
|
return terminal;
|
|
8598
9706
|
}
|
|
8599
9707
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -8610,7 +9718,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8610
9718
|
updatedAt: now
|
|
8611
9719
|
};
|
|
8612
9720
|
await tx.execute({
|
|
8613
|
-
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,?,?)`,
|
|
8614
9722
|
args: [
|
|
8615
9723
|
node.id,
|
|
8616
9724
|
"node",
|
|
@@ -8626,6 +9734,8 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8626
9734
|
now.toISOString()
|
|
8627
9735
|
]
|
|
8628
9736
|
});
|
|
9737
|
+
await this.#replaceNodeScopes(tx, node.id, scope, now);
|
|
9738
|
+
await this.#placeNodeInScopes(tx, node.id, input.scopeAddresses, now);
|
|
8629
9739
|
await this.#replaceMentions(tx, "node", node.id, node.content ?? "", input.resolutionScope ?? scope, scope);
|
|
8630
9740
|
await this.#activity(tx, "node-created", "node", node.id, scope);
|
|
8631
9741
|
await this.#outbox(tx, "node", node.id, "upsert", node.version, scope);
|
|
@@ -8642,13 +9752,13 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8642
9752
|
return this.#resolveNode(this.#readExecutor, input.name, (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
|
|
8643
9753
|
}
|
|
8644
9754
|
async listNodes(input) {
|
|
8645
|
-
const
|
|
9755
|
+
const keys = visibleScopeKeys((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
|
|
8646
9756
|
const clauses = [
|
|
8647
9757
|
`type = 'node'`,
|
|
8648
9758
|
"mergedInto IS NULL",
|
|
8649
|
-
visibleSql
|
|
9759
|
+
visibleSql(keys)
|
|
8650
9760
|
];
|
|
8651
|
-
const args = [
|
|
9761
|
+
const args = [...keys];
|
|
8652
9762
|
if (input.namePrefix) {
|
|
8653
9763
|
clauses.push("canonicalName LIKE ? ESCAPE '='");
|
|
8654
9764
|
args.push(`${escapeLikePattern(canonicalName(input.namePrefix))}%`);
|
|
@@ -8700,6 +9810,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8700
9810
|
input.version
|
|
8701
9811
|
]
|
|
8702
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);
|
|
8703
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);
|
|
8704
9815
|
await this.#activity(tx, "node-updated", "node", input.id, scope);
|
|
8705
9816
|
if ((0, _mastra_core_storage.knowledgeScopeKey)(existing.scope) !== (0, _mastra_core_storage.knowledgeScopeKey)(scope)) {
|
|
@@ -8754,8 +9865,12 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8754
9865
|
]
|
|
8755
9866
|
})).rowsAffected === 0) throw new _mastra_core_storage.KnowledgeConflictError(source.id);
|
|
8756
9867
|
await tx.execute({
|
|
8757
|
-
sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET node=? WHERE node=?`,
|
|
8758
|
-
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
|
+
]
|
|
8759
9874
|
});
|
|
8760
9875
|
await tx.execute({
|
|
8761
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=?)`,
|
|
@@ -8795,10 +9910,10 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8795
9910
|
});
|
|
8796
9911
|
}
|
|
8797
9912
|
async appendKnowledge(input) {
|
|
9913
|
+
await assertKnowledgeRecordTextWithinBoundCompat(input.text);
|
|
8798
9914
|
const scope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope);
|
|
8799
9915
|
const resolutionScope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.resolutionScope);
|
|
8800
9916
|
const defaultScope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.defaultScope);
|
|
8801
|
-
(0, _mastra_core_storage.assertKnowledgeScopeWithinCeiling)(scope, input.maxScope);
|
|
8802
9917
|
return this.#transaction(async (tx) => {
|
|
8803
9918
|
const parent = await this.#resolveTerminalNode(tx, nodeReferenceId(input.node));
|
|
8804
9919
|
if (!parent) throw new _mastra_core_storage.KnowledgeNotFoundError("node", nodeReferenceId(input.node));
|
|
@@ -8811,11 +9926,10 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8811
9926
|
sourceThreadId: input.sourceThreadId,
|
|
8812
9927
|
capturedAt: /* @__PURE__ */ new Date(),
|
|
8813
9928
|
when: input.when ? new Date(input.when) : void 0,
|
|
8814
|
-
maxScope: input.maxScope,
|
|
8815
9929
|
metadata: input.metadata
|
|
8816
9930
|
};
|
|
8817
9931
|
await tx.execute({
|
|
8818
|
-
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)`,
|
|
8819
9933
|
args: [
|
|
8820
9934
|
record.id,
|
|
8821
9935
|
record.node,
|
|
@@ -8825,10 +9939,12 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8825
9939
|
record.sourceThreadId,
|
|
8826
9940
|
record.capturedAt.toISOString(),
|
|
8827
9941
|
record.when?.toISOString() ?? null,
|
|
8828
|
-
|
|
8829
|
-
|
|
9942
|
+
metadataJson,
|
|
9943
|
+
1,
|
|
9944
|
+
record.capturedAt.toISOString()
|
|
8830
9945
|
]
|
|
8831
9946
|
});
|
|
9947
|
+
await this.#replaceRecordScopes(tx, record.id, scope, record.capturedAt);
|
|
8832
9948
|
await this.#replaceMentions(tx, "record", record.id, record.text, resolutionScope, defaultScope);
|
|
8833
9949
|
await this.#activity(tx, "record-created", "record", record.id, scope, record.sourceThreadId);
|
|
8834
9950
|
await this.#outbox(tx, "record", record.id, "upsert", record.id, scope);
|
|
@@ -8855,17 +9971,13 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8855
9971
|
return this.#queryKnowledge(input, "related");
|
|
8856
9972
|
}
|
|
8857
9973
|
async knowledgeBySource(input) {
|
|
8858
|
-
const
|
|
8859
|
-
const args = [
|
|
8860
|
-
input.sourceThreadId,
|
|
8861
|
-
key,
|
|
8862
|
-
key
|
|
8863
|
-
];
|
|
9974
|
+
const keys = visibleScopeKeys((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
|
|
9975
|
+
const args = [input.sourceThreadId, ...keys];
|
|
8864
9976
|
if (input.after) args.push(input.after);
|
|
8865
9977
|
const limit = input.limit ?? 100;
|
|
8866
9978
|
args.push(limit + 1);
|
|
8867
9979
|
const records = (await this.#readExecutor.execute({
|
|
8868
|
-
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 ?`,
|
|
8869
9981
|
args
|
|
8870
9982
|
})).rows.map(parseKnowledge);
|
|
8871
9983
|
return {
|
|
@@ -8880,10 +9992,11 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8880
9992
|
if (record.deletedAt) return record;
|
|
8881
9993
|
const deletedAt = /* @__PURE__ */ new Date();
|
|
8882
9994
|
await tx.execute({
|
|
8883
|
-
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`,
|
|
8884
9996
|
args: [
|
|
8885
9997
|
deletedAt.toISOString(),
|
|
8886
9998
|
input.deletedBy,
|
|
9999
|
+
deletedAt.toISOString(),
|
|
8887
10000
|
input.id
|
|
8888
10001
|
]
|
|
8889
10002
|
});
|
|
@@ -8902,8 +10015,8 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8902
10015
|
if (!record) throw new _mastra_core_storage.KnowledgeNotFoundError("record", input.id);
|
|
8903
10016
|
if (!record.deletedAt) return record;
|
|
8904
10017
|
await tx.execute({
|
|
8905
|
-
sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET deletedAt=NULL,deletedBy=NULL WHERE id=?`,
|
|
8906
|
-
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]
|
|
8907
10020
|
});
|
|
8908
10021
|
await this.#activity(tx, "record-restored", "record", input.id, record.scope, record.sourceThreadId);
|
|
8909
10022
|
await this.#outbox(tx, "record", input.id, "upsert", (0, _mastra_core_storage.createKnowledgeUlid)(), record.scope);
|
|
@@ -8919,15 +10032,17 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8919
10032
|
return this.#transaction(async (tx) => {
|
|
8920
10033
|
const record = await this.#getKnowledge(tx, input.id, true);
|
|
8921
10034
|
if (!record) throw new _mastra_core_storage.KnowledgeNotFoundError("record", input.id);
|
|
8922
|
-
|
|
10035
|
+
const updatedAt = /* @__PURE__ */ new Date();
|
|
8923
10036
|
await tx.execute({
|
|
8924
|
-
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=?`,
|
|
8925
10038
|
args: [
|
|
8926
10039
|
JSON.stringify(scope),
|
|
8927
10040
|
(0, _mastra_core_storage.knowledgeScopeKey)(scope),
|
|
10041
|
+
updatedAt.toISOString(),
|
|
8928
10042
|
input.id
|
|
8929
10043
|
]
|
|
8930
10044
|
});
|
|
10045
|
+
await this.#replaceRecordScopes(tx, input.id, scope, updatedAt);
|
|
8931
10046
|
await this.#activity(tx, "record-rescoped", "record", input.id, scope, record.sourceThreadId);
|
|
8932
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);
|
|
8933
10048
|
if (!record.deletedAt) await this.#outbox(tx, "record", input.id, "upsert", (0, _mastra_core_storage.createKnowledgeUlid)(), scope);
|
|
@@ -8937,33 +10052,16 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8937
10052
|
};
|
|
8938
10053
|
});
|
|
8939
10054
|
}
|
|
8940
|
-
async raiseKnowledgeCeiling(input) {
|
|
8941
|
-
return this.#transaction(async (tx) => {
|
|
8942
|
-
const record = await this.#getKnowledge(tx, input.id, true);
|
|
8943
|
-
if (!record) throw new _mastra_core_storage.KnowledgeNotFoundError("record", input.id);
|
|
8944
|
-
(0, _mastra_core_storage.assertKnowledgeScopeWithinCeiling)(record.scope, input.maxScope);
|
|
8945
|
-
(0, _mastra_core_storage.assertKnowledgeCeilingRaised)(record.maxScope, input.maxScope);
|
|
8946
|
-
await tx.execute({
|
|
8947
|
-
sql: `UPDATE "${_mastra_core_storage.TABLE_KNOWLEDGE_RECORDS}" SET maxScope=? WHERE id=?`,
|
|
8948
|
-
args: [input.maxScope ?? null, input.id]
|
|
8949
|
-
});
|
|
8950
|
-
return {
|
|
8951
|
-
...record,
|
|
8952
|
-
maxScope: input.maxScope
|
|
8953
|
-
};
|
|
8954
|
-
});
|
|
8955
|
-
}
|
|
8956
10055
|
async search(input) {
|
|
8957
10056
|
const scope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope);
|
|
8958
|
-
const
|
|
10057
|
+
const keys = visibleScopeKeys(scope);
|
|
8959
10058
|
const normalizedQuery = input.query.trim().toLocaleLowerCase();
|
|
8960
10059
|
if (!normalizedQuery) return [];
|
|
8961
10060
|
const query = `%${escapeLikePattern(normalizedQuery)}%`;
|
|
8962
10061
|
const results = (await this.#readExecutor.execute({
|
|
8963
|
-
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 ?`,
|
|
8964
10063
|
args: [
|
|
8965
|
-
|
|
8966
|
-
key,
|
|
10064
|
+
...keys,
|
|
8967
10065
|
query,
|
|
8968
10066
|
query,
|
|
8969
10067
|
query,
|
|
@@ -8984,10 +10082,9 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8984
10082
|
}));
|
|
8985
10083
|
if (results.length < (input.limit ?? 20)) {
|
|
8986
10084
|
const records = await this.#readExecutor.execute({
|
|
8987
|
-
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 ?`,
|
|
8988
10086
|
args: [
|
|
8989
|
-
|
|
8990
|
-
key,
|
|
10087
|
+
...keys,
|
|
8991
10088
|
query,
|
|
8992
10089
|
(input.limit ?? 20) - results.length
|
|
8993
10090
|
]
|
|
@@ -8997,7 +10094,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
8997
10094
|
return {
|
|
8998
10095
|
type: "record",
|
|
8999
10096
|
id: String(row.id),
|
|
9000
|
-
recordId: String(row.node),
|
|
10097
|
+
recordId: parentVisible ? String(row.node) : String(row.id),
|
|
9001
10098
|
name: parentVisible ? String(row.name) : "(private node)",
|
|
9002
10099
|
text: String(row.text),
|
|
9003
10100
|
scope: parseJson$1(row.scopeJson)
|
|
@@ -9006,41 +10103,26 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9006
10103
|
}
|
|
9007
10104
|
return results;
|
|
9008
10105
|
}
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
const updatedAt = /* @__PURE__ */ new Date();
|
|
9023
|
-
if ((await this.#executor.execute({
|
|
9024
|
-
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`,
|
|
9025
|
-
args: [
|
|
9026
|
-
input.sourceThreadId,
|
|
9027
|
-
input.agent,
|
|
9028
|
-
input.lastKnowledgeId,
|
|
9029
|
-
updatedAt.toISOString()
|
|
9030
|
-
]
|
|
9031
|
-
})).rowsAffected === 0) throw new Error("Knowledge curation cursor cannot move backwards");
|
|
9032
|
-
return {
|
|
9033
|
-
...input,
|
|
9034
|
-
updatedAt
|
|
9035
|
-
};
|
|
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);
|
|
9036
10119
|
}
|
|
9037
10120
|
async listActivity(input) {
|
|
9038
|
-
const
|
|
10121
|
+
const keys = visibleScopeKeys((0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope));
|
|
9039
10122
|
return (await this.#readExecutor.execute({
|
|
9040
|
-
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 ?`,
|
|
9041
10124
|
args: [
|
|
9042
|
-
|
|
9043
|
-
key,
|
|
10125
|
+
...keys,
|
|
9044
10126
|
...input.after ? [input.after] : [],
|
|
9045
10127
|
input.limit ?? 100
|
|
9046
10128
|
]
|
|
@@ -9062,9 +10144,9 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9062
10144
|
args.push(input.status);
|
|
9063
10145
|
}
|
|
9064
10146
|
if (input.scope) {
|
|
9065
|
-
const
|
|
9066
|
-
clauses.push(visibleSql);
|
|
9067
|
-
args.push(
|
|
10147
|
+
const keys = visibleScopeKeys(input.scope);
|
|
10148
|
+
clauses.push(visibleSql(keys));
|
|
10149
|
+
args.push(...keys);
|
|
9068
10150
|
}
|
|
9069
10151
|
args.push(input.limit ?? 100);
|
|
9070
10152
|
return (await this.#executor.execute({
|
|
@@ -9083,9 +10165,9 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9083
10165
|
];
|
|
9084
10166
|
const args = [now.toISOString(), stale.toISOString()];
|
|
9085
10167
|
if (input.scope) {
|
|
9086
|
-
const
|
|
9087
|
-
clauses.push(visibleSql);
|
|
9088
|
-
args.push(
|
|
10168
|
+
const keys = visibleScopeKeys(input.scope);
|
|
10169
|
+
clauses.push(visibleSql(keys));
|
|
10170
|
+
args.push(...keys);
|
|
9089
10171
|
}
|
|
9090
10172
|
args.push(input.limit ?? 100);
|
|
9091
10173
|
const ids = (await tx.execute({
|
|
@@ -9152,12 +10234,14 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9152
10234
|
return result.rows[0] ? parseNode(result.rows[0]) : null;
|
|
9153
10235
|
}
|
|
9154
10236
|
async #resolveNode(executor, name, scope) {
|
|
9155
|
-
|
|
9156
|
-
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
|
|
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;
|
|
9161
10245
|
}
|
|
9162
10246
|
return null;
|
|
9163
10247
|
}
|
|
@@ -9182,17 +10266,16 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9182
10266
|
const scope = (0, _mastra_core_storage.canonicalizeKnowledgeScope)(input.scope);
|
|
9183
10267
|
const node = await this.#resolveTerminalNode(this.#readExecutor, nodeReferenceId(input.node));
|
|
9184
10268
|
if (!node) return { records: [] };
|
|
9185
|
-
const
|
|
10269
|
+
const keys = visibleScopeKeys(scope);
|
|
9186
10270
|
const args = [
|
|
9187
10271
|
node.id,
|
|
9188
10272
|
...relationship === "related" ? [node.id] : [],
|
|
9189
|
-
|
|
9190
|
-
key
|
|
10273
|
+
...keys
|
|
9191
10274
|
];
|
|
9192
10275
|
if (input.after) args.push(input.after);
|
|
9193
10276
|
args.push((input.limit ?? 100) + 1);
|
|
9194
10277
|
const records = (await this.#readExecutor.execute({
|
|
9195
|
-
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 ?`,
|
|
9196
10279
|
args
|
|
9197
10280
|
})).rows.map(parseKnowledge);
|
|
9198
10281
|
const limit = input.limit ?? 100;
|
|
@@ -9201,6 +10284,90 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9201
10284
|
nextCursor: records.length > limit ? records[limit - 1]?.id : void 0
|
|
9202
10285
|
};
|
|
9203
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
|
+
}
|
|
9204
10371
|
async #replaceMentions(tx, sourceType, sourceId, text, resolutionScope, defaultScope) {
|
|
9205
10372
|
await tx.execute({
|
|
9206
10373
|
sql: `DELETE FROM "${_mastra_core_storage.TABLE_KNOWLEDGE_MENTIONS}" WHERE sourceType=? AND sourceId=?`,
|
|
@@ -9224,7 +10391,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9224
10391
|
updatedAt: now
|
|
9225
10392
|
};
|
|
9226
10393
|
await tx.execute({
|
|
9227
|
-
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,?,?)`,
|
|
9228
10395
|
args: [
|
|
9229
10396
|
node.id,
|
|
9230
10397
|
"node",
|
|
@@ -9238,6 +10405,7 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9238
10405
|
now.toISOString()
|
|
9239
10406
|
]
|
|
9240
10407
|
});
|
|
10408
|
+
await this.#replaceNodeScopes(tx, node.id, defaultScope, now);
|
|
9241
10409
|
await this.#activity(tx, "node-created", "node", node.id, defaultScope);
|
|
9242
10410
|
await this.#outbox(tx, "node", node.id, "upsert", 1, defaultScope);
|
|
9243
10411
|
}
|
|
@@ -9254,13 +10422,17 @@ var KnowledgePG = class extends _mastra_core_storage.KnowledgeStorage {
|
|
|
9254
10422
|
}
|
|
9255
10423
|
async #activity(executor, action, recordType, recordId, scope, sourceThreadId) {
|
|
9256
10424
|
const now = /* @__PURE__ */ new Date();
|
|
10425
|
+
const [contextScopeId] = await this.#resolveScopeNodeIds(executor, scope);
|
|
9257
10426
|
await executor.execute({
|
|
9258
|
-
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(?),?,?,?)`,
|
|
9259
10428
|
args: [
|
|
9260
10429
|
(0, _mastra_core_storage.createKnowledgeUlid)(),
|
|
9261
10430
|
action,
|
|
9262
10431
|
recordType,
|
|
9263
10432
|
recordId,
|
|
10433
|
+
contextScopeId ?? null,
|
|
10434
|
+
recordType,
|
|
10435
|
+
recordId,
|
|
9264
10436
|
JSON.stringify(scope),
|
|
9265
10437
|
(0, _mastra_core_storage.knowledgeScopeKey)(scope),
|
|
9266
10438
|
sourceThreadId ?? null,
|
|
@@ -23515,7 +24687,7 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
23515
24687
|
async dangerouslyClearAll() {
|
|
23516
24688
|
await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT });
|
|
23517
24689
|
}
|
|
23518
|
-
async updateWorkflowResults({ workflowName, runId, stepId, result, requestContext }) {
|
|
24690
|
+
async updateWorkflowResults({ workflowName, runId, stepId, result, requestContext, state }) {
|
|
23519
24691
|
try {
|
|
23520
24692
|
return await this.#db.client.tx(async (t) => {
|
|
23521
24693
|
const tableName = getTableName({
|
|
@@ -23546,7 +24718,8 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
23546
24718
|
snapshot,
|
|
23547
24719
|
stepId,
|
|
23548
24720
|
result,
|
|
23549
|
-
requestContext
|
|
24721
|
+
requestContext,
|
|
24722
|
+
state
|
|
23550
24723
|
});
|
|
23551
24724
|
const now = /* @__PURE__ */ new Date();
|
|
23552
24725
|
const sanitizedSnapshot = toPgJson(snapshot);
|
|
@@ -25019,7 +26192,10 @@ var PostgresStore = class extends _mastra_core_storage.MastraCompositeStore {
|
|
|
25019
26192
|
workflows: new WorkflowsPG(domainConfig),
|
|
25020
26193
|
workflowDefinitions: new WorkflowDefinitionsPG(domainConfig),
|
|
25021
26194
|
memory: new MemoryPG(domainConfig),
|
|
25022
|
-
knowledge: new KnowledgePG(
|
|
26195
|
+
knowledge: new KnowledgePG({
|
|
26196
|
+
...domainConfig,
|
|
26197
|
+
storageIsolationKey: config.storageIsolationKey ?? getPgKnowledgeIsolationKey(config)
|
|
26198
|
+
}),
|
|
25023
26199
|
notifications: new NotificationsPG(domainConfig),
|
|
25024
26200
|
observability: new ObservabilityPG(domainConfig),
|
|
25025
26201
|
agents: new AgentsPG(domainConfig),
|
|
@@ -25073,7 +26249,7 @@ var PostgresStore = class extends _mastra_core_storage.MastraCompositeStore {
|
|
|
25073
26249
|
const pinned = new PinnedClientAdapter(this.#writePool, pinnedClient);
|
|
25074
26250
|
this.#db.pin(pinned);
|
|
25075
26251
|
this.#db.setSchemaSnapshot(await loadSchemaSnapshot(pinned, this.schema));
|
|
25076
|
-
await
|
|
26252
|
+
await Promise.all(Object.entries(this.stores).filter(([name, store]) => name !== "knowledge" && store).map(([, store]) => store.init()));
|
|
25077
26253
|
this.isInitialized = true;
|
|
25078
26254
|
} catch (error) {
|
|
25079
26255
|
this.#initPromise = null;
|