@mastra/code-sdk 1.6.1-alpha.0 → 1.7.0-alpha.10

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 (51) hide show
  1. package/dist/agents/instructions.d.ts +14 -2
  2. package/dist/agents/instructions.d.ts.map +1 -1
  3. package/dist/agents/instructions.js +12 -4
  4. package/dist/agents/instructions.js.map +1 -1
  5. package/dist/agents/memory.d.ts +15 -4
  6. package/dist/agents/memory.d.ts.map +1 -1
  7. package/dist/agents/memory.js +29 -17
  8. package/dist/agents/memory.js.map +1 -1
  9. package/dist/agents/prompts/index.d.ts +3 -0
  10. package/dist/agents/prompts/index.d.ts.map +1 -1
  11. package/dist/agents/prompts/index.js +9 -0
  12. package/dist/agents/prompts/index.js.map +1 -1
  13. package/dist/agents/prompts/tool-guidance.d.ts +3 -0
  14. package/dist/agents/prompts/tool-guidance.d.ts.map +1 -1
  15. package/dist/agents/prompts/tool-guidance.js +31 -1
  16. package/dist/agents/prompts/tool-guidance.js.map +1 -1
  17. package/dist/agents/subagents/execute.d.ts +3 -0
  18. package/dist/agents/subagents/execute.d.ts.map +1 -0
  19. package/dist/agents/subagents/execute.js +27 -0
  20. package/dist/agents/subagents/execute.js.map +1 -0
  21. package/dist/agents/subagents/explore.d.ts +3 -0
  22. package/dist/agents/subagents/explore.d.ts.map +1 -0
  23. package/dist/agents/subagents/explore.js +18 -0
  24. package/dist/agents/subagents/explore.js.map +1 -0
  25. package/dist/agents/subagents/plan.d.ts +3 -0
  26. package/dist/agents/subagents/plan.d.ts.map +1 -0
  27. package/dist/agents/subagents/plan.js +18 -0
  28. package/dist/agents/subagents/plan.js.map +1 -0
  29. package/dist/index.d.ts +6 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +36 -5
  32. package/dist/index.js.map +1 -1
  33. package/dist/knowledge-inspector.d.ts.map +1 -1
  34. package/dist/knowledge-inspector.js +16 -9
  35. package/dist/knowledge-inspector.js.map +1 -1
  36. package/dist/knowledge-scope.d.ts +35 -0
  37. package/dist/knowledge-scope.d.ts.map +1 -0
  38. package/dist/knowledge-scope.js +47 -0
  39. package/dist/knowledge-scope.js.map +1 -0
  40. package/dist/providers/amazon-bedrock-gateway.d.ts.map +1 -1
  41. package/dist/providers/amazon-bedrock-gateway.js +1 -0
  42. package/dist/providers/amazon-bedrock-gateway.js.map +1 -1
  43. package/dist/providers/amazon-bedrock.d.ts.map +1 -1
  44. package/dist/providers/amazon-bedrock.js +20 -1
  45. package/dist/providers/amazon-bedrock.js.map +1 -1
  46. package/dist/tools/workflows/save-workflow.d.ts +36 -0
  47. package/dist/tools/workflows/save-workflow.d.ts.map +1 -1
  48. package/dist/utils/slash-command-processor.d.ts.map +1 -1
  49. package/dist/utils/slash-command-processor.js +7 -3
  50. package/dist/utils/slash-command-processor.js.map +1 -1
  51. package/package.json +11 -11
