@mastra/code-sdk 1.3.0-alpha.12 → 1.3.0-alpha.13

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.
@@ -0,0 +1,501 @@
1
+ import { randomBytes } from "crypto";
2
+ import { createKnowledgeNodeCursor, isKnowledgeScopeVisible, parseKnowledgeWikilinks } from "@mastra/core/storage";
3
+ //#region src/knowledge-inspector.ts
4
+ var KnowledgeInspectorError = class extends Error {
5
+ code;
6
+ constructor(code, message) {
7
+ super(message);
8
+ this.code = code;
9
+ this.name = "KnowledgeInspectorError";
10
+ }
11
+ };
12
+ const HANDLE_TTL_MS = 5 * 6e4;
13
+ const MAX_OPAQUE_ENTRIES = 1e3;
14
+ const DEFAULT_RECORD_LIMIT = 50;
15
+ const MAX_RECORD_LIMIT = 50;
16
+ const DEFAULT_FACT_LIMIT = 25;
17
+ const MAX_FACT_LIMIT = 100;
18
+ const DEFAULT_ACTIVITY_LIMIT = 20;
19
+ const MAX_ACTIVITY_LIMIT = 100;
20
+ const MAX_RELATED_RECORDS = 25;
21
+ const MAX_RANK_CANDIDATES = 50;
22
+ const MAX_RANK_FACTS = 100;
23
+ const RRF_K = 60;
24
+ const MAX_NODE_CONTENT_BYTES = 32 * 1024;
25
+ function opaqueToken() {
26
+ return randomBytes(24).toString("base64url");
27
+ }
28
+ function boundedLimit(value, fallback, maximum) {
29
+ if (value === void 0) return fallback;
30
+ if (!Number.isInteger(value) || value < 1) return fallback;
31
+ return Math.min(value, maximum);
32
+ }
33
+ function scopeBadge(scope) {
34
+ const entry = scope.at(-1);
35
+ if (!entry) throw new KnowledgeInspectorError("unavailable", "Knowledge record has no scope.");
36
+ const separator = entry.indexOf(":");
37
+ return {
38
+ level: entry.slice(0, separator),
39
+ id: entry.slice(separator + 1)
40
+ };
41
+ }
42
+ function knowledgeSummary(record) {
43
+ return {
44
+ text: record.text,
45
+ scope: scopeBadge(record.scope),
46
+ sourceThreadId: record.sourceThreadId,
47
+ capturedAt: record.capturedAt.toISOString(),
48
+ when: record.when?.toISOString()
49
+ };
50
+ }
51
+ function truncateUtf8(value, maxBytes) {
52
+ const encoded = Buffer.from(value);
53
+ if (encoded.byteLength <= maxBytes) return {
54
+ value,
55
+ truncated: false
56
+ };
57
+ let end = maxBytes;
58
+ let truncated = encoded.subarray(0, end).toString("utf8");
59
+ while (Buffer.byteLength(truncated) > maxBytes) truncated = encoded.subarray(0, --end).toString("utf8");
60
+ return {
61
+ value: truncated,
62
+ truncated: true
63
+ };
64
+ }
65
+ var ScopedKnowledgeInspector = class {
66
+ #knowledge;
67
+ #session;
68
+ #handles = /* @__PURE__ */ new Map();
69
+ #cursors = /* @__PURE__ */ new Map();
70
+ #fingerprint;
71
+ #identityKey = opaqueToken();
72
+ constructor(input) {
73
+ this.#knowledge = input.knowledge;
74
+ this.#session = input.session;
75
+ this.#session.subscribe((event) => {
76
+ if (event.type === "thread_changed" || event.type === "thread_created" || event.type === "thread_deleted") this.#invalidateIdnode();
77
+ });
78
+ }
79
+ async getScopeTree() {
80
+ const binding = await this.#binding();
81
+ return {
82
+ identityKey: binding.identityKey,
83
+ defaultLevel: "resource",
84
+ roots: [
85
+ {
86
+ level: "org",
87
+ id: binding.ownerId,
88
+ available: true
89
+ },
90
+ {
91
+ level: "resource",
92
+ id: binding.resourceId,
93
+ available: true
94
+ },
95
+ binding.threadId ? {
96
+ level: "thread",
97
+ id: binding.threadId,
98
+ available: true
99
+ } : {
100
+ level: "thread",
101
+ available: false,
102
+ reason: "No active thread belongs to this project."
103
+ }
104
+ ]
105
+ };
106
+ }
107
+ async listNodes(input) {
108
+ const binding = await this.#binding();
109
+ const scope = this.#scope(binding, input.level);
110
+ const limit = boundedLimit(input.limit, DEFAULT_RECORD_LIMIT, MAX_RECORD_LIMIT);
111
+ const sort = input.sort ?? "relevant";
112
+ if (sort === "recent") {
113
+ const cursor = this.#consumeCursor(input.cursor, binding, input.level, "node", {
114
+ namePrefix: input.namePrefix,
115
+ kind: input.kind,
116
+ sort
117
+ });
118
+ const records = await this.#knowledge.listNodes({
119
+ scope,
120
+ namePrefix: input.namePrefix,
121
+ kind: input.kind,
122
+ cursor,
123
+ limit
124
+ });
125
+ const nodes = await Promise.all(records.map(async (record) => ({
126
+ ...this.#recordSummary(record, binding, input.level),
127
+ relationshipCounts: (await this.#sampledRelationshipCounts(record, scope)).counts
128
+ })));
129
+ await this.#assertStable(binding);
130
+ return {
131
+ identityKey: binding.identityKey,
132
+ scopeLevel: input.level,
133
+ nodes,
134
+ nextCursor: records.length === limit ? this.#mintCursor(binding, input.level, "node", createKnowledgeNodeCursor(records.at(-1), {
135
+ namePrefix: input.namePrefix,
136
+ kind: input.kind
137
+ }), {
138
+ namePrefix: input.namePrefix,
139
+ kind: input.kind,
140
+ sort
141
+ }) : void 0,
142
+ sort,
143
+ coverage: "exact"
144
+ };
145
+ }
146
+ const filters = {
147
+ namePrefix: input.namePrefix,
148
+ kind: input.kind,
149
+ sort
150
+ };
151
+ const encodedSnapshot = this.#consumeCursor(input.cursor, binding, input.level, "ranked-node", filters);
152
+ const snapshot = encodedSnapshot ? JSON.parse(encodedSnapshot) : await this.#rankedNodeSnapshot(scope, input.namePrefix, input.kind, sort);
153
+ const page = snapshot.entries.slice(snapshot.offset, snapshot.offset + limit);
154
+ const nodes = [];
155
+ for (const entry of page) {
156
+ const node = await this.#knowledge.getNode(entry.id);
157
+ if (!node || !isKnowledgeScopeVisible(node.scope, scope)) continue;
158
+ nodes.push({
159
+ ...this.#recordSummary(node, binding, input.level),
160
+ relationshipCounts: entry.counts
161
+ });
162
+ }
163
+ const nextOffset = snapshot.offset + limit;
164
+ await this.#assertStable(binding);
165
+ return {
166
+ identityKey: binding.identityKey,
167
+ scopeLevel: input.level,
168
+ nodes,
169
+ nextCursor: nextOffset < snapshot.entries.length ? this.#mintCursor(binding, input.level, "ranked-node", JSON.stringify({
170
+ ...snapshot,
171
+ offset: nextOffset
172
+ }), filters) : void 0,
173
+ sort,
174
+ coverage: "recent-window"
175
+ };
176
+ }
177
+ async getNode(input) {
178
+ const binding = await this.#binding();
179
+ const handle = this.#readHandle(input.handle, binding, "node");
180
+ const scope = this.#scope(binding, handle.level);
181
+ const node = await this.#knowledge.getNode(handle.recordId);
182
+ this.#assertVisible(node, scope);
183
+ const limit = boundedLimit(input.recordLimit, DEFAULT_FACT_LIMIT, MAX_FACT_LIMIT);
184
+ const recordsAfter = this.#consumeCursor(input.recordsCursor, binding, handle.level, "records");
185
+ const mentioningAfter = this.#consumeCursor(input.mentioningRecordsCursor, binding, handle.level, "mentioning-records");
186
+ const [recordsResult, mentioningResult] = await Promise.all([this.#knowledge.listKnowledgeAbout({
187
+ node: node.id,
188
+ scope,
189
+ after: recordsAfter,
190
+ limit
191
+ }), this.#knowledge.listKnowledgeMentioning({
192
+ node: node.id,
193
+ scope,
194
+ after: mentioningAfter,
195
+ limit
196
+ })]);
197
+ const mentioningRecords = mentioningResult.records.filter((record) => record.node !== node.id);
198
+ const content = truncateUtf8(node.content ?? "", MAX_NODE_CONTENT_BYTES);
199
+ const [outgoingTargets, incomingParents, relationship] = await Promise.all([
200
+ this.#outgoingTargets(node, recordsResult.records, scope, binding, handle.level),
201
+ this.#incomingParents(node, mentioningRecords, scope, binding, handle.level),
202
+ this.#sampledRelationshipCounts(node, scope)
203
+ ]);
204
+ const links = await Promise.all(parseKnowledgeWikilinks(content.value).slice(0, MAX_RELATED_RECORDS).map(async (label) => {
205
+ const target = await this.#knowledge.resolveNode({
206
+ name: label,
207
+ scope
208
+ });
209
+ return {
210
+ label,
211
+ node: target ? this.#recordSummary(target, binding, handle.level) : void 0
212
+ };
213
+ }));
214
+ await this.#assertStable(binding);
215
+ return {
216
+ identityKey: binding.identityKey,
217
+ scopeLevel: handle.level,
218
+ node: {
219
+ ...this.#recordSummary(node, binding, handle.level),
220
+ relationshipCounts: relationship.counts
221
+ },
222
+ records: recordsResult.records.map(knowledgeSummary),
223
+ recordsNextCursor: recordsResult.nextCursor ? this.#mintCursor(binding, handle.level, "records", recordsResult.nextCursor) : void 0,
224
+ mentioningRecords: mentioningRecords.map(knowledgeSummary),
225
+ mentioningRecordsNextCursor: mentioningResult.nextCursor ? this.#mintCursor(binding, handle.level, "mentioning-records", mentioningResult.nextCursor) : void 0,
226
+ outgoingTargets: {
227
+ nodes: outgoingTargets.nodes,
228
+ partial: outgoingTargets.partial || Boolean(recordsResult.nextCursor)
229
+ },
230
+ incomingParents: {
231
+ nodes: incomingParents.nodes,
232
+ partial: incomingParents.partial || Boolean(mentioningResult.nextCursor)
233
+ },
234
+ relationshipCounts: relationship.counts,
235
+ content: node.content === void 0 ? void 0 : content.value,
236
+ contentTruncated: content.truncated,
237
+ links
238
+ };
239
+ }
240
+ async listActivity(input) {
241
+ const binding = await this.#binding();
242
+ const scope = this.#scope(binding, input.level);
243
+ const limit = boundedLimit(input.limit, DEFAULT_ACTIVITY_LIMIT, MAX_ACTIVITY_LIMIT);
244
+ const after = this.#consumeCursor(input.cursor, binding, input.level, "activity");
245
+ const events = await this.#knowledge.listActivity({
246
+ scope,
247
+ after,
248
+ limit
249
+ });
250
+ const activityEvents = [];
251
+ for (const event of events) {
252
+ const record = await this.#activityRecord(event, scope, binding, input.level);
253
+ activityEvents.push({
254
+ action: event.action,
255
+ recordType: event.recordType,
256
+ scope: scopeBadge(event.scope),
257
+ sourceThreadId: record ? event.sourceThreadId : void 0,
258
+ createdAt: event.createdAt.toISOString(),
259
+ record
260
+ });
261
+ }
262
+ await this.#assertStable(binding);
263
+ return {
264
+ identityKey: binding.identityKey,
265
+ scopeLevel: input.level,
266
+ events: activityEvents,
267
+ nextCursor: events.length === limit ? this.#mintCursor(binding, input.level, "activity", events.at(-1).id) : void 0
268
+ };
269
+ }
270
+ async #binding() {
271
+ const ownerId = this.#session.identity.getOwnerId();
272
+ const resourceId = this.#session.identity.getResourceId();
273
+ if (!ownerId || !resourceId) throw new KnowledgeInspectorError("unavailable", "Knowledge inspection requires an active owner and project.");
274
+ const activeThreadId = this.#session.thread.getId() ?? void 0;
275
+ const thread = activeThreadId ? await this.#session.thread.getById({ threadId: activeThreadId }) : null;
276
+ const threadId = thread?.resourceId === resourceId ? thread.id : void 0;
277
+ const fingerprint = `${ownerId}\0${resourceId}\0${threadId ?? ""}`;
278
+ if (this.#fingerprint !== fingerprint) {
279
+ this.#fingerprint = fingerprint;
280
+ this.#identityKey = opaqueToken();
281
+ this.#handles.clear();
282
+ this.#cursors.clear();
283
+ }
284
+ return {
285
+ ownerId,
286
+ resourceId,
287
+ threadId,
288
+ fingerprint,
289
+ identityKey: this.#identityKey
290
+ };
291
+ }
292
+ #scope(binding, level) {
293
+ if (level === "org") return [`org:${binding.ownerId}`];
294
+ const scope = [`org:${binding.ownerId}`, `resource:${binding.resourceId}`];
295
+ if (level === "resource") return scope;
296
+ if (!binding.threadId) throw new KnowledgeInspectorError("unavailable", "The active thread does not belong to this project.");
297
+ return [...scope, `thread:${binding.threadId}`];
298
+ }
299
+ async #assertStable(binding) {
300
+ const current = await this.#binding();
301
+ if (current.identityKey !== binding.identityKey || current.fingerprint !== binding.fingerprint) throw new KnowledgeInspectorError("stale-handle", "Knowledge scope changed while the request was running.");
302
+ }
303
+ #assertVisible(record, scope) {
304
+ if (!record || !isKnowledgeScopeVisible(record.scope, scope)) throw new KnowledgeInspectorError("not-visible", "Knowledge record is not visible in the selected scope.");
305
+ }
306
+ #recordSummary(record, binding, level) {
307
+ const type = "node";
308
+ return {
309
+ handle: this.#mintHandle(binding, level, type, record.id),
310
+ type,
311
+ name: record.name,
312
+ kind: record.kind,
313
+ scope: scopeBadge(record.scope),
314
+ version: record.version,
315
+ updatedAt: record.updatedAt.toISOString()
316
+ };
317
+ }
318
+ async #rankedNodeSnapshot(scope, namePrefix, kind, sort) {
319
+ const records = await this.#knowledge.listNodes({
320
+ scope,
321
+ namePrefix,
322
+ kind,
323
+ limit: MAX_RANK_CANDIDATES
324
+ });
325
+ const ranked = await Promise.all(records.map(async (node, recencyRank) => ({
326
+ node,
327
+ recencyRank,
328
+ ...await this.#sampledRelationshipCounts(node, scope)
329
+ })));
330
+ const connected = [...ranked].sort((a, b) => b.degree - a.degree || a.recencyRank - b.recencyRank || a.node.id.localeCompare(b.node.id));
331
+ const connectedRank = new Map(connected.map((entry, index) => [entry.node.id, index]));
332
+ return {
333
+ offset: 0,
334
+ entries: (sort === "connected" ? connected : [...ranked].sort((a, b) => {
335
+ const aScore = 1 / (RRF_K + a.recencyRank + 1) + 1 / (RRF_K + connectedRank.get(a.node.id) + 1);
336
+ return 1 / (RRF_K + b.recencyRank + 1) + 1 / (RRF_K + connectedRank.get(b.node.id) + 1) - aScore || a.recencyRank - b.recencyRank || a.node.id.localeCompare(b.node.id);
337
+ })).map((entry) => ({
338
+ id: entry.node.id,
339
+ degree: entry.degree,
340
+ counts: entry.counts
341
+ }))
342
+ };
343
+ }
344
+ async #sampledRelationshipCounts(node, scope) {
345
+ const [aboutResult, mentioningResult] = await Promise.all([this.#knowledge.listKnowledgeAbout({
346
+ node: node.id,
347
+ scope,
348
+ limit: MAX_RANK_FACTS
349
+ }), this.#knowledge.listKnowledgeMentioning({
350
+ node: node.id,
351
+ scope,
352
+ limit: MAX_RANK_FACTS
353
+ })]);
354
+ const [outgoing, incoming] = await Promise.all([this.#outgoingNodeRecords(node, aboutResult.records, scope), this.#incomingParentRecords(node, mentioningResult.records, scope)]);
355
+ const mentioningRecords = mentioningResult.records.filter((record) => record.node !== node.id);
356
+ return {
357
+ degree: new Set([...outgoing.nodes, ...incoming.nodes].map((record) => record.id)).size,
358
+ counts: {
359
+ records: aboutResult.records.length + mentioningRecords.length,
360
+ outgoing: outgoing.nodes.length,
361
+ incoming: incoming.nodes.length,
362
+ sampled: Boolean(aboutResult.nextCursor || mentioningResult.nextCursor || outgoing.truncated || incoming.truncated)
363
+ }
364
+ };
365
+ }
366
+ async #outgoingNodeRecords(current, records, scope) {
367
+ const related = /* @__PURE__ */ new Map();
368
+ let truncated = false;
369
+ const sources = [current.content ?? "", ...records.map((record) => record.text)];
370
+ for (const source of sources) {
371
+ for (const name of parseKnowledgeWikilinks(source)) {
372
+ if (related.size >= MAX_RELATED_RECORDS) {
373
+ truncated = true;
374
+ break;
375
+ }
376
+ const node = await this.#knowledge.resolveNode({
377
+ name,
378
+ scope
379
+ });
380
+ if (node && node.id !== current.id && isKnowledgeScopeVisible(node.scope, scope)) related.set(node.id, node);
381
+ }
382
+ if (truncated) break;
383
+ }
384
+ return {
385
+ nodes: [...related.values()],
386
+ truncated
387
+ };
388
+ }
389
+ async #incomingParentRecords(current, records, scope) {
390
+ const related = /* @__PURE__ */ new Map();
391
+ let truncated = false;
392
+ for (const record of records) {
393
+ if (record.node === current.id || related.has(record.node)) continue;
394
+ if (related.size >= MAX_RELATED_RECORDS) {
395
+ truncated = true;
396
+ break;
397
+ }
398
+ const node = await this.#knowledge.getNode(record.node);
399
+ if (node && isKnowledgeScopeVisible(node.scope, scope)) related.set(node.id, node);
400
+ }
401
+ return {
402
+ nodes: [...related.values()],
403
+ truncated
404
+ };
405
+ }
406
+ async #outgoingTargets(current, records, scope, binding, level) {
407
+ const related = await this.#outgoingNodeRecords(current, records, scope);
408
+ return {
409
+ nodes: related.nodes.map((node) => this.#recordSummary(node, binding, level)),
410
+ partial: related.truncated
411
+ };
412
+ }
413
+ async #incomingParents(current, records, scope, binding, level) {
414
+ const related = await this.#incomingParentRecords(current, records, scope);
415
+ return {
416
+ nodes: related.nodes.map((node) => this.#recordSummary(node, binding, level)),
417
+ partial: related.truncated
418
+ };
419
+ }
420
+ async #activityRecord(event, scope, binding, level) {
421
+ if (event.recordType === "node") {
422
+ const node = await this.#knowledge.getNode(event.recordId);
423
+ return node && isKnowledgeScopeVisible(node.scope, scope) ? this.#recordSummary(node, binding, level) : void 0;
424
+ }
425
+ const record = await this.#knowledge.getKnowledge({
426
+ id: event.recordId,
427
+ includeDeleted: true
428
+ });
429
+ if (!record || !isKnowledgeScopeVisible(record.scope, scope)) return void 0;
430
+ const node = await this.#knowledge.getNode(record.node);
431
+ return node && isKnowledgeScopeVisible(node.scope, scope) ? this.#recordSummary(node, binding, level) : void 0;
432
+ }
433
+ #mintHandle(binding, level, type, recordId) {
434
+ this.#pruneOpaqueEntries();
435
+ const token = opaqueToken();
436
+ this.#handles.set(token, {
437
+ identityKey: binding.identityKey,
438
+ level,
439
+ type,
440
+ recordId,
441
+ expiresAt: Date.now() + HANDLE_TTL_MS
442
+ });
443
+ return token;
444
+ }
445
+ #readHandle(handle, binding, expectedType) {
446
+ const entry = this.#handles.get(handle);
447
+ if (!entry || entry.expiresAt < Date.now() || entry.type !== expectedType) throw new KnowledgeInspectorError("invalid-handle", "Knowledge record handle is invalid or expired.");
448
+ if (entry.identityKey !== binding.identityKey) throw new KnowledgeInspectorError("stale-handle", "Knowledge record handle belongs to a previous scope.");
449
+ return entry;
450
+ }
451
+ #mintCursor(binding, level, kind, value, filters) {
452
+ this.#pruneOpaqueEntries();
453
+ const token = opaqueToken();
454
+ this.#cursors.set(token, {
455
+ identityKey: binding.identityKey,
456
+ level,
457
+ kind,
458
+ value,
459
+ filters,
460
+ expiresAt: Date.now() + HANDLE_TTL_MS
461
+ });
462
+ return token;
463
+ }
464
+ #consumeCursor(cursor, binding, level, kind, filters) {
465
+ if (!cursor) return void 0;
466
+ const entry = this.#cursors.get(cursor);
467
+ if (!entry || entry.expiresAt < Date.now() || entry.identityKey !== binding.identityKey || entry.level !== level || entry.kind !== kind || entry.filters?.namePrefix !== filters?.namePrefix || entry.filters?.kind !== filters?.kind || entry.filters?.sort !== filters?.sort) throw new KnowledgeInspectorError("invalid-cursor", "Knowledge cursor does not match the active scope and filters.");
468
+ return entry.value;
469
+ }
470
+ #pruneOpaqueEntries() {
471
+ const now = Date.now();
472
+ for (const [token, entry] of this.#handles) if (entry.expiresAt < now) this.#handles.delete(token);
473
+ for (const [token, entry] of this.#cursors) if (entry.expiresAt < now) this.#cursors.delete(token);
474
+ while (this.#handles.size + this.#cursors.size >= MAX_OPAQUE_ENTRIES) {
475
+ const handle = this.#handles.keys().next().value;
476
+ if (handle) this.#handles.delete(handle);
477
+ else {
478
+ const cursor = this.#cursors.keys().next().value;
479
+ if (cursor) this.#cursors.delete(cursor);
480
+ else break;
481
+ }
482
+ }
483
+ }
484
+ #invalidateIdnode() {
485
+ this.#fingerprint = void 0;
486
+ this.#identityKey = opaqueToken();
487
+ this.#handles.clear();
488
+ this.#cursors.clear();
489
+ }
490
+ };
491
+ async function createKnowledgeInspector(input) {
492
+ const knowledge = await input.storage.getStore("knowledge");
493
+ return knowledge ? new ScopedKnowledgeInspector({
494
+ knowledge,
495
+ session: input.session
496
+ }) : void 0;
497
+ }
498
+ //#endregion
499
+ export { KnowledgeInspectorError, createKnowledgeInspector };
500
+
501
+ //# sourceMappingURL=knowledge-inspector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-inspector.js","names":["#knowledge","#session","#handles","#cursors","#invalidateIdnode","#binding","#scope","#consumeCursor","#recordSummary","#sampledRelationshipCounts","#assertStable","#mintCursor","#rankedNodeSnapshot","#readHandle","#assertVisible","#outgoingTargets","#incomingParents","#activityRecord","#fingerprint","#identityKey","#mintHandle","#outgoingNodeRecords","#incomingParentRecords","#pruneOpaqueEntries"],"sources":["../src/knowledge-inspector.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\n\nimport type { Session } from '@mastra/core/agent-controller';\nimport { createKnowledgeNodeCursor, isKnowledgeScopeVisible, parseKnowledgeWikilinks } from '@mastra/core/storage';\nimport type {\n KnowledgeActivityEvent,\n KnowledgeRecord,\n KnowledgeNode,\n KnowledgeScope,\n KnowledgeStorage,\n MastraCompositeStore,\n} from '@mastra/core/storage';\n\nimport type { MastraCodeState } from './schema.js';\n\nexport type KnowledgeInspectorScopeLevel = 'org' | 'resource' | 'thread';\nexport type KnowledgeInspectorRecordType = 'node';\nexport type KnowledgeInspectorNodeSort = 'relevant' | 'recent' | 'connected';\n\nexport interface KnowledgeInspectorScopeRoot {\n level: KnowledgeInspectorScopeLevel;\n id?: string;\n available: boolean;\n reason?: string;\n}\n\nexport interface KnowledgeInspectorScopeTree {\n identityKey: string;\n defaultLevel: 'resource';\n roots: KnowledgeInspectorScopeRoot[];\n}\n\nexport interface KnowledgeInspectorScopeBadge {\n level: KnowledgeInspectorScopeLevel;\n id: string;\n}\n\nexport interface KnowledgeInspectorRelationshipCounts {\n records: number;\n outgoing: number;\n incoming: number;\n sampled: boolean;\n}\n\nexport interface KnowledgeInspectorNodeSummary {\n handle: string;\n type: KnowledgeInspectorRecordType;\n name: string;\n kind?: string;\n scope: KnowledgeInspectorScopeBadge;\n version: number;\n updatedAt: string;\n relationshipCounts?: KnowledgeInspectorRelationshipCounts;\n}\n\nexport interface KnowledgeInspectorRecordSummary {\n text: string;\n scope: KnowledgeInspectorScopeBadge;\n sourceThreadId: string;\n capturedAt: string;\n when?: string;\n}\n\nexport interface KnowledgeInspectorNodeList {\n identityKey: string;\n scopeLevel: KnowledgeInspectorScopeLevel;\n nodes: KnowledgeInspectorNodeSummary[];\n nextCursor?: string;\n sort?: KnowledgeInspectorNodeSort;\n coverage?: 'exact' | 'recent-window';\n}\n\nexport interface KnowledgeInspectorRelationshipPreview {\n nodes: KnowledgeInspectorNodeSummary[];\n partial: boolean;\n}\n\nexport interface KnowledgeInspectorNodeDetail {\n identityKey: string;\n scopeLevel: KnowledgeInspectorScopeLevel;\n node: KnowledgeInspectorNodeSummary;\n records: KnowledgeInspectorRecordSummary[];\n recordsNextCursor?: string;\n mentioningRecords: KnowledgeInspectorRecordSummary[];\n mentioningRecordsNextCursor?: string;\n outgoingTargets: KnowledgeInspectorRelationshipPreview;\n incomingParents: KnowledgeInspectorRelationshipPreview;\n relationshipCounts: KnowledgeInspectorRelationshipCounts;\n content?: string;\n contentTruncated: boolean;\n links: Array<{ label: string; node?: KnowledgeInspectorNodeSummary }>;\n}\n\nexport interface KnowledgeInspectorActivityEvent {\n action: KnowledgeActivityEvent['action'];\n recordType: KnowledgeActivityEvent['recordType'];\n scope: KnowledgeInspectorScopeBadge;\n sourceThreadId?: string;\n createdAt: string;\n record?: KnowledgeInspectorNodeSummary;\n}\n\nexport interface KnowledgeInspectorActivityList {\n identityKey: string;\n scopeLevel: KnowledgeInspectorScopeLevel;\n events: KnowledgeInspectorActivityEvent[];\n nextCursor?: string;\n}\n\nexport interface KnowledgeInspector {\n getScopeTree(): Promise<KnowledgeInspectorScopeTree>;\n listNodes(input: {\n level: KnowledgeInspectorScopeLevel;\n namePrefix?: string;\n kind?: string;\n sort?: KnowledgeInspectorNodeSort;\n cursor?: string;\n limit?: number;\n }): Promise<KnowledgeInspectorNodeList>;\n getNode(input: {\n handle: string;\n recordsCursor?: string;\n mentioningRecordsCursor?: string;\n recordLimit?: number;\n }): Promise<KnowledgeInspectorNodeDetail>;\n listActivity(input: {\n level: KnowledgeInspectorScopeLevel;\n cursor?: string;\n limit?: number;\n }): Promise<KnowledgeInspectorActivityList>;\n}\n\nexport class KnowledgeInspectorError extends Error {\n constructor(\n readonly code: 'unavailable' | 'invalid-handle' | 'stale-handle' | 'invalid-cursor' | 'not-visible',\n message: string,\n ) {\n super(message);\n this.name = 'KnowledgeInspectorError';\n }\n}\n\ninterface Binding {\n ownerId: string;\n resourceId: string;\n threadId?: string;\n fingerprint: string;\n identityKey: string;\n}\n\ninterface HandleEntry {\n identityKey: string;\n level: KnowledgeInspectorScopeLevel;\n type: KnowledgeInspectorRecordType;\n recordId: string;\n expiresAt: number;\n}\n\ninterface CursorEntry {\n identityKey: string;\n level: KnowledgeInspectorScopeLevel;\n kind: 'node' | 'ranked-node' | 'records' | 'mentioning-records' | 'activity';\n value: string;\n filters?: { namePrefix?: string; kind?: string; sort?: KnowledgeInspectorNodeSort };\n expiresAt: number;\n}\n\ninterface RankedNodeSnapshot {\n offset: number;\n entries: { id: string; degree: number; counts: KnowledgeInspectorRelationshipCounts }[];\n}\n\ninterface RelationshipRecords {\n nodes: KnowledgeNode[];\n truncated: boolean;\n}\n\nconst HANDLE_TTL_MS = 5 * 60_000;\nconst MAX_OPAQUE_ENTRIES = 1_000;\nconst DEFAULT_RECORD_LIMIT = 50;\nconst MAX_RECORD_LIMIT = 50;\nconst DEFAULT_FACT_LIMIT = 25;\nconst MAX_FACT_LIMIT = 100;\nconst DEFAULT_ACTIVITY_LIMIT = 20;\nconst MAX_ACTIVITY_LIMIT = 100;\nconst MAX_RELATED_RECORDS = 25;\nconst MAX_RANK_CANDIDATES = 50;\nconst MAX_RANK_FACTS = 100;\nconst RRF_K = 60;\nconst MAX_NODE_CONTENT_BYTES = 32 * 1024;\n\nfunction opaqueToken(): string {\n return randomBytes(24).toString('base64url');\n}\n\nfunction boundedLimit(value: number | undefined, fallback: number, maximum: number): number {\n if (value === undefined) return fallback;\n if (!Number.isInteger(value) || value < 1) return fallback;\n return Math.min(value, maximum);\n}\n\nfunction scopeBadge(scope: KnowledgeScope): KnowledgeInspectorScopeBadge {\n const entry = scope.at(-1);\n if (!entry) throw new KnowledgeInspectorError('unavailable', 'Knowledge record has no scope.');\n const separator = entry.indexOf(':');\n return {\n level: entry.slice(0, separator) as KnowledgeInspectorScopeLevel,\n id: entry.slice(separator + 1),\n };\n}\n\nfunction knowledgeSummary(record: KnowledgeRecord): KnowledgeInspectorRecordSummary {\n return {\n text: record.text,\n scope: scopeBadge(record.scope),\n sourceThreadId: record.sourceThreadId,\n capturedAt: record.capturedAt.toISOString(),\n when: record.when?.toISOString(),\n };\n}\n\nfunction truncateUtf8(value: string, maxBytes: number): { value: string; truncated: boolean } {\n const encoded = Buffer.from(value);\n if (encoded.byteLength <= maxBytes) return { value, truncated: false };\n let end = maxBytes;\n let truncated = encoded.subarray(0, end).toString('utf8');\n while (Buffer.byteLength(truncated) > maxBytes) {\n truncated = encoded.subarray(0, --end).toString('utf8');\n }\n return { value: truncated, truncated: true };\n}\n\nclass ScopedKnowledgeInspector implements KnowledgeInspector {\n readonly #knowledge: KnowledgeStorage;\n readonly #session: Session<MastraCodeState>;\n readonly #handles = new Map<string, HandleEntry>();\n readonly #cursors = new Map<string, CursorEntry>();\n #fingerprint?: string;\n #identityKey = opaqueToken();\n\n constructor(input: { knowledge: KnowledgeStorage; session: Session<MastraCodeState> }) {\n this.#knowledge = input.knowledge;\n this.#session = input.session;\n this.#session.subscribe(event => {\n if (event.type === 'thread_changed' || event.type === 'thread_created' || event.type === 'thread_deleted') {\n this.#invalidateIdnode();\n }\n });\n }\n\n async getScopeTree(): Promise<KnowledgeInspectorScopeTree> {\n const binding = await this.#binding();\n return {\n identityKey: binding.identityKey,\n defaultLevel: 'resource',\n roots: [\n { level: 'org', id: binding.ownerId, available: true },\n { level: 'resource', id: binding.resourceId, available: true },\n binding.threadId\n ? { level: 'thread', id: binding.threadId, available: true }\n : { level: 'thread', available: false, reason: 'No active thread belongs to this project.' },\n ],\n };\n }\n\n async listNodes(input: {\n level: KnowledgeInspectorScopeLevel;\n namePrefix?: string;\n kind?: string;\n sort?: KnowledgeInspectorNodeSort;\n cursor?: string;\n limit?: number;\n }): Promise<KnowledgeInspectorNodeList> {\n const binding = await this.#binding();\n const scope = this.#scope(binding, input.level);\n const limit = boundedLimit(input.limit, DEFAULT_RECORD_LIMIT, MAX_RECORD_LIMIT);\n const sort = input.sort ?? 'relevant';\n if (sort === 'recent') {\n const cursor = this.#consumeCursor(input.cursor, binding, input.level, 'node', {\n namePrefix: input.namePrefix,\n kind: input.kind,\n sort,\n });\n const records = await this.#knowledge.listNodes({\n scope,\n namePrefix: input.namePrefix,\n kind: input.kind,\n cursor,\n limit,\n });\n const nodes: KnowledgeInspectorNodeSummary[] = await Promise.all(\n records.map(async record => ({\n ...this.#recordSummary(record, binding, input.level),\n relationshipCounts: (await this.#sampledRelationshipCounts(record, scope)).counts,\n })),\n );\n await this.#assertStable(binding);\n return {\n identityKey: binding.identityKey,\n scopeLevel: input.level,\n nodes,\n nextCursor:\n records.length === limit\n ? this.#mintCursor(\n binding,\n input.level,\n 'node',\n createKnowledgeNodeCursor(records.at(-1)!, {\n namePrefix: input.namePrefix,\n kind: input.kind,\n }),\n {\n namePrefix: input.namePrefix,\n kind: input.kind,\n sort,\n },\n )\n : undefined,\n sort,\n coverage: 'exact',\n };\n }\n\n const filters = { namePrefix: input.namePrefix, kind: input.kind, sort };\n const encodedSnapshot = this.#consumeCursor(input.cursor, binding, input.level, 'ranked-node', filters);\n const snapshot = encodedSnapshot\n ? (JSON.parse(encodedSnapshot) as RankedNodeSnapshot)\n : await this.#rankedNodeSnapshot(scope, input.namePrefix, input.kind, sort);\n const page = snapshot.entries.slice(snapshot.offset, snapshot.offset + limit);\n const nodes: KnowledgeInspectorNodeSummary[] = [];\n for (const entry of page) {\n const node = await this.#knowledge.getNode(entry.id);\n if (!node || !isKnowledgeScopeVisible(node.scope, scope)) continue;\n nodes.push({ ...this.#recordSummary(node, binding, input.level), relationshipCounts: entry.counts });\n }\n const nextOffset = snapshot.offset + limit;\n await this.#assertStable(binding);\n return {\n identityKey: binding.identityKey,\n scopeLevel: input.level,\n nodes,\n nextCursor:\n nextOffset < snapshot.entries.length\n ? this.#mintCursor(\n binding,\n input.level,\n 'ranked-node',\n JSON.stringify({ ...snapshot, offset: nextOffset } satisfies RankedNodeSnapshot),\n filters,\n )\n : undefined,\n sort,\n coverage: 'recent-window',\n };\n }\n\n async getNode(input: {\n handle: string;\n recordsCursor?: string;\n mentioningRecordsCursor?: string;\n recordLimit?: number;\n }): Promise<KnowledgeInspectorNodeDetail> {\n const binding = await this.#binding();\n const handle = this.#readHandle(input.handle, binding, 'node');\n const scope = this.#scope(binding, handle.level);\n const node = await this.#knowledge.getNode(handle.recordId);\n this.#assertVisible(node, scope);\n const limit = boundedLimit(input.recordLimit, DEFAULT_FACT_LIMIT, MAX_FACT_LIMIT);\n const recordsAfter = this.#consumeCursor(input.recordsCursor, binding, handle.level, 'records');\n const mentioningAfter = this.#consumeCursor(\n input.mentioningRecordsCursor,\n binding,\n handle.level,\n 'mentioning-records',\n );\n const [recordsResult, mentioningResult] = await Promise.all([\n this.#knowledge.listKnowledgeAbout({ node: node.id, scope, after: recordsAfter, limit }),\n this.#knowledge.listKnowledgeMentioning({ node: node.id, scope, after: mentioningAfter, limit }),\n ]);\n const mentioningRecords = mentioningResult.records.filter(record => record.node !== node.id);\n const content = truncateUtf8(node.content ?? '', MAX_NODE_CONTENT_BYTES);\n const [outgoingTargets, incomingParents, relationship] = await Promise.all([\n this.#outgoingTargets(node, recordsResult.records, scope, binding, handle.level),\n this.#incomingParents(node, mentioningRecords, scope, binding, handle.level),\n this.#sampledRelationshipCounts(node, scope),\n ]);\n const links = await Promise.all(\n parseKnowledgeWikilinks(content.value)\n .slice(0, MAX_RELATED_RECORDS)\n .map(async label => {\n const target = await this.#knowledge.resolveNode({ name: label, scope });\n return {\n label,\n node: target ? this.#recordSummary(target, binding, handle.level) : undefined,\n };\n }),\n );\n await this.#assertStable(binding);\n return {\n identityKey: binding.identityKey,\n scopeLevel: handle.level,\n node: { ...this.#recordSummary(node, binding, handle.level), relationshipCounts: relationship.counts },\n records: recordsResult.records.map(knowledgeSummary),\n recordsNextCursor: recordsResult.nextCursor\n ? this.#mintCursor(binding, handle.level, 'records', recordsResult.nextCursor)\n : undefined,\n mentioningRecords: mentioningRecords.map(knowledgeSummary),\n mentioningRecordsNextCursor: mentioningResult.nextCursor\n ? this.#mintCursor(binding, handle.level, 'mentioning-records', mentioningResult.nextCursor)\n : undefined,\n outgoingTargets: {\n nodes: outgoingTargets.nodes,\n partial: outgoingTargets.partial || Boolean(recordsResult.nextCursor),\n },\n incomingParents: {\n nodes: incomingParents.nodes,\n partial: incomingParents.partial || Boolean(mentioningResult.nextCursor),\n },\n relationshipCounts: relationship.counts,\n content: node.content === undefined ? undefined : content.value,\n contentTruncated: content.truncated,\n links,\n };\n }\n\n async listActivity(input: {\n level: KnowledgeInspectorScopeLevel;\n cursor?: string;\n limit?: number;\n }): Promise<KnowledgeInspectorActivityList> {\n const binding = await this.#binding();\n const scope = this.#scope(binding, input.level);\n const limit = boundedLimit(input.limit, DEFAULT_ACTIVITY_LIMIT, MAX_ACTIVITY_LIMIT);\n const after = this.#consumeCursor(input.cursor, binding, input.level, 'activity');\n const events = await this.#knowledge.listActivity({ scope, after, limit });\n const activityEvents: KnowledgeInspectorActivityEvent[] = [];\n for (const event of events) {\n const record = await this.#activityRecord(event, scope, binding, input.level);\n activityEvents.push({\n action: event.action,\n recordType: event.recordType,\n scope: scopeBadge(event.scope),\n sourceThreadId: record ? event.sourceThreadId : undefined,\n createdAt: event.createdAt.toISOString(),\n record,\n });\n }\n await this.#assertStable(binding);\n return {\n identityKey: binding.identityKey,\n scopeLevel: input.level,\n events: activityEvents,\n nextCursor:\n events.length === limit ? this.#mintCursor(binding, input.level, 'activity', events.at(-1)!.id) : undefined,\n };\n }\n\n async #binding(): Promise<Binding> {\n const ownerId = this.#session.identity.getOwnerId();\n const resourceId = this.#session.identity.getResourceId();\n if (!ownerId || !resourceId) {\n throw new KnowledgeInspectorError('unavailable', 'Knowledge inspection requires an active owner and project.');\n }\n const activeThreadId = this.#session.thread.getId() ?? undefined;\n const thread = activeThreadId ? await this.#session.thread.getById({ threadId: activeThreadId }) : null;\n const threadId = thread?.resourceId === resourceId ? thread.id : undefined;\n const fingerprint = `${ownerId}\\0${resourceId}\\0${threadId ?? ''}`;\n if (this.#fingerprint !== fingerprint) {\n this.#fingerprint = fingerprint;\n this.#identityKey = opaqueToken();\n this.#handles.clear();\n this.#cursors.clear();\n }\n return { ownerId, resourceId, threadId, fingerprint, identityKey: this.#identityKey };\n }\n\n #scope(binding: Binding, level: KnowledgeInspectorScopeLevel): KnowledgeScope {\n if (level === 'org') return [`org:${binding.ownerId}`];\n const scope = [`org:${binding.ownerId}`, `resource:${binding.resourceId}`];\n if (level === 'resource') return scope;\n if (!binding.threadId) {\n throw new KnowledgeInspectorError('unavailable', 'The active thread does not belong to this project.');\n }\n return [...scope, `thread:${binding.threadId}`];\n }\n\n async #assertStable(binding: Binding): Promise<void> {\n const current = await this.#binding();\n if (current.identityKey !== binding.identityKey || current.fingerprint !== binding.fingerprint) {\n throw new KnowledgeInspectorError('stale-handle', 'Knowledge scope changed while the request was running.');\n }\n }\n\n #assertVisible<T extends KnowledgeNode>(record: T | null, scope: KnowledgeScope): asserts record is T {\n if (!record || !isKnowledgeScopeVisible(record.scope, scope)) {\n throw new KnowledgeInspectorError('not-visible', 'Knowledge record is not visible in the selected scope.');\n }\n }\n\n #recordSummary(\n record: KnowledgeNode,\n binding: Binding,\n level: KnowledgeInspectorScopeLevel,\n ): KnowledgeInspectorNodeSummary {\n const type: KnowledgeInspectorRecordType = 'node';\n return {\n handle: this.#mintHandle(binding, level, type, record.id),\n type,\n name: record.name,\n kind: record.kind,\n scope: scopeBadge(record.scope),\n version: record.version,\n updatedAt: record.updatedAt.toISOString(),\n };\n }\n\n async #rankedNodeSnapshot(\n scope: KnowledgeScope,\n namePrefix: string | undefined,\n kind: string | undefined,\n sort: Exclude<KnowledgeInspectorNodeSort, 'recent'>,\n ): Promise<RankedNodeSnapshot> {\n const records = await this.#knowledge.listNodes({\n scope,\n namePrefix,\n kind,\n limit: MAX_RANK_CANDIDATES,\n });\n const ranked = await Promise.all(\n records.map(async (node, recencyRank) => ({\n node,\n recencyRank,\n ...(await this.#sampledRelationshipCounts(node, scope)),\n })),\n );\n const connected = [...ranked].sort(\n (a, b) => b.degree - a.degree || a.recencyRank - b.recencyRank || a.node.id.localeCompare(b.node.id),\n );\n const connectedRank = new Map(connected.map((entry, index) => [entry.node.id, index]));\n const ordered =\n sort === 'connected'\n ? connected\n : [...ranked].sort((a, b) => {\n const aScore = 1 / (RRF_K + a.recencyRank + 1) + 1 / (RRF_K + connectedRank.get(a.node.id)! + 1);\n const bScore = 1 / (RRF_K + b.recencyRank + 1) + 1 / (RRF_K + connectedRank.get(b.node.id)! + 1);\n return bScore - aScore || a.recencyRank - b.recencyRank || a.node.id.localeCompare(b.node.id);\n });\n return {\n offset: 0,\n entries: ordered.map(entry => ({ id: entry.node.id, degree: entry.degree, counts: entry.counts })),\n };\n }\n\n async #sampledRelationshipCounts(\n node: KnowledgeNode,\n scope: KnowledgeScope,\n ): Promise<{ degree: number; counts: KnowledgeInspectorRelationshipCounts }> {\n const [aboutResult, mentioningResult] = await Promise.all([\n this.#knowledge.listKnowledgeAbout({ node: node.id, scope, limit: MAX_RANK_FACTS }),\n this.#knowledge.listKnowledgeMentioning({ node: node.id, scope, limit: MAX_RANK_FACTS }),\n ]);\n const [outgoing, incoming] = await Promise.all([\n this.#outgoingNodeRecords(node, aboutResult.records, scope),\n this.#incomingParentRecords(node, mentioningResult.records, scope),\n ]);\n const mentioningRecords = mentioningResult.records.filter(record => record.node !== node.id);\n const degree = new Set([...outgoing.nodes, ...incoming.nodes].map(record => record.id)).size;\n return {\n degree,\n counts: {\n records: aboutResult.records.length + mentioningRecords.length,\n outgoing: outgoing.nodes.length,\n incoming: incoming.nodes.length,\n sampled: Boolean(\n aboutResult.nextCursor || mentioningResult.nextCursor || outgoing.truncated || incoming.truncated,\n ),\n },\n };\n }\n\n async #outgoingNodeRecords(\n current: KnowledgeNode,\n records: KnowledgeRecord[],\n scope: KnowledgeScope,\n ): Promise<RelationshipRecords> {\n const related = new Map<string, KnowledgeNode>();\n let truncated = false;\n const sources = [current.content ?? '', ...records.map(record => record.text)];\n for (const source of sources) {\n for (const name of parseKnowledgeWikilinks(source)) {\n if (related.size >= MAX_RELATED_RECORDS) {\n truncated = true;\n break;\n }\n const node = await this.#knowledge.resolveNode({ name, scope });\n if (node && node.id !== current.id && isKnowledgeScopeVisible(node.scope, scope)) {\n related.set(node.id, node);\n }\n }\n if (truncated) break;\n }\n return { nodes: [...related.values()], truncated };\n }\n\n async #incomingParentRecords(\n current: KnowledgeNode,\n records: KnowledgeRecord[],\n scope: KnowledgeScope,\n ): Promise<RelationshipRecords> {\n const related = new Map<string, KnowledgeNode>();\n let truncated = false;\n for (const record of records) {\n if (record.node === current.id || related.has(record.node)) continue;\n if (related.size >= MAX_RELATED_RECORDS) {\n truncated = true;\n break;\n }\n const node = await this.#knowledge.getNode(record.node);\n if (node && isKnowledgeScopeVisible(node.scope, scope)) related.set(node.id, node);\n }\n return { nodes: [...related.values()], truncated };\n }\n\n async #outgoingTargets(\n current: KnowledgeNode,\n records: KnowledgeRecord[],\n scope: KnowledgeScope,\n binding: Binding,\n level: KnowledgeInspectorScopeLevel,\n ): Promise<KnowledgeInspectorRelationshipPreview> {\n const related = await this.#outgoingNodeRecords(current, records, scope);\n return {\n nodes: related.nodes.map(node => this.#recordSummary(node, binding, level)),\n partial: related.truncated,\n };\n }\n\n async #incomingParents(\n current: KnowledgeNode,\n records: KnowledgeRecord[],\n scope: KnowledgeScope,\n binding: Binding,\n level: KnowledgeInspectorScopeLevel,\n ): Promise<KnowledgeInspectorRelationshipPreview> {\n const related = await this.#incomingParentRecords(current, records, scope);\n return {\n nodes: related.nodes.map(node => this.#recordSummary(node, binding, level)),\n partial: related.truncated,\n };\n }\n\n async #activityRecord(\n event: KnowledgeActivityEvent,\n scope: KnowledgeScope,\n binding: Binding,\n level: KnowledgeInspectorScopeLevel,\n ): Promise<KnowledgeInspectorNodeSummary | undefined> {\n if (event.recordType === 'node') {\n const node = await this.#knowledge.getNode(event.recordId);\n return node && isKnowledgeScopeVisible(node.scope, scope) ? this.#recordSummary(node, binding, level) : undefined;\n }\n const record = await this.#knowledge.getKnowledge({ id: event.recordId, includeDeleted: true });\n if (!record || !isKnowledgeScopeVisible(record.scope, scope)) return undefined;\n const node = await this.#knowledge.getNode(record.node);\n return node && isKnowledgeScopeVisible(node.scope, scope) ? this.#recordSummary(node, binding, level) : undefined;\n }\n\n #mintHandle(\n binding: Binding,\n level: KnowledgeInspectorScopeLevel,\n type: KnowledgeInspectorRecordType,\n recordId: string,\n ): string {\n this.#pruneOpaqueEntries();\n const token = opaqueToken();\n this.#handles.set(token, {\n identityKey: binding.identityKey,\n level,\n type,\n recordId,\n expiresAt: Date.now() + HANDLE_TTL_MS,\n });\n return token;\n }\n\n #readHandle(handle: string, binding: Binding, expectedType: KnowledgeInspectorRecordType): HandleEntry {\n const entry = this.#handles.get(handle);\n if (!entry || entry.expiresAt < Date.now() || entry.type !== expectedType) {\n throw new KnowledgeInspectorError('invalid-handle', 'Knowledge record handle is invalid or expired.');\n }\n if (entry.identityKey !== binding.identityKey) {\n throw new KnowledgeInspectorError('stale-handle', 'Knowledge record handle belongs to a previous scope.');\n }\n return entry;\n }\n\n #mintCursor(\n binding: Binding,\n level: KnowledgeInspectorScopeLevel,\n kind: CursorEntry['kind'],\n value: string,\n filters?: CursorEntry['filters'],\n ): string {\n this.#pruneOpaqueEntries();\n const token = opaqueToken();\n this.#cursors.set(token, {\n identityKey: binding.identityKey,\n level,\n kind,\n value,\n filters,\n expiresAt: Date.now() + HANDLE_TTL_MS,\n });\n return token;\n }\n\n #consumeCursor(\n cursor: string | undefined,\n binding: Binding,\n level: KnowledgeInspectorScopeLevel,\n kind: CursorEntry['kind'],\n filters?: CursorEntry['filters'],\n ): string | undefined {\n if (!cursor) return undefined;\n const entry = this.#cursors.get(cursor);\n if (\n !entry ||\n entry.expiresAt < Date.now() ||\n entry.identityKey !== binding.identityKey ||\n entry.level !== level ||\n entry.kind !== kind ||\n entry.filters?.namePrefix !== filters?.namePrefix ||\n entry.filters?.kind !== filters?.kind ||\n entry.filters?.sort !== filters?.sort\n ) {\n throw new KnowledgeInspectorError(\n 'invalid-cursor',\n 'Knowledge cursor does not match the active scope and filters.',\n );\n }\n return entry.value;\n }\n\n #pruneOpaqueEntries(): void {\n const now = Date.now();\n for (const [token, entry] of this.#handles) {\n if (entry.expiresAt < now) this.#handles.delete(token);\n }\n for (const [token, entry] of this.#cursors) {\n if (entry.expiresAt < now) this.#cursors.delete(token);\n }\n while (this.#handles.size + this.#cursors.size >= MAX_OPAQUE_ENTRIES) {\n const handle = this.#handles.keys().next().value;\n if (handle) this.#handles.delete(handle);\n else {\n const cursor = this.#cursors.keys().next().value;\n if (cursor) this.#cursors.delete(cursor);\n else break;\n }\n }\n }\n\n #invalidateIdnode(): void {\n this.#fingerprint = undefined;\n this.#identityKey = opaqueToken();\n this.#handles.clear();\n this.#cursors.clear();\n }\n}\n\nexport async function createKnowledgeInspector(input: {\n storage: MastraCompositeStore;\n session: Session<MastraCodeState>;\n}): Promise<KnowledgeInspector | undefined> {\n const knowledge = await input.storage.getStore('knowledge');\n return knowledge ? new ScopedKnowledgeInspector({ knowledge, session: input.session }) : undefined;\n}\n"],"mappings":"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"}
package/dist/schema.d.ts CHANGED
@@ -13,6 +13,8 @@ export interface MastraCodeState {
13
13
  projectName?: string;
14
14
  /** Factory project that owns this session. */
15
15
  factoryProjectId?: string;
16
+ /** Authoritative organization id seeded by factory at session construction. */
17
+ factoryOrgId?: string;
16
18
  /** Linked repository used by this session when source-control execution is required. */
17
19
  projectRepositoryId?: string;
18
20
  /** Persisted sandbox id for reattaching the project's cloud workspace. */
@@ -104,6 +106,7 @@ export declare const stateSchema: z.ZodObject<{
104
106
  projectPath: z.ZodOptional<z.ZodString>;
105
107
  projectName: z.ZodOptional<z.ZodString>;
106
108
  factoryProjectId: z.ZodOptional<z.ZodString>;
109
+ factoryOrgId: z.ZodOptional<z.ZodString>;
107
110
  projectRepositoryId: z.ZodOptional<z.ZodString>;
108
111
  sandboxId: z.ZodOptional<z.ZodString>;
109
112
  sandboxWorkdir: z.ZodOptional<z.ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/dist/schema.js CHANGED
@@ -8,6 +8,7 @@ const stateSchema = z.object({
8
8
  projectPath: z.string().optional(),
9
9
  projectName: z.string().optional(),
10
10
  factoryProjectId: z.string().optional(),
11
+ factoryOrgId: z.string().optional(),
11
12
  projectRepositoryId: z.string().optional(),
12
13
  sandboxId: z.string().optional(),
13
14
  sandboxWorkdir: z.string().optional(),