@mastra/code-sdk 1.17.0-alpha.2 → 1.18.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/agents/instructions.d.ts +2 -10
  2. package/dist/agents/instructions.d.ts.map +1 -1
  3. package/dist/agents/instructions.js +2 -4
  4. package/dist/agents/instructions.js.map +1 -1
  5. package/dist/agents/memory.d.ts +1 -17
  6. package/dist/agents/memory.d.ts.map +1 -1
  7. package/dist/agents/memory.js +6 -55
  8. package/dist/agents/memory.js.map +1 -1
  9. package/dist/agents/prompts/index.d.ts +0 -2
  10. package/dist/agents/prompts/index.d.ts.map +1 -1
  11. package/dist/agents/prompts/index.js +0 -1
  12. package/dist/agents/prompts/index.js.map +1 -1
  13. package/dist/agents/prompts/tool-guidance.d.ts +0 -2
  14. package/dist/agents/prompts/tool-guidance.d.ts.map +1 -1
  15. package/dist/agents/prompts/tool-guidance.js +0 -30
  16. package/dist/agents/prompts/tool-guidance.js.map +1 -1
  17. package/dist/index.d.ts +15 -2
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +28 -16
  20. package/dist/index.js.map +1 -1
  21. package/dist/knowledge-inspector.d.ts +26 -10
  22. package/dist/knowledge-inspector.d.ts.map +1 -1
  23. package/dist/knowledge-inspector.js +266 -241
  24. package/dist/knowledge-inspector.js.map +1 -1
  25. package/dist/knowledge-scope.d.ts +21 -23
  26. package/dist/knowledge-scope.d.ts.map +1 -1
  27. package/dist/knowledge-scope.js +49 -33
  28. package/dist/knowledge-scope.js.map +1 -1
  29. package/dist/mcp/manager.d.ts +3 -1
  30. package/dist/mcp/manager.d.ts.map +1 -1
  31. package/dist/mcp/manager.js +139 -104
  32. package/dist/mcp/manager.js.map +1 -1
  33. package/dist/onboarding/settings.d.ts +2 -0
  34. package/dist/onboarding/settings.d.ts.map +1 -1
  35. package/dist/onboarding/settings.js +3 -1
  36. package/dist/onboarding/settings.js.map +1 -1
  37. package/package.json +15 -15
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge-inspector.js","names":[],"sources":["../src/knowledge-inspector.ts"],"sourcesContent":["import type { Session } from '@mastra/core/agent-controller';\nimport type { Knowledge } from '@mastra/core/knowledge';\nimport type { Mastra } from '@mastra/core/mastra';\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 { resolveKnowledgeScopeIdentity } from './knowledge-scope.js';\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 /** Org rung shared with the subconscious writers (see knowledge-scope.ts). */\n organizationId: string;\n /** Resource rung of the knowledge scope: the Factory project id, else the session resource. */\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 Buffer.from(globalThis.crypto.getRandomValues(new Uint8Array(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.organizationId, 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 // Scope rungs come from the same resolver the subconscious writes under; an\n // owner id is a USER id and never names a knowledge org.\n const identity = resolveKnowledgeScopeIdentity(this.#session.state.get());\n const sessionResourceId = this.#session.identity.getResourceId();\n if (!identity.resolved) {\n // An unresolved org is its own identity: handles minted under the\n // previous scope must not survive into whatever resolves next.\n this.#invalidateIdnode();\n throw new KnowledgeInspectorError(\n 'unavailable',\n identity.reason\n ? `Knowledge inspection unavailable: ${identity.reason}`\n : 'Knowledge inspection requires a resolved organization for this session.',\n );\n }\n if (!sessionResourceId) {\n throw new KnowledgeInspectorError('unavailable', 'Knowledge inspection requires an active project.');\n }\n const organizationId = identity.organizationId;\n const resourceId = identity.knowledgeResourceId ?? sessionResourceId;\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 === sessionResourceId ? thread.id : undefined;\n const fingerprint = `${organizationId}\\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 { organizationId, resourceId, threadId, fingerprint, identityKey: this.#identityKey };\n }\n\n #scope(binding: Binding, level: KnowledgeInspectorScopeLevel): KnowledgeScope {\n if (level === 'org') return [`org:${binding.organizationId}`];\n const scope = [`org:${binding.organizationId}`, `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 knowledge?: Knowledge | string;\n mastra?: Pick<Mastra, 'getKnowledge'>;\n session: Session<MastraCodeState>;\n}): Promise<KnowledgeInspector | undefined> {\n let selected: Knowledge | undefined;\n if (typeof input.knowledge === 'string') {\n try {\n selected = input.mastra?.getKnowledge(input.knowledge);\n } catch {\n throw new KnowledgeInspectorError('unavailable', 'The configured Knowledge runtime is unavailable.');\n }\n if (!selected) {\n throw new KnowledgeInspectorError('unavailable', 'The configured Knowledge runtime is unavailable.');\n }\n } else {\n selected = input.knowledge;\n }\n const knowledge = selected ? await selected.getStorage() : await input.storage.getStore('knowledge');\n return knowledge ? new ScopedKnowledgeInspector({ knowledge, session: input.session }) : undefined;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"knowledge-inspector.js","names":[],"sources":["../src/knowledge-inspector.ts"],"sourcesContent":["import type { Session } from '@mastra/core/agent-controller';\nimport { knowledgeScopeAddress } from '@mastra/core/knowledge';\nimport type { Knowledge } from '@mastra/core/knowledge';\nimport type { Mastra } from '@mastra/core/mastra';\nimport { parseKnowledgeWikilinks } from '@mastra/core/storage';\nimport type {\n KnowledgeNote,\n KnowledgePage,\n KnowledgePageActivityAction,\n KnowledgePageActivityEvent,\n KnowledgeReadScope,\n KnowledgeStorage,\n} from '@mastra/core/storage';\n\nimport { knowledgeSessionTags, resolveKnowledgeSessionScopes } from './knowledge-scope.js';\nimport type { MastraCodeState } from './schema.js';\n\nexport type KnowledgeInspectorScopeLevel = 'org' | 'resource' | 'thread';\nexport type KnowledgeInspectorRecordType = 'node';\n/** `name`: every readable page, by name. `connected`: the first pages by name, most linked first. */\nexport type KnowledgeInspectorNodeSort = 'name' | '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 /** The scope's type, e.g. `org`, `project`, `resource`, `thread`. */\n level: string;\n id: string;\n}\n\nexport interface KnowledgeInspectorRelationshipCounts {\n records: number;\n outgoing: number;\n incoming: number;\n sampled: boolean;\n}\n\n/** A page. */\nexport interface KnowledgeInspectorNodeSummary {\n /** Opaque, freshly minted per result and bound to the session; use it to open the page. */\n handle: string;\n /** The page's stable id: the same page always has the same id, and two pages never share one. */\n id: string;\n type: KnowledgeInspectorRecordType;\n name: string;\n scope: KnowledgeInspectorScopeBadge;\n version: number;\n updatedAt: string;\n relationshipCounts?: KnowledgeInspectorRelationshipCounts;\n}\n\n/** A note. */\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' | '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 /** Notes on the page. */\n records: KnowledgeInspectorRecordSummary[];\n recordsNextCursor?: string;\n /** Notes on other pages that mention this page. */\n mentioningRecords: KnowledgeInspectorRecordSummary[];\n mentioningRecordsNextCursor?: string;\n /** Pages this page's notes and body mention. */\n outgoingTargets: KnowledgeInspectorRelationshipPreview;\n /** Pages whose notes mention this page. */\n incomingParents: KnowledgeInspectorRelationshipPreview;\n relationshipCounts: KnowledgeInspectorRelationshipCounts;\n /** The page body. */\n content?: string;\n contentTruncated: boolean;\n links: Array<{ label: string; node?: KnowledgeInspectorNodeSummary }>;\n}\n\nexport interface KnowledgeInspectorActivityEvent {\n action: KnowledgePageActivityAction;\n recordType: 'page' | 'note';\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 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 /** The session's non-identity scope tags, shared with the code agent (see knowledge-scope.ts). */\n sessionTags: string[];\n /** The session's Memory resource. */\n resourceId: string;\n threadId?: string;\n fingerprint: string;\n identityKey: string;\n}\n\n/** What one level reads with: the level's principals' read scope. */\ninterface LevelView {\n level: KnowledgeInspectorScopeLevel;\n read: KnowledgeReadScope;\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; sort?: KnowledgeInspectorNodeSort };\n expiresAt: number;\n}\n\ninterface RankedNodeSnapshot {\n offset: number;\n entries: { id: string; counts: KnowledgeInspectorRelationshipCounts }[];\n}\n\ninterface Related {\n pages: KnowledgePage[];\n truncated: boolean;\n}\n\nconst HANDLE_TTL_MS = 5 * 60_000;\nconst MAX_OPAQUE_ENTRIES = 1_000;\nconst DEFAULT_PAGE_LIMIT = 50;\nconst MAX_PAGE_LIMIT = 50;\nconst DEFAULT_NOTE_LIMIT = 25;\nconst MAX_NOTE_LIMIT = 100;\nconst DEFAULT_ACTIVITY_LIMIT = 20;\nconst MAX_ACTIVITY_LIMIT = 100;\nconst MAX_RELATED_PAGES = 25;\nconst MAX_RANK_CANDIDATES = 50;\nconst MAX_RANK_NOTES = 100;\nconst MAX_BODY_BYTES = 32 * 1024;\n\nfunction opaqueToken(): string {\n return Buffer.from(globalThis.crypto.getRandomValues(new Uint8Array(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 badgeOf(address: string | undefined): KnowledgeInspectorScopeBadge {\n if (!address) return { level: 'unknown', id: '' };\n const separator = address.indexOf(':');\n return { level: address.slice(0, separator), id: address.slice(separator + 1) };\n}\n\n/** A session tag in Knowledge's canonical form; every type the session holds has one `$param`. */\nfunction canonical(tag: string): string {\n const separator = tag.indexOf(':');\n return knowledgeScopeAddress(`${tag.slice(0, separator)}:$value`, { value: tag.slice(separator + 1) });\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\n/**\n * The /knowledge inspector: reads the pages and notes a session's code agent can read, one level at a\n * time (the session's shared tags, then its project resource, then its thread), through the same\n * Knowledge access rules the agent's runs use.\n */\nclass ScopedKnowledgeInspector implements KnowledgeInspector {\n readonly #knowledge: Knowledge;\n readonly #store: KnowledgeStorage;\n readonly #session: Session<MastraCodeState>;\n readonly #handles = new Map<string, HandleEntry>();\n readonly #cursors = new Map<string, CursorEntry>();\n readonly #scopeAddresses = new Map<string, string | undefined>();\n #fingerprint?: string;\n #identityKey = opaqueToken();\n\n readonly #hostScopes: readonly string[];\n\n constructor(input: {\n knowledge: Knowledge;\n store: KnowledgeStorage;\n session: Session<MastraCodeState>;\n hostScopes?: readonly string[];\n }) {\n this.#knowledge = input.knowledge;\n this.#store = input.store;\n this.#session = input.session;\n this.#hostScopes = input.hostScopes ?? [];\n this.#session.subscribe(event => {\n if (event.type === 'thread_changed' || event.type === 'thread_created' || event.type === 'thread_deleted') {\n this.#invalidate();\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.sessionTags.join(' + '), 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 sort?: KnowledgeInspectorNodeSort;\n cursor?: string;\n limit?: number;\n }): Promise<KnowledgeInspectorNodeList> {\n const binding = await this.#binding();\n const view = await this.#view(binding, input.level);\n const limit = boundedLimit(input.limit, DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT);\n const sort = input.sort ?? 'name';\n const filters = { namePrefix: input.namePrefix, sort };\n\n if (sort === 'name') {\n const cursor = this.#consumeCursor(input.cursor, binding, input.level, 'node', filters);\n const result = await this.#store.listPages({ read: view.read, namePrefix: input.namePrefix, cursor, limit });\n const nodes = await Promise.all(\n result.pages.map(async page => ({\n ...(await this.#summary(page, binding, view)),\n relationshipCounts: await this.#counts(page, view),\n })),\n );\n await this.#assertStable(binding);\n return {\n identityKey: binding.identityKey,\n scopeLevel: input.level,\n nodes,\n nextCursor: result.nextCursor\n ? this.#mintCursor(binding, input.level, 'node', result.nextCursor, filters)\n : undefined,\n sort,\n coverage: 'exact',\n };\n }\n\n const encoded = this.#consumeCursor(input.cursor, binding, input.level, 'ranked-node', filters);\n const snapshot = encoded ? (JSON.parse(encoded) as RankedNodeSnapshot) : await this.#ranked(view, input.namePrefix);\n const nodes: KnowledgeInspectorNodeSummary[] = [];\n for (const entry of snapshot.entries.slice(snapshot.offset, snapshot.offset + limit)) {\n const page = await this.#store.getPage({ id: entry.id, read: view.read });\n if (!page || page.deletedAt) continue;\n nodes.push({ ...(await this.#summary(page, binding, view)), 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: '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 view = await this.#view(binding, handle.level);\n const page = await this.#store.getPage({ id: handle.recordId, read: view.read });\n if (!page || page.deletedAt) {\n throw new KnowledgeInspectorError('not-visible', 'Knowledge page is not visible in the selected scope.');\n }\n const limit = boundedLimit(input.recordLimit, DEFAULT_NOTE_LIMIT, MAX_NOTE_LIMIT);\n const notesAfter = 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 [notes, mentioning] = await Promise.all([\n this.#store.listNotes({ pageId: page.id, read: view.read, cursor: notesAfter, limit }),\n this.#store.listNotesMentioning({ pageId: page.id, read: view.read, cursor: mentioningAfter, limit }),\n ]);\n const body = truncateUtf8(page.body ?? '', MAX_BODY_BYTES);\n const [outgoing, incoming, counts] = await Promise.all([\n this.#outgoing(page, notes.notes, view),\n this.#incoming(mentioning.notes, view),\n this.#counts(page, view),\n ]);\n const links = await Promise.all(\n parseKnowledgeWikilinks(body.value)\n .slice(0, MAX_RELATED_PAGES)\n .map(async label => {\n const [target] = await this.#store.findPagesByName({ name: label, read: view.read, limit: 1 });\n return { label, node: target ? await this.#summary(target, binding, view) : undefined };\n }),\n );\n const summaries = (pages: KnowledgePage[]) =>\n Promise.all(pages.map(related => this.#summary(related, binding, view)));\n const detail: KnowledgeInspectorNodeDetail = {\n identityKey: binding.identityKey,\n scopeLevel: handle.level,\n node: { ...(await this.#summary(page, binding, view)), relationshipCounts: counts },\n records: await Promise.all(notes.notes.map(note => this.#noteSummary(note))),\n recordsNextCursor: notes.nextCursor\n ? this.#mintCursor(binding, handle.level, 'records', notes.nextCursor)\n : undefined,\n mentioningRecords: await Promise.all(mentioning.notes.map(note => this.#noteSummary(note))),\n mentioningRecordsNextCursor: mentioning.nextCursor\n ? this.#mintCursor(binding, handle.level, 'mentioning-records', mentioning.nextCursor)\n : undefined,\n outgoingTargets: {\n nodes: await summaries(outgoing.pages),\n partial: outgoing.truncated || Boolean(notes.nextCursor),\n },\n incomingParents: {\n nodes: await summaries(incoming.pages),\n partial: incoming.truncated || Boolean(mentioning.nextCursor),\n },\n relationshipCounts: counts,\n content: page.body === undefined ? undefined : body.value,\n contentTruncated: body.truncated,\n links,\n };\n await this.#assertStable(binding);\n return detail;\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 view = await this.#view(binding, input.level);\n const limit = boundedLimit(input.limit, DEFAULT_ACTIVITY_LIMIT, MAX_ACTIVITY_LIMIT);\n const cursor = this.#consumeCursor(input.cursor, binding, input.level, 'activity');\n const result = await this.#store.listPageActivity({ read: view.read, cursor, limit });\n const events: KnowledgeInspectorActivityEvent[] = [];\n for (const event of result.events) events.push(await this.#activityEvent(event, binding, view));\n await this.#assertStable(binding);\n return {\n identityKey: binding.identityKey,\n scopeLevel: input.level,\n events,\n nextCursor: result.nextCursor ? this.#mintCursor(binding, input.level, 'activity', result.nextCursor) : undefined,\n };\n }\n\n async #binding(): Promise<Binding> {\n // Session tags come from the same resolver the code agent's run scopes use.\n const session = resolveKnowledgeSessionScopes(this.#session.state.get(), this.#hostScopes);\n const sessionResourceId = this.#session.identity.getResourceId();\n if (!session.resolved) {\n // An unresolved session is its own identity: handles minted under the\n // previous scope must not survive into whatever resolves next.\n this.#invalidate();\n throw new KnowledgeInspectorError('unavailable', `Knowledge inspection unavailable: ${session.reason}`);\n }\n if (!sessionResourceId) {\n throw new KnowledgeInspectorError('unavailable', 'Knowledge inspection requires an active project.');\n }\n const sessionTags = knowledgeSessionTags(session.scopes);\n const resourceId = sessionResourceId;\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 === sessionResourceId ? thread.id : undefined;\n const fingerprint = `${sessionTags.join('\\u001f')}\\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 { sessionTags, resourceId, threadId, fingerprint, identityKey: this.#identityKey };\n }\n\n /** The principals a level reads with: the session's shared tags, plus its resource, plus its thread. */\n async #view(binding: Binding, level: KnowledgeInspectorScopeLevel): Promise<LevelView> {\n let principals: string[];\n if (level === 'org') {\n if (binding.sessionTags.length === 0) {\n throw new KnowledgeInspectorError('unavailable', 'This session holds no shared scope tags.');\n }\n principals = [...binding.sessionTags];\n } else {\n principals = [...binding.sessionTags, `resource:${binding.resourceId}`];\n if (level === 'thread') {\n if (!binding.threadId) {\n throw new KnowledgeInspectorError('unavailable', 'The active thread does not belong to this project.');\n }\n principals.push(`thread:${binding.threadId}`);\n }\n }\n try {\n return { level, read: await this.#knowledge.readScopeFor(principals.map(canonical)) };\n } catch (error) {\n throw new KnowledgeInspectorError(\n 'unavailable',\n `Knowledge inspection unavailable: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\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 async #scopeAddress(scopeId: string): Promise<string | undefined> {\n if (!this.#scopeAddresses.has(scopeId)) {\n // Scope names and addresses aren't secret to the host; the page itself was already read through the view.\n const page = await this.#store.getPage({ id: scopeId, read: 'all' });\n this.#scopeAddresses.set(scopeId, page?.address);\n }\n return this.#scopeAddresses.get(scopeId);\n }\n\n async #summary(page: KnowledgePage, binding: Binding, view: LevelView): Promise<KnowledgeInspectorNodeSummary> {\n return {\n handle: this.#mintHandle(binding, view.level, 'node', page.id),\n id: page.id,\n type: 'node',\n name: page.name,\n scope: badgeOf(await this.#scopeAddress(page.scopeId)),\n version: page.version,\n updatedAt: page.updatedAt.toISOString(),\n };\n }\n\n async #noteSummary(note: KnowledgeNote): Promise<KnowledgeInspectorRecordSummary> {\n return {\n text: note.text,\n scope: badgeOf(await this.#scopeAddress(note.stampScopeIds[0]!)),\n sourceThreadId: note.provenance.sourceThreadId,\n capturedAt: note.createdAt.toISOString(),\n when: note.when?.toISOString(),\n };\n }\n\n /** The first pages by name, most linked first; ties keep name order. */\n async #ranked(view: LevelView, namePrefix: string | undefined): Promise<RankedNodeSnapshot> {\n const { pages } = await this.#store.listPages({ read: view.read, namePrefix, limit: MAX_RANK_CANDIDATES });\n const ranked = await Promise.all(\n pages.map(async (page, order) => {\n const counts = await this.#counts(page, view);\n return { id: page.id, order, counts, degree: counts.outgoing + counts.incoming };\n }),\n );\n ranked.sort((a, b) => b.degree - a.degree || a.order - b.order);\n return { offset: 0, entries: ranked.map(({ id, counts }) => ({ id, counts })) };\n }\n\n async #counts(page: KnowledgePage, view: LevelView): Promise<KnowledgeInspectorRelationshipCounts> {\n const [notes, mentioning] = await Promise.all([\n this.#store.listNotes({ pageId: page.id, read: view.read, limit: MAX_RANK_NOTES }),\n this.#store.listNotesMentioning({ pageId: page.id, read: view.read, limit: MAX_RANK_NOTES }),\n ]);\n const [outgoing, incoming] = await Promise.all([\n this.#outgoing(page, notes.notes, view),\n this.#incoming(mentioning.notes, view),\n ]);\n return {\n records: notes.notes.length + mentioning.notes.length,\n outgoing: outgoing.pages.length,\n incoming: incoming.pages.length,\n sampled: Boolean(notes.nextCursor || mentioning.nextCursor || outgoing.truncated || incoming.truncated),\n };\n }\n\n /** Readable pages this page's notes mention, then pages its body links to by name. */\n async #outgoing(page: KnowledgePage, notes: KnowledgeNote[], view: LevelView): Promise<Related> {\n const related = new Map<string, KnowledgePage>();\n const add = (target: KnowledgePage | null | undefined) => {\n if (target && !target.deletedAt && target.id !== page.id) related.set(target.id, target);\n };\n for (const id of new Set(notes.flatMap(note => note.mentions))) {\n if (related.size >= MAX_RELATED_PAGES) return { pages: [...related.values()], truncated: true };\n add(await this.#store.getPage({ id, read: view.read }));\n }\n for (const name of parseKnowledgeWikilinks(page.body ?? '')) {\n if (related.size >= MAX_RELATED_PAGES) return { pages: [...related.values()], truncated: true };\n const [target] = await this.#store.findPagesByName({ name, read: view.read, limit: 1 });\n add(target);\n }\n return { pages: [...related.values()], truncated: false };\n }\n\n /** Readable pages whose notes mention this page. */\n async #incoming(mentioning: KnowledgeNote[], view: LevelView): Promise<Related> {\n const related = new Map<string, KnowledgePage>();\n for (const pageId of new Set(mentioning.map(note => note.pageId))) {\n if (related.size >= MAX_RELATED_PAGES) return { pages: [...related.values()], truncated: true };\n const source = await this.#store.getPage({ id: pageId, read: view.read });\n if (source && !source.deletedAt) related.set(source.id, source);\n }\n return { pages: [...related.values()], truncated: false };\n }\n\n async #activityEvent(\n event: KnowledgePageActivityEvent,\n binding: Binding,\n view: LevelView,\n ): Promise<KnowledgeInspectorActivityEvent> {\n const page = await this.#store.getPage({ id: event.pageId, read: view.read });\n const live = page && !page.deletedAt ? page : undefined;\n return {\n action: event.action,\n recordType: event.noteId ? 'note' : 'page',\n scope: badgeOf(await this.#scopeAddress(event.scopeId)),\n sourceThreadId: event.provenance.sourceThreadId,\n createdAt: event.createdAt.toISOString(),\n record: live ? await this.#summary(live, binding, view) : undefined,\n };\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?.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 #invalidate(): void {\n this.#fingerprint = undefined;\n this.#identityKey = opaqueToken();\n this.#handles.clear();\n this.#cursors.clear();\n }\n}\n\n/**\n * The /knowledge inspector for a session, reading through the session's Knowledge runtime (a key\n * resolves through `mastra`). Undefined when there is no Knowledge runtime: access rules live on the\n * runtime, so a bare storage domain can't be inspected.\n */\nexport async function createKnowledgeInspector(input: {\n knowledge?: Knowledge | string;\n mastra?: Pick<Mastra, 'getKnowledge'>;\n session: Session<MastraCodeState>;\n /** The host's `knowledge.scopes`, so the inspector reads what the code agent writes. */\n hostScopes?: readonly string[];\n}): Promise<KnowledgeInspector | undefined> {\n let selected: Knowledge | undefined;\n if (typeof input.knowledge === 'string') {\n try {\n selected = input.mastra?.getKnowledge(input.knowledge);\n } catch {\n throw new KnowledgeInspectorError('unavailable', 'The configured Knowledge runtime is unavailable.');\n }\n if (!selected) {\n throw new KnowledgeInspectorError('unavailable', 'The configured Knowledge runtime is unavailable.');\n }\n } else {\n selected = input.knowledge;\n }\n if (!selected) return undefined;\n const store = await selected.getStorage();\n return new ScopedKnowledgeInspector({\n knowledge: selected,\n store,\n session: input.session,\n hostScopes: input.hostScopes,\n });\n}\n"],"mappings":"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"}
@@ -1,35 +1,33 @@
1
1
  import type { MastraCodeState } from './schema.js';
2
2
  /**
3
- * The organization rung local (TUI/studio) knowledge is curated under. A fixed
4
- * literal on purpose: deriving it from a hostname, machine id, or path would
5
- * fragment local knowledge per machine or checkout, and a user running several
6
- * machines against one shared store could never share knowledge between them.
7
- * Resolving a real org id (settings, /knowledge, login) is future work; when it
8
- * lands, it replaces this default here.
3
+ * The org tag the built-in (`knowledge: true`) Knowledge writes under when the host gives no scopes. A
4
+ * fixed literal on purpose: deriving it from a hostname, machine id or path would fragment local
5
+ * Knowledge per machine or checkout, so several machines sharing one store could never share it.
9
6
  */
10
7
  export declare const LOCAL_KNOWLEDGE_ORG_ID = "local";
11
- export type KnowledgeScopeIdentity = {
8
+ export type KnowledgeSessionScopes = {
12
9
  resolved: true;
13
- organizationId: string;
14
- /** Set when the resource rung is anchored on something other than the session resource. */
15
- knowledgeResourceId?: string;
10
+ scopes: string[];
16
11
  } | {
17
12
  resolved: false;
18
- knowledgeResourceId?: string;
19
- reason?: string;
13
+ reason: string;
20
14
  };
21
15
  /**
22
- * The single source of truth for which org/resource rungs a session's knowledge
23
- * lives under. Every reader and writer of the knowledge store (the subconscious
24
- * memory factory, the /knowledge inspector) must derive its scope from here so
25
- * that what curation writes is what the browser reads.
16
+ * The scope tags a session's runs act with: the host's `knowledge.scopes` plus the session's own.
17
+ * Every Knowledge reader and writer in a session (the code agent, the /knowledge inspector) uses
18
+ * this, so what the agent writes is what the inspector reads.
26
19
  *
27
- * - Factory seeds the authoritative org id into session state. There is no
28
- * fallback: a session owner is a USER id, never an organization, so a
29
- * Factory-owned session without an org resolves to nothing (fail closed).
30
- * - Factory runs share one knowledge graph per project, so the resource rung is
31
- * anchored on the project id.
32
- * - TUI/studio sessions use {@link LOCAL_KNOWLEDGE_ORG_ID}.
20
+ * - Factory sessions require `org:<factoryOrgId>` and `project:<factoryProjectId>`, so projects stay
21
+ * isolated. A host tag of the same type with another value is refused. A Factory session with
22
+ * no org resolves to nothing (fail closed): a session owner is a user id, never an org.
23
+ * - Local sessions act with the host's scopes as given.
33
24
  */
34
- export declare function resolveKnowledgeScopeIdentity(state: MastraCodeState | undefined): KnowledgeScopeIdentity;
25
+ export declare function resolveKnowledgeSessionScopes(state: MastraCodeState | undefined, hostScopes?: readonly string[]): KnowledgeSessionScopes;
26
+ /**
27
+ * The scopes a run acts with when its session is unresolved: only the host's `resource:`/`thread:`
28
+ * tags, so its writes stay private to the run and no host tag stands in for the missing org.
29
+ */
30
+ export declare function knowledgeUnresolvedScopes(hostScopes: readonly string[]): string[];
31
+ /** The non-identity tags of a session's scopes, as plain strings. */
32
+ export declare function knowledgeSessionTags(scopes: readonly string[]): string[];
35
33
  //# sourceMappingURL=knowledge-scope.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge-scope.d.ts","sourceRoot":"","sources":["../src/knowledge-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,UAAU,CAAC;AAE9C,MAAM,MAAM,sBAAsB,GAC9B;IACE,QAAQ,EAAE,IAAI,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,2FAA2F;IAC3F,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,GACD;IAAE,QAAQ,EAAE,KAAK,CAAC;IAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE;;;;;;;;;;;;GAYG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,sBAAsB,CAoBxG"}
1
+ {"version":3,"file":"knowledge-scope.d.ts","sourceRoot":"","sources":["../src/knowledge-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,UAAU,CAAC;AAE9C,MAAM,MAAM,sBAAsB,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAMhH;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,eAAe,GAAG,SAAS,EAClC,UAAU,GAAE,SAAS,MAAM,EAAO,GACjC,sBAAsB,CAoBxB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAEjF;AAED,qEAAqE;AACrE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAExE"}
@@ -1,46 +1,62 @@
1
1
  // src/knowledge-scope.ts
2
2
  /**
3
- * The organization rung local (TUI/studio) knowledge is curated under. A fixed
4
- * literal on purpose: deriving it from a hostname, machine id, or path would
5
- * fragment local knowledge per machine or checkout, and a user running several
6
- * machines against one shared store could never share knowledge between them.
7
- * Resolving a real org id (settings, /knowledge, login) is future work; when it
8
- * lands, it replaces this default here.
3
+ * The org tag the built-in (`knowledge: true`) Knowledge writes under when the host gives no scopes. A
4
+ * fixed literal on purpose: deriving it from a hostname, machine id or path would fragment local
5
+ * Knowledge per machine or checkout, so several machines sharing one store could never share it.
9
6
  */
10
7
  const LOCAL_KNOWLEDGE_ORG_ID = "local";
8
+ function isIdentityTag(tag) {
9
+ return tag.startsWith("resource:") || tag.startsWith("thread:");
10
+ }
11
11
  /**
12
- * The single source of truth for which org/resource rungs a session's knowledge
13
- * lives under. Every reader and writer of the knowledge store (the subconscious
14
- * memory factory, the /knowledge inspector) must derive its scope from here so
15
- * that what curation writes is what the browser reads.
12
+ * The scope tags a session's runs act with: the host's `knowledge.scopes` plus the session's own.
13
+ * Every Knowledge reader and writer in a session (the code agent, the /knowledge inspector) uses
14
+ * this, so what the agent writes is what the inspector reads.
16
15
  *
17
- * - Factory seeds the authoritative org id into session state. There is no
18
- * fallback: a session owner is a USER id, never an organization, so a
19
- * Factory-owned session without an org resolves to nothing (fail closed).
20
- * - Factory runs share one knowledge graph per project, so the resource rung is
21
- * anchored on the project id.
22
- * - TUI/studio sessions use {@link LOCAL_KNOWLEDGE_ORG_ID}.
16
+ * - Factory sessions require `org:<factoryOrgId>` and `project:<factoryProjectId>`, so projects stay
17
+ * isolated. A host tag of the same type with another value is refused. A Factory session with
18
+ * no org resolves to nothing (fail closed): a session owner is a user id, never an org.
19
+ * - Local sessions act with the host's scopes as given.
23
20
  */
24
- function resolveKnowledgeScopeIdentity(state) {
25
- const factoryProjectId = state?.factoryProjectId;
26
- const isFactory = typeof factoryProjectId === "string" && factoryProjectId.trim().length > 0;
27
- const factoryOrgId = state?.factoryOrgId;
28
- const factoryOwned = isFactory || state?.factoryOrgUnresolved === true;
29
- const organizationId = typeof factoryOrgId === "string" ? factoryOrgId.trim() : "";
30
- if (organizationId) return {
31
- resolved: true,
32
- organizationId,
33
- knowledgeResourceId: isFactory ? factoryProjectId : void 0
34
- };
35
- if (factoryOwned) return {
36
- resolved: false,
37
- knowledgeResourceId: isFactory ? factoryProjectId : void 0
38
- };
21
+ function resolveKnowledgeSessionScopes(state, hostScopes = []) {
22
+ const projectId = typeof state?.factoryProjectId === "string" ? state.factoryProjectId.trim() : "";
23
+ const orgId = typeof state?.factoryOrgId === "string" ? state.factoryOrgId.trim() : "";
24
+ if (projectId.length > 0 || orgId.length > 0 || state?.factoryOrgUnresolved === true) {
25
+ if (!orgId) return {
26
+ resolved: false,
27
+ reason: "This Factory session has no resolved organization."
28
+ };
29
+ const required = [`org:${orgId}`, ...projectId ? [`project:${projectId}`] : []];
30
+ for (const tag of hostScopes) {
31
+ const type = tag.slice(0, tag.indexOf(":") + 1);
32
+ const conflict = required.find((requiredTag) => requiredTag.startsWith(type) && requiredTag !== tag);
33
+ if (type && conflict && (type === "org:" || type === "project:")) return {
34
+ resolved: false,
35
+ reason: `Scope ${tag} conflicts with this Factory session's ${conflict}.`
36
+ };
37
+ }
38
+ const held = new Set(hostScopes);
39
+ return {
40
+ resolved: true,
41
+ scopes: [...hostScopes, ...required.filter((tag) => !held.has(tag))]
42
+ };
43
+ }
39
44
  return {
40
45
  resolved: true,
41
- organizationId: LOCAL_KNOWLEDGE_ORG_ID
46
+ scopes: [...hostScopes]
42
47
  };
43
48
  }
44
- export { LOCAL_KNOWLEDGE_ORG_ID, resolveKnowledgeScopeIdentity };
49
+ /**
50
+ * The scopes a run acts with when its session is unresolved: only the host's `resource:`/`thread:`
51
+ * tags, so its writes stay private to the run and no host tag stands in for the missing org.
52
+ */
53
+ function knowledgeUnresolvedScopes(hostScopes) {
54
+ return hostScopes.filter(isIdentityTag);
55
+ }
56
+ /** The non-identity tags of a session's scopes, as plain strings. */
57
+ function knowledgeSessionTags(scopes) {
58
+ return scopes.filter((tag) => !isIdentityTag(tag));
59
+ }
60
+ export { LOCAL_KNOWLEDGE_ORG_ID, knowledgeSessionTags, knowledgeUnresolvedScopes, resolveKnowledgeSessionScopes };
45
61
 
46
62
  //# sourceMappingURL=knowledge-scope.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge-scope.js","names":[],"sources":["../src/knowledge-scope.ts"],"sourcesContent":["import type { MastraCodeState } from './schema.js';\n\n/**\n * The organization rung local (TUI/studio) knowledge is curated under. A fixed\n * literal on purpose: deriving it from a hostname, machine id, or path would\n * fragment local knowledge per machine or checkout, and a user running several\n * machines against one shared store could never share knowledge between them.\n * Resolving a real org id (settings, /knowledge, login) is future work; when it\n * lands, it replaces this default here.\n */\nexport const LOCAL_KNOWLEDGE_ORG_ID = 'local';\n\nexport type KnowledgeScopeIdentity =\n | {\n resolved: true;\n organizationId: string;\n /** Set when the resource rung is anchored on something other than the session resource. */\n knowledgeResourceId?: string;\n }\n | { resolved: false; knowledgeResourceId?: string; reason?: string };\n\n/**\n * The single source of truth for which org/resource rungs a session's knowledge\n * lives under. Every reader and writer of the knowledge store (the subconscious\n * memory factory, the /knowledge inspector) must derive its scope from here so\n * that what curation writes is what the browser reads.\n *\n * - Factory seeds the authoritative org id into session state. There is no\n * fallback: a session owner is a USER id, never an organization, so a\n * Factory-owned session without an org resolves to nothing (fail closed).\n * - Factory runs share one knowledge graph per project, so the resource rung is\n * anchored on the project id.\n * - TUI/studio sessions use {@link LOCAL_KNOWLEDGE_ORG_ID}.\n */\nexport function resolveKnowledgeScopeIdentity(state: MastraCodeState | undefined): KnowledgeScopeIdentity {\n const factoryProjectId = state?.factoryProjectId;\n const isFactory = typeof factoryProjectId === 'string' && factoryProjectId.trim().length > 0;\n const factoryOrgId = state?.factoryOrgId;\n const factoryOwned = isFactory || state?.factoryOrgUnresolved === true;\n\n // Trimmed to match what the Factory org seeder stores; not every seam routes\n // its seed through it.\n const organizationId = typeof factoryOrgId === 'string' ? factoryOrgId.trim() : '';\n if (organizationId) {\n return {\n resolved: true,\n organizationId,\n knowledgeResourceId: isFactory ? factoryProjectId : undefined,\n };\n }\n if (factoryOwned) {\n return { resolved: false, knowledgeResourceId: isFactory ? factoryProjectId : undefined };\n }\n return { resolved: true, organizationId: LOCAL_KNOWLEDGE_ORG_ID };\n}\n"],"mappings":";;;;;;;;;AAUA,MAAa,yBAAyB;;;;;;;;;;;;;;AAwBtC,SAAgB,8BAA8B,OAA4D;CACxG,MAAM,mBAAmB,OAAO;CAChC,MAAM,YAAY,OAAO,qBAAqB,YAAY,iBAAiB,KAAK,CAAC,CAAC,SAAS;CAC3F,MAAM,eAAe,OAAO;CAC5B,MAAM,eAAe,aAAa,OAAO,yBAAyB;CAIlE,MAAM,iBAAiB,OAAO,iBAAiB,WAAW,aAAa,KAAK,IAAI;CAChF,IAAI,gBACF,OAAO;EACL,UAAU;EACV;EACA,qBAAqB,YAAY,mBAAmB,KAAA;CACtD;CAEF,IAAI,cACF,OAAO;EAAE,UAAU;EAAO,qBAAqB,YAAY,mBAAmB,KAAA;CAAU;CAE1F,OAAO;EAAE,UAAU;EAAM,gBAAgB;CAAuB;AAClE"}
1
+ {"version":3,"file":"knowledge-scope.js","names":[],"sources":["../src/knowledge-scope.ts"],"sourcesContent":["import type { MastraCodeState } from './schema.js';\n\n/**\n * The org tag the built-in (`knowledge: true`) Knowledge writes under when the host gives no scopes. A\n * fixed literal on purpose: deriving it from a hostname, machine id or path would fragment local\n * Knowledge per machine or checkout, so several machines sharing one store could never share it.\n */\nexport const LOCAL_KNOWLEDGE_ORG_ID = 'local';\n\nexport type KnowledgeSessionScopes = { resolved: true; scopes: string[] } | { resolved: false; reason: string };\n\nfunction isIdentityTag(tag: string): boolean {\n return tag.startsWith('resource:') || tag.startsWith('thread:');\n}\n\n/**\n * The scope tags a session's runs act with: the host's `knowledge.scopes` plus the session's own.\n * Every Knowledge reader and writer in a session (the code agent, the /knowledge inspector) uses\n * this, so what the agent writes is what the inspector reads.\n *\n * - Factory sessions require `org:<factoryOrgId>` and `project:<factoryProjectId>`, so projects stay\n * isolated. A host tag of the same type with another value is refused. A Factory session with\n * no org resolves to nothing (fail closed): a session owner is a user id, never an org.\n * - Local sessions act with the host's scopes as given.\n */\nexport function resolveKnowledgeSessionScopes(\n state: MastraCodeState | undefined,\n hostScopes: readonly string[] = [],\n): KnowledgeSessionScopes {\n const projectId = typeof state?.factoryProjectId === 'string' ? state.factoryProjectId.trim() : '';\n const orgId = typeof state?.factoryOrgId === 'string' ? state.factoryOrgId.trim() : '';\n const factoryOwned = projectId.length > 0 || orgId.length > 0 || state?.factoryOrgUnresolved === true;\n\n if (factoryOwned) {\n if (!orgId) return { resolved: false, reason: 'This Factory session has no resolved organization.' };\n const required = [`org:${orgId}`, ...(projectId ? [`project:${projectId}`] : [])];\n for (const tag of hostScopes) {\n const type = tag.slice(0, tag.indexOf(':') + 1);\n const conflict = required.find(requiredTag => requiredTag.startsWith(type) && requiredTag !== tag);\n if (type && conflict && (type === 'org:' || type === 'project:')) {\n return { resolved: false, reason: `Scope ${tag} conflicts with this Factory session's ${conflict}.` };\n }\n }\n const held = new Set(hostScopes);\n return { resolved: true, scopes: [...hostScopes, ...required.filter(tag => !held.has(tag))] };\n }\n\n return { resolved: true, scopes: [...hostScopes] };\n}\n\n/**\n * The scopes a run acts with when its session is unresolved: only the host's `resource:`/`thread:`\n * tags, so its writes stay private to the run and no host tag stands in for the missing org.\n */\nexport function knowledgeUnresolvedScopes(hostScopes: readonly string[]): string[] {\n return hostScopes.filter(isIdentityTag);\n}\n\n/** The non-identity tags of a session's scopes, as plain strings. */\nexport function knowledgeSessionTags(scopes: readonly string[]): string[] {\n return scopes.filter(tag => !isIdentityTag(tag));\n}\n"],"mappings":";;;;;;AAOA,MAAa,yBAAyB;AAItC,SAAS,cAAc,KAAsB;CAC3C,OAAO,IAAI,WAAW,WAAW,KAAK,IAAI,WAAW,SAAS;AAChE;;;;;;;;;;;AAYA,SAAgB,8BACd,OACA,aAAgC,CAAC,GACT;CACxB,MAAM,YAAY,OAAO,OAAO,qBAAqB,WAAW,MAAM,iBAAiB,KAAK,IAAI;CAChG,MAAM,QAAQ,OAAO,OAAO,iBAAiB,WAAW,MAAM,aAAa,KAAK,IAAI;CAGpF,IAFqB,UAAU,SAAS,KAAK,MAAM,SAAS,KAAK,OAAO,yBAAyB,MAE/E;EAChB,IAAI,CAAC,OAAO,OAAO;GAAE,UAAU;GAAO,QAAQ;EAAqD;EACnG,MAAM,WAAW,CAAC,OAAO,SAAS,GAAI,YAAY,CAAC,WAAW,WAAW,IAAI,CAAC,CAAE;EAChF,KAAK,MAAM,OAAO,YAAY;GAC5B,MAAM,OAAO,IAAI,MAAM,GAAG,IAAI,QAAQ,GAAG,IAAI,CAAC;GAC9C,MAAM,WAAW,SAAS,MAAK,gBAAe,YAAY,WAAW,IAAI,KAAK,gBAAgB,GAAG;GACjG,IAAI,QAAQ,aAAa,SAAS,UAAU,SAAS,aACnD,OAAO;IAAE,UAAU;IAAO,QAAQ,SAAS,IAAI,yCAAyC,SAAS;GAAG;EAExG;EACA,MAAM,OAAO,IAAI,IAAI,UAAU;EAC/B,OAAO;GAAE,UAAU;GAAM,QAAQ,CAAC,GAAG,YAAY,GAAG,SAAS,QAAO,QAAO,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC;EAAE;CAC9F;CAEA,OAAO;EAAE,UAAU;EAAM,QAAQ,CAAC,GAAG,UAAU;CAAE;AACnD;;;;;AAMA,SAAgB,0BAA0B,YAAyC;CACjF,OAAO,WAAW,OAAO,aAAa;AACxC;;AAGA,SAAgB,qBAAqB,QAAqC;CACxE,OAAO,OAAO,QAAO,QAAO,CAAC,cAAc,GAAG,CAAC;AACjD"}
@@ -98,5 +98,7 @@ export interface McpManager {
98
98
  * Create an MCP manager that wraps MCPClient with config-file discovery
99
99
  * and per-server status tracking.
100
100
  */
101
- export declare function createMcpManager(projectDir: string, configDirName?: string, extraServers?: Record<string, McpServerConfig>, externalDiscovery?: ExternalMcpDiscoveryOptions): McpManager;
101
+ export declare function createMcpManager(projectDir: string, configDirName?: string, extraServers?: Record<string, McpServerConfig>, externalDiscovery?: ExternalMcpDiscoveryOptions, options?: {
102
+ discoveryTimeoutMs?: number;
103
+ }): McpManager;
102
104
  //# sourceMappingURL=manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/mcp/manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAQ/D,OAAO,KAAK,EACV,SAAS,EAGT,eAAe,EACf,eAAe,EACf,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAIpB,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,2EAA2E;AAC3E,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,2FAA2F;IAC3F,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,kEAAkE;IAClE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,iEAAiE;IACjE,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACxD;;;;;;;;;;;OAWG;IACH,kBAAkB,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3E,OAAO,CAAC,eAAe,CAAC,CAAC;IAC5B;;;;;OAKG;IACH,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D;;;;;;;;OAQG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC7G,oFAAoF;IACpF,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACtD;;;;;OAKG;IACH,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,oFAAoF;IACpF,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,2EAA2E;IAC3E,kBAAkB,IAAI,MAAM,EAAE,CAAC;IAC/B,mEAAmE;IACnE,qBAAqB,IAAI,OAAO,CAAC;IACjC,oDAAoD;IACpD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,oFAAoF;IACpF,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,4DAA4D;IAC5D,UAAU,IAAI,OAAO,CAAC;IACtB,iCAAiC;IACjC,iBAAiB,IAAI,eAAe,EAAE,CAAC;IACvC,2DAA2D;IAC3D,iBAAiB,IAAI,gBAAgB,EAAE,CAAC;IACxC,yCAAyC;IACzC,cAAc,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,6BAA6B;IAC7B,SAAS,IAAI,SAAS,CAAC;IACvB,6CAA6C;IAC7C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACvC;AA0FD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,aAAa,SAAqB,EAClC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,EAC9C,iBAAiB,CAAC,EAAE,2BAA2B,GAC9C,UAAU,CA6vBZ"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/mcp/manager.ts"],"names":[],"mappings":"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"}