@@ -1 +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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"}
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 { 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 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.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 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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"}
@@ -0,0 +1,35 @@
1
+ import type { MastraCodeState } from './schema.js';
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.
9
+ */
10
+ export declare const LOCAL_KNOWLEDGE_ORG_ID = "local";
11
+ export type KnowledgeScopeIdentity = {
12
+ resolved: true;
13
+ organizationId: string;
14
+ /** Set when the resource rung is anchored on something other than the session resource. */
15
+ knowledgeResourceId?: string;
16
+ } | {
17
+ resolved: false;
18
+ knowledgeResourceId?: string;
19
+ reason?: string;
20
+ };
21
+ /**
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.
26
+ *
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}.
33
+ */
34
+ export declare function resolveKnowledgeScopeIdentity(state: MastraCodeState | undefined): KnowledgeScopeIdentity;
35
+ //# sourceMappingURL=knowledge-scope.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,47 @@
1
+ //#region src/knowledge-scope.ts
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.
9
+ */
10
+ const LOCAL_KNOWLEDGE_ORG_ID = "local";
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.
16
+ *
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}.
23
+ */
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
+ };
39
+ return {
40
+ resolved: true,
41
+ organizationId: LOCAL_KNOWLEDGE_ORG_ID
42
+ };
43
+ }
44
+ //#endregion
45
+ export { LOCAL_KNOWLEDGE_ORG_ID, resolveKnowledgeScopeIdentity };
46
+
47
+ //# sourceMappingURL=knowledge-scope.js.map
@@ -0,0 +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 +1 @@
1
- {"version":3,"file":"amazon-bedrock-gateway.d.ts","sourceRoot":"","sources":["../../src/providers/amazon-bedrock-gateway.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIpH,KAAK,YAAY,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC;AACvE,KAAK,aAAa,GAAG,UAAU,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAazE,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAErE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAsC1E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CAclE;AAED,eAAO,MAAM,yBAAyB,mBAAmB,CAAC;AAE1D;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAuB3C;AA0BD;;;;;;;GAOG;AACH,qBAAa,oBAAqB,SAAQ,kBAAkB;IAC1D,QAAQ,CAAC,EAAE,oBAA6B;IACxC,QAAQ,CAAC,IAAI,oBAAoB;IAEjC,YAAY,IAAI,OAAO;IAIjB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAiB/D,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIxC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlD,WAAW,CAAC,QAAQ,EAAE,kBAAkB,GAAG,iBAAiB,GAAG,SAAS;IAUxE,oBAAoB,CAAC,IAAI,EAAE;QACzB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,SAAS,CAAC,EAAE,GAAG,CAAC;QAChB,kBAAkB,CAAC,EAAE,GAAG,CAAC;KAC1B,GAAG,oBAAoB;CAGzB;AAED,wBAAgB,0BAA0B,IAAI,oBAAoB,CAEjE"}
1
+ {"version":3,"file":"amazon-bedrock-gateway.d.ts","sourceRoot":"","sources":["../../src/providers/amazon-bedrock-gateway.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIpH,KAAK,YAAY,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC;AACvE,KAAK,aAAa,GAAG,UAAU,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAczE,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAErE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAsC1E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CAclE;AAED,eAAO,MAAM,yBAAyB,mBAAmB,CAAC;AAE1D;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAuB3C;AA0BD;;;;;;;GAOG;AACH,qBAAa,oBAAqB,SAAQ,kBAAkB;IAC1D,QAAQ,CAAC,EAAE,oBAA6B;IACxC,QAAQ,CAAC,IAAI,oBAAoB;IAEjC,YAAY,IAAI,OAAO;IAIjB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAiB/D,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIxC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlD,WAAW,CAAC,QAAQ,EAAE,kBAAkB,GAAG,iBAAiB,GAAG,SAAS;IAUxE,oBAAoB,CAAC,IAAI,EAAE;QACzB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,SAAS,CAAC,EAAE,GAAG,CAAC;QAChB,kBAAkB,CAAC,EAAE,GAAG,CAAC;KAC1B,GAAG,oBAAoB;CAGzB;AAED,wBAAgB,0BAA0B,IAAI,oBAAoB,CAEjE"}
@@ -12,6 +12,7 @@ const CACHEABLE_BEDROCK_MODEL_IDS = [
12
12
  "anthropic.claude-fable-5",
13
13
  "anthropic.claude-haiku-4-5-",
14
14
  "anthropic.claude-opus-4-",
15
+ "anthropic.claude-opus-5",
15
16
  "anthropic.claude-sonnet-4-",
16
17
  "anthropic.claude-sonnet-5"
17
18
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"amazon-bedrock-gateway.js","names":[],"sources":["../../src/providers/amazon-bedrock-gateway.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';\nimport { fromNodeProviderChain } from '@aws-sdk/credential-providers';\nimport { MastraModelGateway } from '@mastra/core/llm';\nimport type { GatewayAuthRequest, GatewayAuthResult, GatewayLanguageModel, ProviderConfig } from '@mastra/core/llm';\nimport { getBedrockModelCatalog } from './amazon-bedrock.js';\n\ntype ModelRequestHeaders = Record<string, string>;\ntype BedrockModel = ReturnType<ReturnType<typeof createAmazonBedrock>>;\ntype BedrockPrompt = Parameters<BedrockModel['doGenerate']>[0]['prompt'];\n\nconst CACHEABLE_BEDROCK_MODEL_IDS = [\n 'anthropic.claude-3-5-haiku-',\n 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n 'anthropic.claude-3-7-sonnet-',\n 'anthropic.claude-fable-5',\n 'anthropic.claude-haiku-4-5-',\n 'anthropic.claude-opus-4-',\n 'anthropic.claude-sonnet-4-',\n 'anthropic.claude-sonnet-5',\n];\n\nexport function supportsBedrockPromptCaching(modelId: string): boolean {\n return CACHEABLE_BEDROCK_MODEL_IDS.some(cacheableModelId => modelId.includes(cacheableModelId));\n}\n\nexport function addBedrockCachePoints(prompt: BedrockPrompt): BedrockPrompt {\n const result = [...prompt];\n const markCachePoint = (message: (typeof result)[number]) => ({\n ...message,\n providerOptions: {\n ...message.providerOptions,\n bedrock: {\n ...message.providerOptions?.bedrock,\n cachePoint: { type: 'default' },\n },\n },\n });\n\n let lastSystemIndex = -1;\n for (let index = result.length - 1; index >= 0; index--) {\n if (result[index]!.role === 'system') {\n lastSystemIndex = index;\n break;\n }\n }\n\n if (lastSystemIndex >= 0) {\n result[lastSystemIndex] = markCachePoint(result[lastSystemIndex]!);\n }\n\n let lastNonSystemIndex = -1;\n for (let index = result.length - 1; index >= 0; index--) {\n if (result[index]!.role !== 'system') {\n lastNonSystemIndex = index;\n break;\n }\n }\n\n if (lastNonSystemIndex >= 0) {\n result[lastNonSystemIndex] = markCachePoint(result[lastNonSystemIndex]!);\n }\n\n return result;\n}\n\nexport function withBedrockCache(model: BedrockModel): BedrockModel {\n return new Proxy(model, {\n get(target, property, receiver) {\n if (property === 'doGenerate') {\n return (options: Parameters<BedrockModel['doGenerate']>[0]) =>\n target.doGenerate({ ...options, prompt: addBedrockCachePoints(options.prompt) });\n }\n if (property === 'doStream') {\n return (options: Parameters<BedrockModel['doStream']>[0]) =>\n target.doStream({ ...options, prompt: addBedrockCachePoints(options.prompt) });\n }\n return Reflect.get(target, property, receiver);\n },\n });\n}\n\nexport const AMAZON_BEDROCK_GATEWAY_ID = 'amazon-bedrock';\n\n/**\n * Whether AWS credentials look available for Bedrock.\n *\n * Amazon Bedrock authenticates with AWS SigV4 rather than a bearer API key, so\n * this only governs whether Bedrock models are offered as \"authenticated\" in the\n * picker. We look for the common signals (env vars, bearer token, a configured\n * profile, or a shared credentials/config file) rather than resolving\n * credentials here, since the auth checker must stay sync.\n */\nexport function hasAwsCredentials(): boolean {\n if (\n process.env.AWS_BEARER_TOKEN_BEDROCK ||\n (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ||\n process.env.AWS_SHARED_CREDENTIALS_FILE ||\n process.env.AWS_CONFIG_FILE ||\n process.env.AWS_PROFILE ||\n process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI ||\n process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI ||\n process.env.AWS_WEB_IDENTITY_TOKEN_FILE\n ) {\n return true;\n }\n const home = process.env.HOME || process.env.USERPROFILE;\n if (home) {\n const awsDir = path.join(home, '.aws');\n const credentialsPath = process.env.AWS_SHARED_CREDENTIALS_FILE ?? path.join(awsDir, 'credentials');\n const configPath = process.env.AWS_CONFIG_FILE ?? path.join(awsDir, 'config');\n if (existsSync(credentialsPath) || existsSync(configPath)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Create an Amazon Bedrock model.\n *\n * Bedrock authenticates with AWS SigV4 rather than a bearer API key, so this\n * resolves credentials through the standard AWS provider chain\n * (`fromNodeProviderChain`): environment variables, shared `~/.aws` config and\n * SSO profiles, and container/instance roles — the same resolution order the AWS\n * CLI uses. The region falls back to `us-east-1` to match the AWS SDK default.\n *\n * When `AWS_BEARER_TOKEN_BEDROCK` is set, `@ai-sdk/amazon-bedrock` uses bearer\n * auth instead and ignores the credential provider, so we leave that path to the\n * SDK and only wire up SigV4 here.\n */\nfunction bedrockProvider(modelId: string, headers?: ModelRequestHeaders) {\n const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'us-east-1';\n const bedrock = createAmazonBedrock({\n region,\n credentialProvider: fromNodeProviderChain(),\n headers,\n });\n const model = bedrock(modelId);\n return supportsBedrockPromptCaching(modelId) ? withBedrockCache(model) : model;\n}\n\n/**\n * Standalone Amazon Bedrock gateway.\n *\n * Bedrock is resolved directly via AWS SigV4 (not through the model router) and\n * its models are surfaced from the public models.dev catalog. It is exposed as\n * its own gateway/provider (`amazon-bedrock/...`) rather than nested under the\n * MastraCode gateway namespace.\n */\nexport class AmazonBedrockGateway extends MastraModelGateway {\n readonly id = AMAZON_BEDROCK_GATEWAY_ID;\n readonly name = 'Amazon Bedrock';\n\n shouldEnable(): boolean {\n return hasAwsCredentials();\n }\n\n async fetchProviders(): Promise<Record<string, ProviderConfig>> {\n const providers: Record<string, ProviderConfig> = {};\n try {\n const bedrockModels = await getBedrockModelCatalog();\n providers['amazon-bedrock'] = {\n name: 'Amazon Bedrock',\n apiKeyEnvVar: '',\n apiKeyHeader: 'Authorization',\n gateway: this.id,\n models: bedrockModels.map(model => model.id),\n };\n } catch (error) {\n console.warn('Failed to load Amazon Bedrock model catalog:', error);\n }\n return providers;\n }\n\n buildUrl(_modelId: string): string | undefined {\n return undefined;\n }\n\n async getApiKey(_modelId: string): Promise<string> {\n return hasAwsCredentials() ? 'aws-credential-chain' : '';\n }\n\n resolveAuth(_request: GatewayAuthRequest): GatewayAuthResult | undefined {\n // Amazon Bedrock authenticates via the AWS credential chain rather than a\n // stored API key, so report it as authenticated whenever AWS credentials look\n // available. The actual SigV4 signing happens inside `bedrockProvider()`.\n if (hasAwsCredentials()) {\n return { apiKey: 'aws-credential-chain', source: 'gateway' };\n }\n return undefined;\n }\n\n resolveLanguageModel(args: {\n modelId: string;\n providerId: string;\n apiKey: string;\n headers?: Record<string, string>;\n transport?: any;\n responsesWebSocket?: any;\n }): GatewayLanguageModel {\n return bedrockProvider(args.modelId, args.headers) as unknown as GatewayLanguageModel;\n }\n}\n\nexport function createAmazonBedrockGateway(): AmazonBedrockGateway {\n return new AmazonBedrockGateway();\n}\n"],"mappings":";;;;;;;AAYA,MAAM,8BAA8B;CAClC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,6BAA6B,SAA0B;CACrE,OAAO,4BAA4B,MAAK,qBAAoB,QAAQ,SAAS,gBAAgB,CAAC;AAChG;AAEA,SAAgB,sBAAsB,QAAsC;CAC1E,MAAM,SAAS,CAAC,GAAG,MAAM;CACzB,MAAM,kBAAkB,aAAsC;EAC5D,GAAG;EACH,iBAAiB;GACf,GAAG,QAAQ;GACX,SAAS;IACP,GAAG,QAAQ,iBAAiB;IAC5B,YAAY,EAAE,MAAM,UAAU;GAChC;EACF;CACF;CAEA,IAAI,kBAAkB;CACtB,KAAK,IAAI,QAAQ,OAAO,SAAS,GAAG,SAAS,GAAG,SAC9C,IAAI,OAAO,MAAM,CAAE,SAAS,UAAU;EACpC,kBAAkB;EAClB;CACF;CAGF,IAAI,mBAAmB,GACrB,OAAO,mBAAmB,eAAe,OAAO,gBAAiB;CAGnE,IAAI,qBAAqB;CACzB,KAAK,IAAI,QAAQ,OAAO,SAAS,GAAG,SAAS,GAAG,SAC9C,IAAI,OAAO,MAAM,CAAE,SAAS,UAAU;EACpC,qBAAqB;EACrB;CACF;CAGF,IAAI,sBAAsB,GACxB,OAAO,sBAAsB,eAAe,OAAO,mBAAoB;CAGzE,OAAO;AACT;AAEA,SAAgB,iBAAiB,OAAmC;CAClE,OAAO,IAAI,MAAM,OAAO,EACtB,IAAI,QAAQ,UAAU,UAAU;EAC9B,IAAI,aAAa,cACf,QAAQ,YACN,OAAO,WAAW;GAAE,GAAG;GAAS,QAAQ,sBAAsB,QAAQ,MAAM;EAAE,CAAC;EAEnF,IAAI,aAAa,YACf,QAAQ,YACN,OAAO,SAAS;GAAE,GAAG;GAAS,QAAQ,sBAAsB,QAAQ,MAAM;EAAE,CAAC;EAEjF,OAAO,QAAQ,IAAI,QAAQ,UAAU,QAAQ;CAC/C,EACF,CAAC;AACH;AAEA,MAAa,4BAA4B;;;;;;;;;;AAWzC,SAAgB,oBAA6B;CAC3C,IACE,QAAQ,IAAI,4BACX,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,yBAC9C,QAAQ,IAAI,+BACZ,QAAQ,IAAI,mBACZ,QAAQ,IAAI,eACZ,QAAQ,IAAI,0CACZ,QAAQ,IAAI,sCACZ,QAAQ,IAAI,6BAEZ,OAAO;CAET,MAAM,OAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI;CAC7C,IAAI,MAAM;EACR,MAAM,SAAS,KAAK,KAAK,MAAM,MAAM;EACrC,MAAM,kBAAkB,QAAQ,IAAI,+BAA+B,KAAK,KAAK,QAAQ,aAAa;EAClG,MAAM,aAAa,QAAQ,IAAI,mBAAmB,KAAK,KAAK,QAAQ,QAAQ;EAC5E,IAAI,WAAW,eAAe,KAAK,WAAW,UAAU,GACtD,OAAO;CAEX;CACA,OAAO;AACT;;;;;;;;;;;;;;AAeA,SAAS,gBAAgB,SAAiB,SAA+B;CAOvE,MAAM,QALU,oBAAoB;EAClC,QAFa,QAAQ,IAAI,cAAc,QAAQ,IAAI,sBAAsB;EAGzE,oBAAoB,sBAAsB;EAC1C;CACF,CACoB,CAAC,CAAC,OAAO;CAC7B,OAAO,6BAA6B,OAAO,IAAI,iBAAiB,KAAK,IAAI;AAC3E;;;;;;;;;AAUA,IAAa,uBAAb,cAA0C,mBAAmB;CAC3D,KAAc;CACd,OAAgB;CAEhB,eAAwB;EACtB,OAAO,kBAAkB;CAC3B;CAEA,MAAM,iBAA0D;EAC9D,MAAM,YAA4C,CAAC;EACnD,IAAI;GACF,MAAM,gBAAgB,MAAM,uBAAuB;GACnD,UAAU,oBAAoB;IAC5B,MAAM;IACN,cAAc;IACd,cAAc;IACd,SAAS,KAAK;IACd,QAAQ,cAAc,KAAI,UAAS,MAAM,EAAE;GAC7C;EACF,SAAS,OAAO;GACd,QAAQ,KAAK,gDAAgD,KAAK;EACpE;EACA,OAAO;CACT;CAEA,SAAS,UAAsC,CAE/C;CAEA,MAAM,UAAU,UAAmC;EACjD,OAAO,kBAAkB,IAAI,yBAAyB;CACxD;CAEA,YAAY,UAA6D;EAIvE,IAAI,kBAAkB,GACpB,OAAO;GAAE,QAAQ;GAAwB,QAAQ;EAAU;CAG/D;CAEA,qBAAqB,MAOI;EACvB,OAAO,gBAAgB,KAAK,SAAS,KAAK,OAAO;CACnD;AACF;AAEA,SAAgB,6BAAmD;CACjE,OAAO,IAAI,qBAAqB;AAClC"}
1
+ {"version":3,"file":"amazon-bedrock-gateway.js","names":[],"sources":["../../src/providers/amazon-bedrock-gateway.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';\nimport { fromNodeProviderChain } from '@aws-sdk/credential-providers';\nimport { MastraModelGateway } from '@mastra/core/llm';\nimport type { GatewayAuthRequest, GatewayAuthResult, GatewayLanguageModel, ProviderConfig } from '@mastra/core/llm';\nimport { getBedrockModelCatalog } from './amazon-bedrock.js';\n\ntype ModelRequestHeaders = Record<string, string>;\ntype BedrockModel = ReturnType<ReturnType<typeof createAmazonBedrock>>;\ntype BedrockPrompt = Parameters<BedrockModel['doGenerate']>[0]['prompt'];\n\nconst CACHEABLE_BEDROCK_MODEL_IDS = [\n 'anthropic.claude-3-5-haiku-',\n 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n 'anthropic.claude-3-7-sonnet-',\n 'anthropic.claude-fable-5',\n 'anthropic.claude-haiku-4-5-',\n 'anthropic.claude-opus-4-',\n 'anthropic.claude-opus-5',\n 'anthropic.claude-sonnet-4-',\n 'anthropic.claude-sonnet-5',\n];\n\nexport function supportsBedrockPromptCaching(modelId: string): boolean {\n return CACHEABLE_BEDROCK_MODEL_IDS.some(cacheableModelId => modelId.includes(cacheableModelId));\n}\n\nexport function addBedrockCachePoints(prompt: BedrockPrompt): BedrockPrompt {\n const result = [...prompt];\n const markCachePoint = (message: (typeof result)[number]) => ({\n ...message,\n providerOptions: {\n ...message.providerOptions,\n bedrock: {\n ...message.providerOptions?.bedrock,\n cachePoint: { type: 'default' },\n },\n },\n });\n\n let lastSystemIndex = -1;\n for (let index = result.length - 1; index >= 0; index--) {\n if (result[index]!.role === 'system') {\n lastSystemIndex = index;\n break;\n }\n }\n\n if (lastSystemIndex >= 0) {\n result[lastSystemIndex] = markCachePoint(result[lastSystemIndex]!);\n }\n\n let lastNonSystemIndex = -1;\n for (let index = result.length - 1; index >= 0; index--) {\n if (result[index]!.role !== 'system') {\n lastNonSystemIndex = index;\n break;\n }\n }\n\n if (lastNonSystemIndex >= 0) {\n result[lastNonSystemIndex] = markCachePoint(result[lastNonSystemIndex]!);\n }\n\n return result;\n}\n\nexport function withBedrockCache(model: BedrockModel): BedrockModel {\n return new Proxy(model, {\n get(target, property, receiver) {\n if (property === 'doGenerate') {\n return (options: Parameters<BedrockModel['doGenerate']>[0]) =>\n target.doGenerate({ ...options, prompt: addBedrockCachePoints(options.prompt) });\n }\n if (property === 'doStream') {\n return (options: Parameters<BedrockModel['doStream']>[0]) =>\n target.doStream({ ...options, prompt: addBedrockCachePoints(options.prompt) });\n }\n return Reflect.get(target, property, receiver);\n },\n });\n}\n\nexport const AMAZON_BEDROCK_GATEWAY_ID = 'amazon-bedrock';\n\n/**\n * Whether AWS credentials look available for Bedrock.\n *\n * Amazon Bedrock authenticates with AWS SigV4 rather than a bearer API key, so\n * this only governs whether Bedrock models are offered as \"authenticated\" in the\n * picker. We look for the common signals (env vars, bearer token, a configured\n * profile, or a shared credentials/config file) rather than resolving\n * credentials here, since the auth checker must stay sync.\n */\nexport function hasAwsCredentials(): boolean {\n if (\n process.env.AWS_BEARER_TOKEN_BEDROCK ||\n (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ||\n process.env.AWS_SHARED_CREDENTIALS_FILE ||\n process.env.AWS_CONFIG_FILE ||\n process.env.AWS_PROFILE ||\n process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI ||\n process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI ||\n process.env.AWS_WEB_IDENTITY_TOKEN_FILE\n ) {\n return true;\n }\n const home = process.env.HOME || process.env.USERPROFILE;\n if (home) {\n const awsDir = path.join(home, '.aws');\n const credentialsPath = process.env.AWS_SHARED_CREDENTIALS_FILE ?? path.join(awsDir, 'credentials');\n const configPath = process.env.AWS_CONFIG_FILE ?? path.join(awsDir, 'config');\n if (existsSync(credentialsPath) || existsSync(configPath)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Create an Amazon Bedrock model.\n *\n * Bedrock authenticates with AWS SigV4 rather than a bearer API key, so this\n * resolves credentials through the standard AWS provider chain\n * (`fromNodeProviderChain`): environment variables, shared `~/.aws` config and\n * SSO profiles, and container/instance roles — the same resolution order the AWS\n * CLI uses. The region falls back to `us-east-1` to match the AWS SDK default.\n *\n * When `AWS_BEARER_TOKEN_BEDROCK` is set, `@ai-sdk/amazon-bedrock` uses bearer\n * auth instead and ignores the credential provider, so we leave that path to the\n * SDK and only wire up SigV4 here.\n */\nfunction bedrockProvider(modelId: string, headers?: ModelRequestHeaders) {\n const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'us-east-1';\n const bedrock = createAmazonBedrock({\n region,\n credentialProvider: fromNodeProviderChain(),\n headers,\n });\n const model = bedrock(modelId);\n return supportsBedrockPromptCaching(modelId) ? withBedrockCache(model) : model;\n}\n\n/**\n * Standalone Amazon Bedrock gateway.\n *\n * Bedrock is resolved directly via AWS SigV4 (not through the model router) and\n * its models are surfaced from the public models.dev catalog. It is exposed as\n * its own gateway/provider (`amazon-bedrock/...`) rather than nested under the\n * MastraCode gateway namespace.\n */\nexport class AmazonBedrockGateway extends MastraModelGateway {\n readonly id = AMAZON_BEDROCK_GATEWAY_ID;\n readonly name = 'Amazon Bedrock';\n\n shouldEnable(): boolean {\n return hasAwsCredentials();\n }\n\n async fetchProviders(): Promise<Record<string, ProviderConfig>> {\n const providers: Record<string, ProviderConfig> = {};\n try {\n const bedrockModels = await getBedrockModelCatalog();\n providers['amazon-bedrock'] = {\n name: 'Amazon Bedrock',\n apiKeyEnvVar: '',\n apiKeyHeader: 'Authorization',\n gateway: this.id,\n models: bedrockModels.map(model => model.id),\n };\n } catch (error) {\n console.warn('Failed to load Amazon Bedrock model catalog:', error);\n }\n return providers;\n }\n\n buildUrl(_modelId: string): string | undefined {\n return undefined;\n }\n\n async getApiKey(_modelId: string): Promise<string> {\n return hasAwsCredentials() ? 'aws-credential-chain' : '';\n }\n\n resolveAuth(_request: GatewayAuthRequest): GatewayAuthResult | undefined {\n // Amazon Bedrock authenticates via the AWS credential chain rather than a\n // stored API key, so report it as authenticated whenever AWS credentials look\n // available. The actual SigV4 signing happens inside `bedrockProvider()`.\n if (hasAwsCredentials()) {\n return { apiKey: 'aws-credential-chain', source: 'gateway' };\n }\n return undefined;\n }\n\n resolveLanguageModel(args: {\n modelId: string;\n providerId: string;\n apiKey: string;\n headers?: Record<string, string>;\n transport?: any;\n responsesWebSocket?: any;\n }): GatewayLanguageModel {\n return bedrockProvider(args.modelId, args.headers) as unknown as GatewayLanguageModel;\n }\n}\n\nexport function createAmazonBedrockGateway(): AmazonBedrockGateway {\n return new AmazonBedrockGateway();\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"amazon-bedrock.d.ts","sourceRoot":"","sources":["../../src/providers/amazon-bedrock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;CACZ;AAsBD,8DAA8D;AAC9D,wBAAgB,wBAAwB,IAAI,IAAI,CAG/C;AAeD;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAiC3E"}
1
+ {"version":3,"file":"amazon-bedrock.d.ts","sourceRoot":"","sources":["../../src/providers/amazon-bedrock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;CACZ;AAyDD,8DAA8D;AAC9D,wBAAgB,wBAAwB,IAAI,IAAI,CAG/C;AAiBD;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAiC3E"}
@@ -15,6 +15,25 @@ const CATALOG_TTL_MS = 3600 * 1e3;
15
15
  const CATALOG_FAILURE_TTL_MS = 60 * 1e3;
16
16
  const CATALOG_FETCH_TIMEOUT_MS = 5e3;
17
17
  /**
18
+ * True when the catalog entry asks for a transport this catalog cannot serve.
19
+ *
20
+ * Every id returned here is handed to `createAmazonBedrock()(modelId)` by
21
+ * `amazon-bedrock-gateway.ts`, i.e. the Converse API, unconditionally. A
22
+ * `provider` override in the catalog means the model wants a different endpoint
23
+ * and API shape: the nine `bedrock-mantle` models point at
24
+ * `https://bedrock-mantle.${AWS_REGION}.api.aws/openai/v1` with
25
+ * `shape: "responses"`. Advertising them makes them selectable in `/models` and
26
+ * in packs even though the request that follows cannot reach them.
27
+ *
28
+ * Filtering is deliberately conservative: it hides what is currently unusable
29
+ * rather than guessing at a transport. Routing these to Mantle properly is a
30
+ * separate change and a design call for the maintainers.
31
+ */
32
+ function needsUnsupportedTransport(entry) {
33
+ const provider = entry?.provider;
34
+ return Boolean(provider && (provider.npm || provider.api || provider.shape));
35
+ }
36
+ /**
18
37
  * A small, stable fallback so Bedrock packs keep working offline or when
19
38
  * models.dev is unreachable. Intentionally minimal — the live catalog is the
20
39
  * source of truth and supersedes this within one fetch.
@@ -35,7 +54,7 @@ async function fetchBedrockModels(signal) {
35
54
  const response = await fetch(MODELS_DEV_API_URL, { signal });
36
55
  if (!response.ok) throw new Error(`models.dev returned ${response.status}`);
37
56
  const models = (await response.json())[BEDROCK_PROVIDER_ID]?.models ?? {};
38
- return Object.keys(models).sort().map((id) => ({ id }));
57
+ return Object.entries(models).filter(([, entry]) => !needsUnsupportedTransport(entry)).map(([id]) => id).sort().map((id) => ({ id }));
39
58
  }
40
59
  /**
41
60
  * Return the available Amazon Bedrock models.
@@ -1 +1 @@
1
- {"version":3,"file":"amazon-bedrock.js","names":[],"sources":["../../src/providers/amazon-bedrock.ts"],"sourcesContent":["/**\n * Amazon Bedrock model catalog.\n *\n * Bedrock is not part of mastracode's gateway-synced model router (it\n * authenticates with AWS SigV4 rather than an API key / base URL, so it is\n * resolved directly in `agents/model.ts`). To still offer Bedrock models in the\n * `/models` picker and packs, we fetch the public models.dev catalog — the same\n * source the model router uses — and expose the `amazon-bedrock` provider's\n * model list. This mirrors the GitHub Copilot catalog approach.\n */\n\nconst MODELS_DEV_API_URL = 'https://models.dev/api.json';\nconst BEDROCK_PROVIDER_ID = 'amazon-bedrock';\n\nconst CATALOG_TTL_MS = 60 * 60 * 1000;\nconst CATALOG_FAILURE_TTL_MS = 60 * 1000;\nconst CATALOG_FETCH_TIMEOUT_MS = 5_000;\n\nexport interface BedrockModelEntry {\n id: string;\n}\n\n/**\n * A small, stable fallback so Bedrock packs keep working offline or when\n * models.dev is unreachable. Intentionally minimal — the live catalog is the\n * source of truth and supersedes this within one fetch.\n */\nconst BEDROCK_FALLBACK_MODELS: BedrockModelEntry[] = [\n { id: 'us.anthropic.claude-opus-4-6-v1' },\n { id: 'us.anthropic.claude-sonnet-4-5-20250929-v1:0' },\n { id: 'us.anthropic.claude-haiku-4-5-20251001-v1:0' },\n];\n\ninterface CatalogCacheEntry {\n fetchedAt: number;\n ttl: number;\n models: BedrockModelEntry[];\n}\n\nlet catalogCache: CatalogCacheEntry | null = null;\nlet inflightFetch: Promise<BedrockModelEntry[]> | null = null;\n\n/** Reset the in-process Bedrock catalog cache (test seam). */\nexport function clearBedrockCatalogCache(): void {\n catalogCache = null;\n inflightFetch = null;\n}\n\nasync function fetchBedrockModels(signal: AbortSignal): Promise<BedrockModelEntry[]> {\n const response = await fetch(MODELS_DEV_API_URL, { signal });\n if (!response.ok) {\n throw new Error(`models.dev returned ${response.status}`);\n }\n const data = (await response.json()) as Record<string, { models?: Record<string, unknown> }>;\n const provider = data[BEDROCK_PROVIDER_ID];\n const models = provider?.models ?? {};\n return Object.keys(models)\n .sort()\n .map(id => ({ id }));\n}\n\n/**\n * Return the available Amazon Bedrock models.\n *\n * - Returns the cached list when a recent fetch succeeded.\n * - On cache miss / expiry, fetches the models.dev catalog with a 5s timeout and\n * caches it for an hour.\n * - On fetch failure, returns a small hard-coded fallback (so packs still work\n * offline) and caches that briefly to avoid hammering the network.\n *\n * Concurrent calls during a fetch share the inflight promise.\n */\nexport async function getBedrockModelCatalog(): Promise<BedrockModelEntry[]> {\n const now = Date.now();\n if (catalogCache && now - catalogCache.fetchedAt < catalogCache.ttl) {\n return catalogCache.models;\n }\n\n if (inflightFetch) return inflightFetch;\n\n inflightFetch = (async (): Promise<BedrockModelEntry[]> => {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), CATALOG_FETCH_TIMEOUT_MS);\n try {\n const models = await fetchBedrockModels(controller.signal);\n catalogCache = { fetchedAt: Date.now(), ttl: CATALOG_TTL_MS, models };\n return models;\n } catch (error) {\n catalogCache = {\n fetchedAt: Date.now(),\n ttl: CATALOG_FAILURE_TTL_MS,\n models: BEDROCK_FALLBACK_MODELS,\n };\n console.warn(\n 'Failed to fetch live Amazon Bedrock models, using fallback list:',\n error instanceof Error ? error.message : error,\n );\n return BEDROCK_FALLBACK_MODELS;\n } finally {\n clearTimeout(timer);\n inflightFetch = null;\n }\n })();\n\n return inflightFetch;\n}\n"],"mappings":";;;;;;;;;;;AAWA,MAAM,qBAAqB;AAC3B,MAAM,sBAAsB;AAE5B,MAAM,iBAAiB,OAAU;AACjC,MAAM,yBAAyB,KAAK;AACpC,MAAM,2BAA2B;;;;;;AAWjC,MAAM,0BAA+C;CACnD,EAAE,IAAI,kCAAkC;CACxC,EAAE,IAAI,+CAA+C;CACrD,EAAE,IAAI,8CAA8C;AACtD;AAQA,IAAI,eAAyC;AAC7C,IAAI,gBAAqD;;AAGzD,SAAgB,2BAAiC;CAC/C,eAAe;CACf,gBAAgB;AAClB;AAEA,eAAe,mBAAmB,QAAmD;CACnF,MAAM,WAAW,MAAM,MAAM,oBAAoB,EAAE,OAAO,CAAC;CAC3D,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,uBAAuB,SAAS,QAAQ;CAI1D,MAAM,UADW,MADG,SAAS,KAAK,EAAA,CACZ,oBACC,EAAE,UAAU,CAAC;CACpC,OAAO,OAAO,KAAK,MAAM,CAAC,CACvB,KAAK,CAAC,CACN,KAAI,QAAO,EAAE,GAAG,EAAE;AACvB;;;;;;;;;;;;AAaA,eAAsB,yBAAuD;CAE3E,IAAI,gBADQ,KAAK,IACK,IAAI,aAAa,YAAY,aAAa,KAC9D,OAAO,aAAa;CAGtB,IAAI,eAAe,OAAO;CAE1B,iBAAiB,YAA0C;EACzD,MAAM,aAAa,IAAI,gBAAgB;EACvC,MAAM,QAAQ,iBAAiB,WAAW,MAAM,GAAG,wBAAwB;EAC3E,IAAI;GACF,MAAM,SAAS,MAAM,mBAAmB,WAAW,MAAM;GACzD,eAAe;IAAE,WAAW,KAAK,IAAI;IAAG,KAAK;IAAgB;GAAO;GACpE,OAAO;EACT,SAAS,OAAO;GACd,eAAe;IACb,WAAW,KAAK,IAAI;IACpB,KAAK;IACL,QAAQ;GACV;GACA,QAAQ,KACN,oEACA,iBAAiB,QAAQ,MAAM,UAAU,KAC3C;GACA,OAAO;EACT,UAAU;GACR,aAAa,KAAK;GAClB,gBAAgB;EAClB;CACF,EAAA,CAAG;CAEH,OAAO;AACT"}
1
+ {"version":3,"file":"amazon-bedrock.js","names":[],"sources":["../../src/providers/amazon-bedrock.ts"],"sourcesContent":["/**\n * Amazon Bedrock model catalog.\n *\n * Bedrock is not part of mastracode's gateway-synced model router (it\n * authenticates with AWS SigV4 rather than an API key / base URL, so it is\n * resolved directly in `agents/model.ts`). To still offer Bedrock models in the\n * `/models` picker and packs, we fetch the public models.dev catalog — the same\n * source the model router uses — and expose the `amazon-bedrock` provider's\n * model list. This mirrors the GitHub Copilot catalog approach.\n */\n\nconst MODELS_DEV_API_URL = 'https://models.dev/api.json';\nconst BEDROCK_PROVIDER_ID = 'amazon-bedrock';\n\nconst CATALOG_TTL_MS = 60 * 60 * 1000;\nconst CATALOG_FAILURE_TTL_MS = 60 * 1000;\nconst CATALOG_FETCH_TIMEOUT_MS = 5_000;\n\nexport interface BedrockModelEntry {\n id: string;\n}\n\n/**\n * A models.dev catalog entry for one Bedrock model.\n *\n * Most entries carry no `provider` block: they are served by the SigV4\n * `bedrock-runtime` Converse API, which is what this catalog feeds. An entry\n * that *does* carry one is overriding that transport.\n */\ninterface BedrockCatalogEntry {\n provider?: {\n npm?: string;\n api?: string;\n shape?: string;\n };\n}\n\n/**\n * True when the catalog entry asks for a transport this catalog cannot serve.\n *\n * Every id returned here is handed to `createAmazonBedrock()(modelId)` by\n * `amazon-bedrock-gateway.ts`, i.e. the Converse API, unconditionally. A\n * `provider` override in the catalog means the model wants a different endpoint\n * and API shape: the nine `bedrock-mantle` models point at\n * `https://bedrock-mantle.${AWS_REGION}.api.aws/openai/v1` with\n * `shape: \"responses\"`. Advertising them makes them selectable in `/models` and\n * in packs even though the request that follows cannot reach them.\n *\n * Filtering is deliberately conservative: it hides what is currently unusable\n * rather than guessing at a transport. Routing these to Mantle properly is a\n * separate change and a design call for the maintainers.\n */\nfunction needsUnsupportedTransport(entry: unknown): boolean {\n const provider = (entry as BedrockCatalogEntry | null)?.provider;\n return Boolean(provider && (provider.npm || provider.api || provider.shape));\n}\n\n/**\n * A small, stable fallback so Bedrock packs keep working offline or when\n * models.dev is unreachable. Intentionally minimal — the live catalog is the\n * source of truth and supersedes this within one fetch.\n */\nconst BEDROCK_FALLBACK_MODELS: BedrockModelEntry[] = [\n { id: 'us.anthropic.claude-opus-4-6-v1' },\n { id: 'us.anthropic.claude-sonnet-4-5-20250929-v1:0' },\n { id: 'us.anthropic.claude-haiku-4-5-20251001-v1:0' },\n];\n\ninterface CatalogCacheEntry {\n fetchedAt: number;\n ttl: number;\n models: BedrockModelEntry[];\n}\n\nlet catalogCache: CatalogCacheEntry | null = null;\nlet inflightFetch: Promise<BedrockModelEntry[]> | null = null;\n\n/** Reset the in-process Bedrock catalog cache (test seam). */\nexport function clearBedrockCatalogCache(): void {\n catalogCache = null;\n inflightFetch = null;\n}\n\nasync function fetchBedrockModels(signal: AbortSignal): Promise<BedrockModelEntry[]> {\n const response = await fetch(MODELS_DEV_API_URL, { signal });\n if (!response.ok) {\n throw new Error(`models.dev returned ${response.status}`);\n }\n const data = (await response.json()) as Record<string, { models?: Record<string, unknown> }>;\n const provider = data[BEDROCK_PROVIDER_ID];\n const models = provider?.models ?? {};\n return Object.entries(models)\n .filter(([, entry]) => !needsUnsupportedTransport(entry))\n .map(([id]) => id)\n .sort()\n .map(id => ({ id }));\n}\n\n/**\n * Return the available Amazon Bedrock models.\n *\n * - Returns the cached list when a recent fetch succeeded.\n * - On cache miss / expiry, fetches the models.dev catalog with a 5s timeout and\n * caches it for an hour.\n * - On fetch failure, returns a small hard-coded fallback (so packs still work\n * offline) and caches that briefly to avoid hammering the network.\n *\n * Concurrent calls during a fetch share the inflight promise.\n */\nexport async function getBedrockModelCatalog(): Promise<BedrockModelEntry[]> {\n const now = Date.now();\n if (catalogCache && now - catalogCache.fetchedAt < catalogCache.ttl) {\n return catalogCache.models;\n }\n\n if (inflightFetch) return inflightFetch;\n\n inflightFetch = (async (): Promise<BedrockModelEntry[]> => {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), CATALOG_FETCH_TIMEOUT_MS);\n try {\n const models = await fetchBedrockModels(controller.signal);\n catalogCache = { fetchedAt: Date.now(), ttl: CATALOG_TTL_MS, models };\n return models;\n } catch (error) {\n catalogCache = {\n fetchedAt: Date.now(),\n ttl: CATALOG_FAILURE_TTL_MS,\n models: BEDROCK_FALLBACK_MODELS,\n };\n console.warn(\n 'Failed to fetch live Amazon Bedrock models, using fallback list:',\n error instanceof Error ? error.message : error,\n );\n return BEDROCK_FALLBACK_MODELS;\n } finally {\n clearTimeout(timer);\n inflightFetch = null;\n }\n })();\n\n return inflightFetch;\n}\n"],"mappings":";;;;;;;;;;;AAWA,MAAM,qBAAqB;AAC3B,MAAM,sBAAsB;AAE5B,MAAM,iBAAiB,OAAU;AACjC,MAAM,yBAAyB,KAAK;AACpC,MAAM,2BAA2B;;;;;;;;;;;;;;;;AAoCjC,SAAS,0BAA0B,OAAyB;CAC1D,MAAM,WAAY,OAAsC;CACxD,OAAO,QAAQ,aAAa,SAAS,OAAO,SAAS,OAAO,SAAS,MAAM;AAC7E;;;;;;AAOA,MAAM,0BAA+C;CACnD,EAAE,IAAI,kCAAkC;CACxC,EAAE,IAAI,+CAA+C;CACrD,EAAE,IAAI,8CAA8C;AACtD;AAQA,IAAI,eAAyC;AAC7C,IAAI,gBAAqD;;AAGzD,SAAgB,2BAAiC;CAC/C,eAAe;CACf,gBAAgB;AAClB;AAEA,eAAe,mBAAmB,QAAmD;CACnF,MAAM,WAAW,MAAM,MAAM,oBAAoB,EAAE,OAAO,CAAC;CAC3D,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,uBAAuB,SAAS,QAAQ;CAI1D,MAAM,UADW,MADG,SAAS,KAAK,EAAA,CACZ,oBACC,EAAE,UAAU,CAAC;CACpC,OAAO,OAAO,QAAQ,MAAM,CAAC,CAC1B,QAAQ,GAAG,WAAW,CAAC,0BAA0B,KAAK,CAAC,CAAC,CACxD,KAAK,CAAC,QAAQ,EAAE,CAAC,CACjB,KAAK,CAAC,CACN,KAAI,QAAO,EAAE,GAAG,EAAE;AACvB;;;;;;;;;;;;AAaA,eAAsB,yBAAuD;CAE3E,IAAI,gBADQ,KAAK,IACK,IAAI,aAAa,YAAY,aAAa,KAC9D,OAAO,aAAa;CAGtB,IAAI,eAAe,OAAO;CAE1B,iBAAiB,YAA0C;EACzD,MAAM,aAAa,IAAI,gBAAgB;EACvC,MAAM,QAAQ,iBAAiB,WAAW,MAAM,GAAG,wBAAwB;EAC3E,IAAI;GACF,MAAM,SAAS,MAAM,mBAAmB,WAAW,MAAM;GACzD,eAAe;IAAE,WAAW,KAAK,IAAI;IAAG,KAAK;IAAgB;GAAO;GACpE,OAAO;EACT,SAAS,OAAO;GACd,eAAe;IACb,WAAW,KAAK,IAAI;IACpB,KAAK;IACL,QAAQ;GACV;GACA,QAAQ,KACN,oEACA,iBAAiB,QAAQ,MAAM,UAAU,KAC3C;GACA,OAAO;EACT,UAAU;GACR,aAAa,KAAK;GAClB,gBAAgB;EAClB;CACF,EAAA,CAAG;CAEH,OAAO;AACT"}
@@ -28,6 +28,8 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
28
28
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
29
29
  }, z.core.$strip>>;
30
30
  }, z.core.$strict>, z.ZodObject<{
31
+ description: z.ZodOptional<z.ZodString>;
32
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
31
33
  type: z.ZodLiteral<"mapping">;
32
34
  id: z.ZodString;
33
35
  mapConfig: z.ZodString;
@@ -41,6 +43,9 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
41
43
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
42
44
  }, z.core.$strip>>;
43
45
  }, z.core.$strict>, z.ZodObject<{
46
+ description: z.ZodOptional<z.ZodString>;
47
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
48
+ id: z.ZodOptional<z.ZodString>;
44
49
  type: z.ZodLiteral<"parallel">;
45
50
  steps: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
46
51
  type: z.ZodLiteral<"agent">;
@@ -72,6 +77,9 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
72
77
  }, z.core.$strip>>;
73
78
  }, z.core.$strict>]>>;
74
79
  }, z.core.$strict>, z.ZodObject<{
80
+ description: z.ZodOptional<z.ZodString>;
81
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
82
+ id: z.ZodOptional<z.ZodString>;
75
83
  type: z.ZodLiteral<"foreach">;
76
84
  step: z.ZodUnion<readonly [z.ZodObject<{
77
85
  type: z.ZodLiteral<"agent">;
@@ -106,14 +114,21 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
106
114
  concurrency: z.ZodNumber;
107
115
  }, z.core.$strip>>;
108
116
  }, z.core.$strict>, z.ZodObject<{
117
+ description: z.ZodOptional<z.ZodString>;
118
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
109
119
  type: z.ZodLiteral<"sleep">;
110
120
  id: z.ZodString;
111
121
  duration: z.ZodNumber;
112
122
  }, z.core.$strict>, z.ZodObject<{
123
+ description: z.ZodOptional<z.ZodString>;
124
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
113
125
  type: z.ZodLiteral<"sleepUntil">;
114
126
  id: z.ZodString;
115
127
  date: z.ZodString;
116
128
  }, z.core.$strict>, z.ZodObject<{
129
+ description: z.ZodOptional<z.ZodString>;
130
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
131
+ id: z.ZodOptional<z.ZodString>;
117
132
  type: z.ZodLiteral<"conditional">;
118
133
  steps: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
119
134
  type: z.ZodLiteral<"agent">;
@@ -146,6 +161,9 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
146
161
  }, z.core.$strict>]>>;
147
162
  predicates: z.ZodArray<z.ZodType<import("@mastra/core/predicate").Predicate, unknown, z.core.$ZodTypeInternals<import("@mastra/core/predicate").Predicate, unknown>>>;
148
163
  }, z.core.$strict>, z.ZodObject<{
164
+ description: z.ZodOptional<z.ZodString>;
165
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
166
+ id: z.ZodOptional<z.ZodString>;
149
167
  type: z.ZodLiteral<"loop">;
150
168
  step: z.ZodUnion<readonly [z.ZodObject<{
151
169
  type: z.ZodLiteral<"agent">;
@@ -611,6 +629,8 @@ export declare const saveWorkflowTool: import("@mastra/core/tools").Tool<{
611
629
  type: "mapping";
612
630
  id: string;
613
631
  mapConfig: string;
632
+ description?: string | undefined;
633
+ metadata?: Record<string, unknown> | undefined;
614
634
  } | {
615
635
  type: "workflow";
616
636
  id: string;
@@ -651,6 +671,9 @@ export declare const saveWorkflowTool: import("@mastra/core/tools").Tool<{
651
671
  metadata?: Record<string, unknown> | undefined;
652
672
  } | undefined;
653
673
  })[];
674
+ description?: string | undefined;
675
+ metadata?: Record<string, unknown> | undefined;
676
+ id?: string | undefined;
654
677
  } | {
655
678
  type: "foreach";
656
679
  step: {
@@ -682,6 +705,9 @@ export declare const saveWorkflowTool: import("@mastra/core/tools").Tool<{
682
705
  metadata?: Record<string, unknown> | undefined;
683
706
  } | undefined;
684
707
  };
708
+ description?: string | undefined;
709
+ metadata?: Record<string, unknown> | undefined;
710
+ id?: string | undefined;
685
711
  opts?: {
686
712
  concurrency: number;
687
713
  } | undefined;
@@ -689,10 +715,14 @@ export declare const saveWorkflowTool: import("@mastra/core/tools").Tool<{
689
715
  type: "sleep";
690
716
  id: string;
691
717
  duration: number;
718
+ description?: string | undefined;
719
+ metadata?: Record<string, unknown> | undefined;
692
720
  } | {
693
721
  type: "sleepUntil";
694
722
  id: string;
695
723
  date: string;
724
+ description?: string | undefined;
725
+ metadata?: Record<string, unknown> | undefined;
696
726
  } | {
697
727
  type: "conditional";
698
728
  steps: ({
@@ -725,6 +755,9 @@ export declare const saveWorkflowTool: import("@mastra/core/tools").Tool<{
725
755
  } | undefined;
726
756
  })[];
727
757
  predicates: import("@mastra/core/predicate").Predicate[];
758
+ description?: string | undefined;
759
+ metadata?: Record<string, unknown> | undefined;
760
+ id?: string | undefined;
728
761
  } | {
729
762
  type: "loop";
730
763
  step: {
@@ -758,6 +791,9 @@ export declare const saveWorkflowTool: import("@mastra/core/tools").Tool<{
758
791
  };
759
792
  loopType: "dountil" | "dowhile";
760
793
  predicate: import("@mastra/core/predicate").Predicate;
794
+ description?: string | undefined;
795
+ metadata?: Record<string, unknown> | undefined;
796
+ id?: string | undefined;
761
797
  })[];
762
798
  description?: string | undefined;
763
799
  metadata?: Record<string, unknown> | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"save-workflow.d.ts","sourceRoot":"","sources":["../../../src/tools/workflows/save-workflow.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,2CAA2C,IAAI,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAE3H,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAGzC,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4HAsB3B,CAAC"}
1
+ {"version":3,"file":"save-workflow.d.ts","sourceRoot":"","sources":["../../../src/tools/workflows/save-workflow.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,2CAA2C,IAAI,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAE3H,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAGzC,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4HAsB3B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"slash-command-processor.d.ts","sourceRoot":"","sources":["../../src/utils/slash-command-processor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEtE;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAgBjB;AA0FD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAQ7E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAc9G"}
1
+ {"version":3,"file":"slash-command-processor.d.ts","sourceRoot":"","sources":["../../src/utils/slash-command-processor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEtE;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAkGD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAQ7E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAc9G"}
@@ -64,21 +64,25 @@ async function replaceShellOutput(template, workingDir) {
64
64
  }
65
65
  /**
66
66
  * Replace file references with file content
67
- * Format: @filename or @path/to/file
67
+ * Formats: @filename, @path/to/file, @path\to\file, @C:\path\to\file, or @C:/path/to/file
68
+ * Spaces, quoted paths, and glob patterns are not supported.
68
69
  */
69
70
  async function replaceFileReferences(template, workingDir) {
70
- const matches = [...template.matchAll(/@([\w./-]+)/g)];
71
+ const matches = [...template.matchAll(/@((?:[A-Za-z]:[\\/])?[\w./\\-]+)/g)];
71
72
  let result = template;
72
73
  for (const match of matches) {
73
74
  const [fullMatch, filePath] = match;
74
75
  try {
75
- const fullPath = path$1.resolve(workingDir, filePath);
76
+ const fullPath = resolveFileReferencePath(workingDir, filePath);
76
77
  const content = await promises.readFile(fullPath, "utf-8");
77
78
  result = result.replace(fullMatch, content);
78
79
  } catch {}
79
80
  }
80
81
  return result;
81
82
  }
83
+ function resolveFileReferencePath(workingDir, filePath) {
84
+ return ([workingDir, filePath].some((value) => /^[A-Za-z]:[\\/]/.test(value) || value.includes("\\")) ? path$1.win32 : path$1).resolve(workingDir, filePath);
85
+ }
82
86
  /**
83
87
  * Format a command for display in help/autocomplete
84
88
  */