@mastra/core
Advanced tools
| import { VersionedStorageDomain, normalizePerPage, calculatePagination, FilesystemVersionedHelpers } from './chunk-SKZRHFF3.js'; | ||
| import { deepEqual } from './chunk-M2TW4P2L.js'; | ||
| // src/storage/domains/mcp-servers/base.ts | ||
| var MCPServersStorage = class extends VersionedStorageDomain { | ||
| listKey = "mcpServers"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "mcpServerId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "MCP_SERVERS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-servers/inmemory.ts | ||
| var InMemoryMCPServersStorage = class extends MCPServersStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.mcpServers.clear(); | ||
| this.db.mcpServerVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // MCP Server CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const config = this.db.mcpServers.get(id); | ||
| return config ? this.deepCopyConfig(config) : null; | ||
| } | ||
| async create(input) { | ||
| const { mcpServer } = input; | ||
| if (this.db.mcpServers.has(mcpServer.id)) { | ||
| throw new Error(`MCP server with id ${mcpServer.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newConfig = { | ||
| id: mcpServer.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpServer.authorId, | ||
| metadata: mcpServer.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.mcpServers.set(mcpServer.id, newConfig); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpServerId: mcpServer.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyConfig(newConfig); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingConfig = this.db.mcpServers.get(id); | ||
| if (!existingConfig) { | ||
| throw new Error(`MCP server with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedConfig = { | ||
| ...existingConfig, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingConfig.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpServers.set(id, updatedConfig); | ||
| return this.deepCopyConfig(updatedConfig); | ||
| } | ||
| async delete(id) { | ||
| this.db.mcpServers.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status = "published" } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let configs = Array.from(this.db.mcpServers.values()); | ||
| if (status) { | ||
| configs = configs.filter((config) => config.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| configs = configs.filter((config) => config.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| configs = configs.filter((config) => { | ||
| if (!config.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedConfigs = this.sortConfigs(configs, field, direction); | ||
| const clonedConfigs = sortedConfigs.map((config) => this.deepCopyConfig(config)); | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| mcpServers: clonedConfigs.slice(offset, offset + perPage), | ||
| total: clonedConfigs.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedConfigs.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // MCP Server Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.mcpServerVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.mcpServerVersions.values()) { | ||
| if (version2.mcpServerId === input.mcpServerId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for MCP server ${input.mcpServerId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpServerVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.mcpServerVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(mcpServerId, versionNumber) { | ||
| for (const version of this.db.mcpServerVersions.values()) { | ||
| if (version.mcpServerId === mcpServerId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(mcpServerId) { | ||
| let latest = null; | ||
| for (const version of this.db.mcpServerVersions.values()) { | ||
| if (version.mcpServerId === mcpServerId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { mcpServerId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.mcpServerVersions.values()).filter((v) => v.mcpServerId === mcpServerId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.mcpServerVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.mcpServerVersions.entries()) { | ||
| if (version.mcpServerId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.mcpServerVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(mcpServerId) { | ||
| let count = 0; | ||
| for (const version of this.db.mcpServerVersions.values()) { | ||
| if (version.mcpServerId === mcpServerId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyConfig(config) { | ||
| return { | ||
| ...config, | ||
| metadata: config.metadata ? { ...config.metadata } : config.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| tools: version.tools ? JSON.parse(JSON.stringify(version.tools)) : version.tools, | ||
| agents: version.agents ? JSON.parse(JSON.stringify(version.agents)) : version.agents, | ||
| workflows: version.workflows ? JSON.parse(JSON.stringify(version.workflows)) : version.workflows, | ||
| repository: version.repository ? { ...version.repository } : version.repository, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortConfigs(configs, field, direction) { | ||
| return configs.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-servers/filesystem.ts | ||
| var FilesystemMCPServersStorage = class extends MCPServersStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "mcp-servers.json", | ||
| parentIdField: "mcpServerId", | ||
| name: "FilesystemMCPServersStorage", | ||
| versionMetadataFields: ["id", "mcpServerId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { mcpServer } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: mcpServer.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpServer.authorId, | ||
| metadata: mcpServer.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(mcpServer.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpServerId: mcpServer.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "mcpServers", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(mcpServerId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(mcpServerId, versionNumber); | ||
| } | ||
| async getLatestVersion(mcpServerId) { | ||
| return this.helpers.getLatestVersion(mcpServerId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "mcpServerId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(mcpServerId) { | ||
| return this.helpers.countVersions(mcpServerId); | ||
| } | ||
| }; | ||
| export { FilesystemMCPServersStorage, InMemoryMCPServersStorage, MCPServersStorage }; | ||
| //# sourceMappingURL=chunk-2IBWJI4I.js.map | ||
| //# sourceMappingURL=chunk-2IBWJI4I.js.map |
| {"version":3,"sources":["../src/storage/domains/mcp-servers/base.ts","../src/storage/domains/mcp-servers/inmemory.ts","../src/storage/domains/mcp-servers/filesystem.ts"],"names":["version"],"mappings":"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","file":"chunk-2IBWJI4I.js","sourcesContent":["import type {\n StorageMCPServerType,\n StorageMCPServerSnapshotType,\n StorageResolvedMCPServerType,\n StorageCreateMCPServerInput,\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput,\n StorageListMCPServersOutput,\n StorageListMCPServersResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// MCP Server Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of an MCP server's content.\n * Server fields are top-level on the version row (no nested snapshot object).\n */\nexport interface MCPServerVersion extends StorageMCPServerSnapshotType, VersionBase {\n /** ID of the MCP server this version belongs to */\n mcpServerId: string;\n}\n\n/**\n * Input for creating a new MCP server version.\n * Server fields are top-level (no nested snapshot object).\n */\nexport interface CreateMCPServerVersionInput extends StorageMCPServerSnapshotType, CreateVersionInputBase {\n /** ID of the MCP server this version belongs to */\n mcpServerId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type MCPServerVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type MCPServerVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing MCP server versions with pagination and sorting.\n */\nexport interface ListMCPServerVersionsInput extends ListVersionsInputBase {\n /** ID of the MCP server to list versions for */\n mcpServerId: string;\n}\n\n/**\n * Output for listing MCP server versions with pagination info.\n */\nexport interface ListMCPServerVersionsOutput extends ListVersionsOutputBase<MCPServerVersion> {}\n\n// ============================================================================\n// MCPServersStorage Base Class\n// ============================================================================\n\nexport abstract class MCPServersStorage extends VersionedStorageDomain<\n StorageMCPServerType,\n StorageMCPServerSnapshotType,\n StorageResolvedMCPServerType,\n MCPServerVersion,\n CreateMCPServerVersionInput,\n ListMCPServerVersionsInput,\n ListMCPServerVersionsOutput,\n { mcpServer: StorageCreateMCPServerInput },\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput | undefined,\n StorageListMCPServersOutput,\n StorageListMCPServersResolvedOutput\n> {\n protected readonly listKey = 'mcpServers';\n protected readonly versionMetadataFields = [\n 'id',\n 'mcpServerId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof MCPServerVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'MCP_SERVERS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageMCPServerType,\n StorageCreateMCPServerInput,\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput,\n StorageListMCPServersOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n MCPServerVersion,\n CreateMCPServerVersionInput,\n ListMCPServerVersionsInput,\n ListMCPServerVersionsOutput,\n MCPServerVersionOrderBy,\n MCPServerVersionSortDirection,\n} from './base';\nimport { MCPServersStorage } from './base';\n\nexport class InMemoryMCPServersStorage extends MCPServersStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.mcpServers.clear();\n this.db.mcpServerVersions.clear();\n }\n\n // ==========================================================================\n // MCP Server CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageMCPServerType | null> {\n const config = this.db.mcpServers.get(id);\n return config ? this.deepCopyConfig(config) : null;\n }\n\n async create(input: { mcpServer: StorageCreateMCPServerInput }): Promise<StorageMCPServerType> {\n const { mcpServer } = input;\n\n if (this.db.mcpServers.has(mcpServer.id)) {\n throw new Error(`MCP server with id ${mcpServer.id} already exists`);\n }\n\n const now = new Date();\n const newConfig: StorageMCPServerType = {\n id: mcpServer.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpServer.authorId,\n metadata: mcpServer.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.mcpServers.set(mcpServer.id, newConfig);\n\n // Extract config fields from the flat input (everything except record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpServerId: mcpServer.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin record\n return this.deepCopyConfig(newConfig);\n }\n\n async update(input: StorageUpdateMCPServerInput): Promise<StorageMCPServerType> {\n const { id, ...updates } = input;\n\n const existingConfig = this.db.mcpServers.get(id);\n if (!existingConfig) {\n throw new Error(`MCP server with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the record\n const updatedConfig: StorageMCPServerType = {\n ...existingConfig,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageMCPServerType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingConfig.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated record\n this.db.mcpServers.set(id, updatedConfig);\n return this.deepCopyConfig(updatedConfig);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.mcpServers.delete(id);\n // Also delete all versions for this server\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListMCPServersInput): Promise<StorageListMCPServersOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status = 'published' } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all MCP servers and apply filters\n let configs = Array.from(this.db.mcpServers.values());\n\n // Filter by status\n if (status) {\n configs = configs.filter(config => config.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n configs = configs.filter(config => config.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n configs = configs.filter(config => {\n if (!config.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata![key], value));\n });\n }\n\n // Sort filtered configs\n const sortedConfigs = this.sortConfigs(configs, field, direction);\n\n // Deep clone to avoid mutation\n const clonedConfigs = sortedConfigs.map(config => this.deepCopyConfig(config));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n mcpServers: clonedConfigs.slice(offset, offset + perPage),\n total: clonedConfigs.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedConfigs.length,\n };\n }\n\n // ==========================================================================\n // MCP Server Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateMCPServerVersionInput): Promise<MCPServerVersion> {\n // Check if version with this ID already exists\n if (this.db.mcpServerVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (mcpServerId, versionNumber) pair\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === input.mcpServerId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for MCP server ${input.mcpServerId}`);\n }\n }\n\n const version: MCPServerVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.mcpServerVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<MCPServerVersion | null> {\n const version = this.db.mcpServerVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(mcpServerId: string, versionNumber: number): Promise<MCPServerVersion | null> {\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === mcpServerId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(mcpServerId: string): Promise<MCPServerVersion | null> {\n let latest: MCPServerVersion | null = null;\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === mcpServerId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListMCPServerVersionsInput): Promise<ListMCPServerVersionsOutput> {\n const { mcpServerId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by mcpServerId\n let versions = Array.from(this.db.mcpServerVersions.values()).filter(v => v.mcpServerId === mcpServerId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.mcpServerVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.mcpServerVersions.entries()) {\n if (version.mcpServerId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.mcpServerVersions.delete(id);\n }\n }\n\n async countVersions(mcpServerId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === mcpServerId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyConfig(config: StorageMCPServerType): StorageMCPServerType {\n return {\n ...config,\n metadata: config.metadata ? { ...config.metadata } : config.metadata,\n };\n }\n\n private deepCopyVersion(version: MCPServerVersion): MCPServerVersion {\n return {\n ...version,\n tools: version.tools ? JSON.parse(JSON.stringify(version.tools)) : version.tools,\n agents: version.agents ? JSON.parse(JSON.stringify(version.agents)) : version.agents,\n workflows: version.workflows ? JSON.parse(JSON.stringify(version.workflows)) : version.workflows,\n repository: version.repository ? { ...version.repository } : version.repository,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortConfigs(\n configs: StorageMCPServerType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageMCPServerType[] {\n return configs.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: MCPServerVersion[],\n field: MCPServerVersionOrderBy,\n direction: MCPServerVersionSortDirection,\n ): MCPServerVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageMCPServerType,\n StorageCreateMCPServerInput,\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput,\n StorageListMCPServersOutput,\n} from '../../types';\nimport type {\n MCPServerVersion,\n CreateMCPServerVersionInput,\n ListMCPServerVersionsInput,\n ListMCPServerVersionsOutput,\n} from './base';\nimport { MCPServersStorage } from './base';\n\nexport class FilesystemMCPServersStorage extends MCPServersStorage {\n private helpers: FilesystemVersionedHelpers<StorageMCPServerType, MCPServerVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'mcp-servers.json',\n parentIdField: 'mcpServerId',\n name: 'FilesystemMCPServersStorage',\n versionMetadataFields: ['id', 'mcpServerId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageMCPServerType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { mcpServer: StorageCreateMCPServerInput }): Promise<StorageMCPServerType> {\n const { mcpServer } = input;\n const now = new Date();\n const entity: StorageMCPServerType = {\n id: mcpServer.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpServer.authorId,\n metadata: mcpServer.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(mcpServer.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpServerId: mcpServer.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateMCPServerVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateMCPServerInput): Promise<StorageMCPServerType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListMCPServersInput): Promise<StorageListMCPServersOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'mcpServers',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListMCPServersOutput;\n }\n\n async createVersion(input: CreateMCPServerVersionInput): Promise<MCPServerVersion> {\n return this.helpers.createVersion(input as MCPServerVersion);\n }\n\n async getVersion(id: string): Promise<MCPServerVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(mcpServerId: string, versionNumber: number): Promise<MCPServerVersion | null> {\n return this.helpers.getVersionByNumber(mcpServerId, versionNumber);\n }\n\n async getLatestVersion(mcpServerId: string): Promise<MCPServerVersion | null> {\n return this.helpers.getLatestVersion(mcpServerId);\n }\n\n async listVersions(input: ListMCPServerVersionsInput): Promise<ListMCPServerVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'mcpServerId');\n return result as ListMCPServerVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(mcpServerId: string): Promise<number> {\n return this.helpers.countVersions(mcpServerId);\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { VersionedStorageDomain, normalizePerPage, calculatePagination, FilesystemVersionedHelpers, SOURCE_CONTROL_AGENTS_DIR, getSourceAgentFilePath } from './chunk-SKZRHFF3.js'; | ||
| import { deepEqual } from './chunk-M2TW4P2L.js'; | ||
| // src/storage/domains/agents/base.ts | ||
| var AgentsStorage = class extends VersionedStorageDomain { | ||
| listKey = "agents"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "agentId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "AGENTS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/agents/inmemory.ts | ||
| var InMemoryAgentsStorage = class extends AgentsStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.agents.clear(); | ||
| this.db.agentVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Agent CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const agent = this.db.agents.get(id); | ||
| return agent ? this.deepCopyAgent(agent) : null; | ||
| } | ||
| async create(input) { | ||
| const { agent } = input; | ||
| if (this.db.agents.has(agent.id)) { | ||
| throw new Error(`Agent with id ${agent.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const visibility = agent.visibility ?? (agent.authorId ? "private" : void 0); | ||
| const newAgent = { | ||
| id: agent.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: agent.authorId, | ||
| visibility, | ||
| metadata: agent.metadata, | ||
| favoriteCount: 0, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.agents.set(agent.id, newAgent); | ||
| const { id: _id, authorId: _authorId, visibility: _visibility, metadata: _metadata, ...snapshotConfig } = agent; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| agentId: agent.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyAgent(newAgent); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingAgent = this.db.agents.get(id); | ||
| if (!existingAgent) { | ||
| throw new Error(`Agent with id ${id} not found`); | ||
| } | ||
| const { authorId, visibility, activeVersionId, metadata, status } = updates; | ||
| const updatedAgent = { | ||
| ...existingAgent, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...visibility !== void 0 && { visibility }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingAgent.metadata, ...metadata } | ||
| }, | ||
| ...status !== void 0 && { status }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.agents.set(id, updatedAgent); | ||
| return this.deepCopyAgent(updatedAgent); | ||
| } | ||
| async delete(id) { | ||
| this.db.agents.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { | ||
| page = 0, | ||
| perPage: perPageInput, | ||
| orderBy, | ||
| authorId, | ||
| visibility, | ||
| metadata, | ||
| status, | ||
| entityIds, | ||
| pinFavoritedFor, | ||
| favoritedOnly | ||
| } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let agents = Array.from(this.db.agents.values()); | ||
| if (entityIds !== void 0) { | ||
| if (entityIds.length === 0) { | ||
| return { | ||
| agents: [], | ||
| total: 0, | ||
| page, | ||
| perPage: perPageInput === false ? false : perPage, | ||
| hasMore: false | ||
| }; | ||
| } | ||
| const idSet = new Set(entityIds); | ||
| agents = agents.filter((agent) => idSet.has(agent.id)); | ||
| } | ||
| if (status) { | ||
| agents = agents.filter((agent) => agent.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| agents = agents.filter((agent) => agent.authorId === authorId); | ||
| } | ||
| if (visibility !== void 0) { | ||
| agents = agents.filter((agent) => agent.visibility === visibility); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| agents = agents.filter((agent) => { | ||
| if (!agent.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => deepEqual(agent.metadata[key], value)); | ||
| }); | ||
| } | ||
| const favoritedIds = pinFavoritedFor ? this.collectFavoritedIdsFor(pinFavoritedFor) : void 0; | ||
| if (favoritedOnly) { | ||
| if (favoritedIds) { | ||
| agents = agents.filter((agent) => favoritedIds.has(agent.id)); | ||
| } else { | ||
| agents = []; | ||
| } | ||
| } | ||
| const sortedAgents = this.sortAgents(agents, field, direction, favoritedIds); | ||
| const clonedAgents = sortedAgents.map((agent) => this.deepCopyAgent(agent)); | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| agents: clonedAgents.slice(offset, offset + perPage), | ||
| total: clonedAgents.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedAgents.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Agent Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.agentVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.agentVersions.values()) { | ||
| if (version2.agentId === input.agentId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for agent ${input.agentId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.agentVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.agentVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(agentId, versionNumber) { | ||
| for (const version of this.db.agentVersions.values()) { | ||
| if (version.agentId === agentId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(agentId) { | ||
| let latest = null; | ||
| for (const version of this.db.agentVersions.values()) { | ||
| if (version.agentId === agentId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { agentId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.agentVersions.values()).filter((v) => v.agentId === agentId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.agentVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.agentVersions.entries()) { | ||
| if (version.agentId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.agentVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(agentId) { | ||
| let count = 0; | ||
| for (const version of this.db.agentVersions.values()) { | ||
| if (version.agentId === agentId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| /** | ||
| * Deep copy a thin agent record to prevent external mutation of stored data | ||
| */ | ||
| deepCopyAgent(agent) { | ||
| return { | ||
| ...agent, | ||
| metadata: agent.metadata ? { ...agent.metadata } : agent.metadata | ||
| }; | ||
| } | ||
| /** | ||
| * Deep copy a version to prevent external mutation of stored data | ||
| */ | ||
| deepCopyVersion(version) { | ||
| return structuredClone(version); | ||
| } | ||
| sortAgents(agents, field, direction, favoritedIds) { | ||
| return agents.sort((a, b) => { | ||
| if (favoritedIds) { | ||
| const aFav = favoritedIds.has(a.id) ? 1 : 0; | ||
| const bFav = favoritedIds.has(b.id) ? 1 : 0; | ||
| if (aFav !== bFav) return bFav - aFav; | ||
| } | ||
| const aValue = new Date(a[field]).getTime(); | ||
| const bValue = new Date(b[field]).getTime(); | ||
| if (aValue !== bValue) { | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| } | ||
| return a.id < b.id ? -1 : a.id > b.id ? 1 : 0; | ||
| }); | ||
| } | ||
| /** | ||
| * Collect the set of agent IDs favorited by the given user. Returns an empty | ||
| * Set when the favorites domain is not wired or the user has no favorites. | ||
| */ | ||
| collectFavoritedIdsFor(userId) { | ||
| const favorited = /* @__PURE__ */ new Set(); | ||
| for (const row of this.db.favorites.values()) { | ||
| if (row.userId === userId && row.entityType === "agent") { | ||
| favorited.add(row.entityId); | ||
| } | ||
| } | ||
| return favorited; | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/inmemory-db.ts | ||
| var InMemoryDB = class { | ||
| threads = /* @__PURE__ */ new Map(); | ||
| messages = /* @__PURE__ */ new Map(); | ||
| resources = /* @__PURE__ */ new Map(); | ||
| workflows = /* @__PURE__ */ new Map(); | ||
| scores = /* @__PURE__ */ new Map(); | ||
| traces = /* @__PURE__ */ new Map(); | ||
| metricRecords = []; | ||
| logRecords = []; | ||
| scoreRecords = []; | ||
| feedbackRecords = []; | ||
| observabilityNextCursorId = 1; | ||
| traceCursorIds = /* @__PURE__ */ new Map(); | ||
| branchCursorIds = /* @__PURE__ */ new Map(); | ||
| metricCursorIds = /* @__PURE__ */ new Map(); | ||
| logCursorIds = /* @__PURE__ */ new Map(); | ||
| scoreCursorIds = /* @__PURE__ */ new Map(); | ||
| feedbackCursorIds = /* @__PURE__ */ new Map(); | ||
| agents = /* @__PURE__ */ new Map(); | ||
| agentVersions = /* @__PURE__ */ new Map(); | ||
| promptBlocks = /* @__PURE__ */ new Map(); | ||
| promptBlockVersions = /* @__PURE__ */ new Map(); | ||
| scorerDefinitions = /* @__PURE__ */ new Map(); | ||
| scorerDefinitionVersions = /* @__PURE__ */ new Map(); | ||
| mcpClients = /* @__PURE__ */ new Map(); | ||
| mcpClientVersions = /* @__PURE__ */ new Map(); | ||
| mcpServers = /* @__PURE__ */ new Map(); | ||
| mcpServerVersions = /* @__PURE__ */ new Map(); | ||
| workspaces = /* @__PURE__ */ new Map(); | ||
| workspaceVersions = /* @__PURE__ */ new Map(); | ||
| skills = /* @__PURE__ */ new Map(); | ||
| skillVersions = /* @__PURE__ */ new Map(); | ||
| /** | ||
| * Favorites keyed by `${userId}\u0000${entityType}\u0000${entityId}`. The | ||
| * favorites domain owns reads/writes; this Map lives on InMemoryDB so the | ||
| * favorites domain can also mutate `agents` / `skills` `favoriteCount` atomically | ||
| * within the same synchronous block. | ||
| */ | ||
| favorites = /* @__PURE__ */ new Map(); | ||
| /** Observational memory records, keyed by resourceId, each holding array of records (generations) */ | ||
| observationalMemory = /* @__PURE__ */ new Map(); | ||
| // Dataset domain maps | ||
| datasets = /* @__PURE__ */ new Map(); | ||
| datasetItems = /* @__PURE__ */ new Map(); | ||
| datasetVersions = /* @__PURE__ */ new Map(); | ||
| // Experiment domain maps | ||
| experiments = /* @__PURE__ */ new Map(); | ||
| experimentResults = /* @__PURE__ */ new Map(); | ||
| // Background tasks domain | ||
| backgroundTasks = /* @__PURE__ */ new Map(); | ||
| // Schedules domain | ||
| schedules = /* @__PURE__ */ new Map(); | ||
| scheduleTriggers = []; | ||
| /** | ||
| * Tool provider connections keyed by `${authorId}\u0000${providerId}\u0000${connectionId}`. | ||
| */ | ||
| toolProviderConnections = /* @__PURE__ */ new Map(); | ||
| /** | ||
| * Clears all data from all collections. | ||
| * Useful for testing. | ||
| */ | ||
| clear() { | ||
| this.threads.clear(); | ||
| this.messages.clear(); | ||
| this.resources.clear(); | ||
| this.workflows.clear(); | ||
| this.scores.clear(); | ||
| this.traces.clear(); | ||
| this.metricRecords.length = 0; | ||
| this.logRecords.length = 0; | ||
| this.scoreRecords.length = 0; | ||
| this.feedbackRecords.length = 0; | ||
| this.observabilityNextCursorId = 1; | ||
| this.traceCursorIds.clear(); | ||
| this.branchCursorIds.clear(); | ||
| this.metricCursorIds.clear(); | ||
| this.logCursorIds.clear(); | ||
| this.scoreCursorIds.clear(); | ||
| this.feedbackCursorIds.clear(); | ||
| this.agents.clear(); | ||
| this.agentVersions.clear(); | ||
| this.promptBlocks.clear(); | ||
| this.promptBlockVersions.clear(); | ||
| this.scorerDefinitions.clear(); | ||
| this.scorerDefinitionVersions.clear(); | ||
| this.mcpClients.clear(); | ||
| this.mcpClientVersions.clear(); | ||
| this.mcpServers.clear(); | ||
| this.mcpServerVersions.clear(); | ||
| this.workspaces.clear(); | ||
| this.workspaceVersions.clear(); | ||
| this.skills.clear(); | ||
| this.skillVersions.clear(); | ||
| this.favorites.clear(); | ||
| this.observationalMemory.clear(); | ||
| this.datasets.clear(); | ||
| this.datasetItems.clear(); | ||
| this.datasetVersions.clear(); | ||
| this.experiments.clear(); | ||
| this.experimentResults.clear(); | ||
| this.backgroundTasks.clear(); | ||
| this.schedules.clear(); | ||
| this.scheduleTriggers.length = 0; | ||
| this.toolProviderConnections.clear(); | ||
| } | ||
| }; | ||
| // src/storage/domains/agents/filesystem.ts | ||
| var PERSISTED_SNAPSHOT_FIELDS = /* @__PURE__ */ new Set([ | ||
| "name", | ||
| "instructions", | ||
| "model", | ||
| "tools", | ||
| "integrationTools", | ||
| "toolProviders", | ||
| "mcpClients", | ||
| "requestContextSchema" | ||
| ]); | ||
| var CODE_MODE_EXCLUDED_FIELDS = /* @__PURE__ */ new Set(["model", "name"]); | ||
| var OWNED_FIELDS_BY_GROUP = { | ||
| instructions: ["instructions"], | ||
| tools: ["tools", "integrationTools", "mcpClients"] | ||
| }; | ||
| function ownershipFromEditorConfig(editorConfig) { | ||
| if (editorConfig === false) { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| if (editorConfig === void 0 || editorConfig === null) { | ||
| return { ownsInstructions: true, ownsTools: true }; | ||
| } | ||
| if (typeof editorConfig !== "object") { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| const cfg = editorConfig; | ||
| const ownsInstructions = cfg.instructions === true; | ||
| const toolsCfg = cfg.tools; | ||
| const ownsTools = toolsCfg === true || typeof toolsCfg === "object" && toolsCfg !== null && toolsCfg.description === true; | ||
| return { ownsInstructions, ownsTools }; | ||
| } | ||
| function stripUnusedFields(obj) { | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| if (PERSISTED_SNAPSHOT_FIELDS.has(key)) { | ||
| result[key] = value; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function isAgentNotFoundError(error, entityId) { | ||
| if (!error || typeof error !== "object") return false; | ||
| const maybeError = error; | ||
| return maybeError.id === "MASTRA_GET_AGENT_BY_AGENT_ID_NOT_FOUND" || maybeError.details?.status === 404 && maybeError.details?.agentId === entityId || maybeError.message === `Agent with id ${entityId} not found`; | ||
| } | ||
| var FilesystemAgentsStorage = class extends AgentsStorage { | ||
| helpers; | ||
| storageMastra; | ||
| constructor({ db }) { | ||
| super(); | ||
| const getCodeAgent = (entityId) => { | ||
| try { | ||
| const agent = this.storageMastra?.getAgentById?.(entityId); | ||
| return agent?.source === "code" ? agent : void 0; | ||
| } catch (error) { | ||
| if (isAgentNotFoundError(error, entityId)) { | ||
| return void 0; | ||
| } | ||
| throw error; | ||
| } | ||
| }; | ||
| const isCodeAgent = (entityId) => Boolean(getCodeAgent(entityId)); | ||
| const editorConfigFor = (entityId) => getCodeAgent(entityId)?.__getEditorConfig?.(); | ||
| this.helpers = new FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "agents.json", | ||
| parentIdField: "agentId", | ||
| name: "FilesystemAgentsStorage", | ||
| versionMetadataFields: ["id", "agentId", "versionNumber", "changedFields", "changeMessage", "createdAt"], | ||
| perEntityFilesDir: "agents", | ||
| // Per-entity layout is used only for code-mode agents — i.e. agents | ||
| // that are declared in code (`source === 'code'`). For db-mode and | ||
| // user-created stored agents we keep the shared `agents.json` layout. | ||
| shouldPersistToPerEntityFile: (entity) => isCodeAgent(entity.id), | ||
| perEntitySnapshotFilter: (snapshot, entity) => { | ||
| const { ownsInstructions, ownsTools } = ownershipFromEditorConfig(editorConfigFor(entity.id)); | ||
| const excludedByOwnership = /* @__PURE__ */ new Set(); | ||
| if (!ownsInstructions) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP.instructions) excludedByOwnership.add(field); | ||
| } | ||
| if (!ownsTools) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP.tools) excludedByOwnership.add(field); | ||
| } | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(snapshot)) { | ||
| if (CODE_MODE_EXCLUDED_FIELDS.has(key)) continue; | ||
| if (excludedByOwnership.has(key)) continue; | ||
| result[key] = value; | ||
| } | ||
| return result; | ||
| } | ||
| }); | ||
| } | ||
| __registerMastra(mastra) { | ||
| this.storageMastra = mastra; | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { agent } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const visibility = agent.visibility ?? (agent.authorId ? "private" : void 0); | ||
| const entity = { | ||
| id: agent.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: agent.authorId, | ||
| visibility, | ||
| metadata: agent.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(agent.id, entity); | ||
| const { id: _id, authorId: _authorId, visibility: _visibility, metadata: _metadata, ...snapshotConfig } = agent; | ||
| const filtered = stripUnusedFields(snapshotConfig); | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| agentId: agent.id, | ||
| versionNumber: 1, | ||
| ...filtered, | ||
| changedFields: Object.keys(filtered), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const entityUpdates = {}; | ||
| const entityFields = /* @__PURE__ */ new Set(["authorId", "visibility", "metadata", "activeVersionId", "status"]); | ||
| for (const [key, value] of Object.entries(updates)) { | ||
| if (entityFields.has(key)) { | ||
| entityUpdates[key] = value; | ||
| } | ||
| } | ||
| return this.helpers.updateEntity(id, entityUpdates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, visibility, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "agents", | ||
| filters: { authorId, visibility, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| const { id, agentId, versionNumber, changedFields, changeMessage, ...snapshotFields } = input; | ||
| const filtered = stripUnusedFields(snapshotFields); | ||
| return this.helpers.createVersion({ | ||
| id, | ||
| agentId, | ||
| versionNumber, | ||
| changedFields, | ||
| changeMessage, | ||
| ...filtered | ||
| }); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(agentId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(agentId, versionNumber); | ||
| } | ||
| async getLatestVersion(agentId) { | ||
| return this.helpers.getLatestVersion(agentId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "agentId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(agentId) { | ||
| return this.helpers.countVersions(agentId); | ||
| } | ||
| }; | ||
| // src/storage/domains/agents/source.ts | ||
| var SOURCE_VERSION_PREFIX = "source:"; | ||
| var COMMON_EXCLUDED_FIELDS = /* @__PURE__ */ new Set([ | ||
| "id", | ||
| "model", | ||
| "scorers", | ||
| "skills", | ||
| "workflows", | ||
| "agents", | ||
| "integrationTools", | ||
| "toolProviders", | ||
| "inputProcessors", | ||
| "outputProcessors", | ||
| "memory", | ||
| "mcpClients", | ||
| "workspace", | ||
| "browser", | ||
| "defaultOptions" | ||
| ]); | ||
| var CODE_SOURCE_EXCLUDED_FIELDS = /* @__PURE__ */ new Set(["name"]); | ||
| var OWNED_FIELDS_BY_GROUP2 = { | ||
| instructions: ["instructions"], | ||
| tools: ["tools"] | ||
| }; | ||
| function ownershipFromEditorConfig2(editorConfig) { | ||
| if (editorConfig === false) { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| if (editorConfig === void 0 || editorConfig === null) { | ||
| return { ownsInstructions: true, ownsTools: true }; | ||
| } | ||
| if (typeof editorConfig !== "object") { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| const cfg = editorConfig; | ||
| const ownsInstructions = cfg.instructions === true; | ||
| const toolsCfg = cfg.tools; | ||
| const ownsTools = toolsCfg === true || typeof toolsCfg === "object" && toolsCfg !== null && toolsCfg.description === true; | ||
| return { ownsInstructions, ownsTools }; | ||
| } | ||
| function snapshotFromVersion(version) { | ||
| const { id, agentId, versionNumber, changedFields, changeMessage, createdAt, ...snapshot } = version; | ||
| return snapshot; | ||
| } | ||
| function filterSourceSnapshot(snapshot, editorConfig, isCodeDefinedAgent) { | ||
| const excludedByOwnership = /* @__PURE__ */ new Set(); | ||
| if (isCodeDefinedAgent) { | ||
| const { ownsInstructions, ownsTools } = ownershipFromEditorConfig2(editorConfig); | ||
| if (!ownsInstructions) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP2.instructions) excludedByOwnership.add(field); | ||
| } | ||
| if (!ownsTools) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP2.tools) excludedByOwnership.add(field); | ||
| } | ||
| } | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(snapshot)) { | ||
| if (COMMON_EXCLUDED_FIELDS.has(key)) continue; | ||
| if (isCodeDefinedAgent && CODE_SOURCE_EXCLUDED_FIELDS.has(key)) continue; | ||
| if (excludedByOwnership.has(key)) continue; | ||
| if (value === void 0) continue; | ||
| result[key] = value; | ||
| } | ||
| return result; | ||
| } | ||
| function parseJsonObject(content) { | ||
| try { | ||
| const parsed = JSON.parse(content); | ||
| return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null; | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
| function stableStringify(value) { | ||
| if (Array.isArray(value)) { | ||
| return `[${value.map(stableStringify).join(",")}]`; | ||
| } | ||
| if (value && typeof value === "object") { | ||
| const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([a], [b]) => a.localeCompare(b)); | ||
| return `{${entries.map(([key, entryValue]) => `${JSON.stringify(key)}:${stableStringify(entryValue)}`).join(",")}}`; | ||
| } | ||
| return JSON.stringify(value); | ||
| } | ||
| function agentIdFromSourcePath(path) { | ||
| const prefix = `${SOURCE_CONTROL_AGENTS_DIR}/`; | ||
| if (!path.startsWith(prefix) || !path.endsWith(".json")) return void 0; | ||
| const filename = path.slice(prefix.length, -".json".length); | ||
| if (!filename || filename.includes("/")) return void 0; | ||
| try { | ||
| return decodeURIComponent(filename); | ||
| } catch { | ||
| return filename; | ||
| } | ||
| } | ||
| var SourceAgentsSourceControl = class extends AgentsStorage { | ||
| provider; | ||
| knownAgentIds; | ||
| db = new InMemoryDB(); | ||
| memory = new InMemoryAgentsStorage({ db: this.db }); | ||
| storageMastra; | ||
| providerVersions = /* @__PURE__ */ new Map(); | ||
| loadedHistory = /* @__PURE__ */ new Set(); | ||
| hydratedAgents = /* @__PURE__ */ new Set(); | ||
| activeRefs = /* @__PURE__ */ new Map(); | ||
| providerAgentIdsDiscovered = false; | ||
| constructor({ provider, agentIds = [] }) { | ||
| super(); | ||
| this.provider = provider; | ||
| this.knownAgentIds = new Set(agentIds); | ||
| } | ||
| __registerMastra(mastra) { | ||
| this.storageMastra = mastra; | ||
| } | ||
| async init() { | ||
| const capabilities = await this.provider.getCapabilities(); | ||
| if (!capabilities.canRead) { | ||
| throw new Error(capabilities.reason ?? `Source provider ${this.provider.displayName} cannot read files`); | ||
| } | ||
| this.refreshKnownAgentIds(); | ||
| await this.discoverProviderAgentIds(); | ||
| await Promise.all([...this.knownAgentIds].map((agentId) => this.hydrateAgent(agentId))); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.hydratedAgents.clear(); | ||
| this.loadedHistory.clear(); | ||
| this.providerVersions.clear(); | ||
| this.activeRefs.clear(); | ||
| this.providerAgentIdsDiscovered = false; | ||
| await this.memory.dangerouslyClearAll(); | ||
| } | ||
| async useProviderRef(agentId, ref) { | ||
| this.activeRefs.set(agentId, ref); | ||
| this.hydratedAgents.delete(agentId); | ||
| this.loadedHistory.delete(agentId); | ||
| for (const [versionId, version] of this.providerVersions.entries()) { | ||
| if (version.agentId === agentId) { | ||
| this.providerVersions.delete(versionId); | ||
| } | ||
| } | ||
| await this.memory.delete(agentId); | ||
| await this.hydrateAgent(agentId); | ||
| } | ||
| async getById(id) { | ||
| await this.hydrateAgent(id); | ||
| return this.memory.getById(id); | ||
| } | ||
| async create(input) { | ||
| await this.hydrateAgent(input.agent.id); | ||
| const existing = await this.memory.getById(input.agent.id); | ||
| if (existing) { | ||
| throw new Error(`Agent with id ${input.agent.id} already exists`); | ||
| } | ||
| await this.persistSnapshot(input.agent.id, { ...input.agent }, "Initial version"); | ||
| const created = await this.memory.create(input); | ||
| this.knownAgentIds.add(input.agent.id); | ||
| return created; | ||
| } | ||
| async update(input) { | ||
| await this.hydrateAgent(input.id); | ||
| return this.memory.update(input); | ||
| } | ||
| async delete(id) { | ||
| this.knownAgentIds.delete(id); | ||
| this.hydratedAgents.delete(id); | ||
| this.loadedHistory.delete(id); | ||
| for (const versionId of this.providerVersions.keys()) { | ||
| if (this.providerVersions.get(versionId)?.agentId === id) { | ||
| this.providerVersions.delete(versionId); | ||
| } | ||
| } | ||
| await this.memory.delete(id); | ||
| } | ||
| async list(args) { | ||
| this.refreshKnownAgentIds(); | ||
| await this.discoverProviderAgentIds(); | ||
| await Promise.all([...this.knownAgentIds].map((agentId) => this.hydrateAgent(agentId))); | ||
| return this.memory.list(args); | ||
| } | ||
| async createVersion(input) { | ||
| await this.hydrateAgent(input.agentId); | ||
| const existingVersion = await this.memory.getVersion(input.id); | ||
| if (existingVersion) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| const existingVersionNumber = await this.memory.getVersionByNumber(input.agentId, input.versionNumber); | ||
| if (existingVersionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for agent ${input.agentId}`); | ||
| } | ||
| const snapshot = snapshotFromVersion({ ...input, createdAt: /* @__PURE__ */ new Date() }); | ||
| const result = await this.persistSnapshot(input.agentId, snapshot, input.changeMessage); | ||
| const version = await this.memory.createVersion(input); | ||
| this.rememberProviderVersion(input.agentId, version, result); | ||
| return version; | ||
| } | ||
| async getVersion(id) { | ||
| const providerVersion = this.providerVersions.get(id); | ||
| if (providerVersion) { | ||
| return structuredClone(providerVersion); | ||
| } | ||
| return this.memory.getVersion(id); | ||
| } | ||
| async getVersionByNumber(agentId, versionNumber) { | ||
| await this.loadHistory(agentId); | ||
| const providerVersion = [...this.providerVersions.values()].find( | ||
| (version) => version.agentId === agentId && version.versionNumber === versionNumber | ||
| ); | ||
| if (providerVersion) { | ||
| return structuredClone(providerVersion); | ||
| } | ||
| return this.memory.getVersionByNumber(agentId, versionNumber); | ||
| } | ||
| async getLatestVersion(agentId) { | ||
| await this.loadHistory(agentId); | ||
| const providerLatest = [...this.providerVersions.values()].filter((version) => version.agentId === agentId).sort((a, b) => b.versionNumber - a.versionNumber)[0]; | ||
| if (providerLatest) { | ||
| return structuredClone(providerLatest); | ||
| } | ||
| return this.memory.getLatestVersion(agentId); | ||
| } | ||
| async listVersions(input) { | ||
| await this.loadHistory(input.agentId); | ||
| const providerVersions = [...this.providerVersions.values()].filter((version) => version.agentId === input.agentId); | ||
| if (providerVersions.length === 0) { | ||
| return this.memory.listVersions(input); | ||
| } | ||
| const { page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| const sortedVersions = this.sortVersions(providerVersions, field, direction).map( | ||
| (version) => structuredClone(version) | ||
| ); | ||
| const total = sortedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| versions: sortedVersions.slice(offset, offset + perPage), | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.providerVersions.delete(id); | ||
| await this.memory.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| for (const [versionId, version] of this.providerVersions.entries()) { | ||
| if (version.agentId === entityId) { | ||
| this.providerVersions.delete(versionId); | ||
| } | ||
| } | ||
| await this.memory.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(entityId) { | ||
| await this.loadHistory(entityId); | ||
| const providerCount = [...this.providerVersions.values()].filter((version) => version.agentId === entityId).length; | ||
| return providerCount || this.memory.countVersions(entityId); | ||
| } | ||
| refreshKnownAgentIds() { | ||
| const agents = this.storageMastra?.listAgents?.(); | ||
| if (!agents) return; | ||
| for (const agent of Object.values(agents)) { | ||
| if (agent.source === "code") { | ||
| this.knownAgentIds.add(agent.id); | ||
| } | ||
| } | ||
| } | ||
| async discoverProviderAgentIds() { | ||
| if (this.providerAgentIdsDiscovered || !this.provider.listFiles) return; | ||
| const files = await this.provider.listFiles({ path: SOURCE_CONTROL_AGENTS_DIR }); | ||
| for (const file of files) { | ||
| const agentId = agentIdFromSourcePath(file.path); | ||
| if (agentId) { | ||
| this.knownAgentIds.add(agentId); | ||
| } | ||
| } | ||
| this.providerAgentIdsDiscovered = true; | ||
| } | ||
| async hydrateAgent(agentId) { | ||
| if (this.hydratedAgents.has(agentId)) return; | ||
| const ref = this.activeRefs.get(agentId); | ||
| const file = await this.provider.readFile({ path: getSourceAgentFilePath(agentId), ref }); | ||
| if (!file) { | ||
| this.hydratedAgents.add(agentId); | ||
| return; | ||
| } | ||
| const snapshot = parseJsonObject(file.content); | ||
| if (!snapshot) { | ||
| this.hydratedAgents.add(agentId); | ||
| return; | ||
| } | ||
| this.knownAgentIds.add(agentId); | ||
| this.hydratedAgents.add(agentId); | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const versionId = `hydrated-${agentId}-v1`; | ||
| this.db.agents.set(agentId, { | ||
| id: agentId, | ||
| status: "published", | ||
| activeVersionId: versionId, | ||
| favoriteCount: 0, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }); | ||
| this.db.agentVersions.set(versionId, { | ||
| id: versionId, | ||
| agentId, | ||
| versionNumber: 1, | ||
| ...snapshot, | ||
| createdAt: now | ||
| }); | ||
| } | ||
| getCodeDefinedAgent(agentId) { | ||
| try { | ||
| const agent = this.storageMastra?.getAgentById?.(agentId); | ||
| return agent?.source === "code" ? agent : void 0; | ||
| } catch { | ||
| return void 0; | ||
| } | ||
| } | ||
| async persistSnapshot(agentId, snapshot, message) { | ||
| const capabilities = await this.provider.getCapabilities(); | ||
| if (!capabilities.canWrite) { | ||
| throw new Error(capabilities.reason ?? `Source provider ${this.provider.displayName} cannot write files`); | ||
| } | ||
| const agent = this.getCodeDefinedAgent(agentId); | ||
| const filtered = filterSourceSnapshot(snapshot, agent?.__getEditorConfig?.(), Boolean(agent)); | ||
| return this.provider.writeFile({ | ||
| path: getSourceAgentFilePath(agentId), | ||
| ref: this.activeRefs.get(agentId), | ||
| content: `${stableStringify(filtered)} | ||
| `, | ||
| message | ||
| }); | ||
| } | ||
| async loadHistory(agentId) { | ||
| if (this.loadedHistory.has(agentId)) return; | ||
| const capabilities = await this.provider.getCapabilities(); | ||
| if (!capabilities.canListHistory) { | ||
| this.loadedHistory.add(agentId); | ||
| return; | ||
| } | ||
| const activeRef = this.activeRefs.get(agentId); | ||
| const entries = await this.provider.listFileHistory({ path: getSourceAgentFilePath(agentId), ref: activeRef }); | ||
| const orderedEntries = [...entries].reverse(); | ||
| const versions = /* @__PURE__ */ new Map(); | ||
| let versionNumber = 0; | ||
| for (const entry of orderedEntries) { | ||
| const file = await this.provider.readFile({ path: getSourceAgentFilePath(agentId), ref: entry.ref ?? entry.id }); | ||
| if (!file) continue; | ||
| const snapshot = parseJsonObject(file.content); | ||
| if (!snapshot) continue; | ||
| versionNumber += 1; | ||
| const version = this.versionFromHistoryEntry(agentId, entry, versionNumber, snapshot); | ||
| versions.set(version.id, version); | ||
| } | ||
| for (const [versionId, version] of versions) { | ||
| this.providerVersions.set(versionId, version); | ||
| } | ||
| this.loadedHistory.add(agentId); | ||
| } | ||
| rememberProviderVersion(agentId, version, result) { | ||
| const versionId = result.commitSha ? `${SOURCE_VERSION_PREFIX}${result.commitSha}:${agentId}` : version.id; | ||
| this.providerVersions.set(versionId, { | ||
| ...structuredClone(version), | ||
| id: versionId, | ||
| agentId, | ||
| versionNumber: this.nextProviderVersionNumber(agentId) | ||
| }); | ||
| } | ||
| versionFromHistoryEntry(agentId, entry, versionNumber, snapshot) { | ||
| return { | ||
| id: `${SOURCE_VERSION_PREFIX}${entry.id}:${agentId}`, | ||
| agentId, | ||
| versionNumber, | ||
| changeMessage: entry.message, | ||
| ...snapshot, | ||
| createdAt: new Date(entry.createdAt) | ||
| }; | ||
| } | ||
| nextProviderVersionNumber(agentId) { | ||
| const latest = [...this.providerVersions.values()].filter((version) => version.agentId === agentId).sort((a, b) => b.versionNumber - a.versionNumber)[0]; | ||
| return (latest?.versionNumber ?? 0) + 1; | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| const aVal = field === "createdAt" ? a.createdAt.getTime() : a.versionNumber; | ||
| const bVal = field === "createdAt" ? b.createdAt.getTime() : b.versionNumber; | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| export { AgentsStorage, FilesystemAgentsStorage, InMemoryAgentsStorage, InMemoryDB, SourceAgentsSourceControl }; | ||
| //# sourceMappingURL=chunk-4BSRNVSZ.js.map | ||
| //# sourceMappingURL=chunk-4BSRNVSZ.js.map |
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunk2UAP4LDC_cjs = require('./chunk-2UAP4LDC.cjs'); | ||
| var chunkBP67LMWW_cjs = require('./chunk-BP67LMWW.cjs'); | ||
| // src/storage/domains/mcp-clients/base.ts | ||
| var MCPClientsStorage = class extends chunk2UAP4LDC_cjs.VersionedStorageDomain { | ||
| listKey = "mcpClients"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "mcpClientId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "MCP_CLIENTS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-clients/inmemory.ts | ||
| var InMemoryMCPClientsStorage = class extends MCPClientsStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.mcpClients.clear(); | ||
| this.db.mcpClientVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // MCP Client CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const config = this.db.mcpClients.get(id); | ||
| return config ? this.deepCopyConfig(config) : null; | ||
| } | ||
| async create(input) { | ||
| const { mcpClient } = input; | ||
| if (this.db.mcpClients.has(mcpClient.id)) { | ||
| throw new Error(`MCP client with id ${mcpClient.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newConfig = { | ||
| id: mcpClient.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpClient.authorId, | ||
| metadata: mcpClient.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.mcpClients.set(mcpClient.id, newConfig); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpClientId: mcpClient.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyConfig(newConfig); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingConfig = this.db.mcpClients.get(id); | ||
| if (!existingConfig) { | ||
| throw new Error(`MCP client with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedConfig = { | ||
| ...existingConfig, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingConfig.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpClients.set(id, updatedConfig); | ||
| return this.deepCopyConfig(updatedConfig); | ||
| } | ||
| async delete(id) { | ||
| this.db.mcpClients.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let configs = Array.from(this.db.mcpClients.values()); | ||
| if (status) { | ||
| configs = configs.filter((config) => config.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| configs = configs.filter((config) => config.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| configs = configs.filter((config) => { | ||
| if (!config.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => chunkBP67LMWW_cjs.deepEqual(config.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedConfigs = this.sortConfigs(configs, field, direction); | ||
| const clonedConfigs = sortedConfigs.map((config) => this.deepCopyConfig(config)); | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| mcpClients: clonedConfigs.slice(offset, offset + perPage), | ||
| total: clonedConfigs.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedConfigs.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // MCP Client Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.mcpClientVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.mcpClientVersions.values()) { | ||
| if (version2.mcpClientId === input.mcpClientId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for MCP client ${input.mcpClientId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpClientVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.mcpClientVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(mcpClientId, versionNumber) { | ||
| for (const version of this.db.mcpClientVersions.values()) { | ||
| if (version.mcpClientId === mcpClientId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(mcpClientId) { | ||
| let latest = null; | ||
| for (const version of this.db.mcpClientVersions.values()) { | ||
| if (version.mcpClientId === mcpClientId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { mcpClientId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.mcpClientVersions.values()).filter((v) => v.mcpClientId === mcpClientId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.mcpClientVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.mcpClientVersions.entries()) { | ||
| if (version.mcpClientId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.mcpClientVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(mcpClientId) { | ||
| let count = 0; | ||
| for (const version of this.db.mcpClientVersions.values()) { | ||
| if (version.mcpClientId === mcpClientId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyConfig(config) { | ||
| return { | ||
| ...config, | ||
| metadata: config.metadata ? { ...config.metadata } : config.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| servers: version.servers ? JSON.parse(JSON.stringify(version.servers)) : version.servers, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortConfigs(configs, field, direction) { | ||
| return configs.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-clients/filesystem.ts | ||
| var FilesystemMCPClientsStorage = class extends MCPClientsStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new chunk2UAP4LDC_cjs.FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "mcp-clients.json", | ||
| parentIdField: "mcpClientId", | ||
| name: "FilesystemMCPClientsStorage", | ||
| versionMetadataFields: ["id", "mcpClientId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { mcpClient } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: mcpClient.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpClient.authorId, | ||
| metadata: mcpClient.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(mcpClient.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpClientId: mcpClient.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "mcpClients", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(mcpClientId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(mcpClientId, versionNumber); | ||
| } | ||
| async getLatestVersion(mcpClientId) { | ||
| return this.helpers.getLatestVersion(mcpClientId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "mcpClientId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(mcpClientId) { | ||
| return this.helpers.countVersions(mcpClientId); | ||
| } | ||
| }; | ||
| exports.FilesystemMCPClientsStorage = FilesystemMCPClientsStorage; | ||
| exports.InMemoryMCPClientsStorage = InMemoryMCPClientsStorage; | ||
| exports.MCPClientsStorage = MCPClientsStorage; | ||
| //# sourceMappingURL=chunk-4M6XWZDY.cjs.map | ||
| //# sourceMappingURL=chunk-4M6XWZDY.cjs.map |
| {"version":3,"sources":["../src/storage/domains/mcp-clients/base.ts","../src/storage/domains/mcp-clients/inmemory.ts","../src/storage/domains/mcp-clients/filesystem.ts"],"names":["VersionedStorageDomain","normalizePerPage","deepEqual","calculatePagination","version","FilesystemVersionedHelpers"],"mappings":"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","file":"chunk-4M6XWZDY.cjs","sourcesContent":["import type {\n StorageMCPClientType,\n StorageMCPClientSnapshotType,\n StorageResolvedMCPClientType,\n StorageCreateMCPClientInput,\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput,\n StorageListMCPClientsOutput,\n StorageListMCPClientsResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// MCP Client Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of an MCP client's content.\n * Client fields are top-level on the version row (no nested snapshot object).\n */\nexport interface MCPClientVersion extends StorageMCPClientSnapshotType, VersionBase {\n /** ID of the MCP client this version belongs to */\n mcpClientId: string;\n}\n\n/**\n * Input for creating a new MCP client version.\n * Client fields are top-level (no nested snapshot object).\n */\nexport interface CreateMCPClientVersionInput extends StorageMCPClientSnapshotType, CreateVersionInputBase {\n /** ID of the MCP client this version belongs to */\n mcpClientId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type MCPClientVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type MCPClientVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing MCP client versions with pagination and sorting.\n */\nexport interface ListMCPClientVersionsInput extends ListVersionsInputBase {\n /** ID of the MCP client to list versions for */\n mcpClientId: string;\n}\n\n/**\n * Output for listing MCP client versions with pagination info.\n */\nexport interface ListMCPClientVersionsOutput extends ListVersionsOutputBase<MCPClientVersion> {}\n\n// ============================================================================\n// MCPClientsStorage Base Class\n// ============================================================================\n\nexport abstract class MCPClientsStorage extends VersionedStorageDomain<\n StorageMCPClientType,\n StorageMCPClientSnapshotType,\n StorageResolvedMCPClientType,\n MCPClientVersion,\n CreateMCPClientVersionInput,\n ListMCPClientVersionsInput,\n ListMCPClientVersionsOutput,\n { mcpClient: StorageCreateMCPClientInput },\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput | undefined,\n StorageListMCPClientsOutput,\n StorageListMCPClientsResolvedOutput\n> {\n protected readonly listKey = 'mcpClients';\n protected readonly versionMetadataFields = [\n 'id',\n 'mcpClientId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof MCPClientVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'MCP_CLIENTS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageMCPClientType,\n StorageCreateMCPClientInput,\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput,\n StorageListMCPClientsOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n MCPClientVersion,\n CreateMCPClientVersionInput,\n ListMCPClientVersionsInput,\n ListMCPClientVersionsOutput,\n MCPClientVersionOrderBy,\n MCPClientVersionSortDirection,\n} from './base';\nimport { MCPClientsStorage } from './base';\n\nexport class InMemoryMCPClientsStorage extends MCPClientsStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.mcpClients.clear();\n this.db.mcpClientVersions.clear();\n }\n\n // ==========================================================================\n // MCP Client CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageMCPClientType | null> {\n const config = this.db.mcpClients.get(id);\n return config ? this.deepCopyConfig(config) : null;\n }\n\n async create(input: { mcpClient: StorageCreateMCPClientInput }): Promise<StorageMCPClientType> {\n const { mcpClient } = input;\n\n if (this.db.mcpClients.has(mcpClient.id)) {\n throw new Error(`MCP client with id ${mcpClient.id} already exists`);\n }\n\n const now = new Date();\n const newConfig: StorageMCPClientType = {\n id: mcpClient.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpClient.authorId,\n metadata: mcpClient.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.mcpClients.set(mcpClient.id, newConfig);\n\n // Extract config fields from the flat input (everything except record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpClientId: mcpClient.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin record\n return this.deepCopyConfig(newConfig);\n }\n\n async update(input: StorageUpdateMCPClientInput): Promise<StorageMCPClientType> {\n const { id, ...updates } = input;\n\n const existingConfig = this.db.mcpClients.get(id);\n if (!existingConfig) {\n throw new Error(`MCP client with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the record\n const updatedConfig: StorageMCPClientType = {\n ...existingConfig,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageMCPClientType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingConfig.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated record\n this.db.mcpClients.set(id, updatedConfig);\n return this.deepCopyConfig(updatedConfig);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.mcpClients.delete(id);\n // Also delete all versions for this client\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListMCPClientsInput): Promise<StorageListMCPClientsOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all MCP clients and apply filters\n let configs = Array.from(this.db.mcpClients.values());\n\n // Filter by status\n if (status) {\n configs = configs.filter(config => config.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n configs = configs.filter(config => config.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n configs = configs.filter(config => {\n if (!config.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata![key], value));\n });\n }\n\n // Sort filtered configs\n const sortedConfigs = this.sortConfigs(configs, field, direction);\n\n // Deep clone to avoid mutation\n const clonedConfigs = sortedConfigs.map(config => this.deepCopyConfig(config));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n mcpClients: clonedConfigs.slice(offset, offset + perPage),\n total: clonedConfigs.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedConfigs.length,\n };\n }\n\n // ==========================================================================\n // MCP Client Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateMCPClientVersionInput): Promise<MCPClientVersion> {\n // Check if version with this ID already exists\n if (this.db.mcpClientVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (mcpClientId, versionNumber) pair\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === input.mcpClientId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for MCP client ${input.mcpClientId}`);\n }\n }\n\n const version: MCPClientVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.mcpClientVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<MCPClientVersion | null> {\n const version = this.db.mcpClientVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(mcpClientId: string, versionNumber: number): Promise<MCPClientVersion | null> {\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === mcpClientId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(mcpClientId: string): Promise<MCPClientVersion | null> {\n let latest: MCPClientVersion | null = null;\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === mcpClientId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListMCPClientVersionsInput): Promise<ListMCPClientVersionsOutput> {\n const { mcpClientId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by mcpClientId\n let versions = Array.from(this.db.mcpClientVersions.values()).filter(v => v.mcpClientId === mcpClientId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.mcpClientVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.mcpClientVersions.entries()) {\n if (version.mcpClientId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.mcpClientVersions.delete(id);\n }\n }\n\n async countVersions(mcpClientId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === mcpClientId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyConfig(config: StorageMCPClientType): StorageMCPClientType {\n return {\n ...config,\n metadata: config.metadata ? { ...config.metadata } : config.metadata,\n };\n }\n\n private deepCopyVersion(version: MCPClientVersion): MCPClientVersion {\n return {\n ...version,\n servers: version.servers ? JSON.parse(JSON.stringify(version.servers)) : version.servers,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortConfigs(\n configs: StorageMCPClientType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageMCPClientType[] {\n return configs.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: MCPClientVersion[],\n field: MCPClientVersionOrderBy,\n direction: MCPClientVersionSortDirection,\n ): MCPClientVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageMCPClientType,\n StorageCreateMCPClientInput,\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput,\n StorageListMCPClientsOutput,\n} from '../../types';\nimport type {\n MCPClientVersion,\n CreateMCPClientVersionInput,\n ListMCPClientVersionsInput,\n ListMCPClientVersionsOutput,\n} from './base';\nimport { MCPClientsStorage } from './base';\n\nexport class FilesystemMCPClientsStorage extends MCPClientsStorage {\n private helpers: FilesystemVersionedHelpers<StorageMCPClientType, MCPClientVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'mcp-clients.json',\n parentIdField: 'mcpClientId',\n name: 'FilesystemMCPClientsStorage',\n versionMetadataFields: ['id', 'mcpClientId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageMCPClientType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { mcpClient: StorageCreateMCPClientInput }): Promise<StorageMCPClientType> {\n const { mcpClient } = input;\n const now = new Date();\n const entity: StorageMCPClientType = {\n id: mcpClient.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpClient.authorId,\n metadata: mcpClient.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(mcpClient.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpClientId: mcpClient.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateMCPClientVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateMCPClientInput): Promise<StorageMCPClientType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListMCPClientsInput): Promise<StorageListMCPClientsOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'mcpClients',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListMCPClientsOutput;\n }\n\n async createVersion(input: CreateMCPClientVersionInput): Promise<MCPClientVersion> {\n return this.helpers.createVersion(input as MCPClientVersion);\n }\n\n async getVersion(id: string): Promise<MCPClientVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(mcpClientId: string, versionNumber: number): Promise<MCPClientVersion | null> {\n return this.helpers.getVersionByNumber(mcpClientId, versionNumber);\n }\n\n async getLatestVersion(mcpClientId: string): Promise<MCPClientVersion | null> {\n return this.helpers.getLatestVersion(mcpClientId);\n }\n\n async listVersions(input: ListMCPClientVersionsInput): Promise<ListMCPClientVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'mcpClientId');\n return result as ListMCPClientVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(mcpClientId: string): Promise<number> {\n return this.helpers.countVersions(mcpClientId);\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { VersionedStorageDomain, normalizePerPage, calculatePagination, FilesystemVersionedHelpers } from './chunk-SKZRHFF3.js'; | ||
| import { deepEqual } from './chunk-M2TW4P2L.js'; | ||
| // src/storage/domains/scorer-definitions/base.ts | ||
| var ScorerDefinitionsStorage = class extends VersionedStorageDomain { | ||
| listKey = "scorerDefinitions"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "scorerDefinitionId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "SCORER_DEFINITIONS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/scorer-definitions/inmemory.ts | ||
| var InMemoryScorerDefinitionsStorage = class extends ScorerDefinitionsStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.scorerDefinitions.clear(); | ||
| this.db.scorerDefinitionVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Scorer Definition CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const scorer = this.db.scorerDefinitions.get(id); | ||
| return scorer ? this.deepCopyScorer(scorer) : null; | ||
| } | ||
| async create(input) { | ||
| const { scorerDefinition } = input; | ||
| if (this.db.scorerDefinitions.has(scorerDefinition.id)) { | ||
| throw new Error(`Scorer definition with id ${scorerDefinition.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newScorer = { | ||
| id: scorerDefinition.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: scorerDefinition.authorId, | ||
| metadata: scorerDefinition.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.scorerDefinitions.set(scorerDefinition.id, newScorer); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| scorerDefinitionId: scorerDefinition.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyScorer(newScorer); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingScorer = this.db.scorerDefinitions.get(id); | ||
| if (!existingScorer) { | ||
| throw new Error(`Scorer definition with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedScorer = { | ||
| ...existingScorer, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingScorer.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.scorerDefinitions.set(id, updatedScorer); | ||
| return this.deepCopyScorer(updatedScorer); | ||
| } | ||
| async delete(id) { | ||
| this.db.scorerDefinitions.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let scorers = Array.from(this.db.scorerDefinitions.values()); | ||
| if (status) { | ||
| scorers = scorers.filter((scorer) => scorer.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| scorers = scorers.filter((scorer) => scorer.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| scorers = scorers.filter((scorer) => { | ||
| if (!scorer.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => deepEqual(scorer.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedScorers = this.sortScorers(scorers, field, direction); | ||
| const clonedScorers = sortedScorers.map((scorer) => this.deepCopyScorer(scorer)); | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| scorerDefinitions: clonedScorers.slice(offset, offset + perPage), | ||
| total: clonedScorers.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedScorers.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Scorer Definition Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.scorerDefinitionVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.scorerDefinitionVersions.values()) { | ||
| if (version2.scorerDefinitionId === input.scorerDefinitionId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error( | ||
| `Version number ${input.versionNumber} already exists for scorer definition ${input.scorerDefinitionId}` | ||
| ); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.scorerDefinitionVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.scorerDefinitionVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(scorerDefinitionId, versionNumber) { | ||
| for (const version of this.db.scorerDefinitionVersions.values()) { | ||
| if (version.scorerDefinitionId === scorerDefinitionId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(scorerDefinitionId) { | ||
| let latest = null; | ||
| for (const version of this.db.scorerDefinitionVersions.values()) { | ||
| if (version.scorerDefinitionId === scorerDefinitionId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { scorerDefinitionId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.scorerDefinitionVersions.values()).filter( | ||
| (v) => v.scorerDefinitionId === scorerDefinitionId | ||
| ); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.scorerDefinitionVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.scorerDefinitionVersions.entries()) { | ||
| if (version.scorerDefinitionId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.scorerDefinitionVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(scorerDefinitionId) { | ||
| let count = 0; | ||
| for (const version of this.db.scorerDefinitionVersions.values()) { | ||
| if (version.scorerDefinitionId === scorerDefinitionId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyScorer(scorer) { | ||
| return { | ||
| ...scorer, | ||
| metadata: scorer.metadata ? { ...scorer.metadata } : scorer.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| model: version.model ? JSON.parse(JSON.stringify(version.model)) : version.model, | ||
| scoreRange: version.scoreRange ? JSON.parse(JSON.stringify(version.scoreRange)) : version.scoreRange, | ||
| presetConfig: version.presetConfig ? JSON.parse(JSON.stringify(version.presetConfig)) : version.presetConfig, | ||
| defaultSampling: version.defaultSampling ? JSON.parse(JSON.stringify(version.defaultSampling)) : version.defaultSampling, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortScorers(scorers, field, direction) { | ||
| return scorers.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/scorer-definitions/filesystem.ts | ||
| var FilesystemScorerDefinitionsStorage = class extends ScorerDefinitionsStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "scorer-definitions.json", | ||
| parentIdField: "scorerDefinitionId", | ||
| name: "FilesystemScorerDefinitionsStorage", | ||
| versionMetadataFields: [ | ||
| "id", | ||
| "scorerDefinitionId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { scorerDefinition } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: scorerDefinition.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: scorerDefinition.authorId, | ||
| metadata: scorerDefinition.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(scorerDefinition.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| scorerDefinitionId: scorerDefinition.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "scorerDefinitions", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(scorerDefinitionId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(scorerDefinitionId, versionNumber); | ||
| } | ||
| async getLatestVersion(scorerDefinitionId) { | ||
| return this.helpers.getLatestVersion(scorerDefinitionId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "scorerDefinitionId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(scorerDefinitionId) { | ||
| return this.helpers.countVersions(scorerDefinitionId); | ||
| } | ||
| }; | ||
| export { FilesystemScorerDefinitionsStorage, InMemoryScorerDefinitionsStorage, ScorerDefinitionsStorage }; | ||
| //# sourceMappingURL=chunk-5HRFZGRZ.js.map | ||
| //# sourceMappingURL=chunk-5HRFZGRZ.js.map |
| {"version":3,"sources":["../src/storage/domains/scorer-definitions/base.ts","../src/storage/domains/scorer-definitions/inmemory.ts","../src/storage/domains/scorer-definitions/filesystem.ts"],"names":["version"],"mappings":"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","file":"chunk-5HRFZGRZ.js","sourcesContent":["import type {\n StorageScorerDefinitionType,\n StorageScorerDefinitionSnapshotType,\n StorageResolvedScorerDefinitionType,\n StorageCreateScorerDefinitionInput,\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput,\n StorageListScorerDefinitionsOutput,\n StorageListScorerDefinitionsResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// Scorer Definition Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of a scorer definition's content.\n * Config fields are top-level on the version row (no nested snapshot object).\n */\nexport interface ScorerDefinitionVersion extends StorageScorerDefinitionSnapshotType, VersionBase {\n /** ID of the scorer definition this version belongs to */\n scorerDefinitionId: string;\n}\n\n/**\n * Input for creating a new scorer definition version.\n * Config fields are top-level (no nested snapshot object).\n */\nexport interface CreateScorerDefinitionVersionInput\n extends StorageScorerDefinitionSnapshotType, CreateVersionInputBase {\n /** ID of the scorer definition this version belongs to */\n scorerDefinitionId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type ScorerDefinitionVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type ScorerDefinitionVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing scorer definition versions with pagination and sorting.\n */\nexport interface ListScorerDefinitionVersionsInput extends ListVersionsInputBase {\n /** ID of the scorer definition to list versions for */\n scorerDefinitionId: string;\n}\n\n/**\n * Output for listing scorer definition versions with pagination info.\n */\nexport interface ListScorerDefinitionVersionsOutput extends ListVersionsOutputBase<ScorerDefinitionVersion> {}\n\n// ============================================================================\n// ScorerDefinitionsStorage Base Class\n// ============================================================================\n\nexport abstract class ScorerDefinitionsStorage extends VersionedStorageDomain<\n StorageScorerDefinitionType,\n StorageScorerDefinitionSnapshotType,\n StorageResolvedScorerDefinitionType,\n ScorerDefinitionVersion,\n CreateScorerDefinitionVersionInput,\n ListScorerDefinitionVersionsInput,\n ListScorerDefinitionVersionsOutput,\n { scorerDefinition: StorageCreateScorerDefinitionInput },\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput | undefined,\n StorageListScorerDefinitionsOutput,\n StorageListScorerDefinitionsResolvedOutput\n> {\n protected readonly listKey = 'scorerDefinitions';\n protected readonly versionMetadataFields = [\n 'id',\n 'scorerDefinitionId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof ScorerDefinitionVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'SCORER_DEFINITIONS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageScorerDefinitionType,\n StorageCreateScorerDefinitionInput,\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput,\n StorageListScorerDefinitionsOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n ScorerDefinitionVersion,\n CreateScorerDefinitionVersionInput,\n ListScorerDefinitionVersionsInput,\n ListScorerDefinitionVersionsOutput,\n ScorerDefinitionVersionOrderBy,\n ScorerDefinitionVersionSortDirection,\n} from './base';\nimport { ScorerDefinitionsStorage } from './base';\n\nexport class InMemoryScorerDefinitionsStorage extends ScorerDefinitionsStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.scorerDefinitions.clear();\n this.db.scorerDefinitionVersions.clear();\n }\n\n // ==========================================================================\n // Scorer Definition CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageScorerDefinitionType | null> {\n const scorer = this.db.scorerDefinitions.get(id);\n return scorer ? this.deepCopyScorer(scorer) : null;\n }\n\n async create(input: { scorerDefinition: StorageCreateScorerDefinitionInput }): Promise<StorageScorerDefinitionType> {\n const { scorerDefinition } = input;\n\n if (this.db.scorerDefinitions.has(scorerDefinition.id)) {\n throw new Error(`Scorer definition with id ${scorerDefinition.id} already exists`);\n }\n\n const now = new Date();\n const newScorer: StorageScorerDefinitionType = {\n id: scorerDefinition.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: scorerDefinition.authorId,\n metadata: scorerDefinition.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.scorerDefinitions.set(scorerDefinition.id, newScorer);\n\n // Extract config fields from the flat input (everything except scorer-record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n scorerDefinitionId: scorerDefinition.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin scorer record\n return this.deepCopyScorer(newScorer);\n }\n\n async update(input: StorageUpdateScorerDefinitionInput): Promise<StorageScorerDefinitionType> {\n const { id, ...updates } = input;\n\n const existingScorer = this.db.scorerDefinitions.get(id);\n if (!existingScorer) {\n throw new Error(`Scorer definition with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the scorer record\n const updatedScorer: StorageScorerDefinitionType = {\n ...existingScorer,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageScorerDefinitionType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingScorer.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated scorer record\n this.db.scorerDefinitions.set(id, updatedScorer);\n return this.deepCopyScorer(updatedScorer);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.scorerDefinitions.delete(id);\n // Also delete all versions for this scorer definition\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListScorerDefinitionsInput): Promise<StorageListScorerDefinitionsOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all scorer definitions and apply filters\n let scorers = Array.from(this.db.scorerDefinitions.values());\n\n // Filter by status\n if (status) {\n scorers = scorers.filter(scorer => scorer.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n scorers = scorers.filter(scorer => scorer.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n scorers = scorers.filter(scorer => {\n if (!scorer.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(scorer.metadata![key], value));\n });\n }\n\n // Sort filtered scorer definitions\n const sortedScorers = this.sortScorers(scorers, field, direction);\n\n // Deep clone scorers to avoid mutation\n const clonedScorers = sortedScorers.map(scorer => this.deepCopyScorer(scorer));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n scorerDefinitions: clonedScorers.slice(offset, offset + perPage),\n total: clonedScorers.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedScorers.length,\n };\n }\n\n // ==========================================================================\n // Scorer Definition Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateScorerDefinitionVersionInput): Promise<ScorerDefinitionVersion> {\n // Check if version with this ID already exists\n if (this.db.scorerDefinitionVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (scorerDefinitionId, versionNumber) pair\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === input.scorerDefinitionId && version.versionNumber === input.versionNumber) {\n throw new Error(\n `Version number ${input.versionNumber} already exists for scorer definition ${input.scorerDefinitionId}`,\n );\n }\n }\n\n const version: ScorerDefinitionVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.scorerDefinitionVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<ScorerDefinitionVersion | null> {\n const version = this.db.scorerDefinitionVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(scorerDefinitionId: string, versionNumber: number): Promise<ScorerDefinitionVersion | null> {\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === scorerDefinitionId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(scorerDefinitionId: string): Promise<ScorerDefinitionVersion | null> {\n let latest: ScorerDefinitionVersion | null = null;\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === scorerDefinitionId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListScorerDefinitionVersionsInput): Promise<ListScorerDefinitionVersionsOutput> {\n const { scorerDefinitionId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by scorerDefinitionId\n let versions = Array.from(this.db.scorerDefinitionVersions.values()).filter(\n v => v.scorerDefinitionId === scorerDefinitionId,\n );\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.scorerDefinitionVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.scorerDefinitionVersions.entries()) {\n if (version.scorerDefinitionId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.scorerDefinitionVersions.delete(id);\n }\n }\n\n async countVersions(scorerDefinitionId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === scorerDefinitionId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyScorer(scorer: StorageScorerDefinitionType): StorageScorerDefinitionType {\n return {\n ...scorer,\n metadata: scorer.metadata ? { ...scorer.metadata } : scorer.metadata,\n };\n }\n\n private deepCopyVersion(version: ScorerDefinitionVersion): ScorerDefinitionVersion {\n return {\n ...version,\n model: version.model ? JSON.parse(JSON.stringify(version.model)) : version.model,\n scoreRange: version.scoreRange ? JSON.parse(JSON.stringify(version.scoreRange)) : version.scoreRange,\n presetConfig: version.presetConfig ? JSON.parse(JSON.stringify(version.presetConfig)) : version.presetConfig,\n defaultSampling: version.defaultSampling\n ? JSON.parse(JSON.stringify(version.defaultSampling))\n : version.defaultSampling,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortScorers(\n scorers: StorageScorerDefinitionType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageScorerDefinitionType[] {\n return scorers.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: ScorerDefinitionVersion[],\n field: ScorerDefinitionVersionOrderBy,\n direction: ScorerDefinitionVersionSortDirection,\n ): ScorerDefinitionVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageScorerDefinitionType,\n StorageCreateScorerDefinitionInput,\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput,\n StorageListScorerDefinitionsOutput,\n} from '../../types';\nimport type {\n ScorerDefinitionVersion,\n CreateScorerDefinitionVersionInput,\n ListScorerDefinitionVersionsInput,\n ListScorerDefinitionVersionsOutput,\n} from './base';\nimport { ScorerDefinitionsStorage } from './base';\n\nexport class FilesystemScorerDefinitionsStorage extends ScorerDefinitionsStorage {\n private helpers: FilesystemVersionedHelpers<StorageScorerDefinitionType, ScorerDefinitionVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'scorer-definitions.json',\n parentIdField: 'scorerDefinitionId',\n name: 'FilesystemScorerDefinitionsStorage',\n versionMetadataFields: [\n 'id',\n 'scorerDefinitionId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageScorerDefinitionType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { scorerDefinition: StorageCreateScorerDefinitionInput }): Promise<StorageScorerDefinitionType> {\n const { scorerDefinition } = input;\n const now = new Date();\n const entity: StorageScorerDefinitionType = {\n id: scorerDefinition.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: scorerDefinition.authorId,\n metadata: scorerDefinition.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(scorerDefinition.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n scorerDefinitionId: scorerDefinition.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateScorerDefinitionVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateScorerDefinitionInput): Promise<StorageScorerDefinitionType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListScorerDefinitionsInput): Promise<StorageListScorerDefinitionsOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'scorerDefinitions',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListScorerDefinitionsOutput;\n }\n\n async createVersion(input: CreateScorerDefinitionVersionInput): Promise<ScorerDefinitionVersion> {\n return this.helpers.createVersion(input as ScorerDefinitionVersion);\n }\n\n async getVersion(id: string): Promise<ScorerDefinitionVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(scorerDefinitionId: string, versionNumber: number): Promise<ScorerDefinitionVersion | null> {\n return this.helpers.getVersionByNumber(scorerDefinitionId, versionNumber);\n }\n\n async getLatestVersion(scorerDefinitionId: string): Promise<ScorerDefinitionVersion | null> {\n return this.helpers.getLatestVersion(scorerDefinitionId);\n }\n\n async listVersions(input: ListScorerDefinitionVersionsInput): Promise<ListScorerDefinitionVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'scorerDefinitionId');\n return result as ListScorerDefinitionVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(scorerDefinitionId: string): Promise<number> {\n return this.helpers.countVersions(scorerDefinitionId);\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunkQJ3FDYCK_cjs = require('./chunk-QJ3FDYCK.cjs'); | ||
| // src/signals/task-signal-provider.ts | ||
| var TaskSignalProvider = class extends chunkQJ3FDYCK_cjs.SignalProvider { | ||
| id = "task-signals"; | ||
| #processor = new chunkQJ3FDYCK_cjs.TaskStateProcessor(); | ||
| getInputProcessors() { | ||
| return [this.#processor]; | ||
| } | ||
| getTools() { | ||
| return { | ||
| task_write: chunkQJ3FDYCK_cjs.taskWriteTool, | ||
| task_update: chunkQJ3FDYCK_cjs.taskUpdateTool, | ||
| task_complete: chunkQJ3FDYCK_cjs.taskCompleteTool, | ||
| task_check: chunkQJ3FDYCK_cjs.taskCheckTool | ||
| }; | ||
| } | ||
| }; | ||
| exports.TaskSignalProvider = TaskSignalProvider; | ||
| //# sourceMappingURL=chunk-7QFVYQT7.cjs.map | ||
| //# sourceMappingURL=chunk-7QFVYQT7.cjs.map |
| {"version":3,"sources":["../src/signals/task-signal-provider.ts"],"names":["SignalProvider","TaskStateProcessor","taskWriteTool","taskUpdateTool","taskCompleteTool","taskCheckTool"],"mappings":";;;;;AA0CO,IAAM,kBAAA,GAAN,cAAiCA,gCAAA,CAA+B;AAAA,EAC5D,EAAA,GAAK,cAAA;AAAA,EAEL,UAAA,GAAa,IAAIC,oCAAA,EAAmB;AAAA,EAE7C,kBAAA,GAAiD;AAC/C,IAAA,OAAO,CAAC,KAAK,UAAU,CAAA;AAAA,EACzB;AAAA,EAEA,QAAA,GAAW;AACT,IAAA,OAAO;AAAA,MACL,UAAA,EAAYC,+BAAA;AAAA,MACZ,WAAA,EAAaC,gCAAA;AAAA,MACb,aAAA,EAAeC,kCAAA;AAAA,MACf,UAAA,EAAYC;AAAA,KACd;AAAA,EACF;AACF","file":"chunk-7QFVYQT7.cjs","sourcesContent":["import type { InputProcessorOrWorkflow } from '../processors';\nimport { TaskStateProcessor } from '../tools/builtin/task-state-processor';\nimport { taskCheckTool, taskCompleteTool, taskUpdateTool, taskWriteTool } from '../tools/builtin/task-tools';\n\nimport { SignalProvider } from './signal-provider';\n\n/**\n * Bundles the built-in task tools and the {@link TaskStateProcessor} behind a\n * single agent registration.\n *\n * The task list is held in the thread-scoped `tasks` storage domain (the\n * TaskStore) and projected onto the agent state-signal lane by\n * `TaskStateProcessor`. Wiring task tracking by hand means registering all four\n * task tools **and** the processor, and keeping them in sync — forget the\n * processor and the tools work for a single turn but silently lose the list\n * across turns. This provider wires both together so that cannot happen.\n *\n * Task tracking requires a memory-backed thread (`threadId` + `resourceId`) and\n * a Mastra `storage` instance (the `tasks` domain is always wired in-memory by\n * default). Without memory the tools no-op and report that task tracking\n * requires agent memory.\n *\n * @example\n * ```ts\n * import { Agent } from '@mastra/core/agent';\n * import { TaskSignalProvider } from '@mastra/core/signals';\n *\n * const agent = new Agent({\n * name: 'coder',\n * instructions: '...',\n * model,\n * memory,\n * signals: [new TaskSignalProvider()],\n * });\n * ```\n *\n * The Agent automatically merges the tools into its toolset and registers the\n * processor on its input-processor chain (which propagates the Mastra instance\n * so the processor can resolve the TaskStore).\n *\n * @experimental Agent signals are experimental and may change in a future release.\n */\nexport class TaskSignalProvider extends SignalProvider<'task-signals'> {\n readonly id = 'task-signals';\n\n readonly #processor = new TaskStateProcessor();\n\n getInputProcessors(): InputProcessorOrWorkflow[] {\n return [this.#processor];\n }\n\n getTools() {\n return {\n task_write: taskWriteTool,\n task_update: taskUpdateTool,\n task_complete: taskCompleteTool,\n task_check: taskCheckTool,\n };\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunkDZ44ZU2T_cjs = require('./chunk-DZ44ZU2T.cjs'); | ||
| var chunkXB4FLS7A_cjs = require('./chunk-XB4FLS7A.cjs'); | ||
| var chunkCMKSC37Z_cjs = require('./chunk-CMKSC37Z.cjs'); | ||
| var chunkSZ2THGT4_cjs = require('./chunk-SZ2THGT4.cjs'); | ||
| var chunkLP4WZA6D_cjs = require('./chunk-LP4WZA6D.cjs'); | ||
| var chunkW7RLUWK5_cjs = require('./chunk-W7RLUWK5.cjs'); | ||
| var chunkDRYYU2XF_cjs = require('./chunk-DRYYU2XF.cjs'); | ||
| var chunkWSD4JNMB_cjs = require('./chunk-WSD4JNMB.cjs'); | ||
| var chunkPJIAL3WK_cjs = require('./chunk-PJIAL3WK.cjs'); | ||
| var chunkXSOONORA_cjs = require('./chunk-XSOONORA.cjs'); | ||
| var crypto = require('crypto'); | ||
| var jsonToZod = require('@mastra/schema-compat/json-to-zod'); | ||
| var v4 = require('zod/v4'); | ||
| var schemaCompat = require('@mastra/schema-compat'); | ||
| var web = require('stream/web'); | ||
| var ToolStream = class extends web.WritableStream { | ||
| prefix; | ||
| callId; | ||
| name; | ||
| runId; | ||
| writeFn; | ||
| constructor({ | ||
| prefix, | ||
| callId, | ||
| name, | ||
| runId | ||
| }, writeFn) { | ||
| super({ | ||
| async write(chunk) { | ||
| await getInstance()._write(chunk); | ||
| } | ||
| }); | ||
| const self = this; | ||
| function getInstance() { | ||
| return self; | ||
| } | ||
| this.prefix = prefix; | ||
| this.callId = callId; | ||
| this.name = name; | ||
| this.runId = runId; | ||
| this.writeFn = writeFn; | ||
| } | ||
| async _write(data) { | ||
| if (this.writeFn) { | ||
| await this.writeFn({ | ||
| type: `${this.prefix}-output`, | ||
| runId: this.runId, | ||
| from: "USER", | ||
| payload: { | ||
| output: data, | ||
| ...this.prefix === "workflow-step" ? { | ||
| runId: this.runId, | ||
| stepName: this.name | ||
| } : { | ||
| [`${this.prefix}CallId`]: this.callId, | ||
| [`${this.prefix}Name`]: this.name | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| async write(data) { | ||
| await this._write(data); | ||
| } | ||
| async custom(data) { | ||
| if (this.writeFn) { | ||
| await this.writeFn(data); | ||
| } | ||
| } | ||
| }; | ||
| // src/tools/types.ts | ||
| var noopObserve = { | ||
| async span(_name, fn) { | ||
| return fn(); | ||
| }, | ||
| log() { | ||
| } | ||
| }; | ||
| // src/tools/tool-builder/builder.ts | ||
| function mergeRequestContexts(closureRC, execRC) { | ||
| if (!closureRC && !execRC) return new chunkPJIAL3WK_cjs.RequestContext(); | ||
| if (!closureRC) return execRC instanceof chunkPJIAL3WK_cjs.RequestContext ? execRC : new chunkPJIAL3WK_cjs.RequestContext(); | ||
| if (!execRC || !(execRC instanceof chunkPJIAL3WK_cjs.RequestContext) || execRC.size() === 0) return closureRC; | ||
| const merged = new chunkPJIAL3WK_cjs.RequestContext(); | ||
| for (const [key, value] of execRC.entries()) { | ||
| merged.set(key, value); | ||
| } | ||
| for (const [key, value] of closureRC.entries()) { | ||
| merged.set(key, value); | ||
| } | ||
| return merged; | ||
| } | ||
| function isZodV4Schema(schema) { | ||
| const def = schema?._def; | ||
| return !!def && typeof def.type === "string" && !def.typeName; | ||
| } | ||
| function buildJsonOverrideSchema(originalSchema, splicedJsonSchema, injectedKeys) { | ||
| const fallback = chunkXB4FLS7A_cjs.toStandardSchema(splicedJsonSchema); | ||
| const original = originalSchema; | ||
| const originalValidate = original?.["~standard"]?.validate?.bind(original["~standard"]); | ||
| const splicedProperties = splicedJsonSchema && typeof splicedJsonSchema === "object" && "properties" in splicedJsonSchema ? splicedJsonSchema.properties ?? {} : {}; | ||
| const injectedProperties = {}; | ||
| for (const key of injectedKeys) { | ||
| if (splicedProperties[key] !== void 0) injectedProperties[key] = splicedProperties[key]; | ||
| } | ||
| const injectedValidator = chunkXB4FLS7A_cjs.toStandardSchema({ | ||
| type: "object", | ||
| properties: injectedProperties, | ||
| additionalProperties: false | ||
| }); | ||
| const stripInjected = (input) => { | ||
| if (!input || typeof input !== "object" || Array.isArray(input)) return { stripped: input, injected: {} }; | ||
| const injected = {}; | ||
| const stripped = {}; | ||
| for (const [k, v] of Object.entries(input)) { | ||
| if (injectedKeys.includes(k)) injected[k] = v; | ||
| else stripped[k] = v; | ||
| } | ||
| return { stripped, injected }; | ||
| }; | ||
| const validate = (input) => { | ||
| const { stripped, injected } = stripInjected(input); | ||
| const baseResult = originalValidate ? originalValidate(stripped) : fallback["~standard"].validate(stripped); | ||
| const injectedResult = injectedValidator["~standard"].validate(injected); | ||
| const combine = (base, inj) => { | ||
| const baseIssues = "issues" in base ? base.issues ?? [] : []; | ||
| const injIssues = "issues" in inj ? inj.issues ?? [] : []; | ||
| if (baseIssues.length || injIssues.length) { | ||
| return { issues: [...baseIssues, ...injIssues] }; | ||
| } | ||
| const baseValue = base.value; | ||
| const injValue = inj.value; | ||
| if (baseValue && typeof baseValue === "object" && !Array.isArray(baseValue)) { | ||
| const injMerged = injValue && typeof injValue === "object" && !Array.isArray(injValue) ? injValue : injected; | ||
| return { value: { ...baseValue, ...injMerged } }; | ||
| } | ||
| return base; | ||
| }; | ||
| const baseIsPromise = baseResult && typeof baseResult.then === "function"; | ||
| const injIsPromise = injectedResult && typeof injectedResult.then === "function"; | ||
| if (baseIsPromise || injIsPromise) { | ||
| return Promise.all([baseResult, injectedResult]).then( | ||
| ([b, i]) => combine( | ||
| b, | ||
| i | ||
| ) | ||
| ); | ||
| } | ||
| return combine( | ||
| baseResult, | ||
| injectedResult | ||
| ); | ||
| }; | ||
| return { | ||
| "~standard": { | ||
| version: 1, | ||
| vendor: "mastra-json-override", | ||
| validate, | ||
| jsonSchema: fallback["~standard"].jsonSchema | ||
| } | ||
| }; | ||
| } | ||
| var CoreToolBuilder = class extends chunkWSD4JNMB_cjs.MastraBase { | ||
| originalTool; | ||
| options; | ||
| logType; | ||
| constructor(input) { | ||
| super({ name: "CoreToolBuilder" }); | ||
| this.originalTool = input.originalTool; | ||
| this.options = input.options; | ||
| this.logType = input.logType; | ||
| const isBackgroundEligible = !!input.backgroundTaskEnabled; | ||
| const isResumableTool = input.autoResumeSuspendedTools || this.originalTool.id?.startsWith("agent-") || this.originalTool.id?.startsWith("workflow-"); | ||
| if (!chunkDZ44ZU2T_cjs.isVercelTool(this.originalTool) && !chunkDZ44ZU2T_cjs.isProviderDefinedTool(this.originalTool)) { | ||
| if (isBackgroundEligible || isResumableTool) { | ||
| let schema = this.originalTool.inputSchema; | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| if (!schema) { | ||
| schema = v4.z.object({}); | ||
| } | ||
| if (chunkCMKSC37Z_cjs.isZodObject(schema) && isZodV4Schema(schema)) { | ||
| let nextSchema = schema; | ||
| if (isBackgroundEligible) { | ||
| nextSchema = chunkCMKSC37Z_cjs.safeExtendZodObject(nextSchema, { | ||
| _background: chunkDRYYU2XF_cjs.backgroundOverrideZodSchema | ||
| }); | ||
| } | ||
| if (isResumableTool) { | ||
| nextSchema = chunkCMKSC37Z_cjs.safeExtendZodObject(nextSchema, { | ||
| suspendedToolRunId: v4.z.string().describe("The runId of the suspended tool").nullable().optional(), | ||
| resumeData: v4.z.any().describe("The resumeData object created from the resumeSchema of suspended tool").optional() | ||
| }); | ||
| } | ||
| this.originalTool.inputSchema = nextSchema; | ||
| } else { | ||
| const standardSchema = chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(schema) ? schema : chunkXB4FLS7A_cjs.toStandardSchema(schema); | ||
| const jsonSchema2 = chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(standardSchema, { io: "input" }); | ||
| if (jsonSchema2 && typeof jsonSchema2 === "object" && jsonSchema2.type === "object") { | ||
| const properties = { ...jsonSchema2.properties ?? {} }; | ||
| const injectedKeys = []; | ||
| if (isBackgroundEligible) { | ||
| properties._background = chunkDRYYU2XF_cjs.backgroundOverrideJsonSchema; | ||
| injectedKeys.push("_background"); | ||
| } | ||
| if (isResumableTool) { | ||
| properties.suspendedToolRunId = { | ||
| type: ["string", "null"], | ||
| description: "The runId of the suspended tool" | ||
| }; | ||
| properties.resumeData = { | ||
| description: "The resumeData object created from the resumeSchema of suspended tool" | ||
| }; | ||
| injectedKeys.push("suspendedToolRunId", "resumeData"); | ||
| } | ||
| this.originalTool.inputSchema = buildJsonOverrideSchema( | ||
| schema, | ||
| { ...jsonSchema2, properties }, | ||
| injectedKeys | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // Helper to get parameters based on tool type | ||
| getParameters = () => { | ||
| if (chunkDZ44ZU2T_cjs.isVercelTool(this.originalTool)) { | ||
| let schema2 = this.originalTool.parameters ?? ("inputSchema" in this.originalTool ? this.originalTool.inputSchema : void 0) ?? v4.z.object({}); | ||
| if (typeof schema2 === "function") { | ||
| schema2 = schema2(); | ||
| } | ||
| return schema2; | ||
| } | ||
| let schema = this.originalTool.inputSchema; | ||
| if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(schema)) { | ||
| return schema; | ||
| } | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| }; | ||
| getOutputSchema = () => { | ||
| if ("outputSchema" in this.originalTool) { | ||
| let schema = this.originalTool.outputSchema; | ||
| if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(schema)) { | ||
| return schema; | ||
| } | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| } | ||
| return null; | ||
| }; | ||
| getResumeSchema = () => { | ||
| if ("resumeSchema" in this.originalTool) { | ||
| let schema = this.originalTool.resumeSchema; | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| } | ||
| return null; | ||
| }; | ||
| getSuspendSchema = () => { | ||
| if ("suspendSchema" in this.originalTool) { | ||
| let schema = this.originalTool.suspendSchema; | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| } | ||
| return null; | ||
| }; | ||
| // For provider-defined tools, we need to include all required properties | ||
| // AI SDK v5 uses type: 'provider-defined', AI SDK v6 uses type: 'provider' | ||
| buildProviderTool(tool) { | ||
| if ("type" in tool && (tool.type === "provider-defined" || tool.type === "provider") && "id" in tool && typeof tool.id === "string" && tool.id.includes(".")) { | ||
| let parameters = "parameters" in tool ? tool.parameters : "inputSchema" in tool ? tool.inputSchema : void 0; | ||
| if (typeof parameters === "function") { | ||
| parameters = parameters(); | ||
| } | ||
| let outputSchema = "outputSchema" in tool ? tool.outputSchema : void 0; | ||
| if (typeof outputSchema === "function") { | ||
| outputSchema = outputSchema(); | ||
| } | ||
| let processedParameters; | ||
| if (parameters !== void 0 && parameters !== null) { | ||
| if (typeof parameters === "object" && "jsonSchema" in parameters) { | ||
| processedParameters = parameters; | ||
| } else if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(parameters)) { | ||
| const jsonSchema2 = chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(parameters, { io: "input" }); | ||
| processedParameters = { jsonSchema: jsonSchema2 }; | ||
| } else { | ||
| processedParameters = schemaCompat.convertZodSchemaToAISDKSchema(parameters); | ||
| } | ||
| } else { | ||
| processedParameters = { | ||
| jsonSchema: { | ||
| type: "object", | ||
| properties: {}, | ||
| additionalProperties: false | ||
| } | ||
| }; | ||
| } | ||
| let processedOutputSchema; | ||
| if (outputSchema !== void 0 && outputSchema !== null) { | ||
| if (typeof outputSchema === "object" && "jsonSchema" in outputSchema) { | ||
| processedOutputSchema = outputSchema; | ||
| } else if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(outputSchema)) { | ||
| const jsonSchema2 = chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(outputSchema); | ||
| processedOutputSchema = { jsonSchema: jsonSchema2 }; | ||
| } else { | ||
| processedOutputSchema = schemaCompat.convertZodSchemaToAISDKSchema(outputSchema); | ||
| } | ||
| } | ||
| return { | ||
| ...processedOutputSchema ? { outputSchema: processedOutputSchema } : {}, | ||
| type: "provider-defined", | ||
| id: tool.id, | ||
| // V5 SDK factories set a hardcoded `name` (e.g. "web_search" for | ||
| // anthropic.web_search_20250305). Preserve it so that when this tool | ||
| // is later used with a V6 provider, the bidirectional toolNameMapping | ||
| // resolves the correct model-facing name instead of the versioned ID. | ||
| ..."name" in tool && typeof tool.name === "string" ? { name: tool.name } : {}, | ||
| args: "args" in this.originalTool ? this.originalTool.args : {}, | ||
| description: tool.description, | ||
| parameters: processedParameters, | ||
| execute: this.originalTool.execute ? this.createExecute( | ||
| this.originalTool, | ||
| { ...this.options, description: this.originalTool.description }, | ||
| this.logType | ||
| ) : void 0, | ||
| toModelOutput: "toModelOutput" in this.originalTool ? this.originalTool.toModelOutput : void 0, | ||
| transform: "transform" in this.originalTool ? this.originalTool.transform : void 0, | ||
| inputExamples: "inputExamples" in this.originalTool ? this.originalTool.inputExamples : void 0 | ||
| }; | ||
| } | ||
| return void 0; | ||
| } | ||
| createLogMessageOptions({ agentName, toolName, type }) { | ||
| const toolType = type === "toolset" ? "toolset" : "tool"; | ||
| return { | ||
| start: `Executing ${toolType}`, | ||
| error: `Failed ${toolType} execution`, | ||
| logData: { agent: agentName, tool: toolName } | ||
| }; | ||
| } | ||
| createExecute(tool, options, logType) { | ||
| const { | ||
| logger, | ||
| mastra: _mastra, | ||
| memory: _memory, | ||
| requestContext, | ||
| model, | ||
| tracingContext: _tracingContext, | ||
| tracingPolicy: _tracingPolicy, | ||
| ...rest | ||
| } = options; | ||
| const logModelObject = { | ||
| modelId: model?.modelId, | ||
| provider: model?.provider, | ||
| specificationVersion: model?.specificationVersion | ||
| }; | ||
| const { start, logData } = this.createLogMessageOptions({ | ||
| agentName: options.agentName, | ||
| toolName: options.name, | ||
| type: logType | ||
| }); | ||
| const mcpMeta = !chunkDZ44ZU2T_cjs.isVercelTool(tool) && "mcpMetadata" in tool ? tool.mcpMetadata : void 0; | ||
| const execFunction = async (args, execOptions, toolSpan) => { | ||
| try { | ||
| let result; | ||
| let suspendData = null; | ||
| if (chunkDZ44ZU2T_cjs.isVercelTool(tool)) { | ||
| result = await chunkLP4WZA6D_cjs.executeWithContext({ | ||
| span: toolSpan, | ||
| fn: async () => tool?.execute?.(args, execOptions) | ||
| }); | ||
| } else { | ||
| const wrappedMastra = options.mastra ? chunkSZ2THGT4_cjs.wrapMastra(options.mastra, { currentSpan: toolSpan }) : options.mastra; | ||
| const resumeSchema = this.getResumeSchema(); | ||
| const baseContext = { | ||
| threadId: options.threadId, | ||
| resourceId: options.resourceId, | ||
| mastra: wrappedMastra, | ||
| memory: options.memory, | ||
| runId: options.runId, | ||
| requestContext: mergeRequestContexts(options.requestContext, execOptions.requestContext), | ||
| actor: execOptions.actor, | ||
| // Workspace for file operations and command execution | ||
| // Execution-time workspace (from prepareStep/processInputStep) takes precedence over build-time workspace | ||
| workspace: execOptions.workspace ?? options.workspace, | ||
| // Browser for web automation (lazily initialized on first use) | ||
| browser: options.browser, | ||
| observe: execOptions.observe ?? noopObserve, | ||
| writer: new ToolStream( | ||
| { | ||
| prefix: "tool", | ||
| callId: execOptions.toolCallId, | ||
| name: options.name, | ||
| runId: options.runId | ||
| }, | ||
| options.outputWriter || execOptions.outputWriter | ||
| ), | ||
| ...chunkSZ2THGT4_cjs.createObservabilityContext({ currentSpan: toolSpan }), | ||
| abortSignal: execOptions.abortSignal, | ||
| suspend: (args2, suspendOptions) => { | ||
| suspendData = args2; | ||
| const newSuspendOptions = { | ||
| ...suspendOptions ?? {}, | ||
| resumeSchema: suspendOptions?.resumeSchema ?? (resumeSchema ? JSON.stringify(chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(chunkXB4FLS7A_cjs.toStandardSchema(resumeSchema), { io: "input" })) : void 0) | ||
| }; | ||
| return execOptions.suspend?.(args2, newSuspendOptions); | ||
| }, | ||
| resumeData: execOptions.resumeData | ||
| }; | ||
| const isAgentExecution = execOptions.toolCallId && execOptions.messages || options.agentName && options.threadId && !options.workflowId; | ||
| const isWorkflowExecution = !isAgentExecution && (options.workflow || options.workflowId); | ||
| let toolContext; | ||
| if (isAgentExecution) { | ||
| const { suspend, resumeData: resumeData2, threadId, resourceId, ...restBaseContext } = baseContext; | ||
| toolContext = { | ||
| ...restBaseContext, | ||
| agent: { | ||
| agentId: options.agentId || "", | ||
| toolCallId: execOptions.toolCallId || "", | ||
| messages: execOptions.messages || [], | ||
| suspend, | ||
| resumeData: resumeData2, | ||
| threadId, | ||
| resourceId, | ||
| outputWriter: options.outputWriter || execOptions.outputWriter, | ||
| flushMessages: execOptions.flushMessages | ||
| } | ||
| }; | ||
| } else if (isWorkflowExecution) { | ||
| const { suspend, resumeData: resumeData2, ...restBaseContext } = baseContext; | ||
| toolContext = { | ||
| ...restBaseContext, | ||
| workflow: options.workflow || { | ||
| runId: options.runId, | ||
| workflowId: options.workflowId, | ||
| state: options.state, | ||
| setState: options.setState, | ||
| suspend, | ||
| resumeData: resumeData2 | ||
| } | ||
| }; | ||
| } else if (execOptions.mcp) { | ||
| toolContext = { | ||
| ...baseContext, | ||
| mcp: execOptions.mcp | ||
| }; | ||
| } else { | ||
| toolContext = baseContext; | ||
| } | ||
| const resumeData = execOptions.resumeData; | ||
| if (resumeData) { | ||
| const resumeValidation = chunkDZ44ZU2T_cjs.validateToolInput(resumeSchema, resumeData, options.name); | ||
| if (resumeValidation.error) { | ||
| logger?.warn(resumeValidation.error.message); | ||
| toolSpan?.end({ output: resumeValidation.error, attributes: { success: false } }); | ||
| return resumeValidation.error; | ||
| } | ||
| } | ||
| result = await chunkLP4WZA6D_cjs.executeWithContext({ span: toolSpan, fn: async () => tool?.execute?.(args, toolContext) }); | ||
| } | ||
| if (suspendData) { | ||
| const suspendSchema = this.getSuspendSchema(); | ||
| const suspendValidation = chunkDZ44ZU2T_cjs.validateToolSuspendData(suspendSchema, suspendData, options.name); | ||
| if (suspendValidation.error) { | ||
| logger?.warn(suspendValidation.error.message); | ||
| toolSpan?.end({ output: suspendValidation.error, attributes: { success: false } }); | ||
| return suspendValidation.error; | ||
| } | ||
| } | ||
| const shouldSkipValidation = typeof result === "undefined" && !!suspendData; | ||
| if (shouldSkipValidation) { | ||
| toolSpan?.end({ output: result, attributes: { success: true } }); | ||
| return result; | ||
| } | ||
| if (chunkDZ44ZU2T_cjs.isVercelTool(tool)) { | ||
| const outputSchema = this.getOutputSchema(); | ||
| const outputValidation = chunkDZ44ZU2T_cjs.validateToolOutput(outputSchema, result, options.name, false); | ||
| if (outputValidation.error) { | ||
| logger?.warn(outputValidation.error.message); | ||
| toolSpan?.end({ output: outputValidation.error, attributes: { success: false } }); | ||
| return outputValidation.error; | ||
| } | ||
| result = outputValidation.data; | ||
| } | ||
| toolSpan?.end({ output: result, attributes: { success: true } }); | ||
| return result; | ||
| } catch (error) { | ||
| toolSpan?.error({ error, attributes: { success: false } }); | ||
| throw error; | ||
| } | ||
| }; | ||
| return async (args, execOptions) => { | ||
| let logger2 = options.logger || this.logger; | ||
| const tracingContext = execOptions?.tracingContext || options.tracingContext; | ||
| const toolRequestContext = execOptions?.requestContext ?? options.requestContext; | ||
| const toolSpan = chunkLP4WZA6D_cjs.getOrCreateSpan({ | ||
| type: mcpMeta ? "mcp_tool_call" /* MCP_TOOL_CALL */ : "tool_call" /* TOOL_CALL */, | ||
| name: mcpMeta ? `mcp_tool: '${options.name}' on '${mcpMeta.serverName}'` : `tool: '${options.name}'`, | ||
| input: args, | ||
| entityType: chunkLP4WZA6D_cjs.EntityType.TOOL, | ||
| entityId: options.name, | ||
| entityName: options.name, | ||
| attributes: mcpMeta ? { | ||
| mcpServer: mcpMeta.serverName, | ||
| serverVersion: mcpMeta.serverVersion, | ||
| toolDescription: options.description | ||
| } : { | ||
| toolDescription: options.description, | ||
| toolType: logType || "tool" | ||
| }, | ||
| tracingPolicy: options.tracingPolicy, | ||
| tracingContext, | ||
| requestContext: toolRequestContext, | ||
| mastra: options.mastra && "observability" in options.mastra ? options.mastra : void 0 | ||
| }); | ||
| const fgaProvider = options.mastra?.getServer?.()?.fga; | ||
| const user = toolRequestContext?.get("user"); | ||
| if (fgaProvider) { | ||
| const { getAgentToolFGAResourceId, getMCPToolFGAResourceId, getStandaloneToolFGAResourceId, requireFGA } = await import('./fga-check-BIMTM2YF.cjs'); | ||
| const toolResourceId = mcpMeta?.serverName ? getMCPToolFGAResourceId(mcpMeta.serverName, options.name) : options.agentId ? getAgentToolFGAResourceId(options.agentId, options.name) : getStandaloneToolFGAResourceId(options.name); | ||
| await requireFGA({ | ||
| fgaProvider, | ||
| user, | ||
| resource: { type: "tool", id: toolResourceId }, | ||
| permission: chunkW7RLUWK5_cjs.MastraFGAPermissions.TOOLS_EXECUTE, | ||
| requestContext: toolRequestContext, | ||
| actor: execOptions?.actor, | ||
| context: { | ||
| resourceId: options.resourceId | ||
| }, | ||
| metadata: { | ||
| toolName: options.name, | ||
| agentId: options.agentId, | ||
| agentName: options.agentName, | ||
| runId: options.runId, | ||
| threadId: options.threadId, | ||
| executionResourceId: options.resourceId, | ||
| mcpMetadata: mcpMeta | ||
| } | ||
| }); | ||
| } | ||
| try { | ||
| logger2.debug(start, { ...logData, ...rest, model: logModelObject, args }); | ||
| const isResuming = !!execOptions?.resumeData; | ||
| const parameters = this.getParameters(); | ||
| if (!isResuming) { | ||
| const { data, error } = chunkDZ44ZU2T_cjs.validateToolInput(parameters, args, options.name); | ||
| const suspendedToolRunIdErrToIgnore = error?.message?.includes("suspendedToolRunId: Required") && !args?.resumeData; | ||
| if (error && !suspendedToolRunIdErrToIgnore) { | ||
| logger2.warn("Tool input validation failed", { ...logData, validationError: error.message }); | ||
| toolSpan?.end({ output: error, attributes: { success: false } }); | ||
| return error; | ||
| } | ||
| args = data; | ||
| } | ||
| return await new Promise((resolve, reject) => { | ||
| setImmediate(async () => { | ||
| try { | ||
| const result = await execFunction(args, execOptions, toolSpan); | ||
| resolve(result); | ||
| } catch (err) { | ||
| reject(err); | ||
| } | ||
| }); | ||
| }); | ||
| } catch (err) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "TOOL_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.TOOL, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| errorMessage: String(err), | ||
| argsJson: safeStringify(args), | ||
| model: model?.modelId ?? "" | ||
| } | ||
| }, | ||
| err | ||
| ); | ||
| toolSpan?.error({ error: mastraError, attributes: { success: false } }); | ||
| logger2.trackException(mastraError, { ...logData, ...rest, model: logModelObject, args }); | ||
| throw mastraError; | ||
| } | ||
| }; | ||
| } | ||
| buildV5() { | ||
| const builtTool = this.build(); | ||
| if (!builtTool.parameters) { | ||
| throw new Error("Tool parameters are required"); | ||
| } | ||
| const base = { | ||
| ...builtTool, | ||
| inputSchema: builtTool.parameters, | ||
| onInputStart: "onInputStart" in this.originalTool ? this.originalTool.onInputStart : void 0, | ||
| onInputDelta: "onInputDelta" in this.originalTool ? this.originalTool.onInputDelta : void 0, | ||
| onInputAvailable: "onInputAvailable" in this.originalTool ? this.originalTool.onInputAvailable : void 0, | ||
| onOutput: "onOutput" in this.originalTool ? this.originalTool.onOutput : void 0 | ||
| }; | ||
| if (builtTool.type === "provider-defined") { | ||
| const { execute, parameters, ...rest } = base; | ||
| const name = ("name" in builtTool && typeof builtTool.name === "string" ? builtTool.name : null) || builtTool.id.split(".")[1] || builtTool.id; | ||
| return { | ||
| ...rest, | ||
| type: builtTool.type, | ||
| id: builtTool.id, | ||
| name, | ||
| args: builtTool.args | ||
| }; | ||
| } | ||
| return base; | ||
| } | ||
| build() { | ||
| const providerTool = this.buildProviderTool(this.originalTool); | ||
| if (providerTool) { | ||
| return providerTool; | ||
| } | ||
| const model = this.options.model; | ||
| const schemaCompatLayers = []; | ||
| if (model) { | ||
| const supportsStructuredOutputs = "supportsStructuredOutputs" in model ? model.supportsStructuredOutputs ?? false : false; | ||
| const modelInfo = { | ||
| modelId: model.modelId, | ||
| supportsStructuredOutputs, | ||
| provider: model.provider | ||
| }; | ||
| schemaCompatLayers.push( | ||
| new schemaCompat.OpenAIReasoningSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.OpenAISchemaCompatLayer(modelInfo), | ||
| new schemaCompat.GoogleSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.AnthropicSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.DeepSeekSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.MetaSchemaCompatLayer(modelInfo) | ||
| ); | ||
| } | ||
| const originalSchema = this.getParameters(); | ||
| let processedInputSchema; | ||
| if (originalSchema) { | ||
| if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(originalSchema)) { | ||
| const applicableLayer = schemaCompatLayers.find((layer) => layer.shouldApply()); | ||
| let schemaToUse; | ||
| if (applicableLayer) { | ||
| schemaToUse = applicableLayer.processToCompatSchema(originalSchema); | ||
| } else { | ||
| schemaToUse = chunkXB4FLS7A_cjs.toStandardSchema(originalSchema); | ||
| } | ||
| processedInputSchema = schemaCompat.jsonSchema( | ||
| chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(schemaToUse, { | ||
| io: "input" | ||
| }), | ||
| { | ||
| validate: (value) => { | ||
| const result = schemaToUse["~standard"].validate(value); | ||
| if (result instanceof Promise) { | ||
| return result.then((r) => { | ||
| if ("issues" in r && r.issues) { | ||
| return { | ||
| success: false, | ||
| error: new Error(r.issues.map((i) => i.message).join(", ")) | ||
| }; | ||
| } | ||
| return { success: true, value: r.value }; | ||
| }); | ||
| } | ||
| if ("issues" in result && result.issues) { | ||
| return { | ||
| success: false, | ||
| error: new Error(result.issues.map((i) => i.message).join(", ")) | ||
| }; | ||
| } | ||
| return { success: true, value: result.value }; | ||
| } | ||
| } | ||
| ); | ||
| } else { | ||
| processedInputSchema = schemaCompat.applyCompatLayer({ | ||
| schema: originalSchema, | ||
| compatLayers: schemaCompatLayers, | ||
| mode: "aiSdkSchema" | ||
| }); | ||
| } | ||
| } | ||
| const outputSchema = this.getOutputSchema(); | ||
| let processedOutputSchema; | ||
| if (outputSchema) { | ||
| if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(outputSchema)) { | ||
| processedOutputSchema = chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(outputSchema, { io: "output" }); | ||
| } else { | ||
| processedOutputSchema = schemaCompat.applyCompatLayer({ | ||
| schema: outputSchema, | ||
| compatLayers: [], | ||
| mode: "aiSdkSchema" | ||
| }); | ||
| } | ||
| } | ||
| let requireApproval = false; | ||
| let needsApprovalFn; | ||
| if (typeof this.options.requireApproval === "function") { | ||
| requireApproval = true; | ||
| needsApprovalFn = this.options.requireApproval; | ||
| } else if (typeof this.options.requireApproval === "boolean") { | ||
| requireApproval = this.options.requireApproval; | ||
| needsApprovalFn = void 0; | ||
| } | ||
| if (chunkDZ44ZU2T_cjs.isVercelTool(this.originalTool) && "needsApproval" in this.originalTool) { | ||
| const needsApproval = this.originalTool.needsApproval; | ||
| if (typeof needsApproval === "boolean") { | ||
| requireApproval = needsApproval; | ||
| needsApprovalFn = void 0; | ||
| } else if (typeof needsApproval === "function") { | ||
| needsApprovalFn = needsApproval; | ||
| requireApproval = true; | ||
| } | ||
| } | ||
| const instanceNeedsApprovalFn = chunkDZ44ZU2T_cjs.getNeedsApprovalFn(this.originalTool); | ||
| if (!needsApprovalFn && instanceNeedsApprovalFn) { | ||
| needsApprovalFn = instanceNeedsApprovalFn; | ||
| requireApproval = true; | ||
| } | ||
| const definition = { | ||
| type: "function", | ||
| description: this.originalTool.description, | ||
| requireApproval, | ||
| needsApprovalFn, | ||
| hasSuspendSchema: !!this.getSuspendSchema(), | ||
| execute: this.originalTool.execute ? this.createExecute( | ||
| this.originalTool, | ||
| { ...this.options, description: this.originalTool.description }, | ||
| this.logType | ||
| ) : void 0 | ||
| }; | ||
| return { | ||
| ...definition, | ||
| id: "id" in this.originalTool ? this.originalTool.id : void 0, | ||
| parameters: processedInputSchema ?? v4.z.object({}), | ||
| outputSchema: processedOutputSchema, | ||
| strict: "strict" in this.originalTool ? this.originalTool.strict : void 0, | ||
| providerOptions: "providerOptions" in this.originalTool ? this.originalTool.providerOptions : void 0, | ||
| mcp: "mcp" in this.originalTool ? this.originalTool.mcp : void 0, | ||
| toModelOutput: "toModelOutput" in this.originalTool ? this.originalTool.toModelOutput : void 0, | ||
| transform: "transform" in this.originalTool ? this.originalTool.transform : void 0, | ||
| inputExamples: "inputExamples" in this.originalTool ? this.originalTool.inputExamples : void 0, | ||
| onInputStart: "onInputStart" in this.originalTool ? this.originalTool.onInputStart : void 0, | ||
| onInputDelta: "onInputDelta" in this.originalTool ? this.originalTool.onInputDelta : void 0, | ||
| onInputAvailable: "onInputAvailable" in this.originalTool ? this.originalTool.onInputAvailable : void 0, | ||
| onOutput: "onOutput" in this.originalTool ? this.originalTool.onOutput : void 0, | ||
| // Preserve tool-level background config so the agentic loop can pick it up | ||
| // from the converted CoreTool at dispatch time. | ||
| backgroundConfig: this.options.backgroundConfig | ||
| }; | ||
| } | ||
| }; | ||
| // src/utils.ts | ||
| var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); | ||
| function safeStringify(value, space) { | ||
| const stack = []; | ||
| return JSON.stringify( | ||
| value, | ||
| function(_key, val) { | ||
| if (typeof val === "bigint") return val.toString(); | ||
| if (val !== null && typeof val === "object") { | ||
| while (stack.length > 0 && stack[stack.length - 1] !== this) { | ||
| stack.pop(); | ||
| } | ||
| if (stack.includes(val)) return "[Circular]"; | ||
| stack.push(val); | ||
| } | ||
| return val; | ||
| }, | ||
| space | ||
| ); | ||
| } | ||
| function ensureSerializable(value) { | ||
| if (value === null || typeof value !== "object") return value; | ||
| try { | ||
| JSON.stringify(value); | ||
| return value; | ||
| } catch { | ||
| return JSON.parse(safeStringify(value)); | ||
| } | ||
| } | ||
| function isPlainObject(value) { | ||
| if (value === null || typeof value !== "object") return false; | ||
| const proto = Object.getPrototypeOf(value); | ||
| return proto === Object.prototype || proto === null; | ||
| } | ||
| function deepMerge(target, source) { | ||
| const output = { ...target }; | ||
| if (!source) return output; | ||
| Object.keys(source).forEach((key) => { | ||
| const targetValue = output[key]; | ||
| const sourceValue = source[key]; | ||
| if (isPlainObject(targetValue) && isPlainObject(sourceValue)) { | ||
| output[key] = deepMerge(targetValue, sourceValue); | ||
| } else if (sourceValue !== void 0) { | ||
| output[key] = sourceValue; | ||
| } | ||
| }); | ||
| return output; | ||
| } | ||
| function deepEqual(a, b) { | ||
| if (a === b) return true; | ||
| if (a == null || b == null) return a === b; | ||
| if (typeof a !== typeof b) return false; | ||
| if (Array.isArray(a) && Array.isArray(b)) { | ||
| if (a.length !== b.length) return false; | ||
| return a.every((item, index) => deepEqual(item, b[index])); | ||
| } | ||
| if (a instanceof Date && b instanceof Date) { | ||
| return a.getTime() === b.getTime(); | ||
| } | ||
| if (typeof a === "object" && typeof b === "object") { | ||
| const aObj = a; | ||
| const bObj = b; | ||
| const aKeys = Object.keys(aObj); | ||
| const bKeys = Object.keys(bObj); | ||
| if (aKeys.length !== bKeys.length) return false; | ||
| return aKeys.every((key) => Object.prototype.hasOwnProperty.call(bObj, key) && deepEqual(aObj[key], bObj[key])); | ||
| } | ||
| return false; | ||
| } | ||
| function generateEmptyFromSchema(schema) { | ||
| try { | ||
| const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema; | ||
| if (!parsedSchema || parsedSchema.type !== "object" || !parsedSchema.properties) return {}; | ||
| const obj = {}; | ||
| for (const [key, prop] of Object.entries( | ||
| parsedSchema.properties | ||
| )) { | ||
| if (prop.default !== void 0) { | ||
| obj[key] = typeof prop.default === "object" && prop.default !== null ? JSON.parse(JSON.stringify(prop.default)) : prop.default; | ||
| } else if (prop.type === "object" && prop.properties) { | ||
| obj[key] = generateEmptyFromSchema(prop); | ||
| } else if (prop.type === "object") { | ||
| obj[key] = {}; | ||
| } else if (prop.type === "string") { | ||
| obj[key] = ""; | ||
| } else if (prop.type === "array") { | ||
| obj[key] = []; | ||
| } else if (prop.type === "number" || prop.type === "integer") { | ||
| obj[key] = 0; | ||
| } else if (prop.type === "boolean") { | ||
| obj[key] = false; | ||
| } else { | ||
| obj[key] = null; | ||
| } | ||
| } | ||
| return obj; | ||
| } catch { | ||
| return {}; | ||
| } | ||
| } | ||
| async function* maskStreamTags(stream, tag, options = {}) { | ||
| const { onStart, onEnd, onMask } = options; | ||
| const openTag = `<${tag}>`; | ||
| const closeTag = `</${tag}>`; | ||
| let buffer = ""; | ||
| let fullContent = ""; | ||
| let isMasking = false; | ||
| let isBuffering = false; | ||
| const trimOutsideDelimiter = (text, delimiter, trim) => { | ||
| if (!text.includes(delimiter)) { | ||
| return text; | ||
| } | ||
| const parts = text.split(delimiter); | ||
| if (trim === `before-start`) { | ||
| return `${delimiter}${parts[1]}`; | ||
| } | ||
| return `${parts[0]}${delimiter}`; | ||
| }; | ||
| const startsWith = (text, pattern) => { | ||
| if (pattern.includes(openTag.substring(0, 3))) { | ||
| pattern = trimOutsideDelimiter(pattern, `<`, `before-start`); | ||
| } | ||
| return text.trim().startsWith(pattern.trim()); | ||
| }; | ||
| for await (const chunk of stream) { | ||
| fullContent += chunk; | ||
| if (isBuffering) buffer += chunk; | ||
| const chunkHasTag = startsWith(chunk, openTag); | ||
| const bufferHasTag = !chunkHasTag && isBuffering && startsWith(openTag, buffer); | ||
| let toYieldBeforeMaskedStartTag = ``; | ||
| if (!isMasking && (chunkHasTag || bufferHasTag)) { | ||
| isMasking = true; | ||
| isBuffering = false; | ||
| const taggedTextToMask = trimOutsideDelimiter(buffer, `<`, `before-start`); | ||
| if (taggedTextToMask !== buffer.trim()) { | ||
| toYieldBeforeMaskedStartTag = buffer.replace(taggedTextToMask, ``); | ||
| } | ||
| buffer = ""; | ||
| onStart?.(); | ||
| } | ||
| if (!isMasking && !isBuffering && startsWith(openTag, chunk) && chunk.trim() !== "") { | ||
| isBuffering = true; | ||
| buffer += chunk; | ||
| continue; | ||
| } | ||
| if (isBuffering && buffer && !startsWith(openTag, buffer)) { | ||
| yield buffer; | ||
| buffer = ""; | ||
| isBuffering = false; | ||
| continue; | ||
| } | ||
| if (isMasking && fullContent.includes(closeTag)) { | ||
| onMask?.(chunk); | ||
| onEnd?.(); | ||
| isMasking = false; | ||
| const lastFullContent = fullContent; | ||
| fullContent = ``; | ||
| const textUntilEndTag = trimOutsideDelimiter(lastFullContent, closeTag, "after-end"); | ||
| if (textUntilEndTag !== lastFullContent) { | ||
| yield lastFullContent.replace(textUntilEndTag, ``); | ||
| } | ||
| continue; | ||
| } | ||
| if (isMasking) { | ||
| onMask?.(chunk); | ||
| if (toYieldBeforeMaskedStartTag) { | ||
| yield toYieldBeforeMaskedStartTag; | ||
| } | ||
| continue; | ||
| } | ||
| yield chunk; | ||
| } | ||
| } | ||
| function resolveSerializedZodOutput(schema) { | ||
| return Function("z", `"use strict";return (${schema});`)(v4.z); | ||
| } | ||
| function isZodType(value) { | ||
| return typeof value === "object" && value !== null && "_def" in value && "parse" in value && typeof value.parse === "function" && "safeParse" in value && typeof value.safeParse === "function"; | ||
| } | ||
| function createDeterministicId(input) { | ||
| return crypto.createHash("sha256").update(input).digest("hex").slice(0, 8); | ||
| } | ||
| function setVercelToolProperties(tool) { | ||
| const inputSchema = "inputSchema" in tool ? tool.inputSchema : convertVercelToolParameters(tool); | ||
| const toolId = !("id" in tool) ? tool.description ? `tool-${createDeterministicId(tool.description)}` : `tool-${Math.random().toString(36).substring(2, 9)}` : tool.id; | ||
| return { | ||
| ...tool, | ||
| id: toolId, | ||
| inputSchema | ||
| }; | ||
| } | ||
| function ensureToolProperties(tools) { | ||
| const toolsWithProperties = Object.keys(tools).reduce((acc, key) => { | ||
| const tool = tools?.[key]; | ||
| if (tool) { | ||
| if (typeof tool === "function" && !(tool instanceof chunkDZ44ZU2T_cjs.Tool) && !chunkDZ44ZU2T_cjs.isVercelTool(tool)) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "TOOL_INVALID_FORMAT", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.TOOL, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| text: `Tool "${key}" is not a valid tool format. Tools must be created using createTool() or be a valid Vercel AI SDK tool. Received a function.` | ||
| }); | ||
| } | ||
| if (chunkDZ44ZU2T_cjs.isVercelTool(tool)) { | ||
| acc[key] = setVercelToolProperties(tool); | ||
| } else { | ||
| acc[key] = tool; | ||
| } | ||
| } | ||
| return acc; | ||
| }, {}); | ||
| return toolsWithProperties; | ||
| } | ||
| function convertVercelToolParameters(tool) { | ||
| let schema = tool.parameters ?? v4.z.object({}); | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return isZodType(schema) ? schema : resolveSerializedZodOutput(jsonToZod.jsonSchemaToZod(schema)); | ||
| } | ||
| function makeCoreTool(originalTool, options, logType, autoResumeSuspendedTools, backgroundTaskEnabled) { | ||
| return new CoreToolBuilder({ | ||
| originalTool, | ||
| options, | ||
| logType, | ||
| autoResumeSuspendedTools, | ||
| backgroundTaskEnabled | ||
| }).build(); | ||
| } | ||
| function makeCoreToolV5(originalTool, options, logType, autoResumeSuspendedTools, backgroundTaskEnabled) { | ||
| return new CoreToolBuilder({ | ||
| originalTool, | ||
| options, | ||
| logType, | ||
| autoResumeSuspendedTools, | ||
| backgroundTaskEnabled | ||
| }).buildV5(); | ||
| } | ||
| function createMastraProxy({ mastra, logger }) { | ||
| return new Proxy(mastra, { | ||
| get(target, prop) { | ||
| const hasProp = Reflect.has(target, prop); | ||
| if (hasProp) { | ||
| const value = Reflect.get(target, prop); | ||
| const isFunction = typeof value === "function"; | ||
| if (isFunction) { | ||
| return value.bind(target); | ||
| } | ||
| return value; | ||
| } | ||
| if (prop === "logger") { | ||
| logger.warn("Please use 'getLogger' instead, logger is deprecated"); | ||
| return Reflect.apply(target.getLogger, target, []); | ||
| } | ||
| if (prop === "storage") { | ||
| logger.warn("Please use 'getStorage' instead, storage is deprecated"); | ||
| return Reflect.get(target, "storage"); | ||
| } | ||
| if (prop === "agents") { | ||
| logger.warn("Please use 'listAgents' instead, agents is deprecated"); | ||
| return Reflect.apply(target.listAgents, target, []); | ||
| } | ||
| if (prop === "tts") { | ||
| logger.warn("Please use 'getTTS' instead, tts is deprecated"); | ||
| return Reflect.apply(target.getTTS, target, []); | ||
| } | ||
| if (prop === "vectors") { | ||
| logger.warn("Please use 'getVectors' instead, vectors is deprecated"); | ||
| return Reflect.apply(target.getVectors, target, []); | ||
| } | ||
| if (prop === "memory") { | ||
| logger.warn("Please use 'getMemory' instead, memory is deprecated"); | ||
| return Reflect.get(target, "memory"); | ||
| } | ||
| return Reflect.get(target, prop); | ||
| } | ||
| }); | ||
| } | ||
| function checkEvalStorageFields(traceObject, logger) { | ||
| const missingFields = []; | ||
| if (!traceObject.input) missingFields.push("input"); | ||
| if (!traceObject.output) missingFields.push("output"); | ||
| if (!traceObject.agentName) missingFields.push("agent_name"); | ||
| if (!traceObject.metricName) missingFields.push("metric_name"); | ||
| if (!traceObject.instructions) missingFields.push("instructions"); | ||
| if (!traceObject.globalRunId) missingFields.push("global_run_id"); | ||
| if (!traceObject.runId) missingFields.push("run_id"); | ||
| if (missingFields.length > 0) { | ||
| if (logger) { | ||
| logger.warn("Skipping evaluation storage due to missing required fields", { | ||
| missingFields, | ||
| runId: traceObject.runId, | ||
| agentName: traceObject.agentName | ||
| }); | ||
| } else { | ||
| console.warn("Skipping evaluation storage due to missing required fields", { | ||
| missingFields, | ||
| runId: traceObject.runId, | ||
| agentName: traceObject.agentName | ||
| }); | ||
| } | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| function detectSingleMessageCharacteristics(message) { | ||
| if (typeof message === "object" && message !== null && (message.role === "function" || // UI-only role | ||
| message.role === "data" || // UI-only role | ||
| "toolInvocations" in message || // UI-specific field | ||
| "parts" in message || // UI-specific field | ||
| "experimental_attachments" in message)) { | ||
| return "has-ui-specific-parts"; | ||
| } else if (typeof message === "object" && message !== null && "content" in message && (Array.isArray(message.content) || // Core messages can have array content | ||
| "experimental_providerMetadata" in message || "providerOptions" in message)) { | ||
| return "has-core-specific-parts"; | ||
| } else if (typeof message === "object" && message !== null && "role" in message && "content" in message && typeof message.content === "string" && ["system", "user", "assistant", "tool"].includes(message.role)) { | ||
| return "message"; | ||
| } else { | ||
| return "other"; | ||
| } | ||
| } | ||
| function isUiMessage(message) { | ||
| return detectSingleMessageCharacteristics(message) === `has-ui-specific-parts`; | ||
| } | ||
| function isCoreMessage(message) { | ||
| return [`has-core-specific-parts`, `message`].includes(detectSingleMessageCharacteristics(message)); | ||
| } | ||
| var SQL_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/; | ||
| function parseSqlIdentifier(name, kind = "identifier") { | ||
| if (!SQL_IDENTIFIER_PATTERN.test(name) || name.length > 63) { | ||
| throw new Error( | ||
| `Invalid ${kind}: ${name}. Must start with a letter or underscore, contain only letters, numbers, or underscores, and be at most 63 characters long.` | ||
| ); | ||
| } | ||
| return name; | ||
| } | ||
| function parseFieldKey(key) { | ||
| if (!key) throw new Error("Field key cannot be empty"); | ||
| const segments = key.split("."); | ||
| for (const segment of segments) { | ||
| if (!SQL_IDENTIFIER_PATTERN.test(segment) || segment.length > 63) { | ||
| throw new Error(`Invalid field key segment: ${segment} in ${key}`); | ||
| } | ||
| } | ||
| return key; | ||
| } | ||
| function omitKeys(obj, keysToOmit) { | ||
| return Object.fromEntries(Object.entries(obj).filter(([key]) => !keysToOmit.includes(key))); | ||
| } | ||
| function selectFields(obj, fields) { | ||
| if (!obj || typeof obj !== "object") { | ||
| return obj; | ||
| } | ||
| const result = {}; | ||
| for (const field of fields) { | ||
| const value = getNestedValue(obj, field); | ||
| if (value !== void 0) { | ||
| setNestedValue(result, field, value); | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function getNestedValue(obj, path) { | ||
| return path.split(".").reduce((current, key) => { | ||
| return current && typeof current === "object" ? current[key] : void 0; | ||
| }, obj); | ||
| } | ||
| function setNestedValue(obj, path, value) { | ||
| const keys = path.split("."); | ||
| const lastKey = keys.pop(); | ||
| if (!lastKey) return; | ||
| for (const key of keys) { | ||
| if (key === "__proto__" || key === "constructor" || key === "prototype") { | ||
| return; | ||
| } | ||
| } | ||
| if (lastKey === "__proto__" || lastKey === "constructor" || lastKey === "prototype") { | ||
| return; | ||
| } | ||
| let current = obj; | ||
| for (const key of keys) { | ||
| const existing = Object.prototype.hasOwnProperty.call(current, key) ? current[key] : void 0; | ||
| if (existing === null || typeof existing !== "object") { | ||
| const container = /* @__PURE__ */ Object.create(null); | ||
| Object.defineProperty(current, key, { value: container, writable: true, enumerable: true, configurable: true }); | ||
| } | ||
| current = current[key]; | ||
| } | ||
| Object.defineProperty(current, lastKey, { value, writable: true, enumerable: true, configurable: true }); | ||
| } | ||
| var removeUndefinedValues = (obj) => { | ||
| return Object.fromEntries(Object.entries(obj).filter(([_, value]) => value !== void 0)); | ||
| }; | ||
| exports.ToolStream = ToolStream; | ||
| exports.checkEvalStorageFields = checkEvalStorageFields; | ||
| exports.createMastraProxy = createMastraProxy; | ||
| exports.deepEqual = deepEqual; | ||
| exports.deepMerge = deepMerge; | ||
| exports.delay = delay; | ||
| exports.ensureSerializable = ensureSerializable; | ||
| exports.ensureToolProperties = ensureToolProperties; | ||
| exports.generateEmptyFromSchema = generateEmptyFromSchema; | ||
| exports.getNestedValue = getNestedValue; | ||
| exports.isCoreMessage = isCoreMessage; | ||
| exports.isUiMessage = isUiMessage; | ||
| exports.isZodType = isZodType; | ||
| exports.makeCoreTool = makeCoreTool; | ||
| exports.makeCoreToolV5 = makeCoreToolV5; | ||
| exports.maskStreamTags = maskStreamTags; | ||
| exports.noopObserve = noopObserve; | ||
| exports.omitKeys = omitKeys; | ||
| exports.parseFieldKey = parseFieldKey; | ||
| exports.parseSqlIdentifier = parseSqlIdentifier; | ||
| exports.removeUndefinedValues = removeUndefinedValues; | ||
| exports.resolveSerializedZodOutput = resolveSerializedZodOutput; | ||
| exports.safeStringify = safeStringify; | ||
| exports.selectFields = selectFields; | ||
| exports.setNestedValue = setNestedValue; | ||
| //# sourceMappingURL=chunk-BP67LMWW.cjs.map | ||
| //# sourceMappingURL=chunk-BP67LMWW.cjs.map |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { VersionedStorageDomain, normalizePerPage, calculatePagination, FilesystemVersionedHelpers } from './chunk-SKZRHFF3.js'; | ||
| import { deepEqual } from './chunk-M2TW4P2L.js'; | ||
| // src/storage/domains/prompt-blocks/base.ts | ||
| var PromptBlocksStorage = class extends VersionedStorageDomain { | ||
| listKey = "promptBlocks"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "blockId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "PROMPT_BLOCKS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/prompt-blocks/inmemory.ts | ||
| var InMemoryPromptBlocksStorage = class extends PromptBlocksStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.promptBlocks.clear(); | ||
| this.db.promptBlockVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Prompt Block CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const block = this.db.promptBlocks.get(id); | ||
| return block ? this.deepCopyBlock(block) : null; | ||
| } | ||
| async create(input) { | ||
| const { promptBlock } = input; | ||
| if (this.db.promptBlocks.has(promptBlock.id)) { | ||
| throw new Error(`Prompt block with id ${promptBlock.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newBlock = { | ||
| id: promptBlock.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: promptBlock.authorId, | ||
| metadata: promptBlock.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.promptBlocks.set(promptBlock.id, newBlock); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| blockId: promptBlock.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyBlock(newBlock); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingBlock = this.db.promptBlocks.get(id); | ||
| if (!existingBlock) { | ||
| throw new Error(`Prompt block with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedBlock = { | ||
| ...existingBlock, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingBlock.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.promptBlocks.set(id, updatedBlock); | ||
| return this.deepCopyBlock(updatedBlock); | ||
| } | ||
| async delete(id) { | ||
| this.db.promptBlocks.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let blocks = Array.from(this.db.promptBlocks.values()); | ||
| if (status) { | ||
| blocks = blocks.filter((block) => block.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| blocks = blocks.filter((block) => block.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| blocks = blocks.filter((block) => { | ||
| if (!block.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => deepEqual(block.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedBlocks = this.sortBlocks(blocks, field, direction); | ||
| const clonedBlocks = sortedBlocks.map((block) => this.deepCopyBlock(block)); | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| promptBlocks: clonedBlocks.slice(offset, offset + perPage), | ||
| total: clonedBlocks.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedBlocks.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Prompt Block Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.promptBlockVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.promptBlockVersions.values()) { | ||
| if (version2.blockId === input.blockId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for prompt block ${input.blockId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.promptBlockVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.promptBlockVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(blockId, versionNumber) { | ||
| for (const version of this.db.promptBlockVersions.values()) { | ||
| if (version.blockId === blockId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(blockId) { | ||
| let latest = null; | ||
| for (const version of this.db.promptBlockVersions.values()) { | ||
| if (version.blockId === blockId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { blockId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.promptBlockVersions.values()).filter((v) => v.blockId === blockId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.promptBlockVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.promptBlockVersions.entries()) { | ||
| if (version.blockId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.promptBlockVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(blockId) { | ||
| let count = 0; | ||
| for (const version of this.db.promptBlockVersions.values()) { | ||
| if (version.blockId === blockId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyBlock(block) { | ||
| return { | ||
| ...block, | ||
| metadata: block.metadata ? { ...block.metadata } : block.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| rules: version.rules ? JSON.parse(JSON.stringify(version.rules)) : version.rules, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortBlocks(blocks, field, direction) { | ||
| return blocks.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/prompt-blocks/filesystem.ts | ||
| var FilesystemPromptBlocksStorage = class extends PromptBlocksStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "prompt-blocks.json", | ||
| parentIdField: "blockId", | ||
| name: "FilesystemPromptBlocksStorage", | ||
| versionMetadataFields: ["id", "blockId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { promptBlock } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: promptBlock.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: promptBlock.authorId, | ||
| metadata: promptBlock.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(promptBlock.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| blockId: promptBlock.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "promptBlocks", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(blockId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(blockId, versionNumber); | ||
| } | ||
| async getLatestVersion(blockId) { | ||
| return this.helpers.getLatestVersion(blockId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "blockId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(blockId) { | ||
| return this.helpers.countVersions(blockId); | ||
| } | ||
| }; | ||
| export { FilesystemPromptBlocksStorage, InMemoryPromptBlocksStorage, PromptBlocksStorage }; | ||
| //# sourceMappingURL=chunk-BXKJRFIE.js.map | ||
| //# sourceMappingURL=chunk-BXKJRFIE.js.map |
| {"version":3,"sources":["../src/storage/domains/prompt-blocks/base.ts","../src/storage/domains/prompt-blocks/inmemory.ts","../src/storage/domains/prompt-blocks/filesystem.ts"],"names":["version"],"mappings":"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","file":"chunk-BXKJRFIE.js","sourcesContent":["import type {\n StoragePromptBlockType,\n StoragePromptBlockSnapshotType,\n StorageResolvedPromptBlockType,\n StorageCreatePromptBlockInput,\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput,\n StorageListPromptBlocksOutput,\n StorageListPromptBlocksResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// Prompt Block Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of a prompt block's content.\n * Config fields are top-level on the version row (no nested snapshot object).\n */\nexport interface PromptBlockVersion extends StoragePromptBlockSnapshotType, VersionBase {\n /** ID of the prompt block this version belongs to */\n blockId: string;\n}\n\n/**\n * Input for creating a new prompt block version.\n * Config fields are top-level (no nested snapshot object).\n */\nexport interface CreatePromptBlockVersionInput extends StoragePromptBlockSnapshotType, CreateVersionInputBase {\n /** ID of the prompt block this version belongs to */\n blockId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type PromptBlockVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type PromptBlockVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing prompt block versions with pagination and sorting.\n */\nexport interface ListPromptBlockVersionsInput extends ListVersionsInputBase {\n /** ID of the prompt block to list versions for */\n blockId: string;\n}\n\n/**\n * Output for listing prompt block versions with pagination info.\n */\nexport interface ListPromptBlockVersionsOutput extends ListVersionsOutputBase<PromptBlockVersion> {}\n\n// ============================================================================\n// PromptBlocksStorage Base Class\n// ============================================================================\n\nexport abstract class PromptBlocksStorage extends VersionedStorageDomain<\n StoragePromptBlockType,\n StoragePromptBlockSnapshotType,\n StorageResolvedPromptBlockType,\n PromptBlockVersion,\n CreatePromptBlockVersionInput,\n ListPromptBlockVersionsInput,\n ListPromptBlockVersionsOutput,\n { promptBlock: StorageCreatePromptBlockInput },\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput | undefined,\n StorageListPromptBlocksOutput,\n StorageListPromptBlocksResolvedOutput\n> {\n protected readonly listKey = 'promptBlocks';\n protected readonly versionMetadataFields = [\n 'id',\n 'blockId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof PromptBlockVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'PROMPT_BLOCKS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StoragePromptBlockType,\n StorageCreatePromptBlockInput,\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput,\n StorageListPromptBlocksOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n PromptBlockVersion,\n CreatePromptBlockVersionInput,\n ListPromptBlockVersionsInput,\n ListPromptBlockVersionsOutput,\n PromptBlockVersionOrderBy,\n PromptBlockVersionSortDirection,\n} from './base';\nimport { PromptBlocksStorage } from './base';\n\nexport class InMemoryPromptBlocksStorage extends PromptBlocksStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.promptBlocks.clear();\n this.db.promptBlockVersions.clear();\n }\n\n // ==========================================================================\n // Prompt Block CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StoragePromptBlockType | null> {\n const block = this.db.promptBlocks.get(id);\n return block ? this.deepCopyBlock(block) : null;\n }\n\n async create(input: { promptBlock: StorageCreatePromptBlockInput }): Promise<StoragePromptBlockType> {\n const { promptBlock } = input;\n\n if (this.db.promptBlocks.has(promptBlock.id)) {\n throw new Error(`Prompt block with id ${promptBlock.id} already exists`);\n }\n\n const now = new Date();\n const newBlock: StoragePromptBlockType = {\n id: promptBlock.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: promptBlock.authorId,\n metadata: promptBlock.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.promptBlocks.set(promptBlock.id, newBlock);\n\n // Extract config fields from the flat input (everything except block-record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n blockId: promptBlock.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin block record\n return this.deepCopyBlock(newBlock);\n }\n\n async update(input: StorageUpdatePromptBlockInput): Promise<StoragePromptBlockType> {\n const { id, ...updates } = input;\n\n const existingBlock = this.db.promptBlocks.get(id);\n if (!existingBlock) {\n throw new Error(`Prompt block with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the block record\n const updatedBlock: StoragePromptBlockType = {\n ...existingBlock,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StoragePromptBlockType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingBlock.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated block record\n this.db.promptBlocks.set(id, updatedBlock);\n return this.deepCopyBlock(updatedBlock);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.promptBlocks.delete(id);\n // Also delete all versions for this block\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListPromptBlocksInput): Promise<StorageListPromptBlocksOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all blocks and apply filters\n let blocks = Array.from(this.db.promptBlocks.values());\n\n // Filter by status\n if (status) {\n blocks = blocks.filter(block => block.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n blocks = blocks.filter(block => block.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n blocks = blocks.filter(block => {\n if (!block.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(block.metadata![key], value));\n });\n }\n\n // Sort filtered blocks\n const sortedBlocks = this.sortBlocks(blocks, field, direction);\n\n // Deep clone blocks to avoid mutation\n const clonedBlocks = sortedBlocks.map(block => this.deepCopyBlock(block));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n promptBlocks: clonedBlocks.slice(offset, offset + perPage),\n total: clonedBlocks.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedBlocks.length,\n };\n }\n\n // ==========================================================================\n // Prompt Block Version Methods\n // ==========================================================================\n\n async createVersion(input: CreatePromptBlockVersionInput): Promise<PromptBlockVersion> {\n // Check if version with this ID already exists\n if (this.db.promptBlockVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (blockId, versionNumber) pair\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === input.blockId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for prompt block ${input.blockId}`);\n }\n }\n\n const version: PromptBlockVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.promptBlockVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<PromptBlockVersion | null> {\n const version = this.db.promptBlockVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(blockId: string, versionNumber: number): Promise<PromptBlockVersion | null> {\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === blockId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(blockId: string): Promise<PromptBlockVersion | null> {\n let latest: PromptBlockVersion | null = null;\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === blockId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListPromptBlockVersionsInput): Promise<ListPromptBlockVersionsOutput> {\n const { blockId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by blockId\n let versions = Array.from(this.db.promptBlockVersions.values()).filter(v => v.blockId === blockId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.promptBlockVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.promptBlockVersions.entries()) {\n if (version.blockId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.promptBlockVersions.delete(id);\n }\n }\n\n async countVersions(blockId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === blockId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyBlock(block: StoragePromptBlockType): StoragePromptBlockType {\n return {\n ...block,\n metadata: block.metadata ? { ...block.metadata } : block.metadata,\n };\n }\n\n private deepCopyVersion(version: PromptBlockVersion): PromptBlockVersion {\n return {\n ...version,\n rules: version.rules ? JSON.parse(JSON.stringify(version.rules)) : version.rules,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortBlocks(\n blocks: StoragePromptBlockType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StoragePromptBlockType[] {\n return blocks.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: PromptBlockVersion[],\n field: PromptBlockVersionOrderBy,\n direction: PromptBlockVersionSortDirection,\n ): PromptBlockVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StoragePromptBlockType,\n StorageCreatePromptBlockInput,\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput,\n StorageListPromptBlocksOutput,\n} from '../../types';\nimport type {\n PromptBlockVersion,\n CreatePromptBlockVersionInput,\n ListPromptBlockVersionsInput,\n ListPromptBlockVersionsOutput,\n} from './base';\nimport { PromptBlocksStorage } from './base';\n\nexport class FilesystemPromptBlocksStorage extends PromptBlocksStorage {\n private helpers: FilesystemVersionedHelpers<StoragePromptBlockType, PromptBlockVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'prompt-blocks.json',\n parentIdField: 'blockId',\n name: 'FilesystemPromptBlocksStorage',\n versionMetadataFields: ['id', 'blockId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StoragePromptBlockType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { promptBlock: StorageCreatePromptBlockInput }): Promise<StoragePromptBlockType> {\n const { promptBlock } = input;\n const now = new Date();\n const entity: StoragePromptBlockType = {\n id: promptBlock.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: promptBlock.authorId,\n metadata: promptBlock.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(promptBlock.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n blockId: promptBlock.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreatePromptBlockVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdatePromptBlockInput): Promise<StoragePromptBlockType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListPromptBlocksInput): Promise<StorageListPromptBlocksOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'promptBlocks',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListPromptBlocksOutput;\n }\n\n async createVersion(input: CreatePromptBlockVersionInput): Promise<PromptBlockVersion> {\n return this.helpers.createVersion(input as PromptBlockVersion);\n }\n\n async getVersion(id: string): Promise<PromptBlockVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(blockId: string, versionNumber: number): Promise<PromptBlockVersion | null> {\n return this.helpers.getVersionByNumber(blockId, versionNumber);\n }\n\n async getLatestVersion(blockId: string): Promise<PromptBlockVersion | null> {\n return this.helpers.getLatestVersion(blockId);\n }\n\n async listVersions(input: ListPromptBlockVersionsInput): Promise<ListPromptBlockVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'blockId');\n return result as ListPromptBlockVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(blockId: string): Promise<number> {\n return this.helpers.countVersions(blockId);\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var crypto = require('crypto'); | ||
| var v4 = require('zod/v4'); | ||
| // src/background-tasks/manager.ts | ||
| // src/background-tasks/workflow-id.ts | ||
| var BACKGROUND_TASK_WORKFLOW_ID = "__background-task"; | ||
| // src/background-tasks/manager.ts | ||
| var TOPIC_DISPATCH = "background-tasks"; | ||
| var TOPIC_RESULT = "background-tasks-result"; | ||
| var WORKER_GROUP = "background-task-workers"; | ||
| var BackgroundTaskManager = class { | ||
| pubsub; | ||
| config; | ||
| #mastra; | ||
| // Per-task contexts — keyed by task ID, holds closures from the caller's stream. | ||
| /** @internal — read by the workflow-engine step bodies in workflow.ts */ | ||
| taskContexts = /* @__PURE__ */ new Map(); | ||
| // Static executors keyed by tool name. Populated by `Mastra` for every | ||
| // registered tool, and by `BackgroundTaskWorker.#wireStaticTools` on | ||
| // standalone worker processes. Used as the fallback for cross-process | ||
| // dispatch where the producer's per-task closure (taskContexts) is not | ||
| // visible — a remote worker resolves the tool by name instead. | ||
| staticExecutors = /* @__PURE__ */ new Map(); | ||
| // Track active AbortControllers for running tasks (for cancellation + timeout) | ||
| /** @internal — read by the workflow-engine step bodies in workflow.ts */ | ||
| activeAbortControllers = /* @__PURE__ */ new Map(); | ||
| // Pubsub callbacks (kept for unsubscribe) | ||
| workerCallback; | ||
| resultCallback; | ||
| shuttingDown = false; | ||
| // Cleanup interval handle | ||
| cleanupInterval; | ||
| // Tracks the in-flight `init(pubsub)` so consumers can await readiness. | ||
| // Mastra fires init as fire-and-forget in `#ensureBackgroundTaskManager`, | ||
| // so without this any caller that hits `enqueue`/`resume`/`cancel` | ||
| // before init completes races against worker subscription + workflow | ||
| // registration. Public methods that depend on init await this promise | ||
| // before doing work. | ||
| initPromise; | ||
| constructor(config = { enabled: false }) { | ||
| this.config = { | ||
| globalConcurrency: config.globalConcurrency ?? 10, | ||
| perAgentConcurrency: config.perAgentConcurrency ?? 5, | ||
| backpressure: config.backpressure ?? "queue", | ||
| defaultTimeoutMs: config.defaultTimeoutMs ?? 3e5, | ||
| ...config | ||
| }; | ||
| } | ||
| __registerMastra(mastra) { | ||
| this.#mastra = mastra; | ||
| } | ||
| async getStorage() { | ||
| const storage = this.#mastra?.getStorage(); | ||
| if (!storage) { | ||
| throw new Error("Storage is not initialized"); | ||
| } | ||
| const bgStore = await storage.getStore("backgroundTasks"); | ||
| if (!bgStore) { | ||
| throw new Error("Background tasks storage is not available"); | ||
| } | ||
| return bgStore; | ||
| } | ||
| async init(pubsub) { | ||
| if (this.initPromise) return this.initPromise; | ||
| this.initPromise = this.#doInit(pubsub); | ||
| return this.initPromise; | ||
| } | ||
| async #doInit(pubsub) { | ||
| this.pubsub = pubsub; | ||
| this.workerCallback = async (event, ack) => { | ||
| if (event.type === "task.dispatch") { | ||
| await this.handleDispatch(event); | ||
| } else if (event.type === "task.resume") { | ||
| await this.handleResume(event); | ||
| } else if (event.type === "task.cancel") { | ||
| this.handleCancel(event); | ||
| } | ||
| await ack?.(); | ||
| }; | ||
| this.resultCallback = async (event, ack) => { | ||
| if (event.type === "task.completed" || event.type === "task.failed") { | ||
| await this.handleResult(event); | ||
| } | ||
| await ack?.(); | ||
| }; | ||
| if (this.#mastra) { | ||
| const { buildBackgroundTaskWorkflow } = await import('./workflow-Q6UPZITR.cjs'); | ||
| const workflow = buildBackgroundTaskWorkflow(this); | ||
| if (!this.#mastra.__hasInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID)) { | ||
| this.#mastra.__registerInternalWorkflow( | ||
| workflow | ||
| ); | ||
| } | ||
| } | ||
| await this.pubsub.subscribe(TOPIC_DISPATCH, this.workerCallback, { group: WORKER_GROUP }); | ||
| await this.pubsub.subscribe(TOPIC_RESULT, this.resultCallback); | ||
| await this.recoverStaleTasks(); | ||
| const cleanupConfig = this.config.cleanup; | ||
| if (cleanupConfig) { | ||
| const intervalMs = cleanupConfig.cleanupIntervalMs ?? 6e4; | ||
| this.cleanupInterval = setInterval(() => { | ||
| void this.cleanup(); | ||
| }, intervalMs); | ||
| } | ||
| } | ||
| // --- Per-task context registration --- | ||
| /** | ||
| * Register per-task hooks (executor, stream emitter, result injector). | ||
| * Called internally by createBackgroundTask or directly for advanced usage. | ||
| */ | ||
| registerTaskContext(taskId, context) { | ||
| this.taskContexts.set(taskId, context); | ||
| } | ||
| /** | ||
| * Remove per-task hooks. Called after task reaches terminal state. | ||
| */ | ||
| deregisterTaskContext(taskId) { | ||
| this.taskContexts.delete(taskId); | ||
| } | ||
| /** | ||
| * Register a tool executor by tool name. Used for cross-process dispatch: | ||
| * when a worker in a different process picks up a `task.dispatch` event, | ||
| * it has no per-task closure (`taskContexts`) for that taskId, but it can | ||
| * resolve the executor by tool name via this registry. | ||
| */ | ||
| registerStaticExecutor(toolName, executor) { | ||
| if (this.staticExecutors.has(toolName)) { | ||
| this.#mastra?.getLogger?.()?.debug?.(`Overwriting existing static executor for tool "${toolName}"`); | ||
| } | ||
| this.staticExecutors.set(toolName, executor); | ||
| } | ||
| /** | ||
| * Symmetric to `registerStaticExecutor`. Called when a tool is removed | ||
| * from `Mastra`. | ||
| */ | ||
| unregisterStaticExecutor(toolName) { | ||
| this.staticExecutors.delete(toolName); | ||
| } | ||
| /** | ||
| * Look up an executor by tool name. Read by the workflow-step body in | ||
| * `workflow.ts:runAttemptStep` as a fallback when no per-task `TaskContext` | ||
| * is registered (cross-process path). | ||
| */ | ||
| getStaticExecutor(toolName) { | ||
| return this.staticExecutors.get(toolName); | ||
| } | ||
| // --- Core operations --- | ||
| /** | ||
| * Enqueue a task for background execution. | ||
| * Prefer `createBackgroundTask()` which returns a self-contained handle. | ||
| */ | ||
| async enqueue(payload, context) { | ||
| if (this.shuttingDown) { | ||
| throw new Error("BackgroundTaskManager is shutting down, cannot enqueue new tasks"); | ||
| } | ||
| if (this.initPromise) await this.initPromise; | ||
| const task = { | ||
| id: this.#mastra?.generateId() ?? crypto.randomUUID(), | ||
| status: "pending", | ||
| toolName: payload.toolName, | ||
| toolCallId: payload.toolCallId, | ||
| args: payload.args, | ||
| agentId: payload.agentId, | ||
| threadId: payload.threadId, | ||
| resourceId: payload.resourceId, | ||
| runId: payload.runId, | ||
| retryCount: 0, | ||
| maxRetries: payload.maxRetries ?? this.config.defaultRetries?.maxRetries ?? 0, | ||
| timeoutMs: payload.timeoutMs ?? this.config.defaultTimeoutMs, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| if (context) { | ||
| this.registerTaskContext(task.id, context); | ||
| } | ||
| const storage = await this.getStorage(); | ||
| await storage.createTask(task); | ||
| const canRun = await this.checkConcurrency(task.agentId); | ||
| if (canRun) { | ||
| await this.dispatch(task); | ||
| return { task }; | ||
| } | ||
| switch (this.config.backpressure) { | ||
| case "reject": | ||
| this.deregisterTaskContext(task.id); | ||
| await storage.deleteTask(task.id); | ||
| throw new Error(`Concurrency limit reached, cannot enqueue task for tool "${task.toolName}"`); | ||
| case "fallback-sync": | ||
| this.deregisterTaskContext(task.id); | ||
| await storage.deleteTask(task.id); | ||
| return { task, fallbackToSync: true }; | ||
| case "queue": | ||
| default: | ||
| return { task }; | ||
| } | ||
| } | ||
| async cancel(taskId) { | ||
| if (this.initPromise) await this.initPromise; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task) { | ||
| throw new Error(`Task not found: ${taskId}`); | ||
| } | ||
| if (task.status === "completed" || task.status === "failed" || task.status === "cancelled" || task.status === "timed_out") { | ||
| return; | ||
| } | ||
| if (task.status === "pending") { | ||
| await storage.updateTask(taskId, { status: "cancelled", completedAt: /* @__PURE__ */ new Date() }); | ||
| const cancelledTask = await storage.getTask(taskId); | ||
| if (cancelledTask) await this.publishLifecycleEvent("task.cancelled", cancelledTask); | ||
| this.deregisterTaskContext(taskId); | ||
| return; | ||
| } | ||
| if (task.status === "suspended") { | ||
| await storage.updateTask(taskId, { status: "cancelled", completedAt: /* @__PURE__ */ new Date() }); | ||
| if (this.#mastra) { | ||
| try { | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const wrapper = await workflow.createRun({ runId: taskId }); | ||
| await wrapper.cancel(); | ||
| } catch (err) { | ||
| this.#mastra?.getLogger?.()?.warn(`background-task workflow cancel failed for ${taskId}:`, err); | ||
| } | ||
| } | ||
| const cancelledTask = await storage.getTask(taskId); | ||
| if (cancelledTask) await this.publishLifecycleEvent("task.cancelled", cancelledTask); | ||
| this.deregisterTaskContext(taskId); | ||
| return; | ||
| } | ||
| if (task.status === "running") { | ||
| await storage.updateTask(taskId, { status: "cancelled", completedAt: /* @__PURE__ */ new Date() }); | ||
| const controller = this.activeAbortControllers.get(taskId); | ||
| if (controller) { | ||
| controller.abort(new Error("Task cancelled")); | ||
| this.activeAbortControllers.delete(taskId); | ||
| } | ||
| if (this.#mastra) { | ||
| try { | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const wrapper = await workflow.createRun({ runId: taskId }); | ||
| await wrapper.cancel(); | ||
| } catch (err) { | ||
| this.#mastra?.getLogger?.()?.warn(`background-task workflow cancel failed for ${taskId}:`, err); | ||
| } | ||
| } | ||
| const cancelledTask = await storage.getTask(taskId); | ||
| if (cancelledTask) await this.publishLifecycleEvent("task.cancelled", cancelledTask); | ||
| this.deregisterTaskContext(taskId); | ||
| await this.pubsub.publish(TOPIC_DISPATCH, { | ||
| type: "task.cancel", | ||
| data: { taskId }, | ||
| runId: taskId | ||
| }); | ||
| } | ||
| } | ||
| /** | ||
| * Resume a suspended task. The tool executor must be re-registered via | ||
| * `registerTaskContext(taskId, ...)` before calling this if the original | ||
| * registration is gone (e.g. process restart) — the manager doesn't | ||
| * rehydrate executor closures from storage. | ||
| * | ||
| * `resumeData` is forwarded to the tool's `execute` options on the | ||
| * resumed run. | ||
| */ | ||
| async resume(taskId, resumeData) { | ||
| if (!this.#mastra) { | ||
| throw new Error("Mastra is not registered with this manager"); | ||
| } | ||
| if (this.initPromise) await this.initPromise; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task) { | ||
| throw new Error(`Task not found: ${taskId}`); | ||
| } | ||
| if (task.status !== "suspended") { | ||
| throw new Error(`Cannot resume task in status '${task.status}' (expected 'suspended')`); | ||
| } | ||
| const canRun = await this.checkConcurrency(task.agentId); | ||
| if (!canRun) { | ||
| throw new Error(`Concurrency limit reached, cannot resume task "${taskId}" \u2014 retry once a slot is available`); | ||
| } | ||
| await this.pubsub.publish(TOPIC_DISPATCH, { | ||
| type: "task.resume", | ||
| data: { taskId, resumeData }, | ||
| runId: taskId | ||
| }); | ||
| return task; | ||
| } | ||
| async getTask(taskId) { | ||
| const storage = await this.getStorage(); | ||
| return storage.getTask(taskId); | ||
| } | ||
| async listTasks(filter = {}) { | ||
| const storage = await this.getStorage(); | ||
| return storage.listTasks(filter); | ||
| } | ||
| /** | ||
| * Deletes old completed/failed/cancelled/timed_out task records from storage. | ||
| */ | ||
| async cleanup() { | ||
| const completedTtlMs = this.config.cleanup?.completedTtlMs ?? 36e5; | ||
| const failedTtlMs = this.config.cleanup?.failedTtlMs ?? 864e5; | ||
| const now = Date.now(); | ||
| const storage = await this.getStorage(); | ||
| await storage.deleteTasks({ | ||
| status: ["completed"], | ||
| toDate: new Date(now - completedTtlMs), | ||
| dateFilterBy: "completedAt" | ||
| }); | ||
| await storage.deleteTasks({ | ||
| status: ["failed", "cancelled", "timed_out"], | ||
| toDate: new Date(now - failedTtlMs), | ||
| dateFilterBy: "completedAt" | ||
| }); | ||
| } | ||
| /** | ||
| * Returns a promise that resolves when the next task from the given set | ||
| * reaches a terminal state. | ||
| */ | ||
| async waitForNextTask(taskIds, options) { | ||
| const storage = await this.getStorage(); | ||
| const isTerminal = (status) => status === "completed" || status === "failed" || status === "cancelled" || status === "timed_out"; | ||
| for (const id of taskIds) { | ||
| const task = await storage.getTask(id); | ||
| if (task && isTerminal(task.status)) { | ||
| return task; | ||
| } | ||
| } | ||
| return new Promise((resolve, reject) => { | ||
| const startTime = Date.now(); | ||
| const timeout = options?.timeoutMs ? setTimeout(() => { | ||
| clearInterval(pollInterval); | ||
| if (progressInterval) clearInterval(progressInterval); | ||
| reject(new Error("Timed out waiting for background task")); | ||
| }, options.timeoutMs) : void 0; | ||
| const progressInterval = options?.onProgress ? setInterval(() => { | ||
| options.onProgress(Date.now() - startTime); | ||
| }, options.progressIntervalMs ?? 3e3) : void 0; | ||
| const pollInterval = setInterval(async () => { | ||
| for (const id of taskIds) { | ||
| const task = await storage.getTask(id); | ||
| if (task && isTerminal(task.status)) { | ||
| clearInterval(pollInterval); | ||
| if (timeout) clearTimeout(timeout); | ||
| if (progressInterval) clearInterval(progressInterval); | ||
| resolve(task); | ||
| return; | ||
| } | ||
| } | ||
| }, 50); | ||
| }); | ||
| } | ||
| /** | ||
| * Returns a ReadableStream of all background task lifecycle events, | ||
| * filtered by optional criteria. Intended to be piped directly to an SSE response. | ||
| * | ||
| * On connection, emits the current state of all non-terminal tasks as a snapshot, | ||
| * then subscribes to live pubsub events for subsequent updates. | ||
| * | ||
| * Events include: | ||
| * - `task.running` (status: 'running') — task picked up by a worker | ||
| * - `task.completed` (status: 'completed') — task finished successfully | ||
| * - `task.failed` (status: 'failed' or 'timed_out') — task errored or timed out | ||
| * - `task.cancelled` (status: 'cancelled') — task was cancelled | ||
| * - `task.suspended` (status: 'suspended') — task paused via `suspend()` from | ||
| * inside its tool executor; resume with `manager.resume(taskId, data)` | ||
| * - `task.resumed` (status: 'running') — suspended task resumed | ||
| * | ||
| * The stream stays open until the caller's AbortSignal fires (client disconnect). | ||
| */ | ||
| stream(options) { | ||
| const manager = this; | ||
| const pubsub = this.pubsub; | ||
| const { agentId, runId, threadId, resourceId, abortSignal, taskId } = options ?? {}; | ||
| const EVENT_STATUS_MAP = { | ||
| "task.running": "running", | ||
| "task.output": "running", | ||
| "task.completed": "completed", | ||
| "task.failed": "failed", | ||
| "task.cancelled": "cancelled", | ||
| "task.suspended": "suspended", | ||
| "task.resumed": "running" | ||
| }; | ||
| const CHUNK_EVENT_MAP = { | ||
| "task.running": "background-task-running", | ||
| "task.output": "background-task-output", | ||
| "task.completed": "background-task-completed", | ||
| "task.failed": "background-task-failed", | ||
| "task.cancelled": "background-task-cancelled", | ||
| "task.suspended": "background-task-suspended", | ||
| "task.resumed": "background-task-resumed" | ||
| }; | ||
| return new ReadableStream({ | ||
| async start(controller) { | ||
| const handler = async (event) => { | ||
| const status = EVENT_STATUS_MAP[event.type]; | ||
| if (!status) return; | ||
| const data = event.data; | ||
| if (agentId && data.agentId !== agentId) return; | ||
| if (runId && data.runId !== runId) return; | ||
| if (threadId && data.threadId !== threadId) return; | ||
| if (resourceId && data.resourceId !== resourceId) return; | ||
| if (taskId && data.taskId !== taskId) return; | ||
| const payload = { | ||
| taskId: data.taskId, | ||
| toolName: data.toolName, | ||
| toolCallId: data.toolCallId, | ||
| agentId: data.agentId, | ||
| runId: data.runId | ||
| }; | ||
| switch (event.type) { | ||
| case "task.running": | ||
| payload.startedAt = data.startedAt; | ||
| payload.args = data.args; | ||
| break; | ||
| case "task.completed": | ||
| payload.completedAt = data.completedAt; | ||
| payload.result = data.result; | ||
| break; | ||
| case "task.failed": | ||
| payload.completedAt = data.completedAt; | ||
| payload.error = data.error; | ||
| break; | ||
| case "task.cancelled": | ||
| payload.completedAt = data.completedAt; | ||
| break; | ||
| case "task.output": | ||
| payload.payload = data.chunk; | ||
| break; | ||
| case "task.suspended": | ||
| payload.suspendPayload = data.suspendPayload; | ||
| payload.suspendedAt = data.suspendedAt; | ||
| payload.args = data.args; | ||
| break; | ||
| case "task.resumed": | ||
| payload.startedAt = data.startedAt; | ||
| payload.args = data.args; | ||
| break; | ||
| } | ||
| try { | ||
| controller.enqueue({ | ||
| type: CHUNK_EVENT_MAP[event.type], | ||
| payload | ||
| }); | ||
| } catch { | ||
| } | ||
| }; | ||
| void pubsub.subscribe(TOPIC_RESULT, handler); | ||
| abortSignal?.addEventListener("abort", () => { | ||
| void pubsub.unsubscribe(TOPIC_RESULT, handler); | ||
| try { | ||
| controller.close(); | ||
| } catch { | ||
| } | ||
| }); | ||
| try { | ||
| const storage = await manager.getStorage(); | ||
| if (taskId) { | ||
| const task = await storage.getTask(taskId); | ||
| if (task && task.status === "running") { | ||
| controller.enqueue({ | ||
| type: "background-task-running", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| agentId: task.agentId, | ||
| runId: task.runId, | ||
| startedAt: task.startedAt, | ||
| args: task.args | ||
| } | ||
| }); | ||
| } | ||
| } else { | ||
| const { tasks: existing } = await storage.listTasks({ | ||
| agentId, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| status: ["running"] | ||
| }); | ||
| for (const task of existing) { | ||
| if (abortSignal?.aborted) break; | ||
| try { | ||
| controller.enqueue({ | ||
| type: "background-task-running", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| agentId: task.agentId, | ||
| runId: task.runId, | ||
| startedAt: task.startedAt, | ||
| args: task.args | ||
| } | ||
| }); | ||
| } catch { | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| } catch { | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| async shutdown() { | ||
| this.shuttingDown = true; | ||
| if (this.cleanupInterval) { | ||
| clearInterval(this.cleanupInterval); | ||
| this.cleanupInterval = void 0; | ||
| } | ||
| if (this.workerCallback) { | ||
| await this.pubsub.unsubscribe(TOPIC_DISPATCH, this.workerCallback); | ||
| } | ||
| if (this.resultCallback) { | ||
| await this.pubsub.unsubscribe(TOPIC_RESULT, this.resultCallback); | ||
| } | ||
| this.taskContexts.clear(); | ||
| await this.pubsub.flush(); | ||
| } | ||
| // --- Internal --- | ||
| async dispatch(task) { | ||
| await this.pubsub.publish(TOPIC_DISPATCH, { | ||
| type: "task.dispatch", | ||
| data: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| args: task.args, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| timeoutMs: task.timeoutMs, | ||
| maxRetries: task.maxRetries, | ||
| runId: task.runId | ||
| }, | ||
| runId: task.id | ||
| }); | ||
| } | ||
| /** | ||
| * Handles a task.dispatch event. Returns true if the message was nacked (for retry). | ||
| */ | ||
| async handleDispatch(event) { | ||
| const { taskId } = event.data; | ||
| const deliveryAttempt = event.deliveryAttempt ?? 1; | ||
| let nacked = false; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task || task.status === "cancelled") { | ||
| this.deregisterTaskContext(taskId); | ||
| return false; | ||
| } | ||
| await storage.updateTask(taskId, { status: "running", startedAt: /* @__PURE__ */ new Date(), retryCount: deliveryAttempt - 1 }); | ||
| const runningTask = await storage.getTask(taskId); | ||
| if (runningTask) await this.publishLifecycleEvent("task.running", runningTask); | ||
| if (this.#mastra) { | ||
| if (runningTask) void this.runLocalExecutionHook(runningTask); | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const run = await workflow.createRun({ runId: taskId }); | ||
| void run.start({ inputData: { taskId } }).then((result) => { | ||
| if (result.status !== "suspended") { | ||
| void workflow.deleteWorkflowRunById(taskId); | ||
| } | ||
| }).catch((err) => { | ||
| this.#mastra?.getLogger?.()?.error(`background-task workflow start failed for ${taskId}:`, err); | ||
| }).finally(() => { | ||
| void this.drainPending(); | ||
| }); | ||
| } | ||
| return nacked; | ||
| } | ||
| /** | ||
| * Handles a task.resume event. Mirrors the workflow branch of handleDispatch | ||
| * but resumes an existing run from its suspended snapshot instead of starting | ||
| * a fresh one. Concurrency gating, suspended-status validation, and the | ||
| * `task.resumed` lifecycle publish all happen here so a different process | ||
| * than the one that suspended the task can drive the resume. | ||
| */ | ||
| async handleResume(event) { | ||
| const { taskId, resumeData } = event.data; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task || task.status !== "suspended") { | ||
| return; | ||
| } | ||
| await storage.updateTask(taskId, { | ||
| status: "running", | ||
| startedAt: /* @__PURE__ */ new Date(), | ||
| suspendPayload: void 0, | ||
| suspendedAt: void 0 | ||
| }); | ||
| const resumedTask = await storage.getTask(taskId); | ||
| if (resumedTask) { | ||
| await this.publishLifecycleEvent("task.resumed", resumedTask); | ||
| } | ||
| if (!this.#mastra) return; | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const run = await workflow.createRun({ runId: taskId }); | ||
| void run.resume({ resumeData }).then((result) => { | ||
| if (result.status !== "suspended") { | ||
| void workflow.deleteWorkflowRunById(taskId); | ||
| } | ||
| }).catch((err) => { | ||
| this.#mastra?.getLogger?.()?.error(`background-task workflow resume failed for ${taskId}:`, err); | ||
| }).finally(() => { | ||
| void this.drainPending(); | ||
| }); | ||
| } | ||
| /** | ||
| * Run per-task hooks (onChunk, onResult, onComplete/onFailed) locally in the | ||
| * worker path, before publishing the terminal lifecycle event. Ensures | ||
| * memory / stream state is consistent by the time any pubsub subscriber is | ||
| * notified. After running, the task context is deregistered so | ||
| * `handleResult` (which also fires from pubsub) becomes a no-op for this | ||
| * task in the same process. | ||
| * | ||
| * In distributed deployments where the worker runs in a different process | ||
| * from the dispatcher, `this.taskContexts` won't contain an entry for | ||
| * `task.id` — this method is a no-op there, and `handleResult` in the | ||
| * dispatching process runs the hooks instead. | ||
| */ | ||
| /** | ||
| * Terminal-state hooks only. Called when a task reaches `'completed'` or | ||
| * `'failed'`. Suspend is non-terminal — see `runLocalSuspendHooks` for that | ||
| * path. | ||
| * | ||
| * @internal — also called by the workflow-engine step bodies in workflow.ts | ||
| */ | ||
| async runLocalCompletionHooks(task, status, extras) { | ||
| const ctx = this.taskContexts.get(task.id); | ||
| if (!ctx) return; | ||
| try { | ||
| if (status === "completed") { | ||
| ctx.onChunk?.({ | ||
| type: "background-task-completed", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| runId: task.runId, | ||
| result: extras.result, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx.onResult?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| result: extras.result, | ||
| status: "completed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| await ctx.onComplete?.(task); | ||
| } else { | ||
| ctx.onChunk?.({ | ||
| type: "background-task-failed", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| runId: task.runId, | ||
| error: extras.error ?? { message: "Unknown error" }, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx.onResult?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| error: extras.error, | ||
| status: "failed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| await ctx.onFailed?.(task); | ||
| } | ||
| } finally { | ||
| this.deregisterTaskContext(task.id); | ||
| } | ||
| } | ||
| /** | ||
| * Per-task suspend hooks. Fires `ctx.onResult({ status: 'suspended', ... })` | ||
| * so the message list / memory pick up the suspension as the tool's | ||
| * current invocation state. Does NOT deregister the task context — resume | ||
| * needs the executor closure intact. | ||
| * | ||
| * @internal — called by the workflow-engine step bodies in workflow.ts | ||
| */ | ||
| async runLocalSuspendHooks(task) { | ||
| const ctx = this.taskContexts.get(task.id); | ||
| if (!ctx) return; | ||
| await ctx.onExecution?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| startedAt: task.startedAt, | ||
| suspendedAt: task.suspendedAt | ||
| }); | ||
| } | ||
| /** @internal — also called by the workflow-engine step bodies in workflow.ts */ | ||
| async runLocalExecutionHook(task) { | ||
| const ctx = this.taskContexts.get(task.id); | ||
| if (!ctx) return; | ||
| try { | ||
| await ctx.onExecution?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| startedAt: task.startedAt | ||
| }); | ||
| } catch { | ||
| } | ||
| } | ||
| async handleResult(event) { | ||
| const { taskId, toolName, toolCallId, threadId, resourceId, runId } = event.data; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (task?.completedAt) { | ||
| const ctx = this.taskContexts.get(taskId); | ||
| if (event.type === "task.completed") { | ||
| ctx?.onChunk?.({ | ||
| type: "background-task-completed", | ||
| payload: { | ||
| taskId, | ||
| toolName, | ||
| toolCallId, | ||
| runId, | ||
| result: event.data.result, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx?.onResult?.({ | ||
| runId, | ||
| taskId, | ||
| toolCallId, | ||
| toolName, | ||
| agentId: event.data.agentId, | ||
| threadId, | ||
| resourceId, | ||
| result: event.data.result, | ||
| status: "completed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| if (task) { | ||
| await Promise.all([ctx?.onComplete?.(task), this.config.onTaskComplete?.(task)]); | ||
| } | ||
| } | ||
| if (event.type === "task.failed") { | ||
| ctx?.onChunk?.({ | ||
| type: "background-task-failed", | ||
| payload: { | ||
| taskId, | ||
| toolName, | ||
| toolCallId, | ||
| runId, | ||
| error: event.data.error, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx?.onResult?.({ | ||
| runId, | ||
| taskId, | ||
| toolCallId, | ||
| toolName, | ||
| agentId: event.data.agentId, | ||
| threadId, | ||
| resourceId, | ||
| error: event.data.error, | ||
| status: "failed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| if (task) { | ||
| await Promise.all([ctx?.onFailed?.(task), this.config.onTaskFailed?.(task)]); | ||
| } | ||
| } | ||
| this.deregisterTaskContext(taskId); | ||
| } | ||
| } | ||
| handleCancel(event) { | ||
| const { taskId } = event.data; | ||
| const controller = this.activeAbortControllers.get(taskId); | ||
| if (controller) { | ||
| controller.abort(new Error("Task cancelled")); | ||
| this.activeAbortControllers.delete(taskId); | ||
| } | ||
| this.deregisterTaskContext(taskId); | ||
| } | ||
| /** @internal — also called by the workflow-engine step bodies in workflow.ts */ | ||
| async publishLifecycleEvent(type, task) { | ||
| await this.pubsub.publish(TOPIC_RESULT, { | ||
| type, | ||
| data: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| runId: task.runId, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| args: task.args, | ||
| result: task.result, | ||
| error: task.error, | ||
| chunk: task.chunk, | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt, | ||
| suspendPayload: task.suspendPayload, | ||
| suspendedAt: task.suspendedAt | ||
| }, | ||
| runId: task.id | ||
| }); | ||
| } | ||
| async checkConcurrency(agentId) { | ||
| const storage = await this.getStorage(); | ||
| const globalRunning = await storage.getRunningCount(); | ||
| if (globalRunning >= this.config.globalConcurrency) { | ||
| return false; | ||
| } | ||
| const agentRunning = await storage.getRunningCountByAgent(agentId); | ||
| if (agentRunning >= this.config.perAgentConcurrency) { | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| async drainPending() { | ||
| const storage = await this.getStorage(); | ||
| const { tasks: pending } = await storage.listTasks({ | ||
| status: "pending", | ||
| orderBy: "createdAt", | ||
| orderDirection: "asc" | ||
| }); | ||
| for (const task of pending) { | ||
| if (await this.checkConcurrency(task.agentId)) { | ||
| await this.dispatch(task); | ||
| } | ||
| } | ||
| } | ||
| /** | ||
| * Recovers tasks left in 'running' or 'pending' state from a previous process. | ||
| */ | ||
| async recoverStaleTasks() { | ||
| try { | ||
| const storage = await this.getStorage(); | ||
| const { tasks: staleTasks } = await storage.listTasks({ status: "running" }); | ||
| for (const task of staleTasks) { | ||
| if (task.maxRetries > 0) { | ||
| await storage.updateTask(task.id, { | ||
| status: "pending", | ||
| startedAt: void 0 | ||
| }); | ||
| } else { | ||
| await storage.updateTask(task.id, { | ||
| status: "failed", | ||
| error: { message: "Worker process terminated before task completed" }, | ||
| completedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| } | ||
| } | ||
| const { tasks: pendingTasks } = await storage.listTasks({ | ||
| status: "pending", | ||
| orderBy: "createdAt", | ||
| orderDirection: "asc" | ||
| }); | ||
| for (const task of pendingTasks) { | ||
| if (await this.checkConcurrency(task.agentId)) { | ||
| await this.dispatch(task); | ||
| } | ||
| } | ||
| } catch (error) { | ||
| const logger = this.#mastra?.getLogger(); | ||
| if (logger) { | ||
| logger.error("Failed to recover stale background tasks", error); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| // src/background-tasks/create.ts | ||
| function createBackgroundTask(manager, options) { | ||
| const { context, ...payload } = options; | ||
| let taskId; | ||
| return { | ||
| get task() { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return { id: taskId }; | ||
| }, | ||
| async dispatch() { | ||
| const result = await manager.enqueue(payload, context); | ||
| taskId = result.task.id; | ||
| return result; | ||
| }, | ||
| async checkIfSuspended(args) { | ||
| const result = await manager.listTasks({ | ||
| toolCallId: args.toolCallId, | ||
| runId: args.runId, | ||
| agentId: args.agentId, | ||
| threadId: args.threadId, | ||
| resourceId: args.resourceId, | ||
| toolName: args.toolName, | ||
| status: "suspended" | ||
| }); | ||
| if (result.total > 0) { | ||
| const task = result.tasks[0]; | ||
| if (task) { | ||
| taskId = task.id; | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| }, | ||
| async resume(resumeData) { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return manager.resume(taskId, resumeData); | ||
| }, | ||
| async cancel() { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return manager.cancel(taskId); | ||
| }, | ||
| async waitForCompletion(waitOptions) { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return manager.waitForNextTask([taskId], waitOptions); | ||
| } | ||
| }; | ||
| } | ||
| // src/background-tasks/resolve-config.ts | ||
| function resolveBackgroundConfig({ | ||
| llmBgOverrides, | ||
| toolName, | ||
| toolConfig, | ||
| agentConfig, | ||
| managerConfig | ||
| }) { | ||
| const llmOverride = llmBgOverrides; | ||
| if (agentConfig?.disabled) { | ||
| return { | ||
| runInBackground: false, | ||
| timeoutMs: managerConfig?.defaultTimeoutMs ?? 3e5, | ||
| maxRetries: managerConfig?.defaultRetries?.maxRetries ?? 0 | ||
| }; | ||
| } | ||
| const agentToolConfig = resolveAgentToolConfig(toolName, agentConfig); | ||
| const baseEnabled = agentToolConfig?.enabled ?? toolConfig?.enabled ?? false; | ||
| const enabled = baseEnabled ? llmOverride?.enabled ?? true : false; | ||
| const timeoutMs = llmOverride?.timeoutMs ?? agentToolConfig?.timeoutMs ?? toolConfig?.timeoutMs ?? managerConfig?.defaultTimeoutMs ?? 3e5; | ||
| const maxRetries = llmOverride?.maxRetries ?? toolConfig?.maxRetries ?? managerConfig?.defaultRetries?.maxRetries ?? 0; | ||
| return { runInBackground: enabled, timeoutMs, maxRetries }; | ||
| } | ||
| function resolveAgentToolConfig(toolName, agentConfig) { | ||
| if (!agentConfig?.tools) return void 0; | ||
| if (agentConfig.tools === "all") { | ||
| return { enabled: true }; | ||
| } | ||
| if (toolName.startsWith("agent-")) { | ||
| toolName = toolName.substring("agent-".length); | ||
| } else if (toolName.startsWith("workflow-")) { | ||
| toolName = toolName.substring("workflow-".length); | ||
| } | ||
| const entry = agentConfig.tools[toolName]; | ||
| if (entry === void 0) return void 0; | ||
| if (typeof entry === "boolean") return { enabled: entry }; | ||
| return entry; | ||
| } | ||
| var backgroundOverrideJsonSchema = { | ||
| type: "object", | ||
| description: "Optional: override background execution behavior for this specific call. Set enabled=false to force foreground, enabled=true to force background. Omit entirely to use the default configuration.", | ||
| properties: { | ||
| enabled: { | ||
| type: "boolean", | ||
| description: "Force background (true) or foreground (false) execution for this call." | ||
| }, | ||
| timeoutMs: { | ||
| type: "number", | ||
| description: "Override timeout in milliseconds for this call." | ||
| }, | ||
| maxRetries: { | ||
| type: "number", | ||
| description: "Override maximum retry attempts for this call." | ||
| } | ||
| }, | ||
| additionalProperties: false | ||
| }; | ||
| var backgroundOverrideZodSchema = v4.z.object({ | ||
| enabled: v4.z.boolean().optional().describe("Force background (true) or foreground (false) execution for this call."), | ||
| timeoutMs: v4.z.number().optional().describe("Override timeout in milliseconds for this call."), | ||
| maxRetries: v4.z.number().optional().describe("Override maximum retry attempts for this call.") | ||
| }).optional().describe( | ||
| "Optional: override background execution behavior for this specific call. Set enabled=false to force foreground, enabled=true to force background. Omit entirely to use the default configuration." | ||
| ); | ||
| // src/background-tasks/system-prompt.ts | ||
| function generateBackgroundTaskSystemPrompt(tools, agentConfig) { | ||
| const eligibleTools = []; | ||
| const enableAll = agentConfig?.tools === "all"; | ||
| for (const [toolName, tool] of Object.entries(tools)) { | ||
| const bgEnabledFromAgentConfig = agentConfig?.tools === "all" ? false : typeof agentConfig?.tools?.[toolName] === "boolean" ? agentConfig.tools[toolName] : agentConfig?.tools?.[toolName]?.enabled ?? false; | ||
| eligibleTools.push({ | ||
| toolName, | ||
| toolConfig: tool.background, | ||
| defaultBackground: enableAll ? true : bgEnabledFromAgentConfig ?? tool.background?.enabled ?? false | ||
| }); | ||
| } | ||
| if (eligibleTools.length === 0) { | ||
| return void 0; | ||
| } | ||
| const toolLines = eligibleTools.map((t) => `- ${t.toolName} (default: ${t.defaultBackground ? "background" : "foreground"})`).join("\n"); | ||
| return `You have the ability to run certain tools in the background while continuing the conversation. The following tools support background execution: | ||
| ${toolLines} | ||
| For any of these tools, you can include a "_background" field in the tool arguments to override the default: | ||
| "_background": { "enabled": true/false, "timeoutMs": number, "maxRetries": number } | ||
| All fields in "_background" are optional. Only include what you want to override. | ||
| Guidelines: | ||
| - Use background execution when the user doesn't need the result immediately, or when you're launching multiple independent tasks. | ||
| - Use foreground execution when the user is directly waiting for the result and the conversation can't continue without it. | ||
| - If you don't include "_background", the tool's default configuration is used. | ||
| - When a tool runs in the background, you'll receive a placeholder result with a task ID. You can reference this in your response to the user. | ||
| IMPORTANT: "_background" field is always an object. The fields in the _background field should be inside the _background object, not outside of it.`; | ||
| } | ||
| exports.BACKGROUND_TASK_WORKFLOW_ID = BACKGROUND_TASK_WORKFLOW_ID; | ||
| exports.BackgroundTaskManager = BackgroundTaskManager; | ||
| exports.backgroundOverrideJsonSchema = backgroundOverrideJsonSchema; | ||
| exports.backgroundOverrideZodSchema = backgroundOverrideZodSchema; | ||
| exports.createBackgroundTask = createBackgroundTask; | ||
| exports.generateBackgroundTaskSystemPrompt = generateBackgroundTaskSystemPrompt; | ||
| exports.resolveBackgroundConfig = resolveBackgroundConfig; | ||
| //# sourceMappingURL=chunk-DRYYU2XF.cjs.map | ||
| //# sourceMappingURL=chunk-DRYYU2XF.cjs.map |
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunk2UAP4LDC_cjs = require('./chunk-2UAP4LDC.cjs'); | ||
| var chunkBP67LMWW_cjs = require('./chunk-BP67LMWW.cjs'); | ||
| // src/storage/domains/scorer-definitions/base.ts | ||
| var ScorerDefinitionsStorage = class extends chunk2UAP4LDC_cjs.VersionedStorageDomain { | ||
| listKey = "scorerDefinitions"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "scorerDefinitionId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "SCORER_DEFINITIONS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/scorer-definitions/inmemory.ts | ||
| var InMemoryScorerDefinitionsStorage = class extends ScorerDefinitionsStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.scorerDefinitions.clear(); | ||
| this.db.scorerDefinitionVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Scorer Definition CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const scorer = this.db.scorerDefinitions.get(id); | ||
| return scorer ? this.deepCopyScorer(scorer) : null; | ||
| } | ||
| async create(input) { | ||
| const { scorerDefinition } = input; | ||
| if (this.db.scorerDefinitions.has(scorerDefinition.id)) { | ||
| throw new Error(`Scorer definition with id ${scorerDefinition.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newScorer = { | ||
| id: scorerDefinition.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: scorerDefinition.authorId, | ||
| metadata: scorerDefinition.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.scorerDefinitions.set(scorerDefinition.id, newScorer); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| scorerDefinitionId: scorerDefinition.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyScorer(newScorer); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingScorer = this.db.scorerDefinitions.get(id); | ||
| if (!existingScorer) { | ||
| throw new Error(`Scorer definition with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedScorer = { | ||
| ...existingScorer, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingScorer.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.scorerDefinitions.set(id, updatedScorer); | ||
| return this.deepCopyScorer(updatedScorer); | ||
| } | ||
| async delete(id) { | ||
| this.db.scorerDefinitions.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let scorers = Array.from(this.db.scorerDefinitions.values()); | ||
| if (status) { | ||
| scorers = scorers.filter((scorer) => scorer.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| scorers = scorers.filter((scorer) => scorer.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| scorers = scorers.filter((scorer) => { | ||
| if (!scorer.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => chunkBP67LMWW_cjs.deepEqual(scorer.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedScorers = this.sortScorers(scorers, field, direction); | ||
| const clonedScorers = sortedScorers.map((scorer) => this.deepCopyScorer(scorer)); | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| scorerDefinitions: clonedScorers.slice(offset, offset + perPage), | ||
| total: clonedScorers.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedScorers.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Scorer Definition Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.scorerDefinitionVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.scorerDefinitionVersions.values()) { | ||
| if (version2.scorerDefinitionId === input.scorerDefinitionId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error( | ||
| `Version number ${input.versionNumber} already exists for scorer definition ${input.scorerDefinitionId}` | ||
| ); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.scorerDefinitionVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.scorerDefinitionVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(scorerDefinitionId, versionNumber) { | ||
| for (const version of this.db.scorerDefinitionVersions.values()) { | ||
| if (version.scorerDefinitionId === scorerDefinitionId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(scorerDefinitionId) { | ||
| let latest = null; | ||
| for (const version of this.db.scorerDefinitionVersions.values()) { | ||
| if (version.scorerDefinitionId === scorerDefinitionId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { scorerDefinitionId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.scorerDefinitionVersions.values()).filter( | ||
| (v) => v.scorerDefinitionId === scorerDefinitionId | ||
| ); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.scorerDefinitionVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.scorerDefinitionVersions.entries()) { | ||
| if (version.scorerDefinitionId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.scorerDefinitionVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(scorerDefinitionId) { | ||
| let count = 0; | ||
| for (const version of this.db.scorerDefinitionVersions.values()) { | ||
| if (version.scorerDefinitionId === scorerDefinitionId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyScorer(scorer) { | ||
| return { | ||
| ...scorer, | ||
| metadata: scorer.metadata ? { ...scorer.metadata } : scorer.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| model: version.model ? JSON.parse(JSON.stringify(version.model)) : version.model, | ||
| scoreRange: version.scoreRange ? JSON.parse(JSON.stringify(version.scoreRange)) : version.scoreRange, | ||
| presetConfig: version.presetConfig ? JSON.parse(JSON.stringify(version.presetConfig)) : version.presetConfig, | ||
| defaultSampling: version.defaultSampling ? JSON.parse(JSON.stringify(version.defaultSampling)) : version.defaultSampling, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortScorers(scorers, field, direction) { | ||
| return scorers.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/scorer-definitions/filesystem.ts | ||
| var FilesystemScorerDefinitionsStorage = class extends ScorerDefinitionsStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new chunk2UAP4LDC_cjs.FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "scorer-definitions.json", | ||
| parentIdField: "scorerDefinitionId", | ||
| name: "FilesystemScorerDefinitionsStorage", | ||
| versionMetadataFields: [ | ||
| "id", | ||
| "scorerDefinitionId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { scorerDefinition } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: scorerDefinition.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: scorerDefinition.authorId, | ||
| metadata: scorerDefinition.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(scorerDefinition.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| scorerDefinitionId: scorerDefinition.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "scorerDefinitions", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(scorerDefinitionId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(scorerDefinitionId, versionNumber); | ||
| } | ||
| async getLatestVersion(scorerDefinitionId) { | ||
| return this.helpers.getLatestVersion(scorerDefinitionId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "scorerDefinitionId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(scorerDefinitionId) { | ||
| return this.helpers.countVersions(scorerDefinitionId); | ||
| } | ||
| }; | ||
| exports.FilesystemScorerDefinitionsStorage = FilesystemScorerDefinitionsStorage; | ||
| exports.InMemoryScorerDefinitionsStorage = InMemoryScorerDefinitionsStorage; | ||
| exports.ScorerDefinitionsStorage = ScorerDefinitionsStorage; | ||
| //# sourceMappingURL=chunk-EXFCDNO4.cjs.map | ||
| //# sourceMappingURL=chunk-EXFCDNO4.cjs.map |
| {"version":3,"sources":["../src/storage/domains/scorer-definitions/base.ts","../src/storage/domains/scorer-definitions/inmemory.ts","../src/storage/domains/scorer-definitions/filesystem.ts"],"names":["VersionedStorageDomain","normalizePerPage","deepEqual","calculatePagination","version","FilesystemVersionedHelpers"],"mappings":"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","file":"chunk-EXFCDNO4.cjs","sourcesContent":["import type {\n StorageScorerDefinitionType,\n StorageScorerDefinitionSnapshotType,\n StorageResolvedScorerDefinitionType,\n StorageCreateScorerDefinitionInput,\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput,\n StorageListScorerDefinitionsOutput,\n StorageListScorerDefinitionsResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// Scorer Definition Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of a scorer definition's content.\n * Config fields are top-level on the version row (no nested snapshot object).\n */\nexport interface ScorerDefinitionVersion extends StorageScorerDefinitionSnapshotType, VersionBase {\n /** ID of the scorer definition this version belongs to */\n scorerDefinitionId: string;\n}\n\n/**\n * Input for creating a new scorer definition version.\n * Config fields are top-level (no nested snapshot object).\n */\nexport interface CreateScorerDefinitionVersionInput\n extends StorageScorerDefinitionSnapshotType, CreateVersionInputBase {\n /** ID of the scorer definition this version belongs to */\n scorerDefinitionId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type ScorerDefinitionVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type ScorerDefinitionVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing scorer definition versions with pagination and sorting.\n */\nexport interface ListScorerDefinitionVersionsInput extends ListVersionsInputBase {\n /** ID of the scorer definition to list versions for */\n scorerDefinitionId: string;\n}\n\n/**\n * Output for listing scorer definition versions with pagination info.\n */\nexport interface ListScorerDefinitionVersionsOutput extends ListVersionsOutputBase<ScorerDefinitionVersion> {}\n\n// ============================================================================\n// ScorerDefinitionsStorage Base Class\n// ============================================================================\n\nexport abstract class ScorerDefinitionsStorage extends VersionedStorageDomain<\n StorageScorerDefinitionType,\n StorageScorerDefinitionSnapshotType,\n StorageResolvedScorerDefinitionType,\n ScorerDefinitionVersion,\n CreateScorerDefinitionVersionInput,\n ListScorerDefinitionVersionsInput,\n ListScorerDefinitionVersionsOutput,\n { scorerDefinition: StorageCreateScorerDefinitionInput },\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput | undefined,\n StorageListScorerDefinitionsOutput,\n StorageListScorerDefinitionsResolvedOutput\n> {\n protected readonly listKey = 'scorerDefinitions';\n protected readonly versionMetadataFields = [\n 'id',\n 'scorerDefinitionId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof ScorerDefinitionVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'SCORER_DEFINITIONS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageScorerDefinitionType,\n StorageCreateScorerDefinitionInput,\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput,\n StorageListScorerDefinitionsOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n ScorerDefinitionVersion,\n CreateScorerDefinitionVersionInput,\n ListScorerDefinitionVersionsInput,\n ListScorerDefinitionVersionsOutput,\n ScorerDefinitionVersionOrderBy,\n ScorerDefinitionVersionSortDirection,\n} from './base';\nimport { ScorerDefinitionsStorage } from './base';\n\nexport class InMemoryScorerDefinitionsStorage extends ScorerDefinitionsStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.scorerDefinitions.clear();\n this.db.scorerDefinitionVersions.clear();\n }\n\n // ==========================================================================\n // Scorer Definition CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageScorerDefinitionType | null> {\n const scorer = this.db.scorerDefinitions.get(id);\n return scorer ? this.deepCopyScorer(scorer) : null;\n }\n\n async create(input: { scorerDefinition: StorageCreateScorerDefinitionInput }): Promise<StorageScorerDefinitionType> {\n const { scorerDefinition } = input;\n\n if (this.db.scorerDefinitions.has(scorerDefinition.id)) {\n throw new Error(`Scorer definition with id ${scorerDefinition.id} already exists`);\n }\n\n const now = new Date();\n const newScorer: StorageScorerDefinitionType = {\n id: scorerDefinition.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: scorerDefinition.authorId,\n metadata: scorerDefinition.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.scorerDefinitions.set(scorerDefinition.id, newScorer);\n\n // Extract config fields from the flat input (everything except scorer-record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n scorerDefinitionId: scorerDefinition.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin scorer record\n return this.deepCopyScorer(newScorer);\n }\n\n async update(input: StorageUpdateScorerDefinitionInput): Promise<StorageScorerDefinitionType> {\n const { id, ...updates } = input;\n\n const existingScorer = this.db.scorerDefinitions.get(id);\n if (!existingScorer) {\n throw new Error(`Scorer definition with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the scorer record\n const updatedScorer: StorageScorerDefinitionType = {\n ...existingScorer,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageScorerDefinitionType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingScorer.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated scorer record\n this.db.scorerDefinitions.set(id, updatedScorer);\n return this.deepCopyScorer(updatedScorer);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.scorerDefinitions.delete(id);\n // Also delete all versions for this scorer definition\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListScorerDefinitionsInput): Promise<StorageListScorerDefinitionsOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all scorer definitions and apply filters\n let scorers = Array.from(this.db.scorerDefinitions.values());\n\n // Filter by status\n if (status) {\n scorers = scorers.filter(scorer => scorer.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n scorers = scorers.filter(scorer => scorer.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n scorers = scorers.filter(scorer => {\n if (!scorer.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(scorer.metadata![key], value));\n });\n }\n\n // Sort filtered scorer definitions\n const sortedScorers = this.sortScorers(scorers, field, direction);\n\n // Deep clone scorers to avoid mutation\n const clonedScorers = sortedScorers.map(scorer => this.deepCopyScorer(scorer));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n scorerDefinitions: clonedScorers.slice(offset, offset + perPage),\n total: clonedScorers.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedScorers.length,\n };\n }\n\n // ==========================================================================\n // Scorer Definition Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateScorerDefinitionVersionInput): Promise<ScorerDefinitionVersion> {\n // Check if version with this ID already exists\n if (this.db.scorerDefinitionVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (scorerDefinitionId, versionNumber) pair\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === input.scorerDefinitionId && version.versionNumber === input.versionNumber) {\n throw new Error(\n `Version number ${input.versionNumber} already exists for scorer definition ${input.scorerDefinitionId}`,\n );\n }\n }\n\n const version: ScorerDefinitionVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.scorerDefinitionVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<ScorerDefinitionVersion | null> {\n const version = this.db.scorerDefinitionVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(scorerDefinitionId: string, versionNumber: number): Promise<ScorerDefinitionVersion | null> {\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === scorerDefinitionId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(scorerDefinitionId: string): Promise<ScorerDefinitionVersion | null> {\n let latest: ScorerDefinitionVersion | null = null;\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === scorerDefinitionId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListScorerDefinitionVersionsInput): Promise<ListScorerDefinitionVersionsOutput> {\n const { scorerDefinitionId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by scorerDefinitionId\n let versions = Array.from(this.db.scorerDefinitionVersions.values()).filter(\n v => v.scorerDefinitionId === scorerDefinitionId,\n );\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.scorerDefinitionVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.scorerDefinitionVersions.entries()) {\n if (version.scorerDefinitionId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.scorerDefinitionVersions.delete(id);\n }\n }\n\n async countVersions(scorerDefinitionId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === scorerDefinitionId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyScorer(scorer: StorageScorerDefinitionType): StorageScorerDefinitionType {\n return {\n ...scorer,\n metadata: scorer.metadata ? { ...scorer.metadata } : scorer.metadata,\n };\n }\n\n private deepCopyVersion(version: ScorerDefinitionVersion): ScorerDefinitionVersion {\n return {\n ...version,\n model: version.model ? JSON.parse(JSON.stringify(version.model)) : version.model,\n scoreRange: version.scoreRange ? JSON.parse(JSON.stringify(version.scoreRange)) : version.scoreRange,\n presetConfig: version.presetConfig ? JSON.parse(JSON.stringify(version.presetConfig)) : version.presetConfig,\n defaultSampling: version.defaultSampling\n ? JSON.parse(JSON.stringify(version.defaultSampling))\n : version.defaultSampling,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortScorers(\n scorers: StorageScorerDefinitionType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageScorerDefinitionType[] {\n return scorers.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: ScorerDefinitionVersion[],\n field: ScorerDefinitionVersionOrderBy,\n direction: ScorerDefinitionVersionSortDirection,\n ): ScorerDefinitionVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageScorerDefinitionType,\n StorageCreateScorerDefinitionInput,\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput,\n StorageListScorerDefinitionsOutput,\n} from '../../types';\nimport type {\n ScorerDefinitionVersion,\n CreateScorerDefinitionVersionInput,\n ListScorerDefinitionVersionsInput,\n ListScorerDefinitionVersionsOutput,\n} from './base';\nimport { ScorerDefinitionsStorage } from './base';\n\nexport class FilesystemScorerDefinitionsStorage extends ScorerDefinitionsStorage {\n private helpers: FilesystemVersionedHelpers<StorageScorerDefinitionType, ScorerDefinitionVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'scorer-definitions.json',\n parentIdField: 'scorerDefinitionId',\n name: 'FilesystemScorerDefinitionsStorage',\n versionMetadataFields: [\n 'id',\n 'scorerDefinitionId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageScorerDefinitionType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { scorerDefinition: StorageCreateScorerDefinitionInput }): Promise<StorageScorerDefinitionType> {\n const { scorerDefinition } = input;\n const now = new Date();\n const entity: StorageScorerDefinitionType = {\n id: scorerDefinition.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: scorerDefinition.authorId,\n metadata: scorerDefinition.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(scorerDefinition.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n scorerDefinitionId: scorerDefinition.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateScorerDefinitionVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateScorerDefinitionInput): Promise<StorageScorerDefinitionType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListScorerDefinitionsInput): Promise<StorageListScorerDefinitionsOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'scorerDefinitions',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListScorerDefinitionsOutput;\n }\n\n async createVersion(input: CreateScorerDefinitionVersionInput): Promise<ScorerDefinitionVersion> {\n return this.helpers.createVersion(input as ScorerDefinitionVersion);\n }\n\n async getVersion(id: string): Promise<ScorerDefinitionVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(scorerDefinitionId: string, versionNumber: number): Promise<ScorerDefinitionVersion | null> {\n return this.helpers.getVersionByNumber(scorerDefinitionId, versionNumber);\n }\n\n async getLatestVersion(scorerDefinitionId: string): Promise<ScorerDefinitionVersion | null> {\n return this.helpers.getLatestVersion(scorerDefinitionId);\n }\n\n async listVersions(input: ListScorerDefinitionVersionsInput): Promise<ListScorerDefinitionVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'scorerDefinitionId');\n return result as ListScorerDefinitionVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(scorerDefinitionId: string): Promise<number> {\n return this.helpers.countVersions(scorerDefinitionId);\n }\n}\n"]} |
| import { randomUUID } from 'crypto'; | ||
| import { z } from 'zod/v4'; | ||
| // src/background-tasks/manager.ts | ||
| // src/background-tasks/workflow-id.ts | ||
| var BACKGROUND_TASK_WORKFLOW_ID = "__background-task"; | ||
| // src/background-tasks/manager.ts | ||
| var TOPIC_DISPATCH = "background-tasks"; | ||
| var TOPIC_RESULT = "background-tasks-result"; | ||
| var WORKER_GROUP = "background-task-workers"; | ||
| var BackgroundTaskManager = class { | ||
| pubsub; | ||
| config; | ||
| #mastra; | ||
| // Per-task contexts — keyed by task ID, holds closures from the caller's stream. | ||
| /** @internal — read by the workflow-engine step bodies in workflow.ts */ | ||
| taskContexts = /* @__PURE__ */ new Map(); | ||
| // Static executors keyed by tool name. Populated by `Mastra` for every | ||
| // registered tool, and by `BackgroundTaskWorker.#wireStaticTools` on | ||
| // standalone worker processes. Used as the fallback for cross-process | ||
| // dispatch where the producer's per-task closure (taskContexts) is not | ||
| // visible — a remote worker resolves the tool by name instead. | ||
| staticExecutors = /* @__PURE__ */ new Map(); | ||
| // Track active AbortControllers for running tasks (for cancellation + timeout) | ||
| /** @internal — read by the workflow-engine step bodies in workflow.ts */ | ||
| activeAbortControllers = /* @__PURE__ */ new Map(); | ||
| // Pubsub callbacks (kept for unsubscribe) | ||
| workerCallback; | ||
| resultCallback; | ||
| shuttingDown = false; | ||
| // Cleanup interval handle | ||
| cleanupInterval; | ||
| // Tracks the in-flight `init(pubsub)` so consumers can await readiness. | ||
| // Mastra fires init as fire-and-forget in `#ensureBackgroundTaskManager`, | ||
| // so without this any caller that hits `enqueue`/`resume`/`cancel` | ||
| // before init completes races against worker subscription + workflow | ||
| // registration. Public methods that depend on init await this promise | ||
| // before doing work. | ||
| initPromise; | ||
| constructor(config = { enabled: false }) { | ||
| this.config = { | ||
| globalConcurrency: config.globalConcurrency ?? 10, | ||
| perAgentConcurrency: config.perAgentConcurrency ?? 5, | ||
| backpressure: config.backpressure ?? "queue", | ||
| defaultTimeoutMs: config.defaultTimeoutMs ?? 3e5, | ||
| ...config | ||
| }; | ||
| } | ||
| __registerMastra(mastra) { | ||
| this.#mastra = mastra; | ||
| } | ||
| async getStorage() { | ||
| const storage = this.#mastra?.getStorage(); | ||
| if (!storage) { | ||
| throw new Error("Storage is not initialized"); | ||
| } | ||
| const bgStore = await storage.getStore("backgroundTasks"); | ||
| if (!bgStore) { | ||
| throw new Error("Background tasks storage is not available"); | ||
| } | ||
| return bgStore; | ||
| } | ||
| async init(pubsub) { | ||
| if (this.initPromise) return this.initPromise; | ||
| this.initPromise = this.#doInit(pubsub); | ||
| return this.initPromise; | ||
| } | ||
| async #doInit(pubsub) { | ||
| this.pubsub = pubsub; | ||
| this.workerCallback = async (event, ack) => { | ||
| if (event.type === "task.dispatch") { | ||
| await this.handleDispatch(event); | ||
| } else if (event.type === "task.resume") { | ||
| await this.handleResume(event); | ||
| } else if (event.type === "task.cancel") { | ||
| this.handleCancel(event); | ||
| } | ||
| await ack?.(); | ||
| }; | ||
| this.resultCallback = async (event, ack) => { | ||
| if (event.type === "task.completed" || event.type === "task.failed") { | ||
| await this.handleResult(event); | ||
| } | ||
| await ack?.(); | ||
| }; | ||
| if (this.#mastra) { | ||
| const { buildBackgroundTaskWorkflow } = await import('./workflow-XYGMHLZV.js'); | ||
| const workflow = buildBackgroundTaskWorkflow(this); | ||
| if (!this.#mastra.__hasInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID)) { | ||
| this.#mastra.__registerInternalWorkflow( | ||
| workflow | ||
| ); | ||
| } | ||
| } | ||
| await this.pubsub.subscribe(TOPIC_DISPATCH, this.workerCallback, { group: WORKER_GROUP }); | ||
| await this.pubsub.subscribe(TOPIC_RESULT, this.resultCallback); | ||
| await this.recoverStaleTasks(); | ||
| const cleanupConfig = this.config.cleanup; | ||
| if (cleanupConfig) { | ||
| const intervalMs = cleanupConfig.cleanupIntervalMs ?? 6e4; | ||
| this.cleanupInterval = setInterval(() => { | ||
| void this.cleanup(); | ||
| }, intervalMs); | ||
| } | ||
| } | ||
| // --- Per-task context registration --- | ||
| /** | ||
| * Register per-task hooks (executor, stream emitter, result injector). | ||
| * Called internally by createBackgroundTask or directly for advanced usage. | ||
| */ | ||
| registerTaskContext(taskId, context) { | ||
| this.taskContexts.set(taskId, context); | ||
| } | ||
| /** | ||
| * Remove per-task hooks. Called after task reaches terminal state. | ||
| */ | ||
| deregisterTaskContext(taskId) { | ||
| this.taskContexts.delete(taskId); | ||
| } | ||
| /** | ||
| * Register a tool executor by tool name. Used for cross-process dispatch: | ||
| * when a worker in a different process picks up a `task.dispatch` event, | ||
| * it has no per-task closure (`taskContexts`) for that taskId, but it can | ||
| * resolve the executor by tool name via this registry. | ||
| */ | ||
| registerStaticExecutor(toolName, executor) { | ||
| if (this.staticExecutors.has(toolName)) { | ||
| this.#mastra?.getLogger?.()?.debug?.(`Overwriting existing static executor for tool "${toolName}"`); | ||
| } | ||
| this.staticExecutors.set(toolName, executor); | ||
| } | ||
| /** | ||
| * Symmetric to `registerStaticExecutor`. Called when a tool is removed | ||
| * from `Mastra`. | ||
| */ | ||
| unregisterStaticExecutor(toolName) { | ||
| this.staticExecutors.delete(toolName); | ||
| } | ||
| /** | ||
| * Look up an executor by tool name. Read by the workflow-step body in | ||
| * `workflow.ts:runAttemptStep` as a fallback when no per-task `TaskContext` | ||
| * is registered (cross-process path). | ||
| */ | ||
| getStaticExecutor(toolName) { | ||
| return this.staticExecutors.get(toolName); | ||
| } | ||
| // --- Core operations --- | ||
| /** | ||
| * Enqueue a task for background execution. | ||
| * Prefer `createBackgroundTask()` which returns a self-contained handle. | ||
| */ | ||
| async enqueue(payload, context) { | ||
| if (this.shuttingDown) { | ||
| throw new Error("BackgroundTaskManager is shutting down, cannot enqueue new tasks"); | ||
| } | ||
| if (this.initPromise) await this.initPromise; | ||
| const task = { | ||
| id: this.#mastra?.generateId() ?? randomUUID(), | ||
| status: "pending", | ||
| toolName: payload.toolName, | ||
| toolCallId: payload.toolCallId, | ||
| args: payload.args, | ||
| agentId: payload.agentId, | ||
| threadId: payload.threadId, | ||
| resourceId: payload.resourceId, | ||
| runId: payload.runId, | ||
| retryCount: 0, | ||
| maxRetries: payload.maxRetries ?? this.config.defaultRetries?.maxRetries ?? 0, | ||
| timeoutMs: payload.timeoutMs ?? this.config.defaultTimeoutMs, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| if (context) { | ||
| this.registerTaskContext(task.id, context); | ||
| } | ||
| const storage = await this.getStorage(); | ||
| await storage.createTask(task); | ||
| const canRun = await this.checkConcurrency(task.agentId); | ||
| if (canRun) { | ||
| await this.dispatch(task); | ||
| return { task }; | ||
| } | ||
| switch (this.config.backpressure) { | ||
| case "reject": | ||
| this.deregisterTaskContext(task.id); | ||
| await storage.deleteTask(task.id); | ||
| throw new Error(`Concurrency limit reached, cannot enqueue task for tool "${task.toolName}"`); | ||
| case "fallback-sync": | ||
| this.deregisterTaskContext(task.id); | ||
| await storage.deleteTask(task.id); | ||
| return { task, fallbackToSync: true }; | ||
| case "queue": | ||
| default: | ||
| return { task }; | ||
| } | ||
| } | ||
| async cancel(taskId) { | ||
| if (this.initPromise) await this.initPromise; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task) { | ||
| throw new Error(`Task not found: ${taskId}`); | ||
| } | ||
| if (task.status === "completed" || task.status === "failed" || task.status === "cancelled" || task.status === "timed_out") { | ||
| return; | ||
| } | ||
| if (task.status === "pending") { | ||
| await storage.updateTask(taskId, { status: "cancelled", completedAt: /* @__PURE__ */ new Date() }); | ||
| const cancelledTask = await storage.getTask(taskId); | ||
| if (cancelledTask) await this.publishLifecycleEvent("task.cancelled", cancelledTask); | ||
| this.deregisterTaskContext(taskId); | ||
| return; | ||
| } | ||
| if (task.status === "suspended") { | ||
| await storage.updateTask(taskId, { status: "cancelled", completedAt: /* @__PURE__ */ new Date() }); | ||
| if (this.#mastra) { | ||
| try { | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const wrapper = await workflow.createRun({ runId: taskId }); | ||
| await wrapper.cancel(); | ||
| } catch (err) { | ||
| this.#mastra?.getLogger?.()?.warn(`background-task workflow cancel failed for ${taskId}:`, err); | ||
| } | ||
| } | ||
| const cancelledTask = await storage.getTask(taskId); | ||
| if (cancelledTask) await this.publishLifecycleEvent("task.cancelled", cancelledTask); | ||
| this.deregisterTaskContext(taskId); | ||
| return; | ||
| } | ||
| if (task.status === "running") { | ||
| await storage.updateTask(taskId, { status: "cancelled", completedAt: /* @__PURE__ */ new Date() }); | ||
| const controller = this.activeAbortControllers.get(taskId); | ||
| if (controller) { | ||
| controller.abort(new Error("Task cancelled")); | ||
| this.activeAbortControllers.delete(taskId); | ||
| } | ||
| if (this.#mastra) { | ||
| try { | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const wrapper = await workflow.createRun({ runId: taskId }); | ||
| await wrapper.cancel(); | ||
| } catch (err) { | ||
| this.#mastra?.getLogger?.()?.warn(`background-task workflow cancel failed for ${taskId}:`, err); | ||
| } | ||
| } | ||
| const cancelledTask = await storage.getTask(taskId); | ||
| if (cancelledTask) await this.publishLifecycleEvent("task.cancelled", cancelledTask); | ||
| this.deregisterTaskContext(taskId); | ||
| await this.pubsub.publish(TOPIC_DISPATCH, { | ||
| type: "task.cancel", | ||
| data: { taskId }, | ||
| runId: taskId | ||
| }); | ||
| } | ||
| } | ||
| /** | ||
| * Resume a suspended task. The tool executor must be re-registered via | ||
| * `registerTaskContext(taskId, ...)` before calling this if the original | ||
| * registration is gone (e.g. process restart) — the manager doesn't | ||
| * rehydrate executor closures from storage. | ||
| * | ||
| * `resumeData` is forwarded to the tool's `execute` options on the | ||
| * resumed run. | ||
| */ | ||
| async resume(taskId, resumeData) { | ||
| if (!this.#mastra) { | ||
| throw new Error("Mastra is not registered with this manager"); | ||
| } | ||
| if (this.initPromise) await this.initPromise; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task) { | ||
| throw new Error(`Task not found: ${taskId}`); | ||
| } | ||
| if (task.status !== "suspended") { | ||
| throw new Error(`Cannot resume task in status '${task.status}' (expected 'suspended')`); | ||
| } | ||
| const canRun = await this.checkConcurrency(task.agentId); | ||
| if (!canRun) { | ||
| throw new Error(`Concurrency limit reached, cannot resume task "${taskId}" \u2014 retry once a slot is available`); | ||
| } | ||
| await this.pubsub.publish(TOPIC_DISPATCH, { | ||
| type: "task.resume", | ||
| data: { taskId, resumeData }, | ||
| runId: taskId | ||
| }); | ||
| return task; | ||
| } | ||
| async getTask(taskId) { | ||
| const storage = await this.getStorage(); | ||
| return storage.getTask(taskId); | ||
| } | ||
| async listTasks(filter = {}) { | ||
| const storage = await this.getStorage(); | ||
| return storage.listTasks(filter); | ||
| } | ||
| /** | ||
| * Deletes old completed/failed/cancelled/timed_out task records from storage. | ||
| */ | ||
| async cleanup() { | ||
| const completedTtlMs = this.config.cleanup?.completedTtlMs ?? 36e5; | ||
| const failedTtlMs = this.config.cleanup?.failedTtlMs ?? 864e5; | ||
| const now = Date.now(); | ||
| const storage = await this.getStorage(); | ||
| await storage.deleteTasks({ | ||
| status: ["completed"], | ||
| toDate: new Date(now - completedTtlMs), | ||
| dateFilterBy: "completedAt" | ||
| }); | ||
| await storage.deleteTasks({ | ||
| status: ["failed", "cancelled", "timed_out"], | ||
| toDate: new Date(now - failedTtlMs), | ||
| dateFilterBy: "completedAt" | ||
| }); | ||
| } | ||
| /** | ||
| * Returns a promise that resolves when the next task from the given set | ||
| * reaches a terminal state. | ||
| */ | ||
| async waitForNextTask(taskIds, options) { | ||
| const storage = await this.getStorage(); | ||
| const isTerminal = (status) => status === "completed" || status === "failed" || status === "cancelled" || status === "timed_out"; | ||
| for (const id of taskIds) { | ||
| const task = await storage.getTask(id); | ||
| if (task && isTerminal(task.status)) { | ||
| return task; | ||
| } | ||
| } | ||
| return new Promise((resolve, reject) => { | ||
| const startTime = Date.now(); | ||
| const timeout = options?.timeoutMs ? setTimeout(() => { | ||
| clearInterval(pollInterval); | ||
| if (progressInterval) clearInterval(progressInterval); | ||
| reject(new Error("Timed out waiting for background task")); | ||
| }, options.timeoutMs) : void 0; | ||
| const progressInterval = options?.onProgress ? setInterval(() => { | ||
| options.onProgress(Date.now() - startTime); | ||
| }, options.progressIntervalMs ?? 3e3) : void 0; | ||
| const pollInterval = setInterval(async () => { | ||
| for (const id of taskIds) { | ||
| const task = await storage.getTask(id); | ||
| if (task && isTerminal(task.status)) { | ||
| clearInterval(pollInterval); | ||
| if (timeout) clearTimeout(timeout); | ||
| if (progressInterval) clearInterval(progressInterval); | ||
| resolve(task); | ||
| return; | ||
| } | ||
| } | ||
| }, 50); | ||
| }); | ||
| } | ||
| /** | ||
| * Returns a ReadableStream of all background task lifecycle events, | ||
| * filtered by optional criteria. Intended to be piped directly to an SSE response. | ||
| * | ||
| * On connection, emits the current state of all non-terminal tasks as a snapshot, | ||
| * then subscribes to live pubsub events for subsequent updates. | ||
| * | ||
| * Events include: | ||
| * - `task.running` (status: 'running') — task picked up by a worker | ||
| * - `task.completed` (status: 'completed') — task finished successfully | ||
| * - `task.failed` (status: 'failed' or 'timed_out') — task errored or timed out | ||
| * - `task.cancelled` (status: 'cancelled') — task was cancelled | ||
| * - `task.suspended` (status: 'suspended') — task paused via `suspend()` from | ||
| * inside its tool executor; resume with `manager.resume(taskId, data)` | ||
| * - `task.resumed` (status: 'running') — suspended task resumed | ||
| * | ||
| * The stream stays open until the caller's AbortSignal fires (client disconnect). | ||
| */ | ||
| stream(options) { | ||
| const manager = this; | ||
| const pubsub = this.pubsub; | ||
| const { agentId, runId, threadId, resourceId, abortSignal, taskId } = options ?? {}; | ||
| const EVENT_STATUS_MAP = { | ||
| "task.running": "running", | ||
| "task.output": "running", | ||
| "task.completed": "completed", | ||
| "task.failed": "failed", | ||
| "task.cancelled": "cancelled", | ||
| "task.suspended": "suspended", | ||
| "task.resumed": "running" | ||
| }; | ||
| const CHUNK_EVENT_MAP = { | ||
| "task.running": "background-task-running", | ||
| "task.output": "background-task-output", | ||
| "task.completed": "background-task-completed", | ||
| "task.failed": "background-task-failed", | ||
| "task.cancelled": "background-task-cancelled", | ||
| "task.suspended": "background-task-suspended", | ||
| "task.resumed": "background-task-resumed" | ||
| }; | ||
| return new ReadableStream({ | ||
| async start(controller) { | ||
| const handler = async (event) => { | ||
| const status = EVENT_STATUS_MAP[event.type]; | ||
| if (!status) return; | ||
| const data = event.data; | ||
| if (agentId && data.agentId !== agentId) return; | ||
| if (runId && data.runId !== runId) return; | ||
| if (threadId && data.threadId !== threadId) return; | ||
| if (resourceId && data.resourceId !== resourceId) return; | ||
| if (taskId && data.taskId !== taskId) return; | ||
| const payload = { | ||
| taskId: data.taskId, | ||
| toolName: data.toolName, | ||
| toolCallId: data.toolCallId, | ||
| agentId: data.agentId, | ||
| runId: data.runId | ||
| }; | ||
| switch (event.type) { | ||
| case "task.running": | ||
| payload.startedAt = data.startedAt; | ||
| payload.args = data.args; | ||
| break; | ||
| case "task.completed": | ||
| payload.completedAt = data.completedAt; | ||
| payload.result = data.result; | ||
| break; | ||
| case "task.failed": | ||
| payload.completedAt = data.completedAt; | ||
| payload.error = data.error; | ||
| break; | ||
| case "task.cancelled": | ||
| payload.completedAt = data.completedAt; | ||
| break; | ||
| case "task.output": | ||
| payload.payload = data.chunk; | ||
| break; | ||
| case "task.suspended": | ||
| payload.suspendPayload = data.suspendPayload; | ||
| payload.suspendedAt = data.suspendedAt; | ||
| payload.args = data.args; | ||
| break; | ||
| case "task.resumed": | ||
| payload.startedAt = data.startedAt; | ||
| payload.args = data.args; | ||
| break; | ||
| } | ||
| try { | ||
| controller.enqueue({ | ||
| type: CHUNK_EVENT_MAP[event.type], | ||
| payload | ||
| }); | ||
| } catch { | ||
| } | ||
| }; | ||
| void pubsub.subscribe(TOPIC_RESULT, handler); | ||
| abortSignal?.addEventListener("abort", () => { | ||
| void pubsub.unsubscribe(TOPIC_RESULT, handler); | ||
| try { | ||
| controller.close(); | ||
| } catch { | ||
| } | ||
| }); | ||
| try { | ||
| const storage = await manager.getStorage(); | ||
| if (taskId) { | ||
| const task = await storage.getTask(taskId); | ||
| if (task && task.status === "running") { | ||
| controller.enqueue({ | ||
| type: "background-task-running", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| agentId: task.agentId, | ||
| runId: task.runId, | ||
| startedAt: task.startedAt, | ||
| args: task.args | ||
| } | ||
| }); | ||
| } | ||
| } else { | ||
| const { tasks: existing } = await storage.listTasks({ | ||
| agentId, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| status: ["running"] | ||
| }); | ||
| for (const task of existing) { | ||
| if (abortSignal?.aborted) break; | ||
| try { | ||
| controller.enqueue({ | ||
| type: "background-task-running", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| agentId: task.agentId, | ||
| runId: task.runId, | ||
| startedAt: task.startedAt, | ||
| args: task.args | ||
| } | ||
| }); | ||
| } catch { | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| } catch { | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| async shutdown() { | ||
| this.shuttingDown = true; | ||
| if (this.cleanupInterval) { | ||
| clearInterval(this.cleanupInterval); | ||
| this.cleanupInterval = void 0; | ||
| } | ||
| if (this.workerCallback) { | ||
| await this.pubsub.unsubscribe(TOPIC_DISPATCH, this.workerCallback); | ||
| } | ||
| if (this.resultCallback) { | ||
| await this.pubsub.unsubscribe(TOPIC_RESULT, this.resultCallback); | ||
| } | ||
| this.taskContexts.clear(); | ||
| await this.pubsub.flush(); | ||
| } | ||
| // --- Internal --- | ||
| async dispatch(task) { | ||
| await this.pubsub.publish(TOPIC_DISPATCH, { | ||
| type: "task.dispatch", | ||
| data: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| args: task.args, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| timeoutMs: task.timeoutMs, | ||
| maxRetries: task.maxRetries, | ||
| runId: task.runId | ||
| }, | ||
| runId: task.id | ||
| }); | ||
| } | ||
| /** | ||
| * Handles a task.dispatch event. Returns true if the message was nacked (for retry). | ||
| */ | ||
| async handleDispatch(event) { | ||
| const { taskId } = event.data; | ||
| const deliveryAttempt = event.deliveryAttempt ?? 1; | ||
| let nacked = false; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task || task.status === "cancelled") { | ||
| this.deregisterTaskContext(taskId); | ||
| return false; | ||
| } | ||
| await storage.updateTask(taskId, { status: "running", startedAt: /* @__PURE__ */ new Date(), retryCount: deliveryAttempt - 1 }); | ||
| const runningTask = await storage.getTask(taskId); | ||
| if (runningTask) await this.publishLifecycleEvent("task.running", runningTask); | ||
| if (this.#mastra) { | ||
| if (runningTask) void this.runLocalExecutionHook(runningTask); | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const run = await workflow.createRun({ runId: taskId }); | ||
| void run.start({ inputData: { taskId } }).then((result) => { | ||
| if (result.status !== "suspended") { | ||
| void workflow.deleteWorkflowRunById(taskId); | ||
| } | ||
| }).catch((err) => { | ||
| this.#mastra?.getLogger?.()?.error(`background-task workflow start failed for ${taskId}:`, err); | ||
| }).finally(() => { | ||
| void this.drainPending(); | ||
| }); | ||
| } | ||
| return nacked; | ||
| } | ||
| /** | ||
| * Handles a task.resume event. Mirrors the workflow branch of handleDispatch | ||
| * but resumes an existing run from its suspended snapshot instead of starting | ||
| * a fresh one. Concurrency gating, suspended-status validation, and the | ||
| * `task.resumed` lifecycle publish all happen here so a different process | ||
| * than the one that suspended the task can drive the resume. | ||
| */ | ||
| async handleResume(event) { | ||
| const { taskId, resumeData } = event.data; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task || task.status !== "suspended") { | ||
| return; | ||
| } | ||
| await storage.updateTask(taskId, { | ||
| status: "running", | ||
| startedAt: /* @__PURE__ */ new Date(), | ||
| suspendPayload: void 0, | ||
| suspendedAt: void 0 | ||
| }); | ||
| const resumedTask = await storage.getTask(taskId); | ||
| if (resumedTask) { | ||
| await this.publishLifecycleEvent("task.resumed", resumedTask); | ||
| } | ||
| if (!this.#mastra) return; | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const run = await workflow.createRun({ runId: taskId }); | ||
| void run.resume({ resumeData }).then((result) => { | ||
| if (result.status !== "suspended") { | ||
| void workflow.deleteWorkflowRunById(taskId); | ||
| } | ||
| }).catch((err) => { | ||
| this.#mastra?.getLogger?.()?.error(`background-task workflow resume failed for ${taskId}:`, err); | ||
| }).finally(() => { | ||
| void this.drainPending(); | ||
| }); | ||
| } | ||
| /** | ||
| * Run per-task hooks (onChunk, onResult, onComplete/onFailed) locally in the | ||
| * worker path, before publishing the terminal lifecycle event. Ensures | ||
| * memory / stream state is consistent by the time any pubsub subscriber is | ||
| * notified. After running, the task context is deregistered so | ||
| * `handleResult` (which also fires from pubsub) becomes a no-op for this | ||
| * task in the same process. | ||
| * | ||
| * In distributed deployments where the worker runs in a different process | ||
| * from the dispatcher, `this.taskContexts` won't contain an entry for | ||
| * `task.id` — this method is a no-op there, and `handleResult` in the | ||
| * dispatching process runs the hooks instead. | ||
| */ | ||
| /** | ||
| * Terminal-state hooks only. Called when a task reaches `'completed'` or | ||
| * `'failed'`. Suspend is non-terminal — see `runLocalSuspendHooks` for that | ||
| * path. | ||
| * | ||
| * @internal — also called by the workflow-engine step bodies in workflow.ts | ||
| */ | ||
| async runLocalCompletionHooks(task, status, extras) { | ||
| const ctx = this.taskContexts.get(task.id); | ||
| if (!ctx) return; | ||
| try { | ||
| if (status === "completed") { | ||
| ctx.onChunk?.({ | ||
| type: "background-task-completed", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| runId: task.runId, | ||
| result: extras.result, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx.onResult?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| result: extras.result, | ||
| status: "completed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| await ctx.onComplete?.(task); | ||
| } else { | ||
| ctx.onChunk?.({ | ||
| type: "background-task-failed", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| runId: task.runId, | ||
| error: extras.error ?? { message: "Unknown error" }, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx.onResult?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| error: extras.error, | ||
| status: "failed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| await ctx.onFailed?.(task); | ||
| } | ||
| } finally { | ||
| this.deregisterTaskContext(task.id); | ||
| } | ||
| } | ||
| /** | ||
| * Per-task suspend hooks. Fires `ctx.onResult({ status: 'suspended', ... })` | ||
| * so the message list / memory pick up the suspension as the tool's | ||
| * current invocation state. Does NOT deregister the task context — resume | ||
| * needs the executor closure intact. | ||
| * | ||
| * @internal — called by the workflow-engine step bodies in workflow.ts | ||
| */ | ||
| async runLocalSuspendHooks(task) { | ||
| const ctx = this.taskContexts.get(task.id); | ||
| if (!ctx) return; | ||
| await ctx.onExecution?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| startedAt: task.startedAt, | ||
| suspendedAt: task.suspendedAt | ||
| }); | ||
| } | ||
| /** @internal — also called by the workflow-engine step bodies in workflow.ts */ | ||
| async runLocalExecutionHook(task) { | ||
| const ctx = this.taskContexts.get(task.id); | ||
| if (!ctx) return; | ||
| try { | ||
| await ctx.onExecution?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| startedAt: task.startedAt | ||
| }); | ||
| } catch { | ||
| } | ||
| } | ||
| async handleResult(event) { | ||
| const { taskId, toolName, toolCallId, threadId, resourceId, runId } = event.data; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (task?.completedAt) { | ||
| const ctx = this.taskContexts.get(taskId); | ||
| if (event.type === "task.completed") { | ||
| ctx?.onChunk?.({ | ||
| type: "background-task-completed", | ||
| payload: { | ||
| taskId, | ||
| toolName, | ||
| toolCallId, | ||
| runId, | ||
| result: event.data.result, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx?.onResult?.({ | ||
| runId, | ||
| taskId, | ||
| toolCallId, | ||
| toolName, | ||
| agentId: event.data.agentId, | ||
| threadId, | ||
| resourceId, | ||
| result: event.data.result, | ||
| status: "completed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| if (task) { | ||
| await Promise.all([ctx?.onComplete?.(task), this.config.onTaskComplete?.(task)]); | ||
| } | ||
| } | ||
| if (event.type === "task.failed") { | ||
| ctx?.onChunk?.({ | ||
| type: "background-task-failed", | ||
| payload: { | ||
| taskId, | ||
| toolName, | ||
| toolCallId, | ||
| runId, | ||
| error: event.data.error, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx?.onResult?.({ | ||
| runId, | ||
| taskId, | ||
| toolCallId, | ||
| toolName, | ||
| agentId: event.data.agentId, | ||
| threadId, | ||
| resourceId, | ||
| error: event.data.error, | ||
| status: "failed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| if (task) { | ||
| await Promise.all([ctx?.onFailed?.(task), this.config.onTaskFailed?.(task)]); | ||
| } | ||
| } | ||
| this.deregisterTaskContext(taskId); | ||
| } | ||
| } | ||
| handleCancel(event) { | ||
| const { taskId } = event.data; | ||
| const controller = this.activeAbortControllers.get(taskId); | ||
| if (controller) { | ||
| controller.abort(new Error("Task cancelled")); | ||
| this.activeAbortControllers.delete(taskId); | ||
| } | ||
| this.deregisterTaskContext(taskId); | ||
| } | ||
| /** @internal — also called by the workflow-engine step bodies in workflow.ts */ | ||
| async publishLifecycleEvent(type, task) { | ||
| await this.pubsub.publish(TOPIC_RESULT, { | ||
| type, | ||
| data: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| runId: task.runId, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| args: task.args, | ||
| result: task.result, | ||
| error: task.error, | ||
| chunk: task.chunk, | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt, | ||
| suspendPayload: task.suspendPayload, | ||
| suspendedAt: task.suspendedAt | ||
| }, | ||
| runId: task.id | ||
| }); | ||
| } | ||
| async checkConcurrency(agentId) { | ||
| const storage = await this.getStorage(); | ||
| const globalRunning = await storage.getRunningCount(); | ||
| if (globalRunning >= this.config.globalConcurrency) { | ||
| return false; | ||
| } | ||
| const agentRunning = await storage.getRunningCountByAgent(agentId); | ||
| if (agentRunning >= this.config.perAgentConcurrency) { | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| async drainPending() { | ||
| const storage = await this.getStorage(); | ||
| const { tasks: pending } = await storage.listTasks({ | ||
| status: "pending", | ||
| orderBy: "createdAt", | ||
| orderDirection: "asc" | ||
| }); | ||
| for (const task of pending) { | ||
| if (await this.checkConcurrency(task.agentId)) { | ||
| await this.dispatch(task); | ||
| } | ||
| } | ||
| } | ||
| /** | ||
| * Recovers tasks left in 'running' or 'pending' state from a previous process. | ||
| */ | ||
| async recoverStaleTasks() { | ||
| try { | ||
| const storage = await this.getStorage(); | ||
| const { tasks: staleTasks } = await storage.listTasks({ status: "running" }); | ||
| for (const task of staleTasks) { | ||
| if (task.maxRetries > 0) { | ||
| await storage.updateTask(task.id, { | ||
| status: "pending", | ||
| startedAt: void 0 | ||
| }); | ||
| } else { | ||
| await storage.updateTask(task.id, { | ||
| status: "failed", | ||
| error: { message: "Worker process terminated before task completed" }, | ||
| completedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| } | ||
| } | ||
| const { tasks: pendingTasks } = await storage.listTasks({ | ||
| status: "pending", | ||
| orderBy: "createdAt", | ||
| orderDirection: "asc" | ||
| }); | ||
| for (const task of pendingTasks) { | ||
| if (await this.checkConcurrency(task.agentId)) { | ||
| await this.dispatch(task); | ||
| } | ||
| } | ||
| } catch (error) { | ||
| const logger = this.#mastra?.getLogger(); | ||
| if (logger) { | ||
| logger.error("Failed to recover stale background tasks", error); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| // src/background-tasks/create.ts | ||
| function createBackgroundTask(manager, options) { | ||
| const { context, ...payload } = options; | ||
| let taskId; | ||
| return { | ||
| get task() { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return { id: taskId }; | ||
| }, | ||
| async dispatch() { | ||
| const result = await manager.enqueue(payload, context); | ||
| taskId = result.task.id; | ||
| return result; | ||
| }, | ||
| async checkIfSuspended(args) { | ||
| const result = await manager.listTasks({ | ||
| toolCallId: args.toolCallId, | ||
| runId: args.runId, | ||
| agentId: args.agentId, | ||
| threadId: args.threadId, | ||
| resourceId: args.resourceId, | ||
| toolName: args.toolName, | ||
| status: "suspended" | ||
| }); | ||
| if (result.total > 0) { | ||
| const task = result.tasks[0]; | ||
| if (task) { | ||
| taskId = task.id; | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| }, | ||
| async resume(resumeData) { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return manager.resume(taskId, resumeData); | ||
| }, | ||
| async cancel() { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return manager.cancel(taskId); | ||
| }, | ||
| async waitForCompletion(waitOptions) { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return manager.waitForNextTask([taskId], waitOptions); | ||
| } | ||
| }; | ||
| } | ||
| // src/background-tasks/resolve-config.ts | ||
| function resolveBackgroundConfig({ | ||
| llmBgOverrides, | ||
| toolName, | ||
| toolConfig, | ||
| agentConfig, | ||
| managerConfig | ||
| }) { | ||
| const llmOverride = llmBgOverrides; | ||
| if (agentConfig?.disabled) { | ||
| return { | ||
| runInBackground: false, | ||
| timeoutMs: managerConfig?.defaultTimeoutMs ?? 3e5, | ||
| maxRetries: managerConfig?.defaultRetries?.maxRetries ?? 0 | ||
| }; | ||
| } | ||
| const agentToolConfig = resolveAgentToolConfig(toolName, agentConfig); | ||
| const baseEnabled = agentToolConfig?.enabled ?? toolConfig?.enabled ?? false; | ||
| const enabled = baseEnabled ? llmOverride?.enabled ?? true : false; | ||
| const timeoutMs = llmOverride?.timeoutMs ?? agentToolConfig?.timeoutMs ?? toolConfig?.timeoutMs ?? managerConfig?.defaultTimeoutMs ?? 3e5; | ||
| const maxRetries = llmOverride?.maxRetries ?? toolConfig?.maxRetries ?? managerConfig?.defaultRetries?.maxRetries ?? 0; | ||
| return { runInBackground: enabled, timeoutMs, maxRetries }; | ||
| } | ||
| function resolveAgentToolConfig(toolName, agentConfig) { | ||
| if (!agentConfig?.tools) return void 0; | ||
| if (agentConfig.tools === "all") { | ||
| return { enabled: true }; | ||
| } | ||
| if (toolName.startsWith("agent-")) { | ||
| toolName = toolName.substring("agent-".length); | ||
| } else if (toolName.startsWith("workflow-")) { | ||
| toolName = toolName.substring("workflow-".length); | ||
| } | ||
| const entry = agentConfig.tools[toolName]; | ||
| if (entry === void 0) return void 0; | ||
| if (typeof entry === "boolean") return { enabled: entry }; | ||
| return entry; | ||
| } | ||
| var backgroundOverrideJsonSchema = { | ||
| type: "object", | ||
| description: "Optional: override background execution behavior for this specific call. Set enabled=false to force foreground, enabled=true to force background. Omit entirely to use the default configuration.", | ||
| properties: { | ||
| enabled: { | ||
| type: "boolean", | ||
| description: "Force background (true) or foreground (false) execution for this call." | ||
| }, | ||
| timeoutMs: { | ||
| type: "number", | ||
| description: "Override timeout in milliseconds for this call." | ||
| }, | ||
| maxRetries: { | ||
| type: "number", | ||
| description: "Override maximum retry attempts for this call." | ||
| } | ||
| }, | ||
| additionalProperties: false | ||
| }; | ||
| var backgroundOverrideZodSchema = z.object({ | ||
| enabled: z.boolean().optional().describe("Force background (true) or foreground (false) execution for this call."), | ||
| timeoutMs: z.number().optional().describe("Override timeout in milliseconds for this call."), | ||
| maxRetries: z.number().optional().describe("Override maximum retry attempts for this call.") | ||
| }).optional().describe( | ||
| "Optional: override background execution behavior for this specific call. Set enabled=false to force foreground, enabled=true to force background. Omit entirely to use the default configuration." | ||
| ); | ||
| // src/background-tasks/system-prompt.ts | ||
| function generateBackgroundTaskSystemPrompt(tools, agentConfig) { | ||
| const eligibleTools = []; | ||
| const enableAll = agentConfig?.tools === "all"; | ||
| for (const [toolName, tool] of Object.entries(tools)) { | ||
| const bgEnabledFromAgentConfig = agentConfig?.tools === "all" ? false : typeof agentConfig?.tools?.[toolName] === "boolean" ? agentConfig.tools[toolName] : agentConfig?.tools?.[toolName]?.enabled ?? false; | ||
| eligibleTools.push({ | ||
| toolName, | ||
| toolConfig: tool.background, | ||
| defaultBackground: enableAll ? true : bgEnabledFromAgentConfig ?? tool.background?.enabled ?? false | ||
| }); | ||
| } | ||
| if (eligibleTools.length === 0) { | ||
| return void 0; | ||
| } | ||
| const toolLines = eligibleTools.map((t) => `- ${t.toolName} (default: ${t.defaultBackground ? "background" : "foreground"})`).join("\n"); | ||
| return `You have the ability to run certain tools in the background while continuing the conversation. The following tools support background execution: | ||
| ${toolLines} | ||
| For any of these tools, you can include a "_background" field in the tool arguments to override the default: | ||
| "_background": { "enabled": true/false, "timeoutMs": number, "maxRetries": number } | ||
| All fields in "_background" are optional. Only include what you want to override. | ||
| Guidelines: | ||
| - Use background execution when the user doesn't need the result immediately, or when you're launching multiple independent tasks. | ||
| - Use foreground execution when the user is directly waiting for the result and the conversation can't continue without it. | ||
| - If you don't include "_background", the tool's default configuration is used. | ||
| - When a tool runs in the background, you'll receive a placeholder result with a task ID. You can reference this in your response to the user. | ||
| IMPORTANT: "_background" field is always an object. The fields in the _background field should be inside the _background object, not outside of it.`; | ||
| } | ||
| export { BACKGROUND_TASK_WORKFLOW_ID, BackgroundTaskManager, backgroundOverrideJsonSchema, backgroundOverrideZodSchema, createBackgroundTask, generateBackgroundTaskSystemPrompt, resolveBackgroundConfig }; | ||
| //# sourceMappingURL=chunk-GCIWBMEH.js.map | ||
| //# sourceMappingURL=chunk-GCIWBMEH.js.map |
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunk2UAP4LDC_cjs = require('./chunk-2UAP4LDC.cjs'); | ||
| var chunkBP67LMWW_cjs = require('./chunk-BP67LMWW.cjs'); | ||
| // src/storage/domains/prompt-blocks/base.ts | ||
| var PromptBlocksStorage = class extends chunk2UAP4LDC_cjs.VersionedStorageDomain { | ||
| listKey = "promptBlocks"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "blockId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "PROMPT_BLOCKS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/prompt-blocks/inmemory.ts | ||
| var InMemoryPromptBlocksStorage = class extends PromptBlocksStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.promptBlocks.clear(); | ||
| this.db.promptBlockVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Prompt Block CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const block = this.db.promptBlocks.get(id); | ||
| return block ? this.deepCopyBlock(block) : null; | ||
| } | ||
| async create(input) { | ||
| const { promptBlock } = input; | ||
| if (this.db.promptBlocks.has(promptBlock.id)) { | ||
| throw new Error(`Prompt block with id ${promptBlock.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newBlock = { | ||
| id: promptBlock.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: promptBlock.authorId, | ||
| metadata: promptBlock.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.promptBlocks.set(promptBlock.id, newBlock); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| blockId: promptBlock.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyBlock(newBlock); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingBlock = this.db.promptBlocks.get(id); | ||
| if (!existingBlock) { | ||
| throw new Error(`Prompt block with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedBlock = { | ||
| ...existingBlock, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingBlock.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.promptBlocks.set(id, updatedBlock); | ||
| return this.deepCopyBlock(updatedBlock); | ||
| } | ||
| async delete(id) { | ||
| this.db.promptBlocks.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let blocks = Array.from(this.db.promptBlocks.values()); | ||
| if (status) { | ||
| blocks = blocks.filter((block) => block.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| blocks = blocks.filter((block) => block.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| blocks = blocks.filter((block) => { | ||
| if (!block.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => chunkBP67LMWW_cjs.deepEqual(block.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedBlocks = this.sortBlocks(blocks, field, direction); | ||
| const clonedBlocks = sortedBlocks.map((block) => this.deepCopyBlock(block)); | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| promptBlocks: clonedBlocks.slice(offset, offset + perPage), | ||
| total: clonedBlocks.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedBlocks.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Prompt Block Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.promptBlockVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.promptBlockVersions.values()) { | ||
| if (version2.blockId === input.blockId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for prompt block ${input.blockId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.promptBlockVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.promptBlockVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(blockId, versionNumber) { | ||
| for (const version of this.db.promptBlockVersions.values()) { | ||
| if (version.blockId === blockId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(blockId) { | ||
| let latest = null; | ||
| for (const version of this.db.promptBlockVersions.values()) { | ||
| if (version.blockId === blockId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { blockId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.promptBlockVersions.values()).filter((v) => v.blockId === blockId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.promptBlockVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.promptBlockVersions.entries()) { | ||
| if (version.blockId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.promptBlockVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(blockId) { | ||
| let count = 0; | ||
| for (const version of this.db.promptBlockVersions.values()) { | ||
| if (version.blockId === blockId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyBlock(block) { | ||
| return { | ||
| ...block, | ||
| metadata: block.metadata ? { ...block.metadata } : block.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| rules: version.rules ? JSON.parse(JSON.stringify(version.rules)) : version.rules, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortBlocks(blocks, field, direction) { | ||
| return blocks.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/prompt-blocks/filesystem.ts | ||
| var FilesystemPromptBlocksStorage = class extends PromptBlocksStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new chunk2UAP4LDC_cjs.FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "prompt-blocks.json", | ||
| parentIdField: "blockId", | ||
| name: "FilesystemPromptBlocksStorage", | ||
| versionMetadataFields: ["id", "blockId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { promptBlock } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: promptBlock.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: promptBlock.authorId, | ||
| metadata: promptBlock.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(promptBlock.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| blockId: promptBlock.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "promptBlocks", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(blockId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(blockId, versionNumber); | ||
| } | ||
| async getLatestVersion(blockId) { | ||
| return this.helpers.getLatestVersion(blockId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "blockId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(blockId) { | ||
| return this.helpers.countVersions(blockId); | ||
| } | ||
| }; | ||
| exports.FilesystemPromptBlocksStorage = FilesystemPromptBlocksStorage; | ||
| exports.InMemoryPromptBlocksStorage = InMemoryPromptBlocksStorage; | ||
| exports.PromptBlocksStorage = PromptBlocksStorage; | ||
| //# sourceMappingURL=chunk-GGJVCX4I.cjs.map | ||
| //# sourceMappingURL=chunk-GGJVCX4I.cjs.map |
| {"version":3,"sources":["../src/storage/domains/prompt-blocks/base.ts","../src/storage/domains/prompt-blocks/inmemory.ts","../src/storage/domains/prompt-blocks/filesystem.ts"],"names":["VersionedStorageDomain","normalizePerPage","deepEqual","calculatePagination","version","FilesystemVersionedHelpers"],"mappings":"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","file":"chunk-GGJVCX4I.cjs","sourcesContent":["import type {\n StoragePromptBlockType,\n StoragePromptBlockSnapshotType,\n StorageResolvedPromptBlockType,\n StorageCreatePromptBlockInput,\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput,\n StorageListPromptBlocksOutput,\n StorageListPromptBlocksResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// Prompt Block Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of a prompt block's content.\n * Config fields are top-level on the version row (no nested snapshot object).\n */\nexport interface PromptBlockVersion extends StoragePromptBlockSnapshotType, VersionBase {\n /** ID of the prompt block this version belongs to */\n blockId: string;\n}\n\n/**\n * Input for creating a new prompt block version.\n * Config fields are top-level (no nested snapshot object).\n */\nexport interface CreatePromptBlockVersionInput extends StoragePromptBlockSnapshotType, CreateVersionInputBase {\n /** ID of the prompt block this version belongs to */\n blockId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type PromptBlockVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type PromptBlockVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing prompt block versions with pagination and sorting.\n */\nexport interface ListPromptBlockVersionsInput extends ListVersionsInputBase {\n /** ID of the prompt block to list versions for */\n blockId: string;\n}\n\n/**\n * Output for listing prompt block versions with pagination info.\n */\nexport interface ListPromptBlockVersionsOutput extends ListVersionsOutputBase<PromptBlockVersion> {}\n\n// ============================================================================\n// PromptBlocksStorage Base Class\n// ============================================================================\n\nexport abstract class PromptBlocksStorage extends VersionedStorageDomain<\n StoragePromptBlockType,\n StoragePromptBlockSnapshotType,\n StorageResolvedPromptBlockType,\n PromptBlockVersion,\n CreatePromptBlockVersionInput,\n ListPromptBlockVersionsInput,\n ListPromptBlockVersionsOutput,\n { promptBlock: StorageCreatePromptBlockInput },\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput | undefined,\n StorageListPromptBlocksOutput,\n StorageListPromptBlocksResolvedOutput\n> {\n protected readonly listKey = 'promptBlocks';\n protected readonly versionMetadataFields = [\n 'id',\n 'blockId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof PromptBlockVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'PROMPT_BLOCKS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StoragePromptBlockType,\n StorageCreatePromptBlockInput,\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput,\n StorageListPromptBlocksOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n PromptBlockVersion,\n CreatePromptBlockVersionInput,\n ListPromptBlockVersionsInput,\n ListPromptBlockVersionsOutput,\n PromptBlockVersionOrderBy,\n PromptBlockVersionSortDirection,\n} from './base';\nimport { PromptBlocksStorage } from './base';\n\nexport class InMemoryPromptBlocksStorage extends PromptBlocksStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.promptBlocks.clear();\n this.db.promptBlockVersions.clear();\n }\n\n // ==========================================================================\n // Prompt Block CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StoragePromptBlockType | null> {\n const block = this.db.promptBlocks.get(id);\n return block ? this.deepCopyBlock(block) : null;\n }\n\n async create(input: { promptBlock: StorageCreatePromptBlockInput }): Promise<StoragePromptBlockType> {\n const { promptBlock } = input;\n\n if (this.db.promptBlocks.has(promptBlock.id)) {\n throw new Error(`Prompt block with id ${promptBlock.id} already exists`);\n }\n\n const now = new Date();\n const newBlock: StoragePromptBlockType = {\n id: promptBlock.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: promptBlock.authorId,\n metadata: promptBlock.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.promptBlocks.set(promptBlock.id, newBlock);\n\n // Extract config fields from the flat input (everything except block-record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n blockId: promptBlock.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin block record\n return this.deepCopyBlock(newBlock);\n }\n\n async update(input: StorageUpdatePromptBlockInput): Promise<StoragePromptBlockType> {\n const { id, ...updates } = input;\n\n const existingBlock = this.db.promptBlocks.get(id);\n if (!existingBlock) {\n throw new Error(`Prompt block with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the block record\n const updatedBlock: StoragePromptBlockType = {\n ...existingBlock,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StoragePromptBlockType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingBlock.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated block record\n this.db.promptBlocks.set(id, updatedBlock);\n return this.deepCopyBlock(updatedBlock);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.promptBlocks.delete(id);\n // Also delete all versions for this block\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListPromptBlocksInput): Promise<StorageListPromptBlocksOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all blocks and apply filters\n let blocks = Array.from(this.db.promptBlocks.values());\n\n // Filter by status\n if (status) {\n blocks = blocks.filter(block => block.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n blocks = blocks.filter(block => block.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n blocks = blocks.filter(block => {\n if (!block.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(block.metadata![key], value));\n });\n }\n\n // Sort filtered blocks\n const sortedBlocks = this.sortBlocks(blocks, field, direction);\n\n // Deep clone blocks to avoid mutation\n const clonedBlocks = sortedBlocks.map(block => this.deepCopyBlock(block));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n promptBlocks: clonedBlocks.slice(offset, offset + perPage),\n total: clonedBlocks.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedBlocks.length,\n };\n }\n\n // ==========================================================================\n // Prompt Block Version Methods\n // ==========================================================================\n\n async createVersion(input: CreatePromptBlockVersionInput): Promise<PromptBlockVersion> {\n // Check if version with this ID already exists\n if (this.db.promptBlockVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (blockId, versionNumber) pair\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === input.blockId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for prompt block ${input.blockId}`);\n }\n }\n\n const version: PromptBlockVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.promptBlockVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<PromptBlockVersion | null> {\n const version = this.db.promptBlockVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(blockId: string, versionNumber: number): Promise<PromptBlockVersion | null> {\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === blockId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(blockId: string): Promise<PromptBlockVersion | null> {\n let latest: PromptBlockVersion | null = null;\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === blockId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListPromptBlockVersionsInput): Promise<ListPromptBlockVersionsOutput> {\n const { blockId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by blockId\n let versions = Array.from(this.db.promptBlockVersions.values()).filter(v => v.blockId === blockId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.promptBlockVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.promptBlockVersions.entries()) {\n if (version.blockId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.promptBlockVersions.delete(id);\n }\n }\n\n async countVersions(blockId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === blockId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyBlock(block: StoragePromptBlockType): StoragePromptBlockType {\n return {\n ...block,\n metadata: block.metadata ? { ...block.metadata } : block.metadata,\n };\n }\n\n private deepCopyVersion(version: PromptBlockVersion): PromptBlockVersion {\n return {\n ...version,\n rules: version.rules ? JSON.parse(JSON.stringify(version.rules)) : version.rules,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortBlocks(\n blocks: StoragePromptBlockType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StoragePromptBlockType[] {\n return blocks.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: PromptBlockVersion[],\n field: PromptBlockVersionOrderBy,\n direction: PromptBlockVersionSortDirection,\n ): PromptBlockVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StoragePromptBlockType,\n StorageCreatePromptBlockInput,\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput,\n StorageListPromptBlocksOutput,\n} from '../../types';\nimport type {\n PromptBlockVersion,\n CreatePromptBlockVersionInput,\n ListPromptBlockVersionsInput,\n ListPromptBlockVersionsOutput,\n} from './base';\nimport { PromptBlocksStorage } from './base';\n\nexport class FilesystemPromptBlocksStorage extends PromptBlocksStorage {\n private helpers: FilesystemVersionedHelpers<StoragePromptBlockType, PromptBlockVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'prompt-blocks.json',\n parentIdField: 'blockId',\n name: 'FilesystemPromptBlocksStorage',\n versionMetadataFields: ['id', 'blockId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StoragePromptBlockType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { promptBlock: StorageCreatePromptBlockInput }): Promise<StoragePromptBlockType> {\n const { promptBlock } = input;\n const now = new Date();\n const entity: StoragePromptBlockType = {\n id: promptBlock.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: promptBlock.authorId,\n metadata: promptBlock.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(promptBlock.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n blockId: promptBlock.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreatePromptBlockVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdatePromptBlockInput): Promise<StoragePromptBlockType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListPromptBlocksInput): Promise<StorageListPromptBlocksOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'promptBlocks',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListPromptBlocksOutput;\n }\n\n async createVersion(input: CreatePromptBlockVersionInput): Promise<PromptBlockVersion> {\n return this.helpers.createVersion(input as PromptBlockVersion);\n }\n\n async getVersion(id: string): Promise<PromptBlockVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(blockId: string, versionNumber: number): Promise<PromptBlockVersion | null> {\n return this.helpers.getVersionByNumber(blockId, versionNumber);\n }\n\n async getLatestVersion(blockId: string): Promise<PromptBlockVersion | null> {\n return this.helpers.getLatestVersion(blockId);\n }\n\n async listVersions(input: ListPromptBlockVersionsInput): Promise<ListPromptBlockVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'blockId');\n return result as ListPromptBlockVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(blockId: string): Promise<number> {\n return this.helpers.countVersions(blockId);\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { DelayedPromise } from './chunk-YNS26J6E.js'; | ||
| import { DefaultGeneratedFile, DefaultGeneratedFileWithType } from './chunk-HHYICF3X.js'; | ||
| import { ReadableStream as ReadableStream$1, WritableStream as WritableStream$1 } from 'stream/web'; | ||
| import EventEmitter from 'events'; | ||
| var MastraAgentNetworkStream = class extends ReadableStream$1 { | ||
| #usageCount = { | ||
| inputTokens: 0, | ||
| outputTokens: 0, | ||
| totalTokens: 0, | ||
| cachedInputTokens: 0, | ||
| cacheCreationInputTokens: 0, | ||
| reasoningTokens: 0 | ||
| }; | ||
| #streamPromise; | ||
| #objectPromise; | ||
| #objectStreamController = null; | ||
| #objectStream = null; | ||
| #run; | ||
| runId; | ||
| constructor({ | ||
| createStream, | ||
| run | ||
| }) { | ||
| const deferredPromise = { | ||
| promise: null, | ||
| resolve: null, | ||
| reject: null | ||
| }; | ||
| deferredPromise.promise = new Promise((resolve, reject) => { | ||
| deferredPromise.resolve = resolve; | ||
| deferredPromise.reject = reject; | ||
| }); | ||
| const objectDeferredPromise = { | ||
| promise: null, | ||
| resolve: null, | ||
| reject: null | ||
| }; | ||
| objectDeferredPromise.promise = new Promise((resolve, reject) => { | ||
| objectDeferredPromise.resolve = resolve; | ||
| objectDeferredPromise.reject = reject; | ||
| }); | ||
| let objectStreamController = null; | ||
| const updateUsageCount = (usage) => { | ||
| this.#usageCount.inputTokens += parseInt(usage?.inputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.outputTokens += parseInt(usage?.outputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.totalTokens += parseInt(usage?.totalTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.reasoningTokens += parseInt(usage?.reasoningTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.cachedInputTokens += parseInt(usage?.cachedInputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.cacheCreationInputTokens += parseInt(usage?.cacheCreationInputTokens?.toString() ?? "0", 10); | ||
| }; | ||
| super({ | ||
| start: async (controller) => { | ||
| try { | ||
| const writer = new WritableStream({ | ||
| write: (chunk) => { | ||
| if (chunk.type === "step-output" && chunk.payload?.output?.from === "AGENT" && chunk.payload?.output?.type === "finish" || chunk.type === "step-output" && chunk.payload?.output?.from === "WORKFLOW" && chunk.payload?.output?.type === "finish") { | ||
| const output = chunk.payload?.output; | ||
| if (output && "payload" in output && output.payload) { | ||
| const finishPayload = output.payload; | ||
| if ("usage" in finishPayload && finishPayload.usage) { | ||
| updateUsageCount(finishPayload.usage); | ||
| } else if ("output" in finishPayload && finishPayload.output) { | ||
| const outputPayload = finishPayload.output; | ||
| if ("usage" in outputPayload && outputPayload.usage) { | ||
| updateUsageCount(outputPayload.usage); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| controller.enqueue(chunk); | ||
| } | ||
| }); | ||
| const stream = await createStream(writer); | ||
| const getInnerChunk = (chunk) => { | ||
| if (chunk.type === "workflow-step-output") { | ||
| return getInnerChunk(chunk.payload.output); | ||
| } | ||
| return chunk; | ||
| }; | ||
| let objectResolved = false; | ||
| for await (const chunk of stream) { | ||
| if (chunk.type === "workflow-step-output") { | ||
| const innerChunk = getInnerChunk(chunk); | ||
| if (innerChunk.type === "routing-agent-end" || innerChunk.type === "agent-execution-end" || innerChunk.type === "workflow-execution-end") { | ||
| if (innerChunk.payload?.usage) { | ||
| updateUsageCount(innerChunk.payload.usage); | ||
| } | ||
| } | ||
| if (innerChunk.type === "network-object") { | ||
| if (objectStreamController) { | ||
| objectStreamController.enqueue(innerChunk.payload?.object); | ||
| } | ||
| controller.enqueue(innerChunk); | ||
| } else if (innerChunk.type === "network-object-result") { | ||
| if (!objectResolved) { | ||
| objectResolved = true; | ||
| objectDeferredPromise.resolve(innerChunk.payload?.object); | ||
| if (objectStreamController) { | ||
| objectStreamController.close(); | ||
| } | ||
| } | ||
| controller.enqueue(innerChunk); | ||
| } else if (innerChunk.type === "network-execution-event-finish") { | ||
| const finishPayload = { | ||
| ...innerChunk.payload, | ||
| usage: this.#usageCount | ||
| }; | ||
| controller.enqueue({ ...innerChunk, payload: finishPayload }); | ||
| } else { | ||
| controller.enqueue(innerChunk); | ||
| } | ||
| } | ||
| } | ||
| if (!objectResolved) { | ||
| objectDeferredPromise.resolve(void 0); | ||
| if (objectStreamController) { | ||
| objectStreamController.close(); | ||
| } | ||
| } | ||
| controller.close(); | ||
| deferredPromise.resolve(); | ||
| } catch (error) { | ||
| controller.error(error); | ||
| deferredPromise.reject(error); | ||
| objectDeferredPromise.reject(error); | ||
| if (objectStreamController) { | ||
| objectStreamController.error(error); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| this.#run = run; | ||
| this.#streamPromise = deferredPromise; | ||
| this.runId = run.runId; | ||
| this.#objectPromise = objectDeferredPromise; | ||
| this.#objectStream = new ReadableStream$1({ | ||
| start: (ctrl) => { | ||
| objectStreamController = ctrl; | ||
| this.#objectStreamController = ctrl; | ||
| } | ||
| }); | ||
| } | ||
| get status() { | ||
| return this.#streamPromise.promise.then(() => this.#run._getExecutionResults()).then((res) => res.status); | ||
| } | ||
| get result() { | ||
| return this.#streamPromise.promise.then(() => this.#run._getExecutionResults()); | ||
| } | ||
| get usage() { | ||
| return this.#streamPromise.promise.then(() => this.#usageCount); | ||
| } | ||
| /** | ||
| * Returns a promise that resolves to the structured output object. | ||
| * Only available when structuredOutput option is provided to network(). | ||
| * Resolves to undefined if no structuredOutput was requested. | ||
| */ | ||
| get object() { | ||
| return this.#objectPromise.promise; | ||
| } | ||
| /** | ||
| * Returns a ReadableStream of partial objects during structured output generation. | ||
| * Useful for streaming partial results as they're being generated. | ||
| */ | ||
| get objectStream() { | ||
| return this.#objectStream; | ||
| } | ||
| }; | ||
| // src/stream/aisdk/v5/compat/ui-message.ts | ||
| function convertFullStreamChunkToUIMessageStream({ | ||
| part, | ||
| messageMetadataValue, | ||
| sendReasoning, | ||
| sendSources, | ||
| onError, | ||
| sendStart, | ||
| sendFinish, | ||
| responseMessageId | ||
| }) { | ||
| const partType = part.type; | ||
| switch (partType) { | ||
| case "text-start": { | ||
| return { | ||
| type: "text-start", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "text-delta": { | ||
| return { | ||
| type: "text-delta", | ||
| id: part.id, | ||
| delta: part.text, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "text-end": { | ||
| return { | ||
| type: "text-end", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "reasoning-start": { | ||
| return { | ||
| type: "reasoning-start", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "reasoning-delta": { | ||
| if (sendReasoning) { | ||
| return { | ||
| type: "reasoning-delta", | ||
| id: part.id, | ||
| delta: part.text, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "reasoning-end": { | ||
| return { | ||
| type: "reasoning-end", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "file": { | ||
| return { | ||
| type: "file", | ||
| mediaType: part.file.mediaType, | ||
| url: `data:${part.file.mediaType};base64,${part.file.base64}` | ||
| }; | ||
| } | ||
| case "source": { | ||
| if (sendSources && part.sourceType === "url") { | ||
| return { | ||
| type: "source-url", | ||
| sourceId: part.id, | ||
| url: part.url, | ||
| title: part.title, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| if (sendSources && part.sourceType === "document") { | ||
| return { | ||
| type: "source-document", | ||
| sourceId: part.id, | ||
| mediaType: part.mediaType, | ||
| title: part.title, | ||
| filename: part.filename, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "tool-input-start": { | ||
| return { | ||
| type: "tool-input-start", | ||
| toolCallId: part.id, | ||
| toolName: part.toolName, | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "tool-input-delta": { | ||
| return { | ||
| type: "tool-input-delta", | ||
| toolCallId: part.id, | ||
| inputTextDelta: part.delta | ||
| }; | ||
| } | ||
| case "tool-call": { | ||
| return { | ||
| type: "tool-input-available", | ||
| toolCallId: part.toolCallId, | ||
| toolName: part.toolName, | ||
| input: part.input, | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "tool-result": { | ||
| return { | ||
| type: "tool-output-available", | ||
| toolCallId: part.toolCallId, | ||
| output: part.output, | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "tool-output": { | ||
| return { | ||
| ...part.output | ||
| }; | ||
| } | ||
| case "tool-error": { | ||
| return { | ||
| type: "tool-output-error", | ||
| toolCallId: part.toolCallId, | ||
| errorText: onError(part.error), | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "error": { | ||
| return { | ||
| type: "error", | ||
| errorText: onError(part.error) | ||
| }; | ||
| } | ||
| case "start-step": { | ||
| return { type: "start-step" }; | ||
| } | ||
| case "finish-step": { | ||
| return { type: "finish-step" }; | ||
| } | ||
| case "start": { | ||
| if (sendStart) { | ||
| return { | ||
| type: "start", | ||
| ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {}, | ||
| ...responseMessageId != null ? { messageId: responseMessageId } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "finish": { | ||
| if (sendFinish) { | ||
| return { | ||
| type: "finish", | ||
| ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "abort": { | ||
| return part; | ||
| } | ||
| case "tool-input-end": { | ||
| return; | ||
| } | ||
| case "raw": { | ||
| return; | ||
| } | ||
| default: { | ||
| const exhaustiveCheck = partType; | ||
| throw new Error(`Unknown chunk type: ${exhaustiveCheck}`); | ||
| } | ||
| } | ||
| } | ||
| // src/stream/base/consume-stream.ts | ||
| async function consumeStream({ | ||
| stream, | ||
| onError | ||
| }) { | ||
| const reader = stream.getReader(); | ||
| try { | ||
| while (true) { | ||
| const { done } = await reader.read(); | ||
| if (done) break; | ||
| } | ||
| } catch (error) { | ||
| onError == null ? void 0 : onError(error); | ||
| } finally { | ||
| reader.releaseLock(); | ||
| } | ||
| } | ||
| // src/stream/RunOutput.ts | ||
| var WorkflowRunOutput = class { | ||
| #status = "running"; | ||
| #tripwireData; | ||
| #usageCount = { | ||
| inputTokens: 0, | ||
| outputTokens: 0, | ||
| totalTokens: 0, | ||
| cachedInputTokens: 0, | ||
| cacheCreationInputTokens: 0, | ||
| reasoningTokens: 0 | ||
| }; | ||
| #consumptionStarted = false; | ||
| #baseStream; | ||
| #emitter = new EventEmitter(); | ||
| #bufferedChunks = []; | ||
| #streamFinished = false; | ||
| #streamError; | ||
| #delayedPromises = { | ||
| usage: new DelayedPromise(), | ||
| result: new DelayedPromise() | ||
| }; | ||
| /** | ||
| * Unique identifier for this workflow run | ||
| */ | ||
| runId; | ||
| /** | ||
| * Unique identifier for this workflow | ||
| */ | ||
| workflowId; | ||
| constructor({ | ||
| runId, | ||
| workflowId, | ||
| stream | ||
| }) { | ||
| const self = this; | ||
| this.runId = runId; | ||
| this.workflowId = workflowId; | ||
| this.#baseStream = stream; | ||
| stream.pipeTo( | ||
| new WritableStream$1({ | ||
| start() { | ||
| const chunk = { | ||
| type: "workflow-start", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowId: self.workflowId | ||
| } | ||
| }; | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| }, | ||
| write(chunk) { | ||
| if (chunk.type !== "workflow-step-finish") { | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| } | ||
| if (chunk.type === "workflow-step-output") { | ||
| if ("output" in chunk.payload && chunk.payload.output) { | ||
| const output = chunk.payload.output; | ||
| if (output.type === "finish") { | ||
| if (output.payload && "usage" in output.payload && output.payload.usage) { | ||
| self.#updateUsageCount(output.payload.usage); | ||
| } else if (output.payload && "output" in output.payload && output.payload.output) { | ||
| const outputPayload = output.payload.output; | ||
| if ("usage" in outputPayload && outputPayload.usage) { | ||
| self.#updateUsageCount(outputPayload.usage); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } else if (chunk.type === "workflow-canceled") { | ||
| self.#status = "canceled"; | ||
| } else if (chunk.type === "workflow-step-suspended") { | ||
| self.#status = "suspended"; | ||
| } else if (chunk.type === "workflow-step-result" && chunk.payload.status === "failed") { | ||
| if (chunk.payload.tripwire) { | ||
| self.#status = "tripwire"; | ||
| self.#tripwireData = chunk.payload.tripwire; | ||
| } else { | ||
| self.#status = "failed"; | ||
| } | ||
| } else if (chunk.type === "workflow-paused") { | ||
| self.#status = "paused"; | ||
| } | ||
| }, | ||
| close() { | ||
| if (self.#status === "running") { | ||
| self.#status = "success"; | ||
| } | ||
| self.#emitter.emit("chunk", { | ||
| type: "workflow-finish", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowStatus: self.#status, | ||
| metadata: self.#streamError ? { | ||
| error: self.#streamError, | ||
| errorMessage: self.#streamError?.message | ||
| } : {}, | ||
| output: { | ||
| usage: self.#usageCount | ||
| }, | ||
| // Include tripwire data when status is 'tripwire' | ||
| ...self.#status === "tripwire" && self.#tripwireData ? { tripwire: self.#tripwireData } : {} | ||
| } | ||
| }); | ||
| self.#delayedPromises.usage.resolve(self.#usageCount); | ||
| Object.entries(self.#delayedPromises).forEach(([key, promise]) => { | ||
| if (promise.status.type === "pending") { | ||
| promise.reject(new Error(`promise '${key}' was not resolved or rejected when stream finished`)); | ||
| } | ||
| }); | ||
| self.#streamFinished = true; | ||
| self.#emitter.emit("finish"); | ||
| } | ||
| }) | ||
| ).catch((reason) => { | ||
| console.log(" something went wrong", reason); | ||
| }); | ||
| } | ||
| #getDelayedPromise(promise) { | ||
| if (!this.#consumptionStarted) { | ||
| void this.consumeStream(); | ||
| } | ||
| return promise.promise; | ||
| } | ||
| #updateUsageCount(usage) { | ||
| let totalUsage = { | ||
| inputTokens: this.#usageCount.inputTokens ?? 0, | ||
| outputTokens: this.#usageCount.outputTokens ?? 0, | ||
| totalTokens: this.#usageCount.totalTokens ?? 0, | ||
| reasoningTokens: this.#usageCount.reasoningTokens ?? 0, | ||
| cachedInputTokens: this.#usageCount.cachedInputTokens ?? 0, | ||
| cacheCreationInputTokens: this.#usageCount.cacheCreationInputTokens ?? 0 | ||
| }; | ||
| if ("inputTokens" in usage) { | ||
| totalUsage.inputTokens += parseInt(usage?.inputTokens?.toString() ?? "0", 10); | ||
| totalUsage.outputTokens += parseInt(usage?.outputTokens?.toString() ?? "0", 10); | ||
| } else if ("promptTokens" in usage) { | ||
| totalUsage.inputTokens += parseInt(usage?.promptTokens?.toString() ?? "0", 10); | ||
| totalUsage.outputTokens += parseInt(usage?.completionTokens?.toString() ?? "0", 10); | ||
| } | ||
| totalUsage.totalTokens += parseInt(usage?.totalTokens?.toString() ?? "0", 10); | ||
| totalUsage.reasoningTokens += parseInt(usage?.reasoningTokens?.toString() ?? "0", 10); | ||
| totalUsage.cachedInputTokens += parseInt(usage?.cachedInputTokens?.toString() ?? "0", 10); | ||
| totalUsage.cacheCreationInputTokens += parseInt(usage?.cacheCreationInputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount = totalUsage; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| updateResults(results) { | ||
| this.#delayedPromises.result.resolve(results); | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| rejectResults(error) { | ||
| this.#delayedPromises.result.reject(error); | ||
| this.#status = "failed"; | ||
| this.#streamError = error; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| resume(stream) { | ||
| this.#baseStream = stream; | ||
| this.#streamFinished = false; | ||
| this.#consumptionStarted = false; | ||
| this.#status = "running"; | ||
| this.#delayedPromises = { | ||
| usage: new DelayedPromise(), | ||
| result: new DelayedPromise() | ||
| }; | ||
| const self = this; | ||
| stream.pipeTo( | ||
| new WritableStream$1({ | ||
| start() { | ||
| const chunk = { | ||
| type: "workflow-start", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowId: self.workflowId | ||
| } | ||
| }; | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| }, | ||
| write(chunk) { | ||
| if (chunk.type !== "workflow-step-finish") { | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| } | ||
| if (chunk.type === "workflow-step-output") { | ||
| if ("output" in chunk.payload && chunk.payload.output) { | ||
| const output = chunk.payload.output; | ||
| if (output.type === "finish") { | ||
| if (output.payload && "usage" in output.payload && output.payload.usage) { | ||
| self.#updateUsageCount(output.payload.usage); | ||
| } else if (output.payload && "output" in output.payload && output.payload.output) { | ||
| const outputPayload = output.payload.output; | ||
| if ("usage" in outputPayload && outputPayload.usage) { | ||
| self.#updateUsageCount(outputPayload.usage); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } else if (chunk.type === "workflow-canceled") { | ||
| self.#status = "canceled"; | ||
| } else if (chunk.type === "workflow-step-suspended") { | ||
| self.#status = "suspended"; | ||
| } else if (chunk.type === "workflow-step-result" && chunk.payload.status === "failed") { | ||
| if (chunk.payload.tripwire) { | ||
| self.#status = "tripwire"; | ||
| self.#tripwireData = chunk.payload.tripwire; | ||
| } else { | ||
| self.#status = "failed"; | ||
| } | ||
| } else if (chunk.type === "workflow-paused") { | ||
| self.#status = "paused"; | ||
| } | ||
| }, | ||
| close() { | ||
| if (self.#status === "running") { | ||
| self.#status = "success"; | ||
| } | ||
| self.#emitter.emit("chunk", { | ||
| type: "workflow-finish", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowStatus: self.#status, | ||
| metadata: self.#streamError ? { | ||
| error: self.#streamError, | ||
| errorMessage: self.#streamError?.message | ||
| } : {}, | ||
| output: { | ||
| usage: self.#usageCount | ||
| }, | ||
| // Include tripwire data when status is 'tripwire' | ||
| ...self.#status === "tripwire" && self.#tripwireData ? { tripwire: self.#tripwireData } : {} | ||
| } | ||
| }); | ||
| self.#streamFinished = true; | ||
| self.#emitter.emit("finish"); | ||
| } | ||
| }) | ||
| ).catch((reason) => { | ||
| console.log(" something went wrong", reason); | ||
| }); | ||
| } | ||
| async consumeStream(options) { | ||
| if (this.#consumptionStarted) { | ||
| return; | ||
| } | ||
| this.#consumptionStarted = true; | ||
| try { | ||
| await consumeStream({ | ||
| stream: this.#baseStream, | ||
| onError: options?.onError | ||
| }); | ||
| } catch (error) { | ||
| options?.onError?.(error); | ||
| } | ||
| } | ||
| get fullStream() { | ||
| const self = this; | ||
| return new ReadableStream$1({ | ||
| start(controller) { | ||
| self.#bufferedChunks.forEach((chunk) => { | ||
| controller.enqueue(chunk); | ||
| }); | ||
| if (self.#streamFinished) { | ||
| controller.close(); | ||
| return; | ||
| } | ||
| const chunkHandler = (chunk) => { | ||
| controller.enqueue(chunk); | ||
| }; | ||
| const finishHandler = () => { | ||
| self.#emitter.off("chunk", chunkHandler); | ||
| self.#emitter.off("finish", finishHandler); | ||
| controller.close(); | ||
| }; | ||
| self.#emitter.on("chunk", chunkHandler); | ||
| self.#emitter.on("finish", finishHandler); | ||
| }, | ||
| pull(_controller) { | ||
| if (!self.#consumptionStarted) { | ||
| void self.consumeStream(); | ||
| } | ||
| }, | ||
| cancel() { | ||
| self.#emitter.removeAllListeners(); | ||
| } | ||
| }); | ||
| } | ||
| get status() { | ||
| return this.#status; | ||
| } | ||
| get result() { | ||
| return this.#getDelayedPromise(this.#delayedPromises.result); | ||
| } | ||
| get usage() { | ||
| return this.#getDelayedPromise(this.#delayedPromises.usage); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.locked` instead | ||
| */ | ||
| get locked() { | ||
| console.warn("WorkflowRunOutput.locked is deprecated. Use fullStream.locked instead."); | ||
| return this.fullStream.locked; | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.cancel()` instead | ||
| */ | ||
| cancel(reason) { | ||
| console.warn("WorkflowRunOutput.cancel() is deprecated. Use fullStream.cancel() instead."); | ||
| return this.fullStream.cancel(reason); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.getReader()` instead | ||
| */ | ||
| getReader(options) { | ||
| console.warn("WorkflowRunOutput.getReader() is deprecated. Use fullStream.getReader() instead."); | ||
| return this.fullStream.getReader(options); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.pipeThrough()` instead | ||
| */ | ||
| pipeThrough(transform, options) { | ||
| console.warn("WorkflowRunOutput.pipeThrough() is deprecated. Use fullStream.pipeThrough() instead."); | ||
| return this.fullStream.pipeThrough(transform, options); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.pipeTo()` instead | ||
| */ | ||
| pipeTo(destination, options) { | ||
| console.warn("WorkflowRunOutput.pipeTo() is deprecated. Use fullStream.pipeTo() instead."); | ||
| return this.fullStream.pipeTo(destination, options); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.tee()` instead | ||
| */ | ||
| tee() { | ||
| console.warn("WorkflowRunOutput.tee() is deprecated. Use fullStream.tee() instead."); | ||
| return this.fullStream.tee(); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream[Symbol.asyncIterator]()` instead | ||
| */ | ||
| [Symbol.asyncIterator]() { | ||
| console.warn( | ||
| "WorkflowRunOutput[Symbol.asyncIterator]() is deprecated. Use fullStream[Symbol.asyncIterator]() instead." | ||
| ); | ||
| return this.fullStream[Symbol.asyncIterator](); | ||
| } | ||
| /** | ||
| * Helper method to treat this object as a ReadableStream | ||
| * @deprecated Use `fullStream` directly instead | ||
| */ | ||
| toReadableStream() { | ||
| console.warn("WorkflowRunOutput.toReadableStream() is deprecated. Use fullStream directly instead."); | ||
| return this.fullStream; | ||
| } | ||
| }; | ||
| // src/stream/aisdk/v5/transform.ts | ||
| function sanitizeToolCallInput(input) { | ||
| try { | ||
| JSON.parse(input); | ||
| return input; | ||
| } catch { | ||
| return input.replace(/[\s]*<\|[^|]*\|>[\s]*/g, "").trim(); | ||
| } | ||
| } | ||
| function tryRepairJson(input) { | ||
| let repaired = input.trim(); | ||
| repaired = repaired.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)"/g, (match, prefix, name) => { | ||
| if (prefix.trimEnd().endsWith('"')) { | ||
| return match; | ||
| } | ||
| return `${prefix}"${name}"`; | ||
| }); | ||
| repaired = repaired.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g, '$1"$2":'); | ||
| repaired = repaired.replace(/'/g, '"'); | ||
| repaired = repaired.replace(/,(\s*[}\]])/g, "$1"); | ||
| repaired = repaired.replace(/:\s*(\d{4}-\d{2}-\d{2}(?:T[\d:]+)?)\s*([,}])/g, ': "$1"$2'); | ||
| try { | ||
| return JSON.parse(repaired); | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
| function convertFullStreamChunkToMastra(value, ctx) { | ||
| switch (value.type) { | ||
| case "response-metadata": | ||
| return { | ||
| type: "response-metadata", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { ...value } | ||
| }; | ||
| case "text-start": | ||
| return { | ||
| type: "text-start", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "text-delta": | ||
| if (value.delta) { | ||
| return { | ||
| type: "text-delta", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata, | ||
| text: value.delta | ||
| } | ||
| }; | ||
| } | ||
| return; | ||
| case "text-end": | ||
| return { | ||
| type: "text-end", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: value | ||
| }; | ||
| case "reasoning-start": | ||
| return { | ||
| type: "reasoning-start", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "reasoning-delta": | ||
| return { | ||
| type: "reasoning-delta", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata, | ||
| text: value.delta | ||
| } | ||
| }; | ||
| case "reasoning-end": | ||
| return { | ||
| type: "reasoning-end", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "source": | ||
| return { | ||
| type: "source", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| sourceType: value.sourceType, | ||
| title: value.title || "", | ||
| mimeType: value.sourceType === "document" ? value.mediaType : void 0, | ||
| filename: value.sourceType === "document" ? value.filename : void 0, | ||
| url: value.sourceType === "url" ? value.url : void 0, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "file": { | ||
| const pm = value.providerMetadata; | ||
| return { | ||
| type: "file", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| data: value.data, | ||
| base64: typeof value.data === "string" ? value.data : void 0, | ||
| mimeType: value.mediaType, | ||
| ...pm != null ? { providerMetadata: pm } : {} | ||
| } | ||
| }; | ||
| } | ||
| case "tool-call": { | ||
| let toolCallInput = void 0; | ||
| if (value.input) { | ||
| const sanitized = sanitizeToolCallInput(value.input); | ||
| if (sanitized) { | ||
| try { | ||
| toolCallInput = JSON.parse(sanitized); | ||
| } catch { | ||
| const repaired = tryRepairJson(sanitized); | ||
| if (repaired) { | ||
| toolCallInput = repaired; | ||
| } else { | ||
| console.error("Error converting tool call input to JSON", { | ||
| input: value.input | ||
| }); | ||
| toolCallInput = void 0; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return { | ||
| type: "tool-call", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.toolCallId, | ||
| toolName: value.toolName, | ||
| args: toolCallInput, | ||
| providerExecuted: value.providerExecuted, | ||
| providerMetadata: value.providerMetadata, | ||
| ...value.observability ? { observability: value.observability } : {} | ||
| } | ||
| }; | ||
| } | ||
| case "tool-result": | ||
| return { | ||
| type: "tool-result", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.toolCallId, | ||
| toolName: value.toolName, | ||
| result: value.result, | ||
| isError: value.isError, | ||
| providerExecuted: value.providerExecuted, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "tool-input-start": | ||
| return { | ||
| type: "tool-call-input-streaming-start", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.id, | ||
| toolName: value.toolName, | ||
| providerExecuted: value.providerExecuted, | ||
| providerMetadata: value.providerMetadata, | ||
| dynamic: value.dynamic, | ||
| ...value.observability ? { observability: value.observability } : {} | ||
| } | ||
| }; | ||
| case "tool-input-delta": | ||
| if (value.delta) { | ||
| return { | ||
| type: "tool-call-delta", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| argsTextDelta: value.delta, | ||
| toolCallId: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| } | ||
| return; | ||
| case "tool-input-end": | ||
| return { | ||
| type: "tool-call-input-streaming-end", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "finish": | ||
| const { finishReason, usage, providerMetadata, messages, ...rest } = value; | ||
| return { | ||
| type: "finish", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| providerMetadata: value.providerMetadata, | ||
| stepResult: { | ||
| reason: normalizeFinishReason(value.finishReason) | ||
| }, | ||
| output: { | ||
| // Normalize usage to handle both V2 (flat) and V3 (nested) formats | ||
| usage: normalizeUsage(value.usage) | ||
| }, | ||
| metadata: { | ||
| providerMetadata: value.providerMetadata | ||
| }, | ||
| messages: messages ?? { | ||
| all: [], | ||
| user: [], | ||
| nonUser: [] | ||
| }, | ||
| ...rest | ||
| } | ||
| }; | ||
| case "error": | ||
| return { | ||
| type: "error", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: value | ||
| }; | ||
| case "raw": | ||
| return { | ||
| type: "raw", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: value.rawValue | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| function convertMastraChunkToAISDKv5({ | ||
| chunk, | ||
| mode = "stream" | ||
| }) { | ||
| switch (chunk.type) { | ||
| case "start": | ||
| return { | ||
| type: "start" | ||
| }; | ||
| case "step-start": | ||
| const { messageId: _messageId, ...rest } = chunk.payload; | ||
| return { | ||
| type: "start-step", | ||
| request: rest.request, | ||
| warnings: rest.warnings || [] | ||
| }; | ||
| case "raw": | ||
| return { | ||
| type: "raw", | ||
| rawValue: chunk.payload | ||
| }; | ||
| case "finish": { | ||
| return { | ||
| type: "finish", | ||
| // Cast needed: Mastra extends reason with 'tripwire' | 'retry' for processor scenarios | ||
| finishReason: chunk.payload.stepResult.reason, | ||
| // Cast needed: Mastra's LanguageModelUsage has optional properties, V2 has required-but-nullable | ||
| totalUsage: chunk.payload.output.usage | ||
| }; | ||
| } | ||
| case "reasoning-start": | ||
| return { | ||
| type: "reasoning-start", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "reasoning-delta": | ||
| return { | ||
| type: "reasoning-delta", | ||
| id: chunk.payload.id, | ||
| text: chunk.payload.text, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "reasoning-signature": | ||
| throw new Error('AISDKv5 chunk type "reasoning-signature" not supported'); | ||
| case "redacted-reasoning": | ||
| throw new Error('AISDKv5 chunk type "redacted-reasoning" not supported'); | ||
| case "reasoning-end": | ||
| return { | ||
| type: "reasoning-end", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "source": | ||
| if (chunk.payload.sourceType === "url") { | ||
| return { | ||
| type: "source", | ||
| sourceType: "url", | ||
| id: chunk.payload.id, | ||
| url: chunk.payload.url, | ||
| title: chunk.payload.title, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| } else { | ||
| return { | ||
| type: "source", | ||
| sourceType: "document", | ||
| id: chunk.payload.id, | ||
| mediaType: chunk.payload.mimeType, | ||
| title: chunk.payload.title, | ||
| filename: chunk.payload.filename, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| } | ||
| case "file": { | ||
| const filePart = mode === "generate" ? { | ||
| type: "file", | ||
| file: new DefaultGeneratedFile({ | ||
| data: chunk.payload.data, | ||
| mediaType: chunk.payload.mimeType | ||
| }) | ||
| } : { | ||
| type: "file", | ||
| file: new DefaultGeneratedFileWithType({ | ||
| data: chunk.payload.data, | ||
| mediaType: chunk.payload.mimeType | ||
| }) | ||
| }; | ||
| if (chunk.payload.providerMetadata) { | ||
| filePart.providerMetadata = chunk.payload.providerMetadata; | ||
| } | ||
| return filePart; | ||
| } | ||
| case "tool-call": { | ||
| const toolCallPart = { | ||
| type: "tool-call", | ||
| toolCallId: chunk.payload.toolCallId, | ||
| providerMetadata: chunk.payload.providerMetadata, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| toolName: chunk.payload.toolName, | ||
| input: chunk.payload.args | ||
| }; | ||
| if (chunk.payload.observability) { | ||
| toolCallPart.observability = chunk.payload.observability; | ||
| } | ||
| return toolCallPart; | ||
| } | ||
| case "tool-call-input-streaming-start": | ||
| return { | ||
| type: "tool-input-start", | ||
| id: chunk.payload.toolCallId, | ||
| toolName: chunk.payload.toolName, | ||
| dynamic: !!chunk.payload.dynamic, | ||
| providerMetadata: chunk.payload.providerMetadata, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| ...chunk.payload.observability ? { observability: chunk.payload.observability } : {} | ||
| }; | ||
| case "tool-call-input-streaming-end": | ||
| return { | ||
| type: "tool-input-end", | ||
| id: chunk.payload.toolCallId, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "tool-call-delta": | ||
| return { | ||
| type: "tool-input-delta", | ||
| id: chunk.payload.toolCallId, | ||
| delta: chunk.payload.argsTextDelta, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "step-finish": { | ||
| const { request: _request, providerMetadata: metadataProviderMetadata, ...rest2 } = chunk.payload.metadata; | ||
| return { | ||
| type: "finish-step", | ||
| response: { | ||
| id: chunk.payload.id || "", | ||
| timestamp: /* @__PURE__ */ new Date(), | ||
| modelId: rest2.modelId || "", | ||
| ...rest2 | ||
| }, | ||
| usage: chunk.payload.output.usage, | ||
| finishReason: chunk.payload.stepResult.reason, | ||
| providerMetadata: metadataProviderMetadata ?? chunk.payload.providerMetadata | ||
| }; | ||
| } | ||
| case "text-delta": | ||
| return { | ||
| type: "text-delta", | ||
| id: chunk.payload.id, | ||
| text: chunk.payload.text, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "text-end": | ||
| return { | ||
| type: "text-end", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "text-start": | ||
| return { | ||
| type: "text-start", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "tool-result": | ||
| return { | ||
| type: "tool-result", | ||
| input: chunk.payload.args, | ||
| toolCallId: chunk.payload.toolCallId, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| toolName: chunk.payload.toolName, | ||
| output: chunk.payload.result | ||
| // providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this? | ||
| }; | ||
| case "tool-error": | ||
| return { | ||
| type: "tool-error", | ||
| error: chunk.payload.error, | ||
| input: chunk.payload.args, | ||
| toolCallId: chunk.payload.toolCallId, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| toolName: chunk.payload.toolName | ||
| // providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this? | ||
| }; | ||
| case "abort": | ||
| return { | ||
| type: "abort" | ||
| }; | ||
| case "error": | ||
| return { | ||
| type: "error", | ||
| error: chunk.payload.error | ||
| }; | ||
| case "object": | ||
| return { | ||
| type: "object", | ||
| object: chunk.object | ||
| }; | ||
| default: | ||
| if (chunk.type && "payload" in chunk && chunk.payload) { | ||
| return { | ||
| type: chunk.type, | ||
| ...chunk.payload || {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| } | ||
| function isV3Usage(usage) { | ||
| if (!usage || typeof usage !== "object") return false; | ||
| const u = usage; | ||
| return typeof u.inputTokens === "object" && u.inputTokens !== null && "total" in u.inputTokens && typeof u.outputTokens === "object" && u.outputTokens !== null && "total" in u.outputTokens; | ||
| } | ||
| function normalizeUsage(usage) { | ||
| if (!usage) { | ||
| return { | ||
| inputTokens: void 0, | ||
| outputTokens: void 0, | ||
| totalTokens: void 0, | ||
| reasoningTokens: void 0, | ||
| cachedInputTokens: void 0, | ||
| cacheCreationInputTokens: void 0, | ||
| raw: void 0 | ||
| }; | ||
| } | ||
| if (isV3Usage(usage)) { | ||
| const inputTokens = usage.inputTokens.total; | ||
| const outputTokens = usage.outputTokens.total; | ||
| return { | ||
| inputTokens, | ||
| outputTokens, | ||
| totalTokens: (inputTokens ?? 0) + (outputTokens ?? 0), | ||
| reasoningTokens: usage.outputTokens.reasoning, | ||
| cachedInputTokens: usage.inputTokens.cacheRead, | ||
| cacheCreationInputTokens: usage.inputTokens.cacheWrite, | ||
| raw: usage | ||
| }; | ||
| } | ||
| const v2Usage = usage; | ||
| return { | ||
| inputTokens: v2Usage.inputTokens, | ||
| outputTokens: v2Usage.outputTokens, | ||
| totalTokens: v2Usage.totalTokens ?? (v2Usage.inputTokens ?? 0) + (v2Usage.outputTokens ?? 0), | ||
| reasoningTokens: v2Usage.reasoningTokens, | ||
| cachedInputTokens: v2Usage.cachedInputTokens, | ||
| cacheCreationInputTokens: v2Usage.cacheCreationInputTokens, | ||
| raw: usage | ||
| }; | ||
| } | ||
| function isV3FinishReason(finishReason) { | ||
| return typeof finishReason === "object" && finishReason !== null && "unified" in finishReason; | ||
| } | ||
| function normalizeFinishReason(finishReason) { | ||
| if (!finishReason) { | ||
| return "other"; | ||
| } | ||
| if (finishReason === "tripwire" || finishReason === "retry") { | ||
| return finishReason; | ||
| } | ||
| if (isV3FinishReason(finishReason)) { | ||
| return finishReason.unified; | ||
| } | ||
| return finishReason === "unknown" ? "other" : finishReason; | ||
| } | ||
| // src/stream/caching-transform-stream.ts | ||
| function createCachingTransformStream(options) { | ||
| const { cache, cacheKey, serialize = (x) => x, deserialize = (x) => x } = options; | ||
| const transform = new TransformStream({ | ||
| transform(chunk, controller) { | ||
| const serialized = serialize(chunk); | ||
| cache.listPush(cacheKey, serialized).catch(() => { | ||
| }); | ||
| controller.enqueue(chunk); | ||
| } | ||
| }); | ||
| const getHistory = async (offset = 0) => { | ||
| const cached = await cache.listFromTo(cacheKey, offset); | ||
| return cached.map((item) => deserialize(item)); | ||
| }; | ||
| const clearCache = async () => { | ||
| await cache.delete(cacheKey); | ||
| }; | ||
| return { transform, getHistory, clearCache }; | ||
| } | ||
| function createReplayStream(options) { | ||
| const { history, liveSource, cache, cacheKey, serialize = (x) => x } = options; | ||
| let historyIndex = 0; | ||
| let liveReader = null; | ||
| let historyComplete = false; | ||
| return new ReadableStream({ | ||
| async pull(controller) { | ||
| if (!historyComplete) { | ||
| if (historyIndex < history.length) { | ||
| controller.enqueue(history[historyIndex]); | ||
| historyIndex++; | ||
| return; | ||
| } | ||
| historyComplete = true; | ||
| liveReader = liveSource.getReader(); | ||
| } | ||
| if (liveReader) { | ||
| try { | ||
| const { done, value } = await liveReader.read(); | ||
| if (done) { | ||
| controller.close(); | ||
| return; | ||
| } | ||
| if (cache && cacheKey) { | ||
| const serialized = serialize(value); | ||
| cache.listPush(cacheKey, serialized).catch(() => { | ||
| }); | ||
| } | ||
| controller.enqueue(value); | ||
| } catch (error) { | ||
| controller.error(error); | ||
| } | ||
| } | ||
| }, | ||
| cancel() { | ||
| if (liveReader) { | ||
| void liveReader.cancel(); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| function withStreamCaching(options) { | ||
| const { cache, cacheKey, serialize, deserialize } = options; | ||
| return { | ||
| pipeThrough: () => { | ||
| const { transform } = createCachingTransformStream({ cache, cacheKey, serialize, deserialize }); | ||
| return transform; | ||
| }, | ||
| getHistory: async (offset = 0) => { | ||
| const deserializeFn = deserialize ?? ((x) => x); | ||
| const cached = await cache.listFromTo(cacheKey, offset); | ||
| return cached.map((item) => deserializeFn(item)); | ||
| }, | ||
| clearCache: async () => { | ||
| await cache.delete(cacheKey); | ||
| } | ||
| }; | ||
| } | ||
| export { MastraAgentNetworkStream, WorkflowRunOutput, convertFullStreamChunkToMastra, convertFullStreamChunkToUIMessageStream, convertMastraChunkToAISDKv5, createCachingTransformStream, createReplayStream, withStreamCaching }; | ||
| //# sourceMappingURL=chunk-HIJT3Z73.js.map | ||
| //# sourceMappingURL=chunk-HIJT3Z73.js.map |
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunk2UAP4LDC_cjs = require('./chunk-2UAP4LDC.cjs'); | ||
| var chunkBP67LMWW_cjs = require('./chunk-BP67LMWW.cjs'); | ||
| // src/storage/domains/agents/base.ts | ||
| var AgentsStorage = class extends chunk2UAP4LDC_cjs.VersionedStorageDomain { | ||
| listKey = "agents"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "agentId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "AGENTS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/agents/inmemory.ts | ||
| var InMemoryAgentsStorage = class extends AgentsStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.agents.clear(); | ||
| this.db.agentVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Agent CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const agent = this.db.agents.get(id); | ||
| return agent ? this.deepCopyAgent(agent) : null; | ||
| } | ||
| async create(input) { | ||
| const { agent } = input; | ||
| if (this.db.agents.has(agent.id)) { | ||
| throw new Error(`Agent with id ${agent.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const visibility = agent.visibility ?? (agent.authorId ? "private" : void 0); | ||
| const newAgent = { | ||
| id: agent.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: agent.authorId, | ||
| visibility, | ||
| metadata: agent.metadata, | ||
| favoriteCount: 0, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.agents.set(agent.id, newAgent); | ||
| const { id: _id, authorId: _authorId, visibility: _visibility, metadata: _metadata, ...snapshotConfig } = agent; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| agentId: agent.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyAgent(newAgent); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingAgent = this.db.agents.get(id); | ||
| if (!existingAgent) { | ||
| throw new Error(`Agent with id ${id} not found`); | ||
| } | ||
| const { authorId, visibility, activeVersionId, metadata, status } = updates; | ||
| const updatedAgent = { | ||
| ...existingAgent, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...visibility !== void 0 && { visibility }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingAgent.metadata, ...metadata } | ||
| }, | ||
| ...status !== void 0 && { status }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.agents.set(id, updatedAgent); | ||
| return this.deepCopyAgent(updatedAgent); | ||
| } | ||
| async delete(id) { | ||
| this.db.agents.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { | ||
| page = 0, | ||
| perPage: perPageInput, | ||
| orderBy, | ||
| authorId, | ||
| visibility, | ||
| metadata, | ||
| status, | ||
| entityIds, | ||
| pinFavoritedFor, | ||
| favoritedOnly | ||
| } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let agents = Array.from(this.db.agents.values()); | ||
| if (entityIds !== void 0) { | ||
| if (entityIds.length === 0) { | ||
| return { | ||
| agents: [], | ||
| total: 0, | ||
| page, | ||
| perPage: perPageInput === false ? false : perPage, | ||
| hasMore: false | ||
| }; | ||
| } | ||
| const idSet = new Set(entityIds); | ||
| agents = agents.filter((agent) => idSet.has(agent.id)); | ||
| } | ||
| if (status) { | ||
| agents = agents.filter((agent) => agent.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| agents = agents.filter((agent) => agent.authorId === authorId); | ||
| } | ||
| if (visibility !== void 0) { | ||
| agents = agents.filter((agent) => agent.visibility === visibility); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| agents = agents.filter((agent) => { | ||
| if (!agent.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => chunkBP67LMWW_cjs.deepEqual(agent.metadata[key], value)); | ||
| }); | ||
| } | ||
| const favoritedIds = pinFavoritedFor ? this.collectFavoritedIdsFor(pinFavoritedFor) : void 0; | ||
| if (favoritedOnly) { | ||
| if (favoritedIds) { | ||
| agents = agents.filter((agent) => favoritedIds.has(agent.id)); | ||
| } else { | ||
| agents = []; | ||
| } | ||
| } | ||
| const sortedAgents = this.sortAgents(agents, field, direction, favoritedIds); | ||
| const clonedAgents = sortedAgents.map((agent) => this.deepCopyAgent(agent)); | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| agents: clonedAgents.slice(offset, offset + perPage), | ||
| total: clonedAgents.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedAgents.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Agent Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.agentVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.agentVersions.values()) { | ||
| if (version2.agentId === input.agentId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for agent ${input.agentId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.agentVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.agentVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(agentId, versionNumber) { | ||
| for (const version of this.db.agentVersions.values()) { | ||
| if (version.agentId === agentId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(agentId) { | ||
| let latest = null; | ||
| for (const version of this.db.agentVersions.values()) { | ||
| if (version.agentId === agentId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { agentId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.agentVersions.values()).filter((v) => v.agentId === agentId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.agentVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.agentVersions.entries()) { | ||
| if (version.agentId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.agentVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(agentId) { | ||
| let count = 0; | ||
| for (const version of this.db.agentVersions.values()) { | ||
| if (version.agentId === agentId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| /** | ||
| * Deep copy a thin agent record to prevent external mutation of stored data | ||
| */ | ||
| deepCopyAgent(agent) { | ||
| return { | ||
| ...agent, | ||
| metadata: agent.metadata ? { ...agent.metadata } : agent.metadata | ||
| }; | ||
| } | ||
| /** | ||
| * Deep copy a version to prevent external mutation of stored data | ||
| */ | ||
| deepCopyVersion(version) { | ||
| return structuredClone(version); | ||
| } | ||
| sortAgents(agents, field, direction, favoritedIds) { | ||
| return agents.sort((a, b) => { | ||
| if (favoritedIds) { | ||
| const aFav = favoritedIds.has(a.id) ? 1 : 0; | ||
| const bFav = favoritedIds.has(b.id) ? 1 : 0; | ||
| if (aFav !== bFav) return bFav - aFav; | ||
| } | ||
| const aValue = new Date(a[field]).getTime(); | ||
| const bValue = new Date(b[field]).getTime(); | ||
| if (aValue !== bValue) { | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| } | ||
| return a.id < b.id ? -1 : a.id > b.id ? 1 : 0; | ||
| }); | ||
| } | ||
| /** | ||
| * Collect the set of agent IDs favorited by the given user. Returns an empty | ||
| * Set when the favorites domain is not wired or the user has no favorites. | ||
| */ | ||
| collectFavoritedIdsFor(userId) { | ||
| const favorited = /* @__PURE__ */ new Set(); | ||
| for (const row of this.db.favorites.values()) { | ||
| if (row.userId === userId && row.entityType === "agent") { | ||
| favorited.add(row.entityId); | ||
| } | ||
| } | ||
| return favorited; | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/inmemory-db.ts | ||
| var InMemoryDB = class { | ||
| threads = /* @__PURE__ */ new Map(); | ||
| messages = /* @__PURE__ */ new Map(); | ||
| resources = /* @__PURE__ */ new Map(); | ||
| workflows = /* @__PURE__ */ new Map(); | ||
| scores = /* @__PURE__ */ new Map(); | ||
| traces = /* @__PURE__ */ new Map(); | ||
| metricRecords = []; | ||
| logRecords = []; | ||
| scoreRecords = []; | ||
| feedbackRecords = []; | ||
| observabilityNextCursorId = 1; | ||
| traceCursorIds = /* @__PURE__ */ new Map(); | ||
| branchCursorIds = /* @__PURE__ */ new Map(); | ||
| metricCursorIds = /* @__PURE__ */ new Map(); | ||
| logCursorIds = /* @__PURE__ */ new Map(); | ||
| scoreCursorIds = /* @__PURE__ */ new Map(); | ||
| feedbackCursorIds = /* @__PURE__ */ new Map(); | ||
| agents = /* @__PURE__ */ new Map(); | ||
| agentVersions = /* @__PURE__ */ new Map(); | ||
| promptBlocks = /* @__PURE__ */ new Map(); | ||
| promptBlockVersions = /* @__PURE__ */ new Map(); | ||
| scorerDefinitions = /* @__PURE__ */ new Map(); | ||
| scorerDefinitionVersions = /* @__PURE__ */ new Map(); | ||
| mcpClients = /* @__PURE__ */ new Map(); | ||
| mcpClientVersions = /* @__PURE__ */ new Map(); | ||
| mcpServers = /* @__PURE__ */ new Map(); | ||
| mcpServerVersions = /* @__PURE__ */ new Map(); | ||
| workspaces = /* @__PURE__ */ new Map(); | ||
| workspaceVersions = /* @__PURE__ */ new Map(); | ||
| skills = /* @__PURE__ */ new Map(); | ||
| skillVersions = /* @__PURE__ */ new Map(); | ||
| /** | ||
| * Favorites keyed by `${userId}\u0000${entityType}\u0000${entityId}`. The | ||
| * favorites domain owns reads/writes; this Map lives on InMemoryDB so the | ||
| * favorites domain can also mutate `agents` / `skills` `favoriteCount` atomically | ||
| * within the same synchronous block. | ||
| */ | ||
| favorites = /* @__PURE__ */ new Map(); | ||
| /** Observational memory records, keyed by resourceId, each holding array of records (generations) */ | ||
| observationalMemory = /* @__PURE__ */ new Map(); | ||
| // Dataset domain maps | ||
| datasets = /* @__PURE__ */ new Map(); | ||
| datasetItems = /* @__PURE__ */ new Map(); | ||
| datasetVersions = /* @__PURE__ */ new Map(); | ||
| // Experiment domain maps | ||
| experiments = /* @__PURE__ */ new Map(); | ||
| experimentResults = /* @__PURE__ */ new Map(); | ||
| // Background tasks domain | ||
| backgroundTasks = /* @__PURE__ */ new Map(); | ||
| // Schedules domain | ||
| schedules = /* @__PURE__ */ new Map(); | ||
| scheduleTriggers = []; | ||
| /** | ||
| * Tool provider connections keyed by `${authorId}\u0000${providerId}\u0000${connectionId}`. | ||
| */ | ||
| toolProviderConnections = /* @__PURE__ */ new Map(); | ||
| /** | ||
| * Clears all data from all collections. | ||
| * Useful for testing. | ||
| */ | ||
| clear() { | ||
| this.threads.clear(); | ||
| this.messages.clear(); | ||
| this.resources.clear(); | ||
| this.workflows.clear(); | ||
| this.scores.clear(); | ||
| this.traces.clear(); | ||
| this.metricRecords.length = 0; | ||
| this.logRecords.length = 0; | ||
| this.scoreRecords.length = 0; | ||
| this.feedbackRecords.length = 0; | ||
| this.observabilityNextCursorId = 1; | ||
| this.traceCursorIds.clear(); | ||
| this.branchCursorIds.clear(); | ||
| this.metricCursorIds.clear(); | ||
| this.logCursorIds.clear(); | ||
| this.scoreCursorIds.clear(); | ||
| this.feedbackCursorIds.clear(); | ||
| this.agents.clear(); | ||
| this.agentVersions.clear(); | ||
| this.promptBlocks.clear(); | ||
| this.promptBlockVersions.clear(); | ||
| this.scorerDefinitions.clear(); | ||
| this.scorerDefinitionVersions.clear(); | ||
| this.mcpClients.clear(); | ||
| this.mcpClientVersions.clear(); | ||
| this.mcpServers.clear(); | ||
| this.mcpServerVersions.clear(); | ||
| this.workspaces.clear(); | ||
| this.workspaceVersions.clear(); | ||
| this.skills.clear(); | ||
| this.skillVersions.clear(); | ||
| this.favorites.clear(); | ||
| this.observationalMemory.clear(); | ||
| this.datasets.clear(); | ||
| this.datasetItems.clear(); | ||
| this.datasetVersions.clear(); | ||
| this.experiments.clear(); | ||
| this.experimentResults.clear(); | ||
| this.backgroundTasks.clear(); | ||
| this.schedules.clear(); | ||
| this.scheduleTriggers.length = 0; | ||
| this.toolProviderConnections.clear(); | ||
| } | ||
| }; | ||
| // src/storage/domains/agents/filesystem.ts | ||
| var PERSISTED_SNAPSHOT_FIELDS = /* @__PURE__ */ new Set([ | ||
| "name", | ||
| "instructions", | ||
| "model", | ||
| "tools", | ||
| "integrationTools", | ||
| "toolProviders", | ||
| "mcpClients", | ||
| "requestContextSchema" | ||
| ]); | ||
| var CODE_MODE_EXCLUDED_FIELDS = /* @__PURE__ */ new Set(["model", "name"]); | ||
| var OWNED_FIELDS_BY_GROUP = { | ||
| instructions: ["instructions"], | ||
| tools: ["tools", "integrationTools", "mcpClients"] | ||
| }; | ||
| function ownershipFromEditorConfig(editorConfig) { | ||
| if (editorConfig === false) { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| if (editorConfig === void 0 || editorConfig === null) { | ||
| return { ownsInstructions: true, ownsTools: true }; | ||
| } | ||
| if (typeof editorConfig !== "object") { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| const cfg = editorConfig; | ||
| const ownsInstructions = cfg.instructions === true; | ||
| const toolsCfg = cfg.tools; | ||
| const ownsTools = toolsCfg === true || typeof toolsCfg === "object" && toolsCfg !== null && toolsCfg.description === true; | ||
| return { ownsInstructions, ownsTools }; | ||
| } | ||
| function stripUnusedFields(obj) { | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| if (PERSISTED_SNAPSHOT_FIELDS.has(key)) { | ||
| result[key] = value; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function isAgentNotFoundError(error, entityId) { | ||
| if (!error || typeof error !== "object") return false; | ||
| const maybeError = error; | ||
| return maybeError.id === "MASTRA_GET_AGENT_BY_AGENT_ID_NOT_FOUND" || maybeError.details?.status === 404 && maybeError.details?.agentId === entityId || maybeError.message === `Agent with id ${entityId} not found`; | ||
| } | ||
| var FilesystemAgentsStorage = class extends AgentsStorage { | ||
| helpers; | ||
| storageMastra; | ||
| constructor({ db }) { | ||
| super(); | ||
| const getCodeAgent = (entityId) => { | ||
| try { | ||
| const agent = this.storageMastra?.getAgentById?.(entityId); | ||
| return agent?.source === "code" ? agent : void 0; | ||
| } catch (error) { | ||
| if (isAgentNotFoundError(error, entityId)) { | ||
| return void 0; | ||
| } | ||
| throw error; | ||
| } | ||
| }; | ||
| const isCodeAgent = (entityId) => Boolean(getCodeAgent(entityId)); | ||
| const editorConfigFor = (entityId) => getCodeAgent(entityId)?.__getEditorConfig?.(); | ||
| this.helpers = new chunk2UAP4LDC_cjs.FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "agents.json", | ||
| parentIdField: "agentId", | ||
| name: "FilesystemAgentsStorage", | ||
| versionMetadataFields: ["id", "agentId", "versionNumber", "changedFields", "changeMessage", "createdAt"], | ||
| perEntityFilesDir: "agents", | ||
| // Per-entity layout is used only for code-mode agents — i.e. agents | ||
| // that are declared in code (`source === 'code'`). For db-mode and | ||
| // user-created stored agents we keep the shared `agents.json` layout. | ||
| shouldPersistToPerEntityFile: (entity) => isCodeAgent(entity.id), | ||
| perEntitySnapshotFilter: (snapshot, entity) => { | ||
| const { ownsInstructions, ownsTools } = ownershipFromEditorConfig(editorConfigFor(entity.id)); | ||
| const excludedByOwnership = /* @__PURE__ */ new Set(); | ||
| if (!ownsInstructions) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP.instructions) excludedByOwnership.add(field); | ||
| } | ||
| if (!ownsTools) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP.tools) excludedByOwnership.add(field); | ||
| } | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(snapshot)) { | ||
| if (CODE_MODE_EXCLUDED_FIELDS.has(key)) continue; | ||
| if (excludedByOwnership.has(key)) continue; | ||
| result[key] = value; | ||
| } | ||
| return result; | ||
| } | ||
| }); | ||
| } | ||
| __registerMastra(mastra) { | ||
| this.storageMastra = mastra; | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { agent } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const visibility = agent.visibility ?? (agent.authorId ? "private" : void 0); | ||
| const entity = { | ||
| id: agent.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: agent.authorId, | ||
| visibility, | ||
| metadata: agent.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(agent.id, entity); | ||
| const { id: _id, authorId: _authorId, visibility: _visibility, metadata: _metadata, ...snapshotConfig } = agent; | ||
| const filtered = stripUnusedFields(snapshotConfig); | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| agentId: agent.id, | ||
| versionNumber: 1, | ||
| ...filtered, | ||
| changedFields: Object.keys(filtered), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const entityUpdates = {}; | ||
| const entityFields = /* @__PURE__ */ new Set(["authorId", "visibility", "metadata", "activeVersionId", "status"]); | ||
| for (const [key, value] of Object.entries(updates)) { | ||
| if (entityFields.has(key)) { | ||
| entityUpdates[key] = value; | ||
| } | ||
| } | ||
| return this.helpers.updateEntity(id, entityUpdates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, visibility, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "agents", | ||
| filters: { authorId, visibility, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| const { id, agentId, versionNumber, changedFields, changeMessage, ...snapshotFields } = input; | ||
| const filtered = stripUnusedFields(snapshotFields); | ||
| return this.helpers.createVersion({ | ||
| id, | ||
| agentId, | ||
| versionNumber, | ||
| changedFields, | ||
| changeMessage, | ||
| ...filtered | ||
| }); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(agentId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(agentId, versionNumber); | ||
| } | ||
| async getLatestVersion(agentId) { | ||
| return this.helpers.getLatestVersion(agentId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "agentId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(agentId) { | ||
| return this.helpers.countVersions(agentId); | ||
| } | ||
| }; | ||
| // src/storage/domains/agents/source.ts | ||
| var SOURCE_VERSION_PREFIX = "source:"; | ||
| var COMMON_EXCLUDED_FIELDS = /* @__PURE__ */ new Set([ | ||
| "id", | ||
| "model", | ||
| "scorers", | ||
| "skills", | ||
| "workflows", | ||
| "agents", | ||
| "integrationTools", | ||
| "toolProviders", | ||
| "inputProcessors", | ||
| "outputProcessors", | ||
| "memory", | ||
| "mcpClients", | ||
| "workspace", | ||
| "browser", | ||
| "defaultOptions" | ||
| ]); | ||
| var CODE_SOURCE_EXCLUDED_FIELDS = /* @__PURE__ */ new Set(["name"]); | ||
| var OWNED_FIELDS_BY_GROUP2 = { | ||
| instructions: ["instructions"], | ||
| tools: ["tools"] | ||
| }; | ||
| function ownershipFromEditorConfig2(editorConfig) { | ||
| if (editorConfig === false) { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| if (editorConfig === void 0 || editorConfig === null) { | ||
| return { ownsInstructions: true, ownsTools: true }; | ||
| } | ||
| if (typeof editorConfig !== "object") { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| const cfg = editorConfig; | ||
| const ownsInstructions = cfg.instructions === true; | ||
| const toolsCfg = cfg.tools; | ||
| const ownsTools = toolsCfg === true || typeof toolsCfg === "object" && toolsCfg !== null && toolsCfg.description === true; | ||
| return { ownsInstructions, ownsTools }; | ||
| } | ||
| function snapshotFromVersion(version) { | ||
| const { id, agentId, versionNumber, changedFields, changeMessage, createdAt, ...snapshot } = version; | ||
| return snapshot; | ||
| } | ||
| function filterSourceSnapshot(snapshot, editorConfig, isCodeDefinedAgent) { | ||
| const excludedByOwnership = /* @__PURE__ */ new Set(); | ||
| if (isCodeDefinedAgent) { | ||
| const { ownsInstructions, ownsTools } = ownershipFromEditorConfig2(editorConfig); | ||
| if (!ownsInstructions) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP2.instructions) excludedByOwnership.add(field); | ||
| } | ||
| if (!ownsTools) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP2.tools) excludedByOwnership.add(field); | ||
| } | ||
| } | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(snapshot)) { | ||
| if (COMMON_EXCLUDED_FIELDS.has(key)) continue; | ||
| if (isCodeDefinedAgent && CODE_SOURCE_EXCLUDED_FIELDS.has(key)) continue; | ||
| if (excludedByOwnership.has(key)) continue; | ||
| if (value === void 0) continue; | ||
| result[key] = value; | ||
| } | ||
| return result; | ||
| } | ||
| function parseJsonObject(content) { | ||
| try { | ||
| const parsed = JSON.parse(content); | ||
| return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null; | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
| function stableStringify(value) { | ||
| if (Array.isArray(value)) { | ||
| return `[${value.map(stableStringify).join(",")}]`; | ||
| } | ||
| if (value && typeof value === "object") { | ||
| const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([a], [b]) => a.localeCompare(b)); | ||
| return `{${entries.map(([key, entryValue]) => `${JSON.stringify(key)}:${stableStringify(entryValue)}`).join(",")}}`; | ||
| } | ||
| return JSON.stringify(value); | ||
| } | ||
| function agentIdFromSourcePath(path) { | ||
| const prefix = `${chunk2UAP4LDC_cjs.SOURCE_CONTROL_AGENTS_DIR}/`; | ||
| if (!path.startsWith(prefix) || !path.endsWith(".json")) return void 0; | ||
| const filename = path.slice(prefix.length, -".json".length); | ||
| if (!filename || filename.includes("/")) return void 0; | ||
| try { | ||
| return decodeURIComponent(filename); | ||
| } catch { | ||
| return filename; | ||
| } | ||
| } | ||
| var SourceAgentsSourceControl = class extends AgentsStorage { | ||
| provider; | ||
| knownAgentIds; | ||
| db = new InMemoryDB(); | ||
| memory = new InMemoryAgentsStorage({ db: this.db }); | ||
| storageMastra; | ||
| providerVersions = /* @__PURE__ */ new Map(); | ||
| loadedHistory = /* @__PURE__ */ new Set(); | ||
| hydratedAgents = /* @__PURE__ */ new Set(); | ||
| activeRefs = /* @__PURE__ */ new Map(); | ||
| providerAgentIdsDiscovered = false; | ||
| constructor({ provider, agentIds = [] }) { | ||
| super(); | ||
| this.provider = provider; | ||
| this.knownAgentIds = new Set(agentIds); | ||
| } | ||
| __registerMastra(mastra) { | ||
| this.storageMastra = mastra; | ||
| } | ||
| async init() { | ||
| const capabilities = await this.provider.getCapabilities(); | ||
| if (!capabilities.canRead) { | ||
| throw new Error(capabilities.reason ?? `Source provider ${this.provider.displayName} cannot read files`); | ||
| } | ||
| this.refreshKnownAgentIds(); | ||
| await this.discoverProviderAgentIds(); | ||
| await Promise.all([...this.knownAgentIds].map((agentId) => this.hydrateAgent(agentId))); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.hydratedAgents.clear(); | ||
| this.loadedHistory.clear(); | ||
| this.providerVersions.clear(); | ||
| this.activeRefs.clear(); | ||
| this.providerAgentIdsDiscovered = false; | ||
| await this.memory.dangerouslyClearAll(); | ||
| } | ||
| async useProviderRef(agentId, ref) { | ||
| this.activeRefs.set(agentId, ref); | ||
| this.hydratedAgents.delete(agentId); | ||
| this.loadedHistory.delete(agentId); | ||
| for (const [versionId, version] of this.providerVersions.entries()) { | ||
| if (version.agentId === agentId) { | ||
| this.providerVersions.delete(versionId); | ||
| } | ||
| } | ||
| await this.memory.delete(agentId); | ||
| await this.hydrateAgent(agentId); | ||
| } | ||
| async getById(id) { | ||
| await this.hydrateAgent(id); | ||
| return this.memory.getById(id); | ||
| } | ||
| async create(input) { | ||
| await this.hydrateAgent(input.agent.id); | ||
| const existing = await this.memory.getById(input.agent.id); | ||
| if (existing) { | ||
| throw new Error(`Agent with id ${input.agent.id} already exists`); | ||
| } | ||
| await this.persistSnapshot(input.agent.id, { ...input.agent }, "Initial version"); | ||
| const created = await this.memory.create(input); | ||
| this.knownAgentIds.add(input.agent.id); | ||
| return created; | ||
| } | ||
| async update(input) { | ||
| await this.hydrateAgent(input.id); | ||
| return this.memory.update(input); | ||
| } | ||
| async delete(id) { | ||
| this.knownAgentIds.delete(id); | ||
| this.hydratedAgents.delete(id); | ||
| this.loadedHistory.delete(id); | ||
| for (const versionId of this.providerVersions.keys()) { | ||
| if (this.providerVersions.get(versionId)?.agentId === id) { | ||
| this.providerVersions.delete(versionId); | ||
| } | ||
| } | ||
| await this.memory.delete(id); | ||
| } | ||
| async list(args) { | ||
| this.refreshKnownAgentIds(); | ||
| await this.discoverProviderAgentIds(); | ||
| await Promise.all([...this.knownAgentIds].map((agentId) => this.hydrateAgent(agentId))); | ||
| return this.memory.list(args); | ||
| } | ||
| async createVersion(input) { | ||
| await this.hydrateAgent(input.agentId); | ||
| const existingVersion = await this.memory.getVersion(input.id); | ||
| if (existingVersion) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| const existingVersionNumber = await this.memory.getVersionByNumber(input.agentId, input.versionNumber); | ||
| if (existingVersionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for agent ${input.agentId}`); | ||
| } | ||
| const snapshot = snapshotFromVersion({ ...input, createdAt: /* @__PURE__ */ new Date() }); | ||
| const result = await this.persistSnapshot(input.agentId, snapshot, input.changeMessage); | ||
| const version = await this.memory.createVersion(input); | ||
| this.rememberProviderVersion(input.agentId, version, result); | ||
| return version; | ||
| } | ||
| async getVersion(id) { | ||
| const providerVersion = this.providerVersions.get(id); | ||
| if (providerVersion) { | ||
| return structuredClone(providerVersion); | ||
| } | ||
| return this.memory.getVersion(id); | ||
| } | ||
| async getVersionByNumber(agentId, versionNumber) { | ||
| await this.loadHistory(agentId); | ||
| const providerVersion = [...this.providerVersions.values()].find( | ||
| (version) => version.agentId === agentId && version.versionNumber === versionNumber | ||
| ); | ||
| if (providerVersion) { | ||
| return structuredClone(providerVersion); | ||
| } | ||
| return this.memory.getVersionByNumber(agentId, versionNumber); | ||
| } | ||
| async getLatestVersion(agentId) { | ||
| await this.loadHistory(agentId); | ||
| const providerLatest = [...this.providerVersions.values()].filter((version) => version.agentId === agentId).sort((a, b) => b.versionNumber - a.versionNumber)[0]; | ||
| if (providerLatest) { | ||
| return structuredClone(providerLatest); | ||
| } | ||
| return this.memory.getLatestVersion(agentId); | ||
| } | ||
| async listVersions(input) { | ||
| await this.loadHistory(input.agentId); | ||
| const providerVersions = [...this.providerVersions.values()].filter((version) => version.agentId === input.agentId); | ||
| if (providerVersions.length === 0) { | ||
| return this.memory.listVersions(input); | ||
| } | ||
| const { page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| const sortedVersions = this.sortVersions(providerVersions, field, direction).map( | ||
| (version) => structuredClone(version) | ||
| ); | ||
| const total = sortedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| versions: sortedVersions.slice(offset, offset + perPage), | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.providerVersions.delete(id); | ||
| await this.memory.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| for (const [versionId, version] of this.providerVersions.entries()) { | ||
| if (version.agentId === entityId) { | ||
| this.providerVersions.delete(versionId); | ||
| } | ||
| } | ||
| await this.memory.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(entityId) { | ||
| await this.loadHistory(entityId); | ||
| const providerCount = [...this.providerVersions.values()].filter((version) => version.agentId === entityId).length; | ||
| return providerCount || this.memory.countVersions(entityId); | ||
| } | ||
| refreshKnownAgentIds() { | ||
| const agents = this.storageMastra?.listAgents?.(); | ||
| if (!agents) return; | ||
| for (const agent of Object.values(agents)) { | ||
| if (agent.source === "code") { | ||
| this.knownAgentIds.add(agent.id); | ||
| } | ||
| } | ||
| } | ||
| async discoverProviderAgentIds() { | ||
| if (this.providerAgentIdsDiscovered || !this.provider.listFiles) return; | ||
| const files = await this.provider.listFiles({ path: chunk2UAP4LDC_cjs.SOURCE_CONTROL_AGENTS_DIR }); | ||
| for (const file of files) { | ||
| const agentId = agentIdFromSourcePath(file.path); | ||
| if (agentId) { | ||
| this.knownAgentIds.add(agentId); | ||
| } | ||
| } | ||
| this.providerAgentIdsDiscovered = true; | ||
| } | ||
| async hydrateAgent(agentId) { | ||
| if (this.hydratedAgents.has(agentId)) return; | ||
| const ref = this.activeRefs.get(agentId); | ||
| const file = await this.provider.readFile({ path: chunk2UAP4LDC_cjs.getSourceAgentFilePath(agentId), ref }); | ||
| if (!file) { | ||
| this.hydratedAgents.add(agentId); | ||
| return; | ||
| } | ||
| const snapshot = parseJsonObject(file.content); | ||
| if (!snapshot) { | ||
| this.hydratedAgents.add(agentId); | ||
| return; | ||
| } | ||
| this.knownAgentIds.add(agentId); | ||
| this.hydratedAgents.add(agentId); | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const versionId = `hydrated-${agentId}-v1`; | ||
| this.db.agents.set(agentId, { | ||
| id: agentId, | ||
| status: "published", | ||
| activeVersionId: versionId, | ||
| favoriteCount: 0, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }); | ||
| this.db.agentVersions.set(versionId, { | ||
| id: versionId, | ||
| agentId, | ||
| versionNumber: 1, | ||
| ...snapshot, | ||
| createdAt: now | ||
| }); | ||
| } | ||
| getCodeDefinedAgent(agentId) { | ||
| try { | ||
| const agent = this.storageMastra?.getAgentById?.(agentId); | ||
| return agent?.source === "code" ? agent : void 0; | ||
| } catch { | ||
| return void 0; | ||
| } | ||
| } | ||
| async persistSnapshot(agentId, snapshot, message) { | ||
| const capabilities = await this.provider.getCapabilities(); | ||
| if (!capabilities.canWrite) { | ||
| throw new Error(capabilities.reason ?? `Source provider ${this.provider.displayName} cannot write files`); | ||
| } | ||
| const agent = this.getCodeDefinedAgent(agentId); | ||
| const filtered = filterSourceSnapshot(snapshot, agent?.__getEditorConfig?.(), Boolean(agent)); | ||
| return this.provider.writeFile({ | ||
| path: chunk2UAP4LDC_cjs.getSourceAgentFilePath(agentId), | ||
| ref: this.activeRefs.get(agentId), | ||
| content: `${stableStringify(filtered)} | ||
| `, | ||
| message | ||
| }); | ||
| } | ||
| async loadHistory(agentId) { | ||
| if (this.loadedHistory.has(agentId)) return; | ||
| const capabilities = await this.provider.getCapabilities(); | ||
| if (!capabilities.canListHistory) { | ||
| this.loadedHistory.add(agentId); | ||
| return; | ||
| } | ||
| const activeRef = this.activeRefs.get(agentId); | ||
| const entries = await this.provider.listFileHistory({ path: chunk2UAP4LDC_cjs.getSourceAgentFilePath(agentId), ref: activeRef }); | ||
| const orderedEntries = [...entries].reverse(); | ||
| const versions = /* @__PURE__ */ new Map(); | ||
| let versionNumber = 0; | ||
| for (const entry of orderedEntries) { | ||
| const file = await this.provider.readFile({ path: chunk2UAP4LDC_cjs.getSourceAgentFilePath(agentId), ref: entry.ref ?? entry.id }); | ||
| if (!file) continue; | ||
| const snapshot = parseJsonObject(file.content); | ||
| if (!snapshot) continue; | ||
| versionNumber += 1; | ||
| const version = this.versionFromHistoryEntry(agentId, entry, versionNumber, snapshot); | ||
| versions.set(version.id, version); | ||
| } | ||
| for (const [versionId, version] of versions) { | ||
| this.providerVersions.set(versionId, version); | ||
| } | ||
| this.loadedHistory.add(agentId); | ||
| } | ||
| rememberProviderVersion(agentId, version, result) { | ||
| const versionId = result.commitSha ? `${SOURCE_VERSION_PREFIX}${result.commitSha}:${agentId}` : version.id; | ||
| this.providerVersions.set(versionId, { | ||
| ...structuredClone(version), | ||
| id: versionId, | ||
| agentId, | ||
| versionNumber: this.nextProviderVersionNumber(agentId) | ||
| }); | ||
| } | ||
| versionFromHistoryEntry(agentId, entry, versionNumber, snapshot) { | ||
| return { | ||
| id: `${SOURCE_VERSION_PREFIX}${entry.id}:${agentId}`, | ||
| agentId, | ||
| versionNumber, | ||
| changeMessage: entry.message, | ||
| ...snapshot, | ||
| createdAt: new Date(entry.createdAt) | ||
| }; | ||
| } | ||
| nextProviderVersionNumber(agentId) { | ||
| const latest = [...this.providerVersions.values()].filter((version) => version.agentId === agentId).sort((a, b) => b.versionNumber - a.versionNumber)[0]; | ||
| return (latest?.versionNumber ?? 0) + 1; | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| const aVal = field === "createdAt" ? a.createdAt.getTime() : a.versionNumber; | ||
| const bVal = field === "createdAt" ? b.createdAt.getTime() : b.versionNumber; | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| exports.AgentsStorage = AgentsStorage; | ||
| exports.FilesystemAgentsStorage = FilesystemAgentsStorage; | ||
| exports.InMemoryAgentsStorage = InMemoryAgentsStorage; | ||
| exports.InMemoryDB = InMemoryDB; | ||
| exports.SourceAgentsSourceControl = SourceAgentsSourceControl; | ||
| //# sourceMappingURL=chunk-HLSFGO57.cjs.map | ||
| //# sourceMappingURL=chunk-HLSFGO57.cjs.map |
Sorry, the diff of this file is too big to display
| import { VersionedStorageDomain, normalizePerPage, calculatePagination, FilesystemVersionedHelpers } from './chunk-SKZRHFF3.js'; | ||
| import { deepEqual } from './chunk-M2TW4P2L.js'; | ||
| // src/storage/domains/workspaces/base.ts | ||
| var WorkspacesStorage = class extends VersionedStorageDomain { | ||
| listKey = "workspaces"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "workspaceId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "WORKSPACES" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/workspaces/inmemory.ts | ||
| var InMemoryWorkspacesStorage = class extends WorkspacesStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.workspaces.clear(); | ||
| this.db.workspaceVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Workspace CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const config = this.db.workspaces.get(id); | ||
| return config ? this.deepCopyConfig(config) : null; | ||
| } | ||
| async create(input) { | ||
| const { workspace } = input; | ||
| if (this.db.workspaces.has(workspace.id)) { | ||
| throw new Error(`Workspace with id ${workspace.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newConfig = { | ||
| id: workspace.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: workspace.authorId, | ||
| metadata: workspace.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.workspaces.set(workspace.id, newConfig); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| workspaceId: workspace.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyConfig(newConfig); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingConfig = this.db.workspaces.get(id); | ||
| if (!existingConfig) { | ||
| throw new Error(`Workspace with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status, ...rawConfigFields } = updates; | ||
| const configFields = {}; | ||
| for (const [key, value] of Object.entries(rawConfigFields)) { | ||
| if (value !== void 0) configFields[key] = value; | ||
| } | ||
| const configFieldNames = [ | ||
| "name", | ||
| "description", | ||
| "filesystem", | ||
| "sandbox", | ||
| "mounts", | ||
| "search", | ||
| "skills", | ||
| "tools", | ||
| "autoSync", | ||
| "operationTimeout" | ||
| ]; | ||
| const hasConfigUpdate = configFieldNames.some((field) => field in configFields); | ||
| const updatedConfig = { | ||
| ...existingConfig, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingConfig.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| if (activeVersionId !== void 0 && status === void 0) { | ||
| updatedConfig.status = "published"; | ||
| } | ||
| if (hasConfigUpdate) { | ||
| const latestVersion = await this.getLatestVersion(id); | ||
| if (!latestVersion) { | ||
| throw new Error(`No versions found for workspace ${id}`); | ||
| } | ||
| const { | ||
| id: _versionId, | ||
| workspaceId: _workspaceId, | ||
| versionNumber: _versionNumber, | ||
| changedFields: _changedFields, | ||
| changeMessage: _changeMessage, | ||
| createdAt: _createdAt, | ||
| ...latestConfig | ||
| } = latestVersion; | ||
| const newConfig = { | ||
| ...latestConfig, | ||
| ...configFields | ||
| }; | ||
| const changedFields = configFieldNames.filter( | ||
| (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field]) | ||
| ); | ||
| if (changedFields.length > 0) { | ||
| const newVersionId = crypto.randomUUID(); | ||
| const newVersionNumber = latestVersion.versionNumber + 1; | ||
| await this.createVersion({ | ||
| id: newVersionId, | ||
| workspaceId: id, | ||
| versionNumber: newVersionNumber, | ||
| ...newConfig, | ||
| changedFields, | ||
| changeMessage: `Updated ${changedFields.join(", ")}` | ||
| }); | ||
| } | ||
| } | ||
| this.db.workspaces.set(id, updatedConfig); | ||
| return this.deepCopyConfig(updatedConfig); | ||
| } | ||
| async delete(id) { | ||
| this.db.workspaces.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let configs = Array.from(this.db.workspaces.values()); | ||
| if (authorId !== void 0) { | ||
| configs = configs.filter((config) => config.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| configs = configs.filter((config) => { | ||
| if (!config.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedConfigs = this.sortConfigs(configs, field, direction); | ||
| const clonedConfigs = sortedConfigs.map((config) => this.deepCopyConfig(config)); | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| workspaces: clonedConfigs.slice(offset, offset + perPage), | ||
| total: clonedConfigs.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedConfigs.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Workspace Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.workspaceVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.workspaceVersions.values()) { | ||
| if (version2.workspaceId === input.workspaceId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for workspace ${input.workspaceId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.workspaceVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.workspaceVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(workspaceId, versionNumber) { | ||
| for (const version of this.db.workspaceVersions.values()) { | ||
| if (version.workspaceId === workspaceId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(workspaceId) { | ||
| let latest = null; | ||
| for (const version of this.db.workspaceVersions.values()) { | ||
| if (version.workspaceId === workspaceId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { workspaceId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.workspaceVersions.values()).filter((v) => v.workspaceId === workspaceId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.workspaceVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.workspaceVersions.entries()) { | ||
| if (version.workspaceId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.workspaceVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(workspaceId) { | ||
| let count = 0; | ||
| for (const version of this.db.workspaceVersions.values()) { | ||
| if (version.workspaceId === workspaceId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyConfig(config) { | ||
| return { | ||
| ...config, | ||
| metadata: config.metadata ? { ...config.metadata } : config.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return structuredClone(version); | ||
| } | ||
| sortConfigs(configs, field, direction) { | ||
| return configs.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/workspaces/filesystem.ts | ||
| var FilesystemWorkspacesStorage = class extends WorkspacesStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "workspaces.json", | ||
| parentIdField: "workspaceId", | ||
| name: "FilesystemWorkspacesStorage", | ||
| versionMetadataFields: ["id", "workspaceId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { workspace } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: workspace.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: workspace.authorId, | ||
| metadata: workspace.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(workspace.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| workspaceId: workspace.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "workspaces", | ||
| filters: { authorId, metadata } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(workspaceId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(workspaceId, versionNumber); | ||
| } | ||
| async getLatestVersion(workspaceId) { | ||
| return this.helpers.getLatestVersion(workspaceId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "workspaceId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(workspaceId) { | ||
| return this.helpers.countVersions(workspaceId); | ||
| } | ||
| }; | ||
| export { FilesystemWorkspacesStorage, InMemoryWorkspacesStorage, WorkspacesStorage }; | ||
| //# sourceMappingURL=chunk-IZ3TT3AZ.js.map | ||
| //# sourceMappingURL=chunk-IZ3TT3AZ.js.map |
| {"version":3,"sources":["../src/storage/domains/workspaces/base.ts","../src/storage/domains/workspaces/inmemory.ts","../src/storage/domains/workspaces/filesystem.ts"],"names":["version"],"mappings":"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","file":"chunk-IZ3TT3AZ.js","sourcesContent":["import type {\n StorageWorkspaceType,\n StorageWorkspaceSnapshotType,\n StorageResolvedWorkspaceType,\n StorageCreateWorkspaceInput,\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput,\n StorageListWorkspacesOutput,\n StorageListWorkspacesResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// Workspace Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of a workspace's configuration.\n * Config fields are top-level on the version row (no nested snapshot object).\n */\nexport interface WorkspaceVersion extends StorageWorkspaceSnapshotType, VersionBase {\n /** ID of the workspace this version belongs to */\n workspaceId: string;\n}\n\n/**\n * Input for creating a new workspace version.\n * Config fields are top-level (no nested snapshot object).\n */\nexport interface CreateWorkspaceVersionInput extends StorageWorkspaceSnapshotType, CreateVersionInputBase {\n /** ID of the workspace this version belongs to */\n workspaceId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type WorkspaceVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type WorkspaceVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing workspace versions with pagination and sorting.\n */\nexport interface ListWorkspaceVersionsInput extends ListVersionsInputBase {\n /** ID of the workspace to list versions for */\n workspaceId: string;\n}\n\n/**\n * Output for listing workspace versions with pagination info.\n */\nexport interface ListWorkspaceVersionsOutput extends ListVersionsOutputBase<WorkspaceVersion> {}\n\n// ============================================================================\n// WorkspacesStorage Base Class\n// ============================================================================\n\nexport abstract class WorkspacesStorage extends VersionedStorageDomain<\n StorageWorkspaceType,\n StorageWorkspaceSnapshotType,\n StorageResolvedWorkspaceType,\n WorkspaceVersion,\n CreateWorkspaceVersionInput,\n ListWorkspaceVersionsInput,\n ListWorkspaceVersionsOutput,\n { workspace: StorageCreateWorkspaceInput },\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput | undefined,\n StorageListWorkspacesOutput,\n StorageListWorkspacesResolvedOutput\n> {\n protected readonly listKey = 'workspaces';\n protected readonly versionMetadataFields = [\n 'id',\n 'workspaceId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof WorkspaceVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'WORKSPACES',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageWorkspaceType,\n StorageCreateWorkspaceInput,\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput,\n StorageListWorkspacesOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n WorkspaceVersion,\n CreateWorkspaceVersionInput,\n ListWorkspaceVersionsInput,\n ListWorkspaceVersionsOutput,\n WorkspaceVersionOrderBy,\n WorkspaceVersionSortDirection,\n} from './base';\nimport { WorkspacesStorage } from './base';\n\nexport class InMemoryWorkspacesStorage extends WorkspacesStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.workspaces.clear();\n this.db.workspaceVersions.clear();\n }\n\n // ==========================================================================\n // Workspace CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageWorkspaceType | null> {\n const config = this.db.workspaces.get(id);\n return config ? this.deepCopyConfig(config) : null;\n }\n\n async create(input: { workspace: StorageCreateWorkspaceInput }): Promise<StorageWorkspaceType> {\n const { workspace } = input;\n\n if (this.db.workspaces.has(workspace.id)) {\n throw new Error(`Workspace with id ${workspace.id} already exists`);\n }\n\n const now = new Date();\n const newConfig: StorageWorkspaceType = {\n id: workspace.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: workspace.authorId,\n metadata: workspace.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.workspaces.set(workspace.id, newConfig);\n\n // Extract config fields from the flat input (everything except record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n workspaceId: workspace.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin record\n return this.deepCopyConfig(newConfig);\n }\n\n async update(input: StorageUpdateWorkspaceInput): Promise<StorageWorkspaceType> {\n const { id, ...updates } = input;\n\n const existingConfig = this.db.workspaces.get(id);\n if (!existingConfig) {\n throw new Error(`Workspace with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status, ...rawConfigFields } = updates;\n\n // Strip undefined keys so omitted PATCH fields don't overwrite persisted values\n const configFields: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(rawConfigFields)) {\n if (value !== undefined) configFields[key] = value;\n }\n\n // Config field names from StorageWorkspaceSnapshotType\n const configFieldNames = [\n 'name',\n 'description',\n 'filesystem',\n 'sandbox',\n 'mounts',\n 'search',\n 'skills',\n 'tools',\n 'autoSync',\n 'operationTimeout',\n ];\n\n // Check if any config fields are present in the update\n const hasConfigUpdate = configFieldNames.some(field => field in configFields);\n\n // Update metadata fields on the record\n const updatedConfig: StorageWorkspaceType = {\n ...existingConfig,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageWorkspaceType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingConfig.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Auto-set status to 'published' when activeVersionId is set, only if status is not explicitly provided\n if (activeVersionId !== undefined && status === undefined) {\n updatedConfig.status = 'published';\n }\n\n // If config fields are being updated, create a new version\n if (hasConfigUpdate) {\n // Get the latest version to use as base\n const latestVersion = await this.getLatestVersion(id);\n if (!latestVersion) {\n throw new Error(`No versions found for workspace ${id}`);\n }\n\n // Extract config from latest version\n const {\n id: _versionId,\n workspaceId: _workspaceId,\n versionNumber: _versionNumber,\n changedFields: _changedFields,\n changeMessage: _changeMessage,\n createdAt: _createdAt,\n ...latestConfig\n } = latestVersion;\n\n // Merge updates into latest config\n const newConfig = {\n ...latestConfig,\n ...configFields,\n };\n\n // Identify which fields changed\n const changedFields = configFieldNames.filter(\n field =>\n field in configFields &&\n JSON.stringify(configFields[field as keyof typeof configFields]) !==\n JSON.stringify(latestConfig[field as keyof typeof latestConfig]),\n );\n\n // Only create a new version if something actually changed\n if (changedFields.length > 0) {\n const newVersionId = crypto.randomUUID();\n const newVersionNumber = latestVersion.versionNumber + 1;\n\n await this.createVersion({\n id: newVersionId,\n workspaceId: id,\n versionNumber: newVersionNumber,\n ...newConfig,\n changedFields,\n changeMessage: `Updated ${changedFields.join(', ')}`,\n });\n }\n }\n\n // Save the updated record\n this.db.workspaces.set(id, updatedConfig);\n return this.deepCopyConfig(updatedConfig);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.workspaces.delete(id);\n // Also delete all versions for this workspace\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListWorkspacesInput): Promise<StorageListWorkspacesOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all workspaces and apply filters\n let configs = Array.from(this.db.workspaces.values());\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n configs = configs.filter(config => config.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n configs = configs.filter(config => {\n if (!config.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata![key], value));\n });\n }\n\n // Sort filtered configs\n const sortedConfigs = this.sortConfigs(configs, field, direction);\n\n // Deep clone to avoid mutation\n const clonedConfigs = sortedConfigs.map(config => this.deepCopyConfig(config));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n workspaces: clonedConfigs.slice(offset, offset + perPage),\n total: clonedConfigs.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedConfigs.length,\n };\n }\n\n // ==========================================================================\n // Workspace Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateWorkspaceVersionInput): Promise<WorkspaceVersion> {\n // Check if version with this ID already exists\n if (this.db.workspaceVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (workspaceId, versionNumber) pair\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === input.workspaceId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for workspace ${input.workspaceId}`);\n }\n }\n\n const version: WorkspaceVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.workspaceVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<WorkspaceVersion | null> {\n const version = this.db.workspaceVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(workspaceId: string, versionNumber: number): Promise<WorkspaceVersion | null> {\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === workspaceId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(workspaceId: string): Promise<WorkspaceVersion | null> {\n let latest: WorkspaceVersion | null = null;\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === workspaceId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListWorkspaceVersionsInput): Promise<ListWorkspaceVersionsOutput> {\n const { workspaceId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by workspaceId\n let versions = Array.from(this.db.workspaceVersions.values()).filter(v => v.workspaceId === workspaceId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.workspaceVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.workspaceVersions.entries()) {\n if (version.workspaceId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.workspaceVersions.delete(id);\n }\n }\n\n async countVersions(workspaceId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === workspaceId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyConfig(config: StorageWorkspaceType): StorageWorkspaceType {\n return {\n ...config,\n metadata: config.metadata ? { ...config.metadata } : config.metadata,\n };\n }\n\n private deepCopyVersion(version: WorkspaceVersion): WorkspaceVersion {\n return structuredClone(version);\n }\n\n private sortConfigs(\n configs: StorageWorkspaceType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageWorkspaceType[] {\n return configs.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: WorkspaceVersion[],\n field: WorkspaceVersionOrderBy,\n direction: WorkspaceVersionSortDirection,\n ): WorkspaceVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageWorkspaceType,\n StorageCreateWorkspaceInput,\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput,\n StorageListWorkspacesOutput,\n} from '../../types';\nimport type {\n WorkspaceVersion,\n CreateWorkspaceVersionInput,\n ListWorkspaceVersionsInput,\n ListWorkspaceVersionsOutput,\n} from './base';\nimport { WorkspacesStorage } from './base';\n\nexport class FilesystemWorkspacesStorage extends WorkspacesStorage {\n private helpers: FilesystemVersionedHelpers<StorageWorkspaceType, WorkspaceVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'workspaces.json',\n parentIdField: 'workspaceId',\n name: 'FilesystemWorkspacesStorage',\n versionMetadataFields: ['id', 'workspaceId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageWorkspaceType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { workspace: StorageCreateWorkspaceInput }): Promise<StorageWorkspaceType> {\n const { workspace } = input;\n const now = new Date();\n const entity: StorageWorkspaceType = {\n id: workspace.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: workspace.authorId,\n metadata: workspace.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(workspace.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n workspaceId: workspace.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateWorkspaceVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateWorkspaceInput): Promise<StorageWorkspaceType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListWorkspacesInput): Promise<StorageListWorkspacesOutput> {\n const { page, perPage, orderBy, authorId, metadata } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'workspaces',\n filters: { authorId, metadata },\n });\n return result as unknown as StorageListWorkspacesOutput;\n }\n\n async createVersion(input: CreateWorkspaceVersionInput): Promise<WorkspaceVersion> {\n return this.helpers.createVersion(input as WorkspaceVersion);\n }\n\n async getVersion(id: string): Promise<WorkspaceVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(workspaceId: string, versionNumber: number): Promise<WorkspaceVersion | null> {\n return this.helpers.getVersionByNumber(workspaceId, versionNumber);\n }\n\n async getLatestVersion(workspaceId: string): Promise<WorkspaceVersion | null> {\n return this.helpers.getLatestVersion(workspaceId);\n }\n\n async listVersions(input: ListWorkspaceVersionsInput): Promise<ListWorkspaceVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'workspaceId');\n return result as ListWorkspaceVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(workspaceId: string): Promise<number> {\n return this.helpers.countVersions(workspaceId);\n }\n}\n"]} |
| 'use strict'; | ||
| var chunk2UAP4LDC_cjs = require('./chunk-2UAP4LDC.cjs'); | ||
| var chunkBP67LMWW_cjs = require('./chunk-BP67LMWW.cjs'); | ||
| // src/storage/domains/mcp-servers/base.ts | ||
| var MCPServersStorage = class extends chunk2UAP4LDC_cjs.VersionedStorageDomain { | ||
| listKey = "mcpServers"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "mcpServerId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "MCP_SERVERS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-servers/inmemory.ts | ||
| var InMemoryMCPServersStorage = class extends MCPServersStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.mcpServers.clear(); | ||
| this.db.mcpServerVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // MCP Server CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const config = this.db.mcpServers.get(id); | ||
| return config ? this.deepCopyConfig(config) : null; | ||
| } | ||
| async create(input) { | ||
| const { mcpServer } = input; | ||
| if (this.db.mcpServers.has(mcpServer.id)) { | ||
| throw new Error(`MCP server with id ${mcpServer.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newConfig = { | ||
| id: mcpServer.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpServer.authorId, | ||
| metadata: mcpServer.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.mcpServers.set(mcpServer.id, newConfig); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpServerId: mcpServer.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyConfig(newConfig); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingConfig = this.db.mcpServers.get(id); | ||
| if (!existingConfig) { | ||
| throw new Error(`MCP server with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedConfig = { | ||
| ...existingConfig, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingConfig.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpServers.set(id, updatedConfig); | ||
| return this.deepCopyConfig(updatedConfig); | ||
| } | ||
| async delete(id) { | ||
| this.db.mcpServers.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status = "published" } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let configs = Array.from(this.db.mcpServers.values()); | ||
| if (status) { | ||
| configs = configs.filter((config) => config.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| configs = configs.filter((config) => config.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| configs = configs.filter((config) => { | ||
| if (!config.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => chunkBP67LMWW_cjs.deepEqual(config.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedConfigs = this.sortConfigs(configs, field, direction); | ||
| const clonedConfigs = sortedConfigs.map((config) => this.deepCopyConfig(config)); | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| mcpServers: clonedConfigs.slice(offset, offset + perPage), | ||
| total: clonedConfigs.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedConfigs.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // MCP Server Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.mcpServerVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.mcpServerVersions.values()) { | ||
| if (version2.mcpServerId === input.mcpServerId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for MCP server ${input.mcpServerId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpServerVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.mcpServerVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(mcpServerId, versionNumber) { | ||
| for (const version of this.db.mcpServerVersions.values()) { | ||
| if (version.mcpServerId === mcpServerId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(mcpServerId) { | ||
| let latest = null; | ||
| for (const version of this.db.mcpServerVersions.values()) { | ||
| if (version.mcpServerId === mcpServerId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { mcpServerId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.mcpServerVersions.values()).filter((v) => v.mcpServerId === mcpServerId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.mcpServerVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.mcpServerVersions.entries()) { | ||
| if (version.mcpServerId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.mcpServerVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(mcpServerId) { | ||
| let count = 0; | ||
| for (const version of this.db.mcpServerVersions.values()) { | ||
| if (version.mcpServerId === mcpServerId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyConfig(config) { | ||
| return { | ||
| ...config, | ||
| metadata: config.metadata ? { ...config.metadata } : config.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| tools: version.tools ? JSON.parse(JSON.stringify(version.tools)) : version.tools, | ||
| agents: version.agents ? JSON.parse(JSON.stringify(version.agents)) : version.agents, | ||
| workflows: version.workflows ? JSON.parse(JSON.stringify(version.workflows)) : version.workflows, | ||
| repository: version.repository ? { ...version.repository } : version.repository, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortConfigs(configs, field, direction) { | ||
| return configs.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-servers/filesystem.ts | ||
| var FilesystemMCPServersStorage = class extends MCPServersStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new chunk2UAP4LDC_cjs.FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "mcp-servers.json", | ||
| parentIdField: "mcpServerId", | ||
| name: "FilesystemMCPServersStorage", | ||
| versionMetadataFields: ["id", "mcpServerId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { mcpServer } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: mcpServer.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpServer.authorId, | ||
| metadata: mcpServer.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(mcpServer.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpServerId: mcpServer.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "mcpServers", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(mcpServerId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(mcpServerId, versionNumber); | ||
| } | ||
| async getLatestVersion(mcpServerId) { | ||
| return this.helpers.getLatestVersion(mcpServerId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "mcpServerId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(mcpServerId) { | ||
| return this.helpers.countVersions(mcpServerId); | ||
| } | ||
| }; | ||
| exports.FilesystemMCPServersStorage = FilesystemMCPServersStorage; | ||
| exports.InMemoryMCPServersStorage = InMemoryMCPServersStorage; | ||
| exports.MCPServersStorage = MCPServersStorage; | ||
| //# sourceMappingURL=chunk-KWXEVPXK.cjs.map | ||
| //# sourceMappingURL=chunk-KWXEVPXK.cjs.map |
| {"version":3,"sources":["../src/storage/domains/mcp-servers/base.ts","../src/storage/domains/mcp-servers/inmemory.ts","../src/storage/domains/mcp-servers/filesystem.ts"],"names":["VersionedStorageDomain","normalizePerPage","deepEqual","calculatePagination","version","FilesystemVersionedHelpers"],"mappings":"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","file":"chunk-KWXEVPXK.cjs","sourcesContent":["import type {\n StorageMCPServerType,\n StorageMCPServerSnapshotType,\n StorageResolvedMCPServerType,\n StorageCreateMCPServerInput,\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput,\n StorageListMCPServersOutput,\n StorageListMCPServersResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// MCP Server Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of an MCP server's content.\n * Server fields are top-level on the version row (no nested snapshot object).\n */\nexport interface MCPServerVersion extends StorageMCPServerSnapshotType, VersionBase {\n /** ID of the MCP server this version belongs to */\n mcpServerId: string;\n}\n\n/**\n * Input for creating a new MCP server version.\n * Server fields are top-level (no nested snapshot object).\n */\nexport interface CreateMCPServerVersionInput extends StorageMCPServerSnapshotType, CreateVersionInputBase {\n /** ID of the MCP server this version belongs to */\n mcpServerId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type MCPServerVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type MCPServerVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing MCP server versions with pagination and sorting.\n */\nexport interface ListMCPServerVersionsInput extends ListVersionsInputBase {\n /** ID of the MCP server to list versions for */\n mcpServerId: string;\n}\n\n/**\n * Output for listing MCP server versions with pagination info.\n */\nexport interface ListMCPServerVersionsOutput extends ListVersionsOutputBase<MCPServerVersion> {}\n\n// ============================================================================\n// MCPServersStorage Base Class\n// ============================================================================\n\nexport abstract class MCPServersStorage extends VersionedStorageDomain<\n StorageMCPServerType,\n StorageMCPServerSnapshotType,\n StorageResolvedMCPServerType,\n MCPServerVersion,\n CreateMCPServerVersionInput,\n ListMCPServerVersionsInput,\n ListMCPServerVersionsOutput,\n { mcpServer: StorageCreateMCPServerInput },\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput | undefined,\n StorageListMCPServersOutput,\n StorageListMCPServersResolvedOutput\n> {\n protected readonly listKey = 'mcpServers';\n protected readonly versionMetadataFields = [\n 'id',\n 'mcpServerId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof MCPServerVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'MCP_SERVERS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageMCPServerType,\n StorageCreateMCPServerInput,\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput,\n StorageListMCPServersOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n MCPServerVersion,\n CreateMCPServerVersionInput,\n ListMCPServerVersionsInput,\n ListMCPServerVersionsOutput,\n MCPServerVersionOrderBy,\n MCPServerVersionSortDirection,\n} from './base';\nimport { MCPServersStorage } from './base';\n\nexport class InMemoryMCPServersStorage extends MCPServersStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.mcpServers.clear();\n this.db.mcpServerVersions.clear();\n }\n\n // ==========================================================================\n // MCP Server CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageMCPServerType | null> {\n const config = this.db.mcpServers.get(id);\n return config ? this.deepCopyConfig(config) : null;\n }\n\n async create(input: { mcpServer: StorageCreateMCPServerInput }): Promise<StorageMCPServerType> {\n const { mcpServer } = input;\n\n if (this.db.mcpServers.has(mcpServer.id)) {\n throw new Error(`MCP server with id ${mcpServer.id} already exists`);\n }\n\n const now = new Date();\n const newConfig: StorageMCPServerType = {\n id: mcpServer.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpServer.authorId,\n metadata: mcpServer.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.mcpServers.set(mcpServer.id, newConfig);\n\n // Extract config fields from the flat input (everything except record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpServerId: mcpServer.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin record\n return this.deepCopyConfig(newConfig);\n }\n\n async update(input: StorageUpdateMCPServerInput): Promise<StorageMCPServerType> {\n const { id, ...updates } = input;\n\n const existingConfig = this.db.mcpServers.get(id);\n if (!existingConfig) {\n throw new Error(`MCP server with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the record\n const updatedConfig: StorageMCPServerType = {\n ...existingConfig,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageMCPServerType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingConfig.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated record\n this.db.mcpServers.set(id, updatedConfig);\n return this.deepCopyConfig(updatedConfig);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.mcpServers.delete(id);\n // Also delete all versions for this server\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListMCPServersInput): Promise<StorageListMCPServersOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status = 'published' } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all MCP servers and apply filters\n let configs = Array.from(this.db.mcpServers.values());\n\n // Filter by status\n if (status) {\n configs = configs.filter(config => config.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n configs = configs.filter(config => config.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n configs = configs.filter(config => {\n if (!config.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata![key], value));\n });\n }\n\n // Sort filtered configs\n const sortedConfigs = this.sortConfigs(configs, field, direction);\n\n // Deep clone to avoid mutation\n const clonedConfigs = sortedConfigs.map(config => this.deepCopyConfig(config));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n mcpServers: clonedConfigs.slice(offset, offset + perPage),\n total: clonedConfigs.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedConfigs.length,\n };\n }\n\n // ==========================================================================\n // MCP Server Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateMCPServerVersionInput): Promise<MCPServerVersion> {\n // Check if version with this ID already exists\n if (this.db.mcpServerVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (mcpServerId, versionNumber) pair\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === input.mcpServerId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for MCP server ${input.mcpServerId}`);\n }\n }\n\n const version: MCPServerVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.mcpServerVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<MCPServerVersion | null> {\n const version = this.db.mcpServerVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(mcpServerId: string, versionNumber: number): Promise<MCPServerVersion | null> {\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === mcpServerId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(mcpServerId: string): Promise<MCPServerVersion | null> {\n let latest: MCPServerVersion | null = null;\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === mcpServerId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListMCPServerVersionsInput): Promise<ListMCPServerVersionsOutput> {\n const { mcpServerId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by mcpServerId\n let versions = Array.from(this.db.mcpServerVersions.values()).filter(v => v.mcpServerId === mcpServerId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.mcpServerVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.mcpServerVersions.entries()) {\n if (version.mcpServerId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.mcpServerVersions.delete(id);\n }\n }\n\n async countVersions(mcpServerId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === mcpServerId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyConfig(config: StorageMCPServerType): StorageMCPServerType {\n return {\n ...config,\n metadata: config.metadata ? { ...config.metadata } : config.metadata,\n };\n }\n\n private deepCopyVersion(version: MCPServerVersion): MCPServerVersion {\n return {\n ...version,\n tools: version.tools ? JSON.parse(JSON.stringify(version.tools)) : version.tools,\n agents: version.agents ? JSON.parse(JSON.stringify(version.agents)) : version.agents,\n workflows: version.workflows ? JSON.parse(JSON.stringify(version.workflows)) : version.workflows,\n repository: version.repository ? { ...version.repository } : version.repository,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortConfigs(\n configs: StorageMCPServerType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageMCPServerType[] {\n return configs.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: MCPServerVersion[],\n field: MCPServerVersionOrderBy,\n direction: MCPServerVersionSortDirection,\n ): MCPServerVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageMCPServerType,\n StorageCreateMCPServerInput,\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput,\n StorageListMCPServersOutput,\n} from '../../types';\nimport type {\n MCPServerVersion,\n CreateMCPServerVersionInput,\n ListMCPServerVersionsInput,\n ListMCPServerVersionsOutput,\n} from './base';\nimport { MCPServersStorage } from './base';\n\nexport class FilesystemMCPServersStorage extends MCPServersStorage {\n private helpers: FilesystemVersionedHelpers<StorageMCPServerType, MCPServerVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'mcp-servers.json',\n parentIdField: 'mcpServerId',\n name: 'FilesystemMCPServersStorage',\n versionMetadataFields: ['id', 'mcpServerId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageMCPServerType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { mcpServer: StorageCreateMCPServerInput }): Promise<StorageMCPServerType> {\n const { mcpServer } = input;\n const now = new Date();\n const entity: StorageMCPServerType = {\n id: mcpServer.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpServer.authorId,\n metadata: mcpServer.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(mcpServer.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpServerId: mcpServer.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateMCPServerVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateMCPServerInput): Promise<StorageMCPServerType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListMCPServersInput): Promise<StorageListMCPServersOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'mcpServers',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListMCPServersOutput;\n }\n\n async createVersion(input: CreateMCPServerVersionInput): Promise<MCPServerVersion> {\n return this.helpers.createVersion(input as MCPServerVersion);\n }\n\n async getVersion(id: string): Promise<MCPServerVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(mcpServerId: string, versionNumber: number): Promise<MCPServerVersion | null> {\n return this.helpers.getVersionByNumber(mcpServerId, versionNumber);\n }\n\n async getLatestVersion(mcpServerId: string): Promise<MCPServerVersion | null> {\n return this.helpers.getLatestVersion(mcpServerId);\n }\n\n async listVersions(input: ListMCPServerVersionsInput): Promise<ListMCPServerVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'mcpServerId');\n return result as ListMCPServerVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(mcpServerId: string): Promise<number> {\n return this.helpers.countVersions(mcpServerId);\n }\n}\n"]} |
| 'use strict'; | ||
| var chunk2UAP4LDC_cjs = require('./chunk-2UAP4LDC.cjs'); | ||
| var chunkBP67LMWW_cjs = require('./chunk-BP67LMWW.cjs'); | ||
| // src/storage/domains/workspaces/base.ts | ||
| var WorkspacesStorage = class extends chunk2UAP4LDC_cjs.VersionedStorageDomain { | ||
| listKey = "workspaces"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "workspaceId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "WORKSPACES" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/workspaces/inmemory.ts | ||
| var InMemoryWorkspacesStorage = class extends WorkspacesStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.workspaces.clear(); | ||
| this.db.workspaceVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Workspace CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const config = this.db.workspaces.get(id); | ||
| return config ? this.deepCopyConfig(config) : null; | ||
| } | ||
| async create(input) { | ||
| const { workspace } = input; | ||
| if (this.db.workspaces.has(workspace.id)) { | ||
| throw new Error(`Workspace with id ${workspace.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newConfig = { | ||
| id: workspace.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: workspace.authorId, | ||
| metadata: workspace.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.workspaces.set(workspace.id, newConfig); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| workspaceId: workspace.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyConfig(newConfig); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingConfig = this.db.workspaces.get(id); | ||
| if (!existingConfig) { | ||
| throw new Error(`Workspace with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status, ...rawConfigFields } = updates; | ||
| const configFields = {}; | ||
| for (const [key, value] of Object.entries(rawConfigFields)) { | ||
| if (value !== void 0) configFields[key] = value; | ||
| } | ||
| const configFieldNames = [ | ||
| "name", | ||
| "description", | ||
| "filesystem", | ||
| "sandbox", | ||
| "mounts", | ||
| "search", | ||
| "skills", | ||
| "tools", | ||
| "autoSync", | ||
| "operationTimeout" | ||
| ]; | ||
| const hasConfigUpdate = configFieldNames.some((field) => field in configFields); | ||
| const updatedConfig = { | ||
| ...existingConfig, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingConfig.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| if (activeVersionId !== void 0 && status === void 0) { | ||
| updatedConfig.status = "published"; | ||
| } | ||
| if (hasConfigUpdate) { | ||
| const latestVersion = await this.getLatestVersion(id); | ||
| if (!latestVersion) { | ||
| throw new Error(`No versions found for workspace ${id}`); | ||
| } | ||
| const { | ||
| id: _versionId, | ||
| workspaceId: _workspaceId, | ||
| versionNumber: _versionNumber, | ||
| changedFields: _changedFields, | ||
| changeMessage: _changeMessage, | ||
| createdAt: _createdAt, | ||
| ...latestConfig | ||
| } = latestVersion; | ||
| const newConfig = { | ||
| ...latestConfig, | ||
| ...configFields | ||
| }; | ||
| const changedFields = configFieldNames.filter( | ||
| (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field]) | ||
| ); | ||
| if (changedFields.length > 0) { | ||
| const newVersionId = crypto.randomUUID(); | ||
| const newVersionNumber = latestVersion.versionNumber + 1; | ||
| await this.createVersion({ | ||
| id: newVersionId, | ||
| workspaceId: id, | ||
| versionNumber: newVersionNumber, | ||
| ...newConfig, | ||
| changedFields, | ||
| changeMessage: `Updated ${changedFields.join(", ")}` | ||
| }); | ||
| } | ||
| } | ||
| this.db.workspaces.set(id, updatedConfig); | ||
| return this.deepCopyConfig(updatedConfig); | ||
| } | ||
| async delete(id) { | ||
| this.db.workspaces.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let configs = Array.from(this.db.workspaces.values()); | ||
| if (authorId !== void 0) { | ||
| configs = configs.filter((config) => config.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| configs = configs.filter((config) => { | ||
| if (!config.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => chunkBP67LMWW_cjs.deepEqual(config.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedConfigs = this.sortConfigs(configs, field, direction); | ||
| const clonedConfigs = sortedConfigs.map((config) => this.deepCopyConfig(config)); | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| workspaces: clonedConfigs.slice(offset, offset + perPage), | ||
| total: clonedConfigs.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedConfigs.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Workspace Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.workspaceVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.workspaceVersions.values()) { | ||
| if (version2.workspaceId === input.workspaceId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for workspace ${input.workspaceId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.workspaceVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.workspaceVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(workspaceId, versionNumber) { | ||
| for (const version of this.db.workspaceVersions.values()) { | ||
| if (version.workspaceId === workspaceId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(workspaceId) { | ||
| let latest = null; | ||
| for (const version of this.db.workspaceVersions.values()) { | ||
| if (version.workspaceId === workspaceId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { workspaceId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.workspaceVersions.values()).filter((v) => v.workspaceId === workspaceId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.workspaceVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.workspaceVersions.entries()) { | ||
| if (version.workspaceId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.workspaceVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(workspaceId) { | ||
| let count = 0; | ||
| for (const version of this.db.workspaceVersions.values()) { | ||
| if (version.workspaceId === workspaceId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyConfig(config) { | ||
| return { | ||
| ...config, | ||
| metadata: config.metadata ? { ...config.metadata } : config.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return structuredClone(version); | ||
| } | ||
| sortConfigs(configs, field, direction) { | ||
| return configs.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/workspaces/filesystem.ts | ||
| var FilesystemWorkspacesStorage = class extends WorkspacesStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new chunk2UAP4LDC_cjs.FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "workspaces.json", | ||
| parentIdField: "workspaceId", | ||
| name: "FilesystemWorkspacesStorage", | ||
| versionMetadataFields: ["id", "workspaceId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { workspace } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: workspace.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: workspace.authorId, | ||
| metadata: workspace.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(workspace.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| workspaceId: workspace.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "workspaces", | ||
| filters: { authorId, metadata } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(workspaceId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(workspaceId, versionNumber); | ||
| } | ||
| async getLatestVersion(workspaceId) { | ||
| return this.helpers.getLatestVersion(workspaceId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "workspaceId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(workspaceId) { | ||
| return this.helpers.countVersions(workspaceId); | ||
| } | ||
| }; | ||
| exports.FilesystemWorkspacesStorage = FilesystemWorkspacesStorage; | ||
| exports.InMemoryWorkspacesStorage = InMemoryWorkspacesStorage; | ||
| exports.WorkspacesStorage = WorkspacesStorage; | ||
| //# sourceMappingURL=chunk-LGSQSQFN.cjs.map | ||
| //# sourceMappingURL=chunk-LGSQSQFN.cjs.map |
| {"version":3,"sources":["../src/storage/domains/workspaces/base.ts","../src/storage/domains/workspaces/inmemory.ts","../src/storage/domains/workspaces/filesystem.ts"],"names":["VersionedStorageDomain","normalizePerPage","deepEqual","calculatePagination","version","FilesystemVersionedHelpers"],"mappings":"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","file":"chunk-LGSQSQFN.cjs","sourcesContent":["import type {\n StorageWorkspaceType,\n StorageWorkspaceSnapshotType,\n StorageResolvedWorkspaceType,\n StorageCreateWorkspaceInput,\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput,\n StorageListWorkspacesOutput,\n StorageListWorkspacesResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// Workspace Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of a workspace's configuration.\n * Config fields are top-level on the version row (no nested snapshot object).\n */\nexport interface WorkspaceVersion extends StorageWorkspaceSnapshotType, VersionBase {\n /** ID of the workspace this version belongs to */\n workspaceId: string;\n}\n\n/**\n * Input for creating a new workspace version.\n * Config fields are top-level (no nested snapshot object).\n */\nexport interface CreateWorkspaceVersionInput extends StorageWorkspaceSnapshotType, CreateVersionInputBase {\n /** ID of the workspace this version belongs to */\n workspaceId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type WorkspaceVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type WorkspaceVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing workspace versions with pagination and sorting.\n */\nexport interface ListWorkspaceVersionsInput extends ListVersionsInputBase {\n /** ID of the workspace to list versions for */\n workspaceId: string;\n}\n\n/**\n * Output for listing workspace versions with pagination info.\n */\nexport interface ListWorkspaceVersionsOutput extends ListVersionsOutputBase<WorkspaceVersion> {}\n\n// ============================================================================\n// WorkspacesStorage Base Class\n// ============================================================================\n\nexport abstract class WorkspacesStorage extends VersionedStorageDomain<\n StorageWorkspaceType,\n StorageWorkspaceSnapshotType,\n StorageResolvedWorkspaceType,\n WorkspaceVersion,\n CreateWorkspaceVersionInput,\n ListWorkspaceVersionsInput,\n ListWorkspaceVersionsOutput,\n { workspace: StorageCreateWorkspaceInput },\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput | undefined,\n StorageListWorkspacesOutput,\n StorageListWorkspacesResolvedOutput\n> {\n protected readonly listKey = 'workspaces';\n protected readonly versionMetadataFields = [\n 'id',\n 'workspaceId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof WorkspaceVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'WORKSPACES',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageWorkspaceType,\n StorageCreateWorkspaceInput,\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput,\n StorageListWorkspacesOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n WorkspaceVersion,\n CreateWorkspaceVersionInput,\n ListWorkspaceVersionsInput,\n ListWorkspaceVersionsOutput,\n WorkspaceVersionOrderBy,\n WorkspaceVersionSortDirection,\n} from './base';\nimport { WorkspacesStorage } from './base';\n\nexport class InMemoryWorkspacesStorage extends WorkspacesStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.workspaces.clear();\n this.db.workspaceVersions.clear();\n }\n\n // ==========================================================================\n // Workspace CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageWorkspaceType | null> {\n const config = this.db.workspaces.get(id);\n return config ? this.deepCopyConfig(config) : null;\n }\n\n async create(input: { workspace: StorageCreateWorkspaceInput }): Promise<StorageWorkspaceType> {\n const { workspace } = input;\n\n if (this.db.workspaces.has(workspace.id)) {\n throw new Error(`Workspace with id ${workspace.id} already exists`);\n }\n\n const now = new Date();\n const newConfig: StorageWorkspaceType = {\n id: workspace.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: workspace.authorId,\n metadata: workspace.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.workspaces.set(workspace.id, newConfig);\n\n // Extract config fields from the flat input (everything except record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n workspaceId: workspace.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin record\n return this.deepCopyConfig(newConfig);\n }\n\n async update(input: StorageUpdateWorkspaceInput): Promise<StorageWorkspaceType> {\n const { id, ...updates } = input;\n\n const existingConfig = this.db.workspaces.get(id);\n if (!existingConfig) {\n throw new Error(`Workspace with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status, ...rawConfigFields } = updates;\n\n // Strip undefined keys so omitted PATCH fields don't overwrite persisted values\n const configFields: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(rawConfigFields)) {\n if (value !== undefined) configFields[key] = value;\n }\n\n // Config field names from StorageWorkspaceSnapshotType\n const configFieldNames = [\n 'name',\n 'description',\n 'filesystem',\n 'sandbox',\n 'mounts',\n 'search',\n 'skills',\n 'tools',\n 'autoSync',\n 'operationTimeout',\n ];\n\n // Check if any config fields are present in the update\n const hasConfigUpdate = configFieldNames.some(field => field in configFields);\n\n // Update metadata fields on the record\n const updatedConfig: StorageWorkspaceType = {\n ...existingConfig,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageWorkspaceType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingConfig.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Auto-set status to 'published' when activeVersionId is set, only if status is not explicitly provided\n if (activeVersionId !== undefined && status === undefined) {\n updatedConfig.status = 'published';\n }\n\n // If config fields are being updated, create a new version\n if (hasConfigUpdate) {\n // Get the latest version to use as base\n const latestVersion = await this.getLatestVersion(id);\n if (!latestVersion) {\n throw new Error(`No versions found for workspace ${id}`);\n }\n\n // Extract config from latest version\n const {\n id: _versionId,\n workspaceId: _workspaceId,\n versionNumber: _versionNumber,\n changedFields: _changedFields,\n changeMessage: _changeMessage,\n createdAt: _createdAt,\n ...latestConfig\n } = latestVersion;\n\n // Merge updates into latest config\n const newConfig = {\n ...latestConfig,\n ...configFields,\n };\n\n // Identify which fields changed\n const changedFields = configFieldNames.filter(\n field =>\n field in configFields &&\n JSON.stringify(configFields[field as keyof typeof configFields]) !==\n JSON.stringify(latestConfig[field as keyof typeof latestConfig]),\n );\n\n // Only create a new version if something actually changed\n if (changedFields.length > 0) {\n const newVersionId = crypto.randomUUID();\n const newVersionNumber = latestVersion.versionNumber + 1;\n\n await this.createVersion({\n id: newVersionId,\n workspaceId: id,\n versionNumber: newVersionNumber,\n ...newConfig,\n changedFields,\n changeMessage: `Updated ${changedFields.join(', ')}`,\n });\n }\n }\n\n // Save the updated record\n this.db.workspaces.set(id, updatedConfig);\n return this.deepCopyConfig(updatedConfig);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.workspaces.delete(id);\n // Also delete all versions for this workspace\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListWorkspacesInput): Promise<StorageListWorkspacesOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all workspaces and apply filters\n let configs = Array.from(this.db.workspaces.values());\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n configs = configs.filter(config => config.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n configs = configs.filter(config => {\n if (!config.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata![key], value));\n });\n }\n\n // Sort filtered configs\n const sortedConfigs = this.sortConfigs(configs, field, direction);\n\n // Deep clone to avoid mutation\n const clonedConfigs = sortedConfigs.map(config => this.deepCopyConfig(config));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n workspaces: clonedConfigs.slice(offset, offset + perPage),\n total: clonedConfigs.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedConfigs.length,\n };\n }\n\n // ==========================================================================\n // Workspace Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateWorkspaceVersionInput): Promise<WorkspaceVersion> {\n // Check if version with this ID already exists\n if (this.db.workspaceVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (workspaceId, versionNumber) pair\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === input.workspaceId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for workspace ${input.workspaceId}`);\n }\n }\n\n const version: WorkspaceVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.workspaceVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<WorkspaceVersion | null> {\n const version = this.db.workspaceVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(workspaceId: string, versionNumber: number): Promise<WorkspaceVersion | null> {\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === workspaceId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(workspaceId: string): Promise<WorkspaceVersion | null> {\n let latest: WorkspaceVersion | null = null;\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === workspaceId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListWorkspaceVersionsInput): Promise<ListWorkspaceVersionsOutput> {\n const { workspaceId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by workspaceId\n let versions = Array.from(this.db.workspaceVersions.values()).filter(v => v.workspaceId === workspaceId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.workspaceVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.workspaceVersions.entries()) {\n if (version.workspaceId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.workspaceVersions.delete(id);\n }\n }\n\n async countVersions(workspaceId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === workspaceId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyConfig(config: StorageWorkspaceType): StorageWorkspaceType {\n return {\n ...config,\n metadata: config.metadata ? { ...config.metadata } : config.metadata,\n };\n }\n\n private deepCopyVersion(version: WorkspaceVersion): WorkspaceVersion {\n return structuredClone(version);\n }\n\n private sortConfigs(\n configs: StorageWorkspaceType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageWorkspaceType[] {\n return configs.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: WorkspaceVersion[],\n field: WorkspaceVersionOrderBy,\n direction: WorkspaceVersionSortDirection,\n ): WorkspaceVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageWorkspaceType,\n StorageCreateWorkspaceInput,\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput,\n StorageListWorkspacesOutput,\n} from '../../types';\nimport type {\n WorkspaceVersion,\n CreateWorkspaceVersionInput,\n ListWorkspaceVersionsInput,\n ListWorkspaceVersionsOutput,\n} from './base';\nimport { WorkspacesStorage } from './base';\n\nexport class FilesystemWorkspacesStorage extends WorkspacesStorage {\n private helpers: FilesystemVersionedHelpers<StorageWorkspaceType, WorkspaceVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'workspaces.json',\n parentIdField: 'workspaceId',\n name: 'FilesystemWorkspacesStorage',\n versionMetadataFields: ['id', 'workspaceId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageWorkspaceType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { workspace: StorageCreateWorkspaceInput }): Promise<StorageWorkspaceType> {\n const { workspace } = input;\n const now = new Date();\n const entity: StorageWorkspaceType = {\n id: workspace.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: workspace.authorId,\n metadata: workspace.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(workspace.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n workspaceId: workspace.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateWorkspaceVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateWorkspaceInput): Promise<StorageWorkspaceType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListWorkspacesInput): Promise<StorageListWorkspacesOutput> {\n const { page, perPage, orderBy, authorId, metadata } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'workspaces',\n filters: { authorId, metadata },\n });\n return result as unknown as StorageListWorkspacesOutput;\n }\n\n async createVersion(input: CreateWorkspaceVersionInput): Promise<WorkspaceVersion> {\n return this.helpers.createVersion(input as WorkspaceVersion);\n }\n\n async getVersion(id: string): Promise<WorkspaceVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(workspaceId: string, versionNumber: number): Promise<WorkspaceVersion | null> {\n return this.helpers.getVersionByNumber(workspaceId, versionNumber);\n }\n\n async getLatestVersion(workspaceId: string): Promise<WorkspaceVersion | null> {\n return this.helpers.getLatestVersion(workspaceId);\n }\n\n async listVersions(input: ListWorkspaceVersionsInput): Promise<ListWorkspaceVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'workspaceId');\n return result as ListWorkspaceVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(workspaceId: string): Promise<number> {\n return this.helpers.countVersions(workspaceId);\n }\n}\n"]} |
| 'use strict'; | ||
| var chunkH3Y3YAMF_cjs = require('./chunk-H3Y3YAMF.cjs'); | ||
| var chunkPUEQNTX6_cjs = require('./chunk-PUEQNTX6.cjs'); | ||
| var web = require('stream/web'); | ||
| var EventEmitter = require('events'); | ||
| function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } | ||
| var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter); | ||
| var MastraAgentNetworkStream = class extends web.ReadableStream { | ||
| #usageCount = { | ||
| inputTokens: 0, | ||
| outputTokens: 0, | ||
| totalTokens: 0, | ||
| cachedInputTokens: 0, | ||
| cacheCreationInputTokens: 0, | ||
| reasoningTokens: 0 | ||
| }; | ||
| #streamPromise; | ||
| #objectPromise; | ||
| #objectStreamController = null; | ||
| #objectStream = null; | ||
| #run; | ||
| runId; | ||
| constructor({ | ||
| createStream, | ||
| run | ||
| }) { | ||
| const deferredPromise = { | ||
| promise: null, | ||
| resolve: null, | ||
| reject: null | ||
| }; | ||
| deferredPromise.promise = new Promise((resolve, reject) => { | ||
| deferredPromise.resolve = resolve; | ||
| deferredPromise.reject = reject; | ||
| }); | ||
| const objectDeferredPromise = { | ||
| promise: null, | ||
| resolve: null, | ||
| reject: null | ||
| }; | ||
| objectDeferredPromise.promise = new Promise((resolve, reject) => { | ||
| objectDeferredPromise.resolve = resolve; | ||
| objectDeferredPromise.reject = reject; | ||
| }); | ||
| let objectStreamController = null; | ||
| const updateUsageCount = (usage) => { | ||
| this.#usageCount.inputTokens += parseInt(usage?.inputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.outputTokens += parseInt(usage?.outputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.totalTokens += parseInt(usage?.totalTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.reasoningTokens += parseInt(usage?.reasoningTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.cachedInputTokens += parseInt(usage?.cachedInputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.cacheCreationInputTokens += parseInt(usage?.cacheCreationInputTokens?.toString() ?? "0", 10); | ||
| }; | ||
| super({ | ||
| start: async (controller) => { | ||
| try { | ||
| const writer = new WritableStream({ | ||
| write: (chunk) => { | ||
| if (chunk.type === "step-output" && chunk.payload?.output?.from === "AGENT" && chunk.payload?.output?.type === "finish" || chunk.type === "step-output" && chunk.payload?.output?.from === "WORKFLOW" && chunk.payload?.output?.type === "finish") { | ||
| const output = chunk.payload?.output; | ||
| if (output && "payload" in output && output.payload) { | ||
| const finishPayload = output.payload; | ||
| if ("usage" in finishPayload && finishPayload.usage) { | ||
| updateUsageCount(finishPayload.usage); | ||
| } else if ("output" in finishPayload && finishPayload.output) { | ||
| const outputPayload = finishPayload.output; | ||
| if ("usage" in outputPayload && outputPayload.usage) { | ||
| updateUsageCount(outputPayload.usage); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| controller.enqueue(chunk); | ||
| } | ||
| }); | ||
| const stream = await createStream(writer); | ||
| const getInnerChunk = (chunk) => { | ||
| if (chunk.type === "workflow-step-output") { | ||
| return getInnerChunk(chunk.payload.output); | ||
| } | ||
| return chunk; | ||
| }; | ||
| let objectResolved = false; | ||
| for await (const chunk of stream) { | ||
| if (chunk.type === "workflow-step-output") { | ||
| const innerChunk = getInnerChunk(chunk); | ||
| if (innerChunk.type === "routing-agent-end" || innerChunk.type === "agent-execution-end" || innerChunk.type === "workflow-execution-end") { | ||
| if (innerChunk.payload?.usage) { | ||
| updateUsageCount(innerChunk.payload.usage); | ||
| } | ||
| } | ||
| if (innerChunk.type === "network-object") { | ||
| if (objectStreamController) { | ||
| objectStreamController.enqueue(innerChunk.payload?.object); | ||
| } | ||
| controller.enqueue(innerChunk); | ||
| } else if (innerChunk.type === "network-object-result") { | ||
| if (!objectResolved) { | ||
| objectResolved = true; | ||
| objectDeferredPromise.resolve(innerChunk.payload?.object); | ||
| if (objectStreamController) { | ||
| objectStreamController.close(); | ||
| } | ||
| } | ||
| controller.enqueue(innerChunk); | ||
| } else if (innerChunk.type === "network-execution-event-finish") { | ||
| const finishPayload = { | ||
| ...innerChunk.payload, | ||
| usage: this.#usageCount | ||
| }; | ||
| controller.enqueue({ ...innerChunk, payload: finishPayload }); | ||
| } else { | ||
| controller.enqueue(innerChunk); | ||
| } | ||
| } | ||
| } | ||
| if (!objectResolved) { | ||
| objectDeferredPromise.resolve(void 0); | ||
| if (objectStreamController) { | ||
| objectStreamController.close(); | ||
| } | ||
| } | ||
| controller.close(); | ||
| deferredPromise.resolve(); | ||
| } catch (error) { | ||
| controller.error(error); | ||
| deferredPromise.reject(error); | ||
| objectDeferredPromise.reject(error); | ||
| if (objectStreamController) { | ||
| objectStreamController.error(error); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| this.#run = run; | ||
| this.#streamPromise = deferredPromise; | ||
| this.runId = run.runId; | ||
| this.#objectPromise = objectDeferredPromise; | ||
| this.#objectStream = new web.ReadableStream({ | ||
| start: (ctrl) => { | ||
| objectStreamController = ctrl; | ||
| this.#objectStreamController = ctrl; | ||
| } | ||
| }); | ||
| } | ||
| get status() { | ||
| return this.#streamPromise.promise.then(() => this.#run._getExecutionResults()).then((res) => res.status); | ||
| } | ||
| get result() { | ||
| return this.#streamPromise.promise.then(() => this.#run._getExecutionResults()); | ||
| } | ||
| get usage() { | ||
| return this.#streamPromise.promise.then(() => this.#usageCount); | ||
| } | ||
| /** | ||
| * Returns a promise that resolves to the structured output object. | ||
| * Only available when structuredOutput option is provided to network(). | ||
| * Resolves to undefined if no structuredOutput was requested. | ||
| */ | ||
| get object() { | ||
| return this.#objectPromise.promise; | ||
| } | ||
| /** | ||
| * Returns a ReadableStream of partial objects during structured output generation. | ||
| * Useful for streaming partial results as they're being generated. | ||
| */ | ||
| get objectStream() { | ||
| return this.#objectStream; | ||
| } | ||
| }; | ||
| // src/stream/aisdk/v5/compat/ui-message.ts | ||
| function convertFullStreamChunkToUIMessageStream({ | ||
| part, | ||
| messageMetadataValue, | ||
| sendReasoning, | ||
| sendSources, | ||
| onError, | ||
| sendStart, | ||
| sendFinish, | ||
| responseMessageId | ||
| }) { | ||
| const partType = part.type; | ||
| switch (partType) { | ||
| case "text-start": { | ||
| return { | ||
| type: "text-start", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "text-delta": { | ||
| return { | ||
| type: "text-delta", | ||
| id: part.id, | ||
| delta: part.text, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "text-end": { | ||
| return { | ||
| type: "text-end", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "reasoning-start": { | ||
| return { | ||
| type: "reasoning-start", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "reasoning-delta": { | ||
| if (sendReasoning) { | ||
| return { | ||
| type: "reasoning-delta", | ||
| id: part.id, | ||
| delta: part.text, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "reasoning-end": { | ||
| return { | ||
| type: "reasoning-end", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "file": { | ||
| return { | ||
| type: "file", | ||
| mediaType: part.file.mediaType, | ||
| url: `data:${part.file.mediaType};base64,${part.file.base64}` | ||
| }; | ||
| } | ||
| case "source": { | ||
| if (sendSources && part.sourceType === "url") { | ||
| return { | ||
| type: "source-url", | ||
| sourceId: part.id, | ||
| url: part.url, | ||
| title: part.title, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| if (sendSources && part.sourceType === "document") { | ||
| return { | ||
| type: "source-document", | ||
| sourceId: part.id, | ||
| mediaType: part.mediaType, | ||
| title: part.title, | ||
| filename: part.filename, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "tool-input-start": { | ||
| return { | ||
| type: "tool-input-start", | ||
| toolCallId: part.id, | ||
| toolName: part.toolName, | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "tool-input-delta": { | ||
| return { | ||
| type: "tool-input-delta", | ||
| toolCallId: part.id, | ||
| inputTextDelta: part.delta | ||
| }; | ||
| } | ||
| case "tool-call": { | ||
| return { | ||
| type: "tool-input-available", | ||
| toolCallId: part.toolCallId, | ||
| toolName: part.toolName, | ||
| input: part.input, | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "tool-result": { | ||
| return { | ||
| type: "tool-output-available", | ||
| toolCallId: part.toolCallId, | ||
| output: part.output, | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "tool-output": { | ||
| return { | ||
| ...part.output | ||
| }; | ||
| } | ||
| case "tool-error": { | ||
| return { | ||
| type: "tool-output-error", | ||
| toolCallId: part.toolCallId, | ||
| errorText: onError(part.error), | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "error": { | ||
| return { | ||
| type: "error", | ||
| errorText: onError(part.error) | ||
| }; | ||
| } | ||
| case "start-step": { | ||
| return { type: "start-step" }; | ||
| } | ||
| case "finish-step": { | ||
| return { type: "finish-step" }; | ||
| } | ||
| case "start": { | ||
| if (sendStart) { | ||
| return { | ||
| type: "start", | ||
| ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {}, | ||
| ...responseMessageId != null ? { messageId: responseMessageId } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "finish": { | ||
| if (sendFinish) { | ||
| return { | ||
| type: "finish", | ||
| ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "abort": { | ||
| return part; | ||
| } | ||
| case "tool-input-end": { | ||
| return; | ||
| } | ||
| case "raw": { | ||
| return; | ||
| } | ||
| default: { | ||
| const exhaustiveCheck = partType; | ||
| throw new Error(`Unknown chunk type: ${exhaustiveCheck}`); | ||
| } | ||
| } | ||
| } | ||
| // src/stream/base/consume-stream.ts | ||
| async function consumeStream({ | ||
| stream, | ||
| onError | ||
| }) { | ||
| const reader = stream.getReader(); | ||
| try { | ||
| while (true) { | ||
| const { done } = await reader.read(); | ||
| if (done) break; | ||
| } | ||
| } catch (error) { | ||
| onError == null ? void 0 : onError(error); | ||
| } finally { | ||
| reader.releaseLock(); | ||
| } | ||
| } | ||
| // src/stream/RunOutput.ts | ||
| var WorkflowRunOutput = class { | ||
| #status = "running"; | ||
| #tripwireData; | ||
| #usageCount = { | ||
| inputTokens: 0, | ||
| outputTokens: 0, | ||
| totalTokens: 0, | ||
| cachedInputTokens: 0, | ||
| cacheCreationInputTokens: 0, | ||
| reasoningTokens: 0 | ||
| }; | ||
| #consumptionStarted = false; | ||
| #baseStream; | ||
| #emitter = new EventEmitter__default.default(); | ||
| #bufferedChunks = []; | ||
| #streamFinished = false; | ||
| #streamError; | ||
| #delayedPromises = { | ||
| usage: new chunkH3Y3YAMF_cjs.DelayedPromise(), | ||
| result: new chunkH3Y3YAMF_cjs.DelayedPromise() | ||
| }; | ||
| /** | ||
| * Unique identifier for this workflow run | ||
| */ | ||
| runId; | ||
| /** | ||
| * Unique identifier for this workflow | ||
| */ | ||
| workflowId; | ||
| constructor({ | ||
| runId, | ||
| workflowId, | ||
| stream | ||
| }) { | ||
| const self = this; | ||
| this.runId = runId; | ||
| this.workflowId = workflowId; | ||
| this.#baseStream = stream; | ||
| stream.pipeTo( | ||
| new web.WritableStream({ | ||
| start() { | ||
| const chunk = { | ||
| type: "workflow-start", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowId: self.workflowId | ||
| } | ||
| }; | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| }, | ||
| write(chunk) { | ||
| if (chunk.type !== "workflow-step-finish") { | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| } | ||
| if (chunk.type === "workflow-step-output") { | ||
| if ("output" in chunk.payload && chunk.payload.output) { | ||
| const output = chunk.payload.output; | ||
| if (output.type === "finish") { | ||
| if (output.payload && "usage" in output.payload && output.payload.usage) { | ||
| self.#updateUsageCount(output.payload.usage); | ||
| } else if (output.payload && "output" in output.payload && output.payload.output) { | ||
| const outputPayload = output.payload.output; | ||
| if ("usage" in outputPayload && outputPayload.usage) { | ||
| self.#updateUsageCount(outputPayload.usage); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } else if (chunk.type === "workflow-canceled") { | ||
| self.#status = "canceled"; | ||
| } else if (chunk.type === "workflow-step-suspended") { | ||
| self.#status = "suspended"; | ||
| } else if (chunk.type === "workflow-step-result" && chunk.payload.status === "failed") { | ||
| if (chunk.payload.tripwire) { | ||
| self.#status = "tripwire"; | ||
| self.#tripwireData = chunk.payload.tripwire; | ||
| } else { | ||
| self.#status = "failed"; | ||
| } | ||
| } else if (chunk.type === "workflow-paused") { | ||
| self.#status = "paused"; | ||
| } | ||
| }, | ||
| close() { | ||
| if (self.#status === "running") { | ||
| self.#status = "success"; | ||
| } | ||
| self.#emitter.emit("chunk", { | ||
| type: "workflow-finish", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowStatus: self.#status, | ||
| metadata: self.#streamError ? { | ||
| error: self.#streamError, | ||
| errorMessage: self.#streamError?.message | ||
| } : {}, | ||
| output: { | ||
| usage: self.#usageCount | ||
| }, | ||
| // Include tripwire data when status is 'tripwire' | ||
| ...self.#status === "tripwire" && self.#tripwireData ? { tripwire: self.#tripwireData } : {} | ||
| } | ||
| }); | ||
| self.#delayedPromises.usage.resolve(self.#usageCount); | ||
| Object.entries(self.#delayedPromises).forEach(([key, promise]) => { | ||
| if (promise.status.type === "pending") { | ||
| promise.reject(new Error(`promise '${key}' was not resolved or rejected when stream finished`)); | ||
| } | ||
| }); | ||
| self.#streamFinished = true; | ||
| self.#emitter.emit("finish"); | ||
| } | ||
| }) | ||
| ).catch((reason) => { | ||
| console.log(" something went wrong", reason); | ||
| }); | ||
| } | ||
| #getDelayedPromise(promise) { | ||
| if (!this.#consumptionStarted) { | ||
| void this.consumeStream(); | ||
| } | ||
| return promise.promise; | ||
| } | ||
| #updateUsageCount(usage) { | ||
| let totalUsage = { | ||
| inputTokens: this.#usageCount.inputTokens ?? 0, | ||
| outputTokens: this.#usageCount.outputTokens ?? 0, | ||
| totalTokens: this.#usageCount.totalTokens ?? 0, | ||
| reasoningTokens: this.#usageCount.reasoningTokens ?? 0, | ||
| cachedInputTokens: this.#usageCount.cachedInputTokens ?? 0, | ||
| cacheCreationInputTokens: this.#usageCount.cacheCreationInputTokens ?? 0 | ||
| }; | ||
| if ("inputTokens" in usage) { | ||
| totalUsage.inputTokens += parseInt(usage?.inputTokens?.toString() ?? "0", 10); | ||
| totalUsage.outputTokens += parseInt(usage?.outputTokens?.toString() ?? "0", 10); | ||
| } else if ("promptTokens" in usage) { | ||
| totalUsage.inputTokens += parseInt(usage?.promptTokens?.toString() ?? "0", 10); | ||
| totalUsage.outputTokens += parseInt(usage?.completionTokens?.toString() ?? "0", 10); | ||
| } | ||
| totalUsage.totalTokens += parseInt(usage?.totalTokens?.toString() ?? "0", 10); | ||
| totalUsage.reasoningTokens += parseInt(usage?.reasoningTokens?.toString() ?? "0", 10); | ||
| totalUsage.cachedInputTokens += parseInt(usage?.cachedInputTokens?.toString() ?? "0", 10); | ||
| totalUsage.cacheCreationInputTokens += parseInt(usage?.cacheCreationInputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount = totalUsage; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| updateResults(results) { | ||
| this.#delayedPromises.result.resolve(results); | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| rejectResults(error) { | ||
| this.#delayedPromises.result.reject(error); | ||
| this.#status = "failed"; | ||
| this.#streamError = error; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| resume(stream) { | ||
| this.#baseStream = stream; | ||
| this.#streamFinished = false; | ||
| this.#consumptionStarted = false; | ||
| this.#status = "running"; | ||
| this.#delayedPromises = { | ||
| usage: new chunkH3Y3YAMF_cjs.DelayedPromise(), | ||
| result: new chunkH3Y3YAMF_cjs.DelayedPromise() | ||
| }; | ||
| const self = this; | ||
| stream.pipeTo( | ||
| new web.WritableStream({ | ||
| start() { | ||
| const chunk = { | ||
| type: "workflow-start", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowId: self.workflowId | ||
| } | ||
| }; | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| }, | ||
| write(chunk) { | ||
| if (chunk.type !== "workflow-step-finish") { | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| } | ||
| if (chunk.type === "workflow-step-output") { | ||
| if ("output" in chunk.payload && chunk.payload.output) { | ||
| const output = chunk.payload.output; | ||
| if (output.type === "finish") { | ||
| if (output.payload && "usage" in output.payload && output.payload.usage) { | ||
| self.#updateUsageCount(output.payload.usage); | ||
| } else if (output.payload && "output" in output.payload && output.payload.output) { | ||
| const outputPayload = output.payload.output; | ||
| if ("usage" in outputPayload && outputPayload.usage) { | ||
| self.#updateUsageCount(outputPayload.usage); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } else if (chunk.type === "workflow-canceled") { | ||
| self.#status = "canceled"; | ||
| } else if (chunk.type === "workflow-step-suspended") { | ||
| self.#status = "suspended"; | ||
| } else if (chunk.type === "workflow-step-result" && chunk.payload.status === "failed") { | ||
| if (chunk.payload.tripwire) { | ||
| self.#status = "tripwire"; | ||
| self.#tripwireData = chunk.payload.tripwire; | ||
| } else { | ||
| self.#status = "failed"; | ||
| } | ||
| } else if (chunk.type === "workflow-paused") { | ||
| self.#status = "paused"; | ||
| } | ||
| }, | ||
| close() { | ||
| if (self.#status === "running") { | ||
| self.#status = "success"; | ||
| } | ||
| self.#emitter.emit("chunk", { | ||
| type: "workflow-finish", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowStatus: self.#status, | ||
| metadata: self.#streamError ? { | ||
| error: self.#streamError, | ||
| errorMessage: self.#streamError?.message | ||
| } : {}, | ||
| output: { | ||
| usage: self.#usageCount | ||
| }, | ||
| // Include tripwire data when status is 'tripwire' | ||
| ...self.#status === "tripwire" && self.#tripwireData ? { tripwire: self.#tripwireData } : {} | ||
| } | ||
| }); | ||
| self.#streamFinished = true; | ||
| self.#emitter.emit("finish"); | ||
| } | ||
| }) | ||
| ).catch((reason) => { | ||
| console.log(" something went wrong", reason); | ||
| }); | ||
| } | ||
| async consumeStream(options) { | ||
| if (this.#consumptionStarted) { | ||
| return; | ||
| } | ||
| this.#consumptionStarted = true; | ||
| try { | ||
| await consumeStream({ | ||
| stream: this.#baseStream, | ||
| onError: options?.onError | ||
| }); | ||
| } catch (error) { | ||
| options?.onError?.(error); | ||
| } | ||
| } | ||
| get fullStream() { | ||
| const self = this; | ||
| return new web.ReadableStream({ | ||
| start(controller) { | ||
| self.#bufferedChunks.forEach((chunk) => { | ||
| controller.enqueue(chunk); | ||
| }); | ||
| if (self.#streamFinished) { | ||
| controller.close(); | ||
| return; | ||
| } | ||
| const chunkHandler = (chunk) => { | ||
| controller.enqueue(chunk); | ||
| }; | ||
| const finishHandler = () => { | ||
| self.#emitter.off("chunk", chunkHandler); | ||
| self.#emitter.off("finish", finishHandler); | ||
| controller.close(); | ||
| }; | ||
| self.#emitter.on("chunk", chunkHandler); | ||
| self.#emitter.on("finish", finishHandler); | ||
| }, | ||
| pull(_controller) { | ||
| if (!self.#consumptionStarted) { | ||
| void self.consumeStream(); | ||
| } | ||
| }, | ||
| cancel() { | ||
| self.#emitter.removeAllListeners(); | ||
| } | ||
| }); | ||
| } | ||
| get status() { | ||
| return this.#status; | ||
| } | ||
| get result() { | ||
| return this.#getDelayedPromise(this.#delayedPromises.result); | ||
| } | ||
| get usage() { | ||
| return this.#getDelayedPromise(this.#delayedPromises.usage); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.locked` instead | ||
| */ | ||
| get locked() { | ||
| console.warn("WorkflowRunOutput.locked is deprecated. Use fullStream.locked instead."); | ||
| return this.fullStream.locked; | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.cancel()` instead | ||
| */ | ||
| cancel(reason) { | ||
| console.warn("WorkflowRunOutput.cancel() is deprecated. Use fullStream.cancel() instead."); | ||
| return this.fullStream.cancel(reason); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.getReader()` instead | ||
| */ | ||
| getReader(options) { | ||
| console.warn("WorkflowRunOutput.getReader() is deprecated. Use fullStream.getReader() instead."); | ||
| return this.fullStream.getReader(options); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.pipeThrough()` instead | ||
| */ | ||
| pipeThrough(transform, options) { | ||
| console.warn("WorkflowRunOutput.pipeThrough() is deprecated. Use fullStream.pipeThrough() instead."); | ||
| return this.fullStream.pipeThrough(transform, options); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.pipeTo()` instead | ||
| */ | ||
| pipeTo(destination, options) { | ||
| console.warn("WorkflowRunOutput.pipeTo() is deprecated. Use fullStream.pipeTo() instead."); | ||
| return this.fullStream.pipeTo(destination, options); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.tee()` instead | ||
| */ | ||
| tee() { | ||
| console.warn("WorkflowRunOutput.tee() is deprecated. Use fullStream.tee() instead."); | ||
| return this.fullStream.tee(); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream[Symbol.asyncIterator]()` instead | ||
| */ | ||
| [Symbol.asyncIterator]() { | ||
| console.warn( | ||
| "WorkflowRunOutput[Symbol.asyncIterator]() is deprecated. Use fullStream[Symbol.asyncIterator]() instead." | ||
| ); | ||
| return this.fullStream[Symbol.asyncIterator](); | ||
| } | ||
| /** | ||
| * Helper method to treat this object as a ReadableStream | ||
| * @deprecated Use `fullStream` directly instead | ||
| */ | ||
| toReadableStream() { | ||
| console.warn("WorkflowRunOutput.toReadableStream() is deprecated. Use fullStream directly instead."); | ||
| return this.fullStream; | ||
| } | ||
| }; | ||
| // src/stream/aisdk/v5/transform.ts | ||
| function sanitizeToolCallInput(input) { | ||
| try { | ||
| JSON.parse(input); | ||
| return input; | ||
| } catch { | ||
| return input.replace(/[\s]*<\|[^|]*\|>[\s]*/g, "").trim(); | ||
| } | ||
| } | ||
| function tryRepairJson(input) { | ||
| let repaired = input.trim(); | ||
| repaired = repaired.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)"/g, (match, prefix, name) => { | ||
| if (prefix.trimEnd().endsWith('"')) { | ||
| return match; | ||
| } | ||
| return `${prefix}"${name}"`; | ||
| }); | ||
| repaired = repaired.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g, '$1"$2":'); | ||
| repaired = repaired.replace(/'/g, '"'); | ||
| repaired = repaired.replace(/,(\s*[}\]])/g, "$1"); | ||
| repaired = repaired.replace(/:\s*(\d{4}-\d{2}-\d{2}(?:T[\d:]+)?)\s*([,}])/g, ': "$1"$2'); | ||
| try { | ||
| return JSON.parse(repaired); | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
| function convertFullStreamChunkToMastra(value, ctx) { | ||
| switch (value.type) { | ||
| case "response-metadata": | ||
| return { | ||
| type: "response-metadata", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { ...value } | ||
| }; | ||
| case "text-start": | ||
| return { | ||
| type: "text-start", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "text-delta": | ||
| if (value.delta) { | ||
| return { | ||
| type: "text-delta", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata, | ||
| text: value.delta | ||
| } | ||
| }; | ||
| } | ||
| return; | ||
| case "text-end": | ||
| return { | ||
| type: "text-end", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: value | ||
| }; | ||
| case "reasoning-start": | ||
| return { | ||
| type: "reasoning-start", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "reasoning-delta": | ||
| return { | ||
| type: "reasoning-delta", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata, | ||
| text: value.delta | ||
| } | ||
| }; | ||
| case "reasoning-end": | ||
| return { | ||
| type: "reasoning-end", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "source": | ||
| return { | ||
| type: "source", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| sourceType: value.sourceType, | ||
| title: value.title || "", | ||
| mimeType: value.sourceType === "document" ? value.mediaType : void 0, | ||
| filename: value.sourceType === "document" ? value.filename : void 0, | ||
| url: value.sourceType === "url" ? value.url : void 0, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "file": { | ||
| const pm = value.providerMetadata; | ||
| return { | ||
| type: "file", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| data: value.data, | ||
| base64: typeof value.data === "string" ? value.data : void 0, | ||
| mimeType: value.mediaType, | ||
| ...pm != null ? { providerMetadata: pm } : {} | ||
| } | ||
| }; | ||
| } | ||
| case "tool-call": { | ||
| let toolCallInput = void 0; | ||
| if (value.input) { | ||
| const sanitized = sanitizeToolCallInput(value.input); | ||
| if (sanitized) { | ||
| try { | ||
| toolCallInput = JSON.parse(sanitized); | ||
| } catch { | ||
| const repaired = tryRepairJson(sanitized); | ||
| if (repaired) { | ||
| toolCallInput = repaired; | ||
| } else { | ||
| console.error("Error converting tool call input to JSON", { | ||
| input: value.input | ||
| }); | ||
| toolCallInput = void 0; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return { | ||
| type: "tool-call", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.toolCallId, | ||
| toolName: value.toolName, | ||
| args: toolCallInput, | ||
| providerExecuted: value.providerExecuted, | ||
| providerMetadata: value.providerMetadata, | ||
| ...value.observability ? { observability: value.observability } : {} | ||
| } | ||
| }; | ||
| } | ||
| case "tool-result": | ||
| return { | ||
| type: "tool-result", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.toolCallId, | ||
| toolName: value.toolName, | ||
| result: value.result, | ||
| isError: value.isError, | ||
| providerExecuted: value.providerExecuted, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "tool-input-start": | ||
| return { | ||
| type: "tool-call-input-streaming-start", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.id, | ||
| toolName: value.toolName, | ||
| providerExecuted: value.providerExecuted, | ||
| providerMetadata: value.providerMetadata, | ||
| dynamic: value.dynamic, | ||
| ...value.observability ? { observability: value.observability } : {} | ||
| } | ||
| }; | ||
| case "tool-input-delta": | ||
| if (value.delta) { | ||
| return { | ||
| type: "tool-call-delta", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| argsTextDelta: value.delta, | ||
| toolCallId: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| } | ||
| return; | ||
| case "tool-input-end": | ||
| return { | ||
| type: "tool-call-input-streaming-end", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "finish": | ||
| const { finishReason, usage, providerMetadata, messages, ...rest } = value; | ||
| return { | ||
| type: "finish", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| providerMetadata: value.providerMetadata, | ||
| stepResult: { | ||
| reason: normalizeFinishReason(value.finishReason) | ||
| }, | ||
| output: { | ||
| // Normalize usage to handle both V2 (flat) and V3 (nested) formats | ||
| usage: normalizeUsage(value.usage) | ||
| }, | ||
| metadata: { | ||
| providerMetadata: value.providerMetadata | ||
| }, | ||
| messages: messages ?? { | ||
| all: [], | ||
| user: [], | ||
| nonUser: [] | ||
| }, | ||
| ...rest | ||
| } | ||
| }; | ||
| case "error": | ||
| return { | ||
| type: "error", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: value | ||
| }; | ||
| case "raw": | ||
| return { | ||
| type: "raw", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: value.rawValue | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| function convertMastraChunkToAISDKv5({ | ||
| chunk, | ||
| mode = "stream" | ||
| }) { | ||
| switch (chunk.type) { | ||
| case "start": | ||
| return { | ||
| type: "start" | ||
| }; | ||
| case "step-start": | ||
| const { messageId: _messageId, ...rest } = chunk.payload; | ||
| return { | ||
| type: "start-step", | ||
| request: rest.request, | ||
| warnings: rest.warnings || [] | ||
| }; | ||
| case "raw": | ||
| return { | ||
| type: "raw", | ||
| rawValue: chunk.payload | ||
| }; | ||
| case "finish": { | ||
| return { | ||
| type: "finish", | ||
| // Cast needed: Mastra extends reason with 'tripwire' | 'retry' for processor scenarios | ||
| finishReason: chunk.payload.stepResult.reason, | ||
| // Cast needed: Mastra's LanguageModelUsage has optional properties, V2 has required-but-nullable | ||
| totalUsage: chunk.payload.output.usage | ||
| }; | ||
| } | ||
| case "reasoning-start": | ||
| return { | ||
| type: "reasoning-start", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "reasoning-delta": | ||
| return { | ||
| type: "reasoning-delta", | ||
| id: chunk.payload.id, | ||
| text: chunk.payload.text, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "reasoning-signature": | ||
| throw new Error('AISDKv5 chunk type "reasoning-signature" not supported'); | ||
| case "redacted-reasoning": | ||
| throw new Error('AISDKv5 chunk type "redacted-reasoning" not supported'); | ||
| case "reasoning-end": | ||
| return { | ||
| type: "reasoning-end", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "source": | ||
| if (chunk.payload.sourceType === "url") { | ||
| return { | ||
| type: "source", | ||
| sourceType: "url", | ||
| id: chunk.payload.id, | ||
| url: chunk.payload.url, | ||
| title: chunk.payload.title, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| } else { | ||
| return { | ||
| type: "source", | ||
| sourceType: "document", | ||
| id: chunk.payload.id, | ||
| mediaType: chunk.payload.mimeType, | ||
| title: chunk.payload.title, | ||
| filename: chunk.payload.filename, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| } | ||
| case "file": { | ||
| const filePart = mode === "generate" ? { | ||
| type: "file", | ||
| file: new chunkPUEQNTX6_cjs.DefaultGeneratedFile({ | ||
| data: chunk.payload.data, | ||
| mediaType: chunk.payload.mimeType | ||
| }) | ||
| } : { | ||
| type: "file", | ||
| file: new chunkPUEQNTX6_cjs.DefaultGeneratedFileWithType({ | ||
| data: chunk.payload.data, | ||
| mediaType: chunk.payload.mimeType | ||
| }) | ||
| }; | ||
| if (chunk.payload.providerMetadata) { | ||
| filePart.providerMetadata = chunk.payload.providerMetadata; | ||
| } | ||
| return filePart; | ||
| } | ||
| case "tool-call": { | ||
| const toolCallPart = { | ||
| type: "tool-call", | ||
| toolCallId: chunk.payload.toolCallId, | ||
| providerMetadata: chunk.payload.providerMetadata, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| toolName: chunk.payload.toolName, | ||
| input: chunk.payload.args | ||
| }; | ||
| if (chunk.payload.observability) { | ||
| toolCallPart.observability = chunk.payload.observability; | ||
| } | ||
| return toolCallPart; | ||
| } | ||
| case "tool-call-input-streaming-start": | ||
| return { | ||
| type: "tool-input-start", | ||
| id: chunk.payload.toolCallId, | ||
| toolName: chunk.payload.toolName, | ||
| dynamic: !!chunk.payload.dynamic, | ||
| providerMetadata: chunk.payload.providerMetadata, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| ...chunk.payload.observability ? { observability: chunk.payload.observability } : {} | ||
| }; | ||
| case "tool-call-input-streaming-end": | ||
| return { | ||
| type: "tool-input-end", | ||
| id: chunk.payload.toolCallId, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "tool-call-delta": | ||
| return { | ||
| type: "tool-input-delta", | ||
| id: chunk.payload.toolCallId, | ||
| delta: chunk.payload.argsTextDelta, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "step-finish": { | ||
| const { request: _request, providerMetadata: metadataProviderMetadata, ...rest2 } = chunk.payload.metadata; | ||
| return { | ||
| type: "finish-step", | ||
| response: { | ||
| id: chunk.payload.id || "", | ||
| timestamp: /* @__PURE__ */ new Date(), | ||
| modelId: rest2.modelId || "", | ||
| ...rest2 | ||
| }, | ||
| usage: chunk.payload.output.usage, | ||
| finishReason: chunk.payload.stepResult.reason, | ||
| providerMetadata: metadataProviderMetadata ?? chunk.payload.providerMetadata | ||
| }; | ||
| } | ||
| case "text-delta": | ||
| return { | ||
| type: "text-delta", | ||
| id: chunk.payload.id, | ||
| text: chunk.payload.text, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "text-end": | ||
| return { | ||
| type: "text-end", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "text-start": | ||
| return { | ||
| type: "text-start", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "tool-result": | ||
| return { | ||
| type: "tool-result", | ||
| input: chunk.payload.args, | ||
| toolCallId: chunk.payload.toolCallId, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| toolName: chunk.payload.toolName, | ||
| output: chunk.payload.result | ||
| // providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this? | ||
| }; | ||
| case "tool-error": | ||
| return { | ||
| type: "tool-error", | ||
| error: chunk.payload.error, | ||
| input: chunk.payload.args, | ||
| toolCallId: chunk.payload.toolCallId, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| toolName: chunk.payload.toolName | ||
| // providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this? | ||
| }; | ||
| case "abort": | ||
| return { | ||
| type: "abort" | ||
| }; | ||
| case "error": | ||
| return { | ||
| type: "error", | ||
| error: chunk.payload.error | ||
| }; | ||
| case "object": | ||
| return { | ||
| type: "object", | ||
| object: chunk.object | ||
| }; | ||
| default: | ||
| if (chunk.type && "payload" in chunk && chunk.payload) { | ||
| return { | ||
| type: chunk.type, | ||
| ...chunk.payload || {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| } | ||
| function isV3Usage(usage) { | ||
| if (!usage || typeof usage !== "object") return false; | ||
| const u = usage; | ||
| return typeof u.inputTokens === "object" && u.inputTokens !== null && "total" in u.inputTokens && typeof u.outputTokens === "object" && u.outputTokens !== null && "total" in u.outputTokens; | ||
| } | ||
| function normalizeUsage(usage) { | ||
| if (!usage) { | ||
| return { | ||
| inputTokens: void 0, | ||
| outputTokens: void 0, | ||
| totalTokens: void 0, | ||
| reasoningTokens: void 0, | ||
| cachedInputTokens: void 0, | ||
| cacheCreationInputTokens: void 0, | ||
| raw: void 0 | ||
| }; | ||
| } | ||
| if (isV3Usage(usage)) { | ||
| const inputTokens = usage.inputTokens.total; | ||
| const outputTokens = usage.outputTokens.total; | ||
| return { | ||
| inputTokens, | ||
| outputTokens, | ||
| totalTokens: (inputTokens ?? 0) + (outputTokens ?? 0), | ||
| reasoningTokens: usage.outputTokens.reasoning, | ||
| cachedInputTokens: usage.inputTokens.cacheRead, | ||
| cacheCreationInputTokens: usage.inputTokens.cacheWrite, | ||
| raw: usage | ||
| }; | ||
| } | ||
| const v2Usage = usage; | ||
| return { | ||
| inputTokens: v2Usage.inputTokens, | ||
| outputTokens: v2Usage.outputTokens, | ||
| totalTokens: v2Usage.totalTokens ?? (v2Usage.inputTokens ?? 0) + (v2Usage.outputTokens ?? 0), | ||
| reasoningTokens: v2Usage.reasoningTokens, | ||
| cachedInputTokens: v2Usage.cachedInputTokens, | ||
| cacheCreationInputTokens: v2Usage.cacheCreationInputTokens, | ||
| raw: usage | ||
| }; | ||
| } | ||
| function isV3FinishReason(finishReason) { | ||
| return typeof finishReason === "object" && finishReason !== null && "unified" in finishReason; | ||
| } | ||
| function normalizeFinishReason(finishReason) { | ||
| if (!finishReason) { | ||
| return "other"; | ||
| } | ||
| if (finishReason === "tripwire" || finishReason === "retry") { | ||
| return finishReason; | ||
| } | ||
| if (isV3FinishReason(finishReason)) { | ||
| return finishReason.unified; | ||
| } | ||
| return finishReason === "unknown" ? "other" : finishReason; | ||
| } | ||
| // src/stream/caching-transform-stream.ts | ||
| function createCachingTransformStream(options) { | ||
| const { cache, cacheKey, serialize = (x) => x, deserialize = (x) => x } = options; | ||
| const transform = new TransformStream({ | ||
| transform(chunk, controller) { | ||
| const serialized = serialize(chunk); | ||
| cache.listPush(cacheKey, serialized).catch(() => { | ||
| }); | ||
| controller.enqueue(chunk); | ||
| } | ||
| }); | ||
| const getHistory = async (offset = 0) => { | ||
| const cached = await cache.listFromTo(cacheKey, offset); | ||
| return cached.map((item) => deserialize(item)); | ||
| }; | ||
| const clearCache = async () => { | ||
| await cache.delete(cacheKey); | ||
| }; | ||
| return { transform, getHistory, clearCache }; | ||
| } | ||
| function createReplayStream(options) { | ||
| const { history, liveSource, cache, cacheKey, serialize = (x) => x } = options; | ||
| let historyIndex = 0; | ||
| let liveReader = null; | ||
| let historyComplete = false; | ||
| return new ReadableStream({ | ||
| async pull(controller) { | ||
| if (!historyComplete) { | ||
| if (historyIndex < history.length) { | ||
| controller.enqueue(history[historyIndex]); | ||
| historyIndex++; | ||
| return; | ||
| } | ||
| historyComplete = true; | ||
| liveReader = liveSource.getReader(); | ||
| } | ||
| if (liveReader) { | ||
| try { | ||
| const { done, value } = await liveReader.read(); | ||
| if (done) { | ||
| controller.close(); | ||
| return; | ||
| } | ||
| if (cache && cacheKey) { | ||
| const serialized = serialize(value); | ||
| cache.listPush(cacheKey, serialized).catch(() => { | ||
| }); | ||
| } | ||
| controller.enqueue(value); | ||
| } catch (error) { | ||
| controller.error(error); | ||
| } | ||
| } | ||
| }, | ||
| cancel() { | ||
| if (liveReader) { | ||
| void liveReader.cancel(); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| function withStreamCaching(options) { | ||
| const { cache, cacheKey, serialize, deserialize } = options; | ||
| return { | ||
| pipeThrough: () => { | ||
| const { transform } = createCachingTransformStream({ cache, cacheKey, serialize, deserialize }); | ||
| return transform; | ||
| }, | ||
| getHistory: async (offset = 0) => { | ||
| const deserializeFn = deserialize ?? ((x) => x); | ||
| const cached = await cache.listFromTo(cacheKey, offset); | ||
| return cached.map((item) => deserializeFn(item)); | ||
| }, | ||
| clearCache: async () => { | ||
| await cache.delete(cacheKey); | ||
| } | ||
| }; | ||
| } | ||
| exports.MastraAgentNetworkStream = MastraAgentNetworkStream; | ||
| exports.WorkflowRunOutput = WorkflowRunOutput; | ||
| exports.convertFullStreamChunkToMastra = convertFullStreamChunkToMastra; | ||
| exports.convertFullStreamChunkToUIMessageStream = convertFullStreamChunkToUIMessageStream; | ||
| exports.convertMastraChunkToAISDKv5 = convertMastraChunkToAISDKv5; | ||
| exports.createCachingTransformStream = createCachingTransformStream; | ||
| exports.createReplayStream = createReplayStream; | ||
| exports.withStreamCaching = withStreamCaching; | ||
| //# sourceMappingURL=chunk-LH3OTIIL.cjs.map | ||
| //# sourceMappingURL=chunk-LH3OTIIL.cjs.map |
Sorry, the diff of this file is too big to display
| import { MastraModelGateway, createOpenAICompatible, MASTRA_USER_AGENT, createAnthropic, createGoogleGenerativeAI, createOpenAI } from './chunk-BQXT5IMT.js'; | ||
| import { InMemoryServerCache } from './chunk-366PLPDH.js'; | ||
| import { MastraError } from './chunk-M7RBQNFP.js'; | ||
| // src/llm/model/gateways/netlify.ts | ||
| var NetlifyGateway = class extends MastraModelGateway { | ||
| id = "netlify"; | ||
| name = "Netlify AI Gateway"; | ||
| tokenCache = new InMemoryServerCache(); | ||
| async fetchProviders() { | ||
| const response = await fetch("https://api.netlify.com/api/v1/ai-gateway/providers"); | ||
| if (!response.ok) { | ||
| throw new Error(`Failed to fetch from Netlify: ${response.statusText}`); | ||
| } | ||
| const data = await response.json(); | ||
| const config = { | ||
| apiKeyEnvVar: ["NETLIFY_TOKEN", "NETLIFY_SITE_ID"], | ||
| apiKeyHeader: "Authorization", | ||
| name: `Netlify`, | ||
| gateway: `netlify`, | ||
| models: [], | ||
| docUrl: "https://docs.netlify.com/build/ai-gateway/overview/" | ||
| }; | ||
| for (const [providerId, provider] of Object.entries(data.providers)) { | ||
| for (const model of provider.models) { | ||
| config.models.push(`${providerId}/${model}`); | ||
| } | ||
| } | ||
| return { netlify: config }; | ||
| } | ||
| async buildUrl(routerId, envVars) { | ||
| const siteId = envVars?.["NETLIFY_SITE_ID"] || process.env["NETLIFY_SITE_ID"]; | ||
| const netlifyToken = envVars?.["NETLIFY_TOKEN"] || process.env["NETLIFY_TOKEN"]; | ||
| if (!netlifyToken) { | ||
| throw new MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_TOKEN", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_TOKEN environment variable required for model: ${routerId}` | ||
| }); | ||
| } | ||
| if (!siteId) { | ||
| throw new MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_SITE_ID", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_SITE_ID environment variable required for model: ${routerId}` | ||
| }); | ||
| } | ||
| try { | ||
| const tokenData = await this.getOrFetchToken(siteId, netlifyToken); | ||
| return tokenData.url.endsWith(`/`) ? tokenData.url.substring(0, tokenData.url.length - 1) : tokenData.url; | ||
| } catch (error) { | ||
| throw new MastraError({ | ||
| id: "NETLIFY_GATEWAY_TOKEN_ERROR", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Failed to get Netlify AI Gateway token for model ${routerId}: ${error instanceof Error ? error.message : String(error)}` | ||
| }); | ||
| } | ||
| } | ||
| /** | ||
| * Get cached token or fetch a new site-specific AI Gateway token from Netlify | ||
| */ | ||
| async getOrFetchToken(siteId, netlifyToken) { | ||
| const cacheKey = `netlify-token:${siteId}:${netlifyToken}`; | ||
| const cached = await this.tokenCache.get(cacheKey); | ||
| if (cached && cached.expiresAt > Date.now() / 1e3 + 60) { | ||
| return { token: cached.token, url: cached.url }; | ||
| } | ||
| const response = await fetch(`https://api.netlify.com/api/v1/sites/${siteId}/ai-gateway/token`, { | ||
| method: "GET", | ||
| headers: { | ||
| Authorization: `Bearer ${netlifyToken}` | ||
| } | ||
| }); | ||
| if (!response.ok) { | ||
| const error = await response.text(); | ||
| throw new Error(`Failed to get Netlify AI Gateway token: ${response.status} ${error}`); | ||
| } | ||
| const tokenResponse = await response.json(); | ||
| await this.tokenCache.set(cacheKey, { | ||
| token: tokenResponse.token, | ||
| url: tokenResponse.url, | ||
| expiresAt: tokenResponse.expires_at | ||
| }); | ||
| return { token: tokenResponse.token, url: tokenResponse.url }; | ||
| } | ||
| /** | ||
| * Get cached token or fetch a new site-specific AI Gateway token from Netlify | ||
| */ | ||
| async getApiKey(modelId) { | ||
| const siteId = process.env["NETLIFY_SITE_ID"]; | ||
| const netlifyToken = process.env["NETLIFY_TOKEN"]; | ||
| if (!netlifyToken) { | ||
| throw new MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_TOKEN", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_TOKEN environment variable required for model: ${modelId}` | ||
| }); | ||
| } | ||
| if (!siteId) { | ||
| throw new MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_SITE_ID", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_SITE_ID environment variable required for model: ${modelId}` | ||
| }); | ||
| } | ||
| try { | ||
| return (await this.getOrFetchToken(siteId, netlifyToken)).token; | ||
| } catch (error) { | ||
| throw new MastraError({ | ||
| id: "NETLIFY_GATEWAY_TOKEN_ERROR", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Failed to get Netlify AI Gateway token for model ${modelId}: ${error instanceof Error ? error.message : String(error)}` | ||
| }); | ||
| } | ||
| } | ||
| async resolveLanguageModel({ | ||
| modelId, | ||
| providerId, | ||
| apiKey, | ||
| headers | ||
| }) { | ||
| const baseURL = await this.buildUrl(`${providerId}/${modelId}`); | ||
| const mastraHeaders = { "User-Agent": MASTRA_USER_AGENT, ...headers }; | ||
| switch (providerId) { | ||
| case "openai": | ||
| return createOpenAI({ apiKey, baseURL, headers: mastraHeaders }).responses(modelId); | ||
| case "gemini": | ||
| return createGoogleGenerativeAI({ | ||
| baseURL: `${baseURL}/v1beta/`, | ||
| apiKey, | ||
| headers: { | ||
| "user-agent": "google-genai-sdk/", | ||
| ...mastraHeaders | ||
| } | ||
| }).chat(modelId); | ||
| case "anthropic": | ||
| return createAnthropic({ | ||
| apiKey, | ||
| baseURL: `${baseURL}/v1/`, | ||
| headers: { | ||
| "anthropic-version": "2023-06-01", | ||
| ...mastraHeaders | ||
| } | ||
| })(modelId); | ||
| default: | ||
| return createOpenAICompatible({ | ||
| name: providerId, | ||
| apiKey, | ||
| baseURL, | ||
| headers: mastraHeaders, | ||
| supportsStructuredOutputs: true | ||
| }).chatModel(modelId); | ||
| } | ||
| } | ||
| }; | ||
| export { NetlifyGateway }; | ||
| //# sourceMappingURL=chunk-LVCGADQS.js.map | ||
| //# sourceMappingURL=chunk-LVCGADQS.js.map |
| {"version":3,"sources":["../src/llm/model/gateways/netlify.ts"],"names":[],"mappings":"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","file":"chunk-LVCGADQS.js","sourcesContent":["import { createAnthropic } from '@ai-sdk/anthropic-v6';\nimport { createGoogleGenerativeAI } from '@ai-sdk/google-v6';\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible-v5';\nimport { createOpenAI } from '@ai-sdk/openai-v6';\nimport { InMemoryServerCache } from '../../../cache/inmemory.js';\nimport { MastraError } from '../../../error/index.js';\nimport { MastraModelGateway } from './base.js';\nimport type { ProviderConfig, GatewayLanguageModel } from './base.js';\nimport { MASTRA_USER_AGENT } from './constants.js';\n\ninterface NetlifyProviderResponse {\n token_env_var: string;\n url_env_var: string;\n models: string[];\n}\ninterface NetlifyResponse {\n providers: Record<string, NetlifyProviderResponse>;\n}\n\ninterface NetlifyTokenResponse {\n token: string;\n url: string;\n expires_at: number;\n}\n\ninterface CachedToken {\n token: string;\n url: string;\n expiresAt: number;\n}\n\ninterface TokenData {\n token: string;\n url: string;\n}\n\nexport class NetlifyGateway extends MastraModelGateway {\n readonly id = 'netlify';\n readonly name = 'Netlify AI Gateway';\n private tokenCache = new InMemoryServerCache();\n\n async fetchProviders(): Promise<Record<string, ProviderConfig>> {\n const response = await fetch('https://api.netlify.com/api/v1/ai-gateway/providers');\n if (!response.ok) {\n throw new Error(`Failed to fetch from Netlify: ${response.statusText}`);\n }\n const data = (await response.json()) as NetlifyResponse;\n const config: ProviderConfig = {\n apiKeyEnvVar: ['NETLIFY_TOKEN', 'NETLIFY_SITE_ID'],\n apiKeyHeader: 'Authorization',\n name: `Netlify`,\n gateway: `netlify`,\n models: [],\n docUrl: 'https://docs.netlify.com/build/ai-gateway/overview/',\n };\n // Convert Netlify format to our standard format\n for (const [providerId, provider] of Object.entries(data.providers)) {\n for (const model of provider.models) {\n config.models.push(`${providerId}/${model}`);\n }\n }\n // Return with gateway ID as key - registry generator will detect this and avoid doubling the prefix\n return { netlify: config };\n }\n\n async buildUrl(routerId: string, envVars?: typeof process.env): Promise<string> {\n // Check for Netlify site ID first (for token exchange)\n const siteId = envVars?.['NETLIFY_SITE_ID'] || process.env['NETLIFY_SITE_ID'];\n const netlifyToken = envVars?.['NETLIFY_TOKEN'] || process.env['NETLIFY_TOKEN'];\n\n if (!netlifyToken) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_TOKEN',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_TOKEN environment variable required for model: ${routerId}`,\n });\n }\n\n if (!siteId) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_SITE_ID',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_SITE_ID environment variable required for model: ${routerId}`,\n });\n }\n\n try {\n const tokenData = await this.getOrFetchToken(siteId, netlifyToken);\n return tokenData.url.endsWith(`/`) ? tokenData.url.substring(0, tokenData.url.length - 1) : tokenData.url;\n } catch (error) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_TOKEN_ERROR',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Failed to get Netlify AI Gateway token for model ${routerId}: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n\n /**\n * Get cached token or fetch a new site-specific AI Gateway token from Netlify\n */\n private async getOrFetchToken(siteId: string, netlifyToken: string): Promise<TokenData> {\n const cacheKey = `netlify-token:${siteId}:${netlifyToken}`;\n\n // Check cache first\n const cached = (await this.tokenCache.get(cacheKey)) as CachedToken | undefined;\n if (cached && cached.expiresAt > Date.now() / 1000 + 60) {\n // Return cached token if it won't expire in the next minute\n return { token: cached.token, url: cached.url };\n }\n\n // Fetch new token\n const response = await fetch(`https://api.netlify.com/api/v1/sites/${siteId}/ai-gateway/token`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${netlifyToken}`,\n },\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Failed to get Netlify AI Gateway token: ${response.status} ${error}`);\n }\n\n const tokenResponse = (await response.json()) as NetlifyTokenResponse;\n\n // Cache the token - InMemoryServerCache will handle the TTL\n await this.tokenCache.set(cacheKey, {\n token: tokenResponse.token,\n url: tokenResponse.url,\n expiresAt: tokenResponse.expires_at,\n });\n\n return { token: tokenResponse.token, url: tokenResponse.url };\n }\n\n /**\n * Get cached token or fetch a new site-specific AI Gateway token from Netlify\n */\n async getApiKey(modelId: string): Promise<string> {\n const siteId = process.env['NETLIFY_SITE_ID'];\n const netlifyToken = process.env['NETLIFY_TOKEN'];\n\n if (!netlifyToken) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_TOKEN',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_TOKEN environment variable required for model: ${modelId}`,\n });\n }\n\n if (!siteId) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_SITE_ID',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_SITE_ID environment variable required for model: ${modelId}`,\n });\n }\n\n try {\n return (await this.getOrFetchToken(siteId, netlifyToken)).token;\n } catch (error) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_TOKEN_ERROR',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Failed to get Netlify AI Gateway token for model ${modelId}: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n\n async resolveLanguageModel({\n modelId,\n providerId,\n apiKey,\n headers,\n }: {\n modelId: string;\n providerId: string;\n apiKey: string;\n headers?: Record<string, string>;\n }): Promise<GatewayLanguageModel> {\n const baseURL = await this.buildUrl(`${providerId}/${modelId}`);\n\n const mastraHeaders = { 'User-Agent': MASTRA_USER_AGENT, ...headers };\n\n switch (providerId) {\n case 'openai':\n return createOpenAI({ apiKey, baseURL, headers: mastraHeaders }).responses(modelId);\n case 'gemini':\n return createGoogleGenerativeAI({\n baseURL: `${baseURL}/v1beta/`,\n apiKey,\n headers: {\n 'user-agent': 'google-genai-sdk/',\n ...mastraHeaders,\n },\n }).chat(modelId);\n case 'anthropic':\n return createAnthropic({\n apiKey,\n baseURL: `${baseURL}/v1/`,\n headers: {\n 'anthropic-version': '2023-06-01',\n ...mastraHeaders,\n },\n })(modelId);\n default:\n return createOpenAICompatible({\n name: providerId,\n apiKey,\n baseURL,\n headers: mastraHeaders,\n supportsStructuredOutputs: true,\n }).chatModel(modelId);\n }\n }\n}\n"]} |
| import { Tool, isVercelTool, isProviderDefinedTool, validateToolInput, getNeedsApprovalFn, validateToolOutput, validateToolSuspendData } from './chunk-VLJMDX6T.js'; | ||
| import { isStandardSchemaWithJSON, toStandardSchema, standardSchemaToJSONSchema } from './chunk-6SRTDZ7S.js'; | ||
| import { isZodObject, safeExtendZodObject } from './chunk-TBHKQLPL.js'; | ||
| import { wrapMastra, createObservabilityContext } from './chunk-JPUBRZLW.js'; | ||
| import { getOrCreateSpan, EntityType, executeWithContext } from './chunk-DEQCJWZZ.js'; | ||
| import { MastraFGAPermissions } from './chunk-JAIH7QCD.js'; | ||
| import { backgroundOverrideZodSchema, backgroundOverrideJsonSchema } from './chunk-GCIWBMEH.js'; | ||
| import { MastraBase } from './chunk-77VL4DNS.js'; | ||
| import { RequestContext } from './chunk-RI37F2KY.js'; | ||
| import { MastraError, ErrorCategory, ErrorDomain } from './chunk-M7RBQNFP.js'; | ||
| import { createHash } from 'crypto'; | ||
| import { jsonSchemaToZod } from '@mastra/schema-compat/json-to-zod'; | ||
| import { z } from 'zod/v4'; | ||
| import { convertZodSchemaToAISDKSchema, OpenAIReasoningSchemaCompatLayer, OpenAISchemaCompatLayer, GoogleSchemaCompatLayer, AnthropicSchemaCompatLayer, DeepSeekSchemaCompatLayer, MetaSchemaCompatLayer, jsonSchema, applyCompatLayer } from '@mastra/schema-compat'; | ||
| import { WritableStream } from 'stream/web'; | ||
| var ToolStream = class extends WritableStream { | ||
| prefix; | ||
| callId; | ||
| name; | ||
| runId; | ||
| writeFn; | ||
| constructor({ | ||
| prefix, | ||
| callId, | ||
| name, | ||
| runId | ||
| }, writeFn) { | ||
| super({ | ||
| async write(chunk) { | ||
| await getInstance()._write(chunk); | ||
| } | ||
| }); | ||
| const self = this; | ||
| function getInstance() { | ||
| return self; | ||
| } | ||
| this.prefix = prefix; | ||
| this.callId = callId; | ||
| this.name = name; | ||
| this.runId = runId; | ||
| this.writeFn = writeFn; | ||
| } | ||
| async _write(data) { | ||
| if (this.writeFn) { | ||
| await this.writeFn({ | ||
| type: `${this.prefix}-output`, | ||
| runId: this.runId, | ||
| from: "USER", | ||
| payload: { | ||
| output: data, | ||
| ...this.prefix === "workflow-step" ? { | ||
| runId: this.runId, | ||
| stepName: this.name | ||
| } : { | ||
| [`${this.prefix}CallId`]: this.callId, | ||
| [`${this.prefix}Name`]: this.name | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| async write(data) { | ||
| await this._write(data); | ||
| } | ||
| async custom(data) { | ||
| if (this.writeFn) { | ||
| await this.writeFn(data); | ||
| } | ||
| } | ||
| }; | ||
| // src/tools/types.ts | ||
| var noopObserve = { | ||
| async span(_name, fn) { | ||
| return fn(); | ||
| }, | ||
| log() { | ||
| } | ||
| }; | ||
| // src/tools/tool-builder/builder.ts | ||
| function mergeRequestContexts(closureRC, execRC) { | ||
| if (!closureRC && !execRC) return new RequestContext(); | ||
| if (!closureRC) return execRC instanceof RequestContext ? execRC : new RequestContext(); | ||
| if (!execRC || !(execRC instanceof RequestContext) || execRC.size() === 0) return closureRC; | ||
| const merged = new RequestContext(); | ||
| for (const [key, value] of execRC.entries()) { | ||
| merged.set(key, value); | ||
| } | ||
| for (const [key, value] of closureRC.entries()) { | ||
| merged.set(key, value); | ||
| } | ||
| return merged; | ||
| } | ||
| function isZodV4Schema(schema) { | ||
| const def = schema?._def; | ||
| return !!def && typeof def.type === "string" && !def.typeName; | ||
| } | ||
| function buildJsonOverrideSchema(originalSchema, splicedJsonSchema, injectedKeys) { | ||
| const fallback = toStandardSchema(splicedJsonSchema); | ||
| const original = originalSchema; | ||
| const originalValidate = original?.["~standard"]?.validate?.bind(original["~standard"]); | ||
| const splicedProperties = splicedJsonSchema && typeof splicedJsonSchema === "object" && "properties" in splicedJsonSchema ? splicedJsonSchema.properties ?? {} : {}; | ||
| const injectedProperties = {}; | ||
| for (const key of injectedKeys) { | ||
| if (splicedProperties[key] !== void 0) injectedProperties[key] = splicedProperties[key]; | ||
| } | ||
| const injectedValidator = toStandardSchema({ | ||
| type: "object", | ||
| properties: injectedProperties, | ||
| additionalProperties: false | ||
| }); | ||
| const stripInjected = (input) => { | ||
| if (!input || typeof input !== "object" || Array.isArray(input)) return { stripped: input, injected: {} }; | ||
| const injected = {}; | ||
| const stripped = {}; | ||
| for (const [k, v] of Object.entries(input)) { | ||
| if (injectedKeys.includes(k)) injected[k] = v; | ||
| else stripped[k] = v; | ||
| } | ||
| return { stripped, injected }; | ||
| }; | ||
| const validate = (input) => { | ||
| const { stripped, injected } = stripInjected(input); | ||
| const baseResult = originalValidate ? originalValidate(stripped) : fallback["~standard"].validate(stripped); | ||
| const injectedResult = injectedValidator["~standard"].validate(injected); | ||
| const combine = (base, inj) => { | ||
| const baseIssues = "issues" in base ? base.issues ?? [] : []; | ||
| const injIssues = "issues" in inj ? inj.issues ?? [] : []; | ||
| if (baseIssues.length || injIssues.length) { | ||
| return { issues: [...baseIssues, ...injIssues] }; | ||
| } | ||
| const baseValue = base.value; | ||
| const injValue = inj.value; | ||
| if (baseValue && typeof baseValue === "object" && !Array.isArray(baseValue)) { | ||
| const injMerged = injValue && typeof injValue === "object" && !Array.isArray(injValue) ? injValue : injected; | ||
| return { value: { ...baseValue, ...injMerged } }; | ||
| } | ||
| return base; | ||
| }; | ||
| const baseIsPromise = baseResult && typeof baseResult.then === "function"; | ||
| const injIsPromise = injectedResult && typeof injectedResult.then === "function"; | ||
| if (baseIsPromise || injIsPromise) { | ||
| return Promise.all([baseResult, injectedResult]).then( | ||
| ([b, i]) => combine( | ||
| b, | ||
| i | ||
| ) | ||
| ); | ||
| } | ||
| return combine( | ||
| baseResult, | ||
| injectedResult | ||
| ); | ||
| }; | ||
| return { | ||
| "~standard": { | ||
| version: 1, | ||
| vendor: "mastra-json-override", | ||
| validate, | ||
| jsonSchema: fallback["~standard"].jsonSchema | ||
| } | ||
| }; | ||
| } | ||
| var CoreToolBuilder = class extends MastraBase { | ||
| originalTool; | ||
| options; | ||
| logType; | ||
| constructor(input) { | ||
| super({ name: "CoreToolBuilder" }); | ||
| this.originalTool = input.originalTool; | ||
| this.options = input.options; | ||
| this.logType = input.logType; | ||
| const isBackgroundEligible = !!input.backgroundTaskEnabled; | ||
| const isResumableTool = input.autoResumeSuspendedTools || this.originalTool.id?.startsWith("agent-") || this.originalTool.id?.startsWith("workflow-"); | ||
| if (!isVercelTool(this.originalTool) && !isProviderDefinedTool(this.originalTool)) { | ||
| if (isBackgroundEligible || isResumableTool) { | ||
| let schema = this.originalTool.inputSchema; | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| if (!schema) { | ||
| schema = z.object({}); | ||
| } | ||
| if (isZodObject(schema) && isZodV4Schema(schema)) { | ||
| let nextSchema = schema; | ||
| if (isBackgroundEligible) { | ||
| nextSchema = safeExtendZodObject(nextSchema, { | ||
| _background: backgroundOverrideZodSchema | ||
| }); | ||
| } | ||
| if (isResumableTool) { | ||
| nextSchema = safeExtendZodObject(nextSchema, { | ||
| suspendedToolRunId: z.string().describe("The runId of the suspended tool").nullable().optional(), | ||
| resumeData: z.any().describe("The resumeData object created from the resumeSchema of suspended tool").optional() | ||
| }); | ||
| } | ||
| this.originalTool.inputSchema = nextSchema; | ||
| } else { | ||
| const standardSchema = isStandardSchemaWithJSON(schema) ? schema : toStandardSchema(schema); | ||
| const jsonSchema2 = standardSchemaToJSONSchema(standardSchema, { io: "input" }); | ||
| if (jsonSchema2 && typeof jsonSchema2 === "object" && jsonSchema2.type === "object") { | ||
| const properties = { ...jsonSchema2.properties ?? {} }; | ||
| const injectedKeys = []; | ||
| if (isBackgroundEligible) { | ||
| properties._background = backgroundOverrideJsonSchema; | ||
| injectedKeys.push("_background"); | ||
| } | ||
| if (isResumableTool) { | ||
| properties.suspendedToolRunId = { | ||
| type: ["string", "null"], | ||
| description: "The runId of the suspended tool" | ||
| }; | ||
| properties.resumeData = { | ||
| description: "The resumeData object created from the resumeSchema of suspended tool" | ||
| }; | ||
| injectedKeys.push("suspendedToolRunId", "resumeData"); | ||
| } | ||
| this.originalTool.inputSchema = buildJsonOverrideSchema( | ||
| schema, | ||
| { ...jsonSchema2, properties }, | ||
| injectedKeys | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // Helper to get parameters based on tool type | ||
| getParameters = () => { | ||
| if (isVercelTool(this.originalTool)) { | ||
| let schema2 = this.originalTool.parameters ?? ("inputSchema" in this.originalTool ? this.originalTool.inputSchema : void 0) ?? z.object({}); | ||
| if (typeof schema2 === "function") { | ||
| schema2 = schema2(); | ||
| } | ||
| return schema2; | ||
| } | ||
| let schema = this.originalTool.inputSchema; | ||
| if (isStandardSchemaWithJSON(schema)) { | ||
| return schema; | ||
| } | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| }; | ||
| getOutputSchema = () => { | ||
| if ("outputSchema" in this.originalTool) { | ||
| let schema = this.originalTool.outputSchema; | ||
| if (isStandardSchemaWithJSON(schema)) { | ||
| return schema; | ||
| } | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| } | ||
| return null; | ||
| }; | ||
| getResumeSchema = () => { | ||
| if ("resumeSchema" in this.originalTool) { | ||
| let schema = this.originalTool.resumeSchema; | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| } | ||
| return null; | ||
| }; | ||
| getSuspendSchema = () => { | ||
| if ("suspendSchema" in this.originalTool) { | ||
| let schema = this.originalTool.suspendSchema; | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| } | ||
| return null; | ||
| }; | ||
| // For provider-defined tools, we need to include all required properties | ||
| // AI SDK v5 uses type: 'provider-defined', AI SDK v6 uses type: 'provider' | ||
| buildProviderTool(tool) { | ||
| if ("type" in tool && (tool.type === "provider-defined" || tool.type === "provider") && "id" in tool && typeof tool.id === "string" && tool.id.includes(".")) { | ||
| let parameters = "parameters" in tool ? tool.parameters : "inputSchema" in tool ? tool.inputSchema : void 0; | ||
| if (typeof parameters === "function") { | ||
| parameters = parameters(); | ||
| } | ||
| let outputSchema = "outputSchema" in tool ? tool.outputSchema : void 0; | ||
| if (typeof outputSchema === "function") { | ||
| outputSchema = outputSchema(); | ||
| } | ||
| let processedParameters; | ||
| if (parameters !== void 0 && parameters !== null) { | ||
| if (typeof parameters === "object" && "jsonSchema" in parameters) { | ||
| processedParameters = parameters; | ||
| } else if (isStandardSchemaWithJSON(parameters)) { | ||
| const jsonSchema2 = standardSchemaToJSONSchema(parameters, { io: "input" }); | ||
| processedParameters = { jsonSchema: jsonSchema2 }; | ||
| } else { | ||
| processedParameters = convertZodSchemaToAISDKSchema(parameters); | ||
| } | ||
| } else { | ||
| processedParameters = { | ||
| jsonSchema: { | ||
| type: "object", | ||
| properties: {}, | ||
| additionalProperties: false | ||
| } | ||
| }; | ||
| } | ||
| let processedOutputSchema; | ||
| if (outputSchema !== void 0 && outputSchema !== null) { | ||
| if (typeof outputSchema === "object" && "jsonSchema" in outputSchema) { | ||
| processedOutputSchema = outputSchema; | ||
| } else if (isStandardSchemaWithJSON(outputSchema)) { | ||
| const jsonSchema2 = standardSchemaToJSONSchema(outputSchema); | ||
| processedOutputSchema = { jsonSchema: jsonSchema2 }; | ||
| } else { | ||
| processedOutputSchema = convertZodSchemaToAISDKSchema(outputSchema); | ||
| } | ||
| } | ||
| return { | ||
| ...processedOutputSchema ? { outputSchema: processedOutputSchema } : {}, | ||
| type: "provider-defined", | ||
| id: tool.id, | ||
| // V5 SDK factories set a hardcoded `name` (e.g. "web_search" for | ||
| // anthropic.web_search_20250305). Preserve it so that when this tool | ||
| // is later used with a V6 provider, the bidirectional toolNameMapping | ||
| // resolves the correct model-facing name instead of the versioned ID. | ||
| ..."name" in tool && typeof tool.name === "string" ? { name: tool.name } : {}, | ||
| args: "args" in this.originalTool ? this.originalTool.args : {}, | ||
| description: tool.description, | ||
| parameters: processedParameters, | ||
| execute: this.originalTool.execute ? this.createExecute( | ||
| this.originalTool, | ||
| { ...this.options, description: this.originalTool.description }, | ||
| this.logType | ||
| ) : void 0, | ||
| toModelOutput: "toModelOutput" in this.originalTool ? this.originalTool.toModelOutput : void 0, | ||
| transform: "transform" in this.originalTool ? this.originalTool.transform : void 0, | ||
| inputExamples: "inputExamples" in this.originalTool ? this.originalTool.inputExamples : void 0 | ||
| }; | ||
| } | ||
| return void 0; | ||
| } | ||
| createLogMessageOptions({ agentName, toolName, type }) { | ||
| const toolType = type === "toolset" ? "toolset" : "tool"; | ||
| return { | ||
| start: `Executing ${toolType}`, | ||
| error: `Failed ${toolType} execution`, | ||
| logData: { agent: agentName, tool: toolName } | ||
| }; | ||
| } | ||
| createExecute(tool, options, logType) { | ||
| const { | ||
| logger, | ||
| mastra: _mastra, | ||
| memory: _memory, | ||
| requestContext, | ||
| model, | ||
| tracingContext: _tracingContext, | ||
| tracingPolicy: _tracingPolicy, | ||
| ...rest | ||
| } = options; | ||
| const logModelObject = { | ||
| modelId: model?.modelId, | ||
| provider: model?.provider, | ||
| specificationVersion: model?.specificationVersion | ||
| }; | ||
| const { start, logData } = this.createLogMessageOptions({ | ||
| agentName: options.agentName, | ||
| toolName: options.name, | ||
| type: logType | ||
| }); | ||
| const mcpMeta = !isVercelTool(tool) && "mcpMetadata" in tool ? tool.mcpMetadata : void 0; | ||
| const execFunction = async (args, execOptions, toolSpan) => { | ||
| try { | ||
| let result; | ||
| let suspendData = null; | ||
| if (isVercelTool(tool)) { | ||
| result = await executeWithContext({ | ||
| span: toolSpan, | ||
| fn: async () => tool?.execute?.(args, execOptions) | ||
| }); | ||
| } else { | ||
| const wrappedMastra = options.mastra ? wrapMastra(options.mastra, { currentSpan: toolSpan }) : options.mastra; | ||
| const resumeSchema = this.getResumeSchema(); | ||
| const baseContext = { | ||
| threadId: options.threadId, | ||
| resourceId: options.resourceId, | ||
| mastra: wrappedMastra, | ||
| memory: options.memory, | ||
| runId: options.runId, | ||
| requestContext: mergeRequestContexts(options.requestContext, execOptions.requestContext), | ||
| actor: execOptions.actor, | ||
| // Workspace for file operations and command execution | ||
| // Execution-time workspace (from prepareStep/processInputStep) takes precedence over build-time workspace | ||
| workspace: execOptions.workspace ?? options.workspace, | ||
| // Browser for web automation (lazily initialized on first use) | ||
| browser: options.browser, | ||
| observe: execOptions.observe ?? noopObserve, | ||
| writer: new ToolStream( | ||
| { | ||
| prefix: "tool", | ||
| callId: execOptions.toolCallId, | ||
| name: options.name, | ||
| runId: options.runId | ||
| }, | ||
| options.outputWriter || execOptions.outputWriter | ||
| ), | ||
| ...createObservabilityContext({ currentSpan: toolSpan }), | ||
| abortSignal: execOptions.abortSignal, | ||
| suspend: (args2, suspendOptions) => { | ||
| suspendData = args2; | ||
| const newSuspendOptions = { | ||
| ...suspendOptions ?? {}, | ||
| resumeSchema: suspendOptions?.resumeSchema ?? (resumeSchema ? JSON.stringify(standardSchemaToJSONSchema(toStandardSchema(resumeSchema), { io: "input" })) : void 0) | ||
| }; | ||
| return execOptions.suspend?.(args2, newSuspendOptions); | ||
| }, | ||
| resumeData: execOptions.resumeData | ||
| }; | ||
| const isAgentExecution = execOptions.toolCallId && execOptions.messages || options.agentName && options.threadId && !options.workflowId; | ||
| const isWorkflowExecution = !isAgentExecution && (options.workflow || options.workflowId); | ||
| let toolContext; | ||
| if (isAgentExecution) { | ||
| const { suspend, resumeData: resumeData2, threadId, resourceId, ...restBaseContext } = baseContext; | ||
| toolContext = { | ||
| ...restBaseContext, | ||
| agent: { | ||
| agentId: options.agentId || "", | ||
| toolCallId: execOptions.toolCallId || "", | ||
| messages: execOptions.messages || [], | ||
| suspend, | ||
| resumeData: resumeData2, | ||
| threadId, | ||
| resourceId, | ||
| outputWriter: options.outputWriter || execOptions.outputWriter, | ||
| flushMessages: execOptions.flushMessages | ||
| } | ||
| }; | ||
| } else if (isWorkflowExecution) { | ||
| const { suspend, resumeData: resumeData2, ...restBaseContext } = baseContext; | ||
| toolContext = { | ||
| ...restBaseContext, | ||
| workflow: options.workflow || { | ||
| runId: options.runId, | ||
| workflowId: options.workflowId, | ||
| state: options.state, | ||
| setState: options.setState, | ||
| suspend, | ||
| resumeData: resumeData2 | ||
| } | ||
| }; | ||
| } else if (execOptions.mcp) { | ||
| toolContext = { | ||
| ...baseContext, | ||
| mcp: execOptions.mcp | ||
| }; | ||
| } else { | ||
| toolContext = baseContext; | ||
| } | ||
| const resumeData = execOptions.resumeData; | ||
| if (resumeData) { | ||
| const resumeValidation = validateToolInput(resumeSchema, resumeData, options.name); | ||
| if (resumeValidation.error) { | ||
| logger?.warn(resumeValidation.error.message); | ||
| toolSpan?.end({ output: resumeValidation.error, attributes: { success: false } }); | ||
| return resumeValidation.error; | ||
| } | ||
| } | ||
| result = await executeWithContext({ span: toolSpan, fn: async () => tool?.execute?.(args, toolContext) }); | ||
| } | ||
| if (suspendData) { | ||
| const suspendSchema = this.getSuspendSchema(); | ||
| const suspendValidation = validateToolSuspendData(suspendSchema, suspendData, options.name); | ||
| if (suspendValidation.error) { | ||
| logger?.warn(suspendValidation.error.message); | ||
| toolSpan?.end({ output: suspendValidation.error, attributes: { success: false } }); | ||
| return suspendValidation.error; | ||
| } | ||
| } | ||
| const shouldSkipValidation = typeof result === "undefined" && !!suspendData; | ||
| if (shouldSkipValidation) { | ||
| toolSpan?.end({ output: result, attributes: { success: true } }); | ||
| return result; | ||
| } | ||
| if (isVercelTool(tool)) { | ||
| const outputSchema = this.getOutputSchema(); | ||
| const outputValidation = validateToolOutput(outputSchema, result, options.name, false); | ||
| if (outputValidation.error) { | ||
| logger?.warn(outputValidation.error.message); | ||
| toolSpan?.end({ output: outputValidation.error, attributes: { success: false } }); | ||
| return outputValidation.error; | ||
| } | ||
| result = outputValidation.data; | ||
| } | ||
| toolSpan?.end({ output: result, attributes: { success: true } }); | ||
| return result; | ||
| } catch (error) { | ||
| toolSpan?.error({ error, attributes: { success: false } }); | ||
| throw error; | ||
| } | ||
| }; | ||
| return async (args, execOptions) => { | ||
| let logger2 = options.logger || this.logger; | ||
| const tracingContext = execOptions?.tracingContext || options.tracingContext; | ||
| const toolRequestContext = execOptions?.requestContext ?? options.requestContext; | ||
| const toolSpan = getOrCreateSpan({ | ||
| type: mcpMeta ? "mcp_tool_call" /* MCP_TOOL_CALL */ : "tool_call" /* TOOL_CALL */, | ||
| name: mcpMeta ? `mcp_tool: '${options.name}' on '${mcpMeta.serverName}'` : `tool: '${options.name}'`, | ||
| input: args, | ||
| entityType: EntityType.TOOL, | ||
| entityId: options.name, | ||
| entityName: options.name, | ||
| attributes: mcpMeta ? { | ||
| mcpServer: mcpMeta.serverName, | ||
| serverVersion: mcpMeta.serverVersion, | ||
| toolDescription: options.description | ||
| } : { | ||
| toolDescription: options.description, | ||
| toolType: logType || "tool" | ||
| }, | ||
| tracingPolicy: options.tracingPolicy, | ||
| tracingContext, | ||
| requestContext: toolRequestContext, | ||
| mastra: options.mastra && "observability" in options.mastra ? options.mastra : void 0 | ||
| }); | ||
| const fgaProvider = options.mastra?.getServer?.()?.fga; | ||
| const user = toolRequestContext?.get("user"); | ||
| if (fgaProvider) { | ||
| const { getAgentToolFGAResourceId, getMCPToolFGAResourceId, getStandaloneToolFGAResourceId, requireFGA } = await import('./fga-check-7DWG6TWM.js'); | ||
| const toolResourceId = mcpMeta?.serverName ? getMCPToolFGAResourceId(mcpMeta.serverName, options.name) : options.agentId ? getAgentToolFGAResourceId(options.agentId, options.name) : getStandaloneToolFGAResourceId(options.name); | ||
| await requireFGA({ | ||
| fgaProvider, | ||
| user, | ||
| resource: { type: "tool", id: toolResourceId }, | ||
| permission: MastraFGAPermissions.TOOLS_EXECUTE, | ||
| requestContext: toolRequestContext, | ||
| actor: execOptions?.actor, | ||
| context: { | ||
| resourceId: options.resourceId | ||
| }, | ||
| metadata: { | ||
| toolName: options.name, | ||
| agentId: options.agentId, | ||
| agentName: options.agentName, | ||
| runId: options.runId, | ||
| threadId: options.threadId, | ||
| executionResourceId: options.resourceId, | ||
| mcpMetadata: mcpMeta | ||
| } | ||
| }); | ||
| } | ||
| try { | ||
| logger2.debug(start, { ...logData, ...rest, model: logModelObject, args }); | ||
| const isResuming = !!execOptions?.resumeData; | ||
| const parameters = this.getParameters(); | ||
| if (!isResuming) { | ||
| const { data, error } = validateToolInput(parameters, args, options.name); | ||
| const suspendedToolRunIdErrToIgnore = error?.message?.includes("suspendedToolRunId: Required") && !args?.resumeData; | ||
| if (error && !suspendedToolRunIdErrToIgnore) { | ||
| logger2.warn("Tool input validation failed", { ...logData, validationError: error.message }); | ||
| toolSpan?.end({ output: error, attributes: { success: false } }); | ||
| return error; | ||
| } | ||
| args = data; | ||
| } | ||
| return await new Promise((resolve, reject) => { | ||
| setImmediate(async () => { | ||
| try { | ||
| const result = await execFunction(args, execOptions, toolSpan); | ||
| resolve(result); | ||
| } catch (err) { | ||
| reject(err); | ||
| } | ||
| }); | ||
| }); | ||
| } catch (err) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "TOOL_EXECUTION_FAILED", | ||
| domain: ErrorDomain.TOOL, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| errorMessage: String(err), | ||
| argsJson: safeStringify(args), | ||
| model: model?.modelId ?? "" | ||
| } | ||
| }, | ||
| err | ||
| ); | ||
| toolSpan?.error({ error: mastraError, attributes: { success: false } }); | ||
| logger2.trackException(mastraError, { ...logData, ...rest, model: logModelObject, args }); | ||
| throw mastraError; | ||
| } | ||
| }; | ||
| } | ||
| buildV5() { | ||
| const builtTool = this.build(); | ||
| if (!builtTool.parameters) { | ||
| throw new Error("Tool parameters are required"); | ||
| } | ||
| const base = { | ||
| ...builtTool, | ||
| inputSchema: builtTool.parameters, | ||
| onInputStart: "onInputStart" in this.originalTool ? this.originalTool.onInputStart : void 0, | ||
| onInputDelta: "onInputDelta" in this.originalTool ? this.originalTool.onInputDelta : void 0, | ||
| onInputAvailable: "onInputAvailable" in this.originalTool ? this.originalTool.onInputAvailable : void 0, | ||
| onOutput: "onOutput" in this.originalTool ? this.originalTool.onOutput : void 0 | ||
| }; | ||
| if (builtTool.type === "provider-defined") { | ||
| const { execute, parameters, ...rest } = base; | ||
| const name = ("name" in builtTool && typeof builtTool.name === "string" ? builtTool.name : null) || builtTool.id.split(".")[1] || builtTool.id; | ||
| return { | ||
| ...rest, | ||
| type: builtTool.type, | ||
| id: builtTool.id, | ||
| name, | ||
| args: builtTool.args | ||
| }; | ||
| } | ||
| return base; | ||
| } | ||
| build() { | ||
| const providerTool = this.buildProviderTool(this.originalTool); | ||
| if (providerTool) { | ||
| return providerTool; | ||
| } | ||
| const model = this.options.model; | ||
| const schemaCompatLayers = []; | ||
| if (model) { | ||
| const supportsStructuredOutputs = "supportsStructuredOutputs" in model ? model.supportsStructuredOutputs ?? false : false; | ||
| const modelInfo = { | ||
| modelId: model.modelId, | ||
| supportsStructuredOutputs, | ||
| provider: model.provider | ||
| }; | ||
| schemaCompatLayers.push( | ||
| new OpenAIReasoningSchemaCompatLayer(modelInfo), | ||
| new OpenAISchemaCompatLayer(modelInfo), | ||
| new GoogleSchemaCompatLayer(modelInfo), | ||
| new AnthropicSchemaCompatLayer(modelInfo), | ||
| new DeepSeekSchemaCompatLayer(modelInfo), | ||
| new MetaSchemaCompatLayer(modelInfo) | ||
| ); | ||
| } | ||
| const originalSchema = this.getParameters(); | ||
| let processedInputSchema; | ||
| if (originalSchema) { | ||
| if (isStandardSchemaWithJSON(originalSchema)) { | ||
| const applicableLayer = schemaCompatLayers.find((layer) => layer.shouldApply()); | ||
| let schemaToUse; | ||
| if (applicableLayer) { | ||
| schemaToUse = applicableLayer.processToCompatSchema(originalSchema); | ||
| } else { | ||
| schemaToUse = toStandardSchema(originalSchema); | ||
| } | ||
| processedInputSchema = jsonSchema( | ||
| standardSchemaToJSONSchema(schemaToUse, { | ||
| io: "input" | ||
| }), | ||
| { | ||
| validate: (value) => { | ||
| const result = schemaToUse["~standard"].validate(value); | ||
| if (result instanceof Promise) { | ||
| return result.then((r) => { | ||
| if ("issues" in r && r.issues) { | ||
| return { | ||
| success: false, | ||
| error: new Error(r.issues.map((i) => i.message).join(", ")) | ||
| }; | ||
| } | ||
| return { success: true, value: r.value }; | ||
| }); | ||
| } | ||
| if ("issues" in result && result.issues) { | ||
| return { | ||
| success: false, | ||
| error: new Error(result.issues.map((i) => i.message).join(", ")) | ||
| }; | ||
| } | ||
| return { success: true, value: result.value }; | ||
| } | ||
| } | ||
| ); | ||
| } else { | ||
| processedInputSchema = applyCompatLayer({ | ||
| schema: originalSchema, | ||
| compatLayers: schemaCompatLayers, | ||
| mode: "aiSdkSchema" | ||
| }); | ||
| } | ||
| } | ||
| const outputSchema = this.getOutputSchema(); | ||
| let processedOutputSchema; | ||
| if (outputSchema) { | ||
| if (isStandardSchemaWithJSON(outputSchema)) { | ||
| processedOutputSchema = standardSchemaToJSONSchema(outputSchema, { io: "output" }); | ||
| } else { | ||
| processedOutputSchema = applyCompatLayer({ | ||
| schema: outputSchema, | ||
| compatLayers: [], | ||
| mode: "aiSdkSchema" | ||
| }); | ||
| } | ||
| } | ||
| let requireApproval = false; | ||
| let needsApprovalFn; | ||
| if (typeof this.options.requireApproval === "function") { | ||
| requireApproval = true; | ||
| needsApprovalFn = this.options.requireApproval; | ||
| } else if (typeof this.options.requireApproval === "boolean") { | ||
| requireApproval = this.options.requireApproval; | ||
| needsApprovalFn = void 0; | ||
| } | ||
| if (isVercelTool(this.originalTool) && "needsApproval" in this.originalTool) { | ||
| const needsApproval = this.originalTool.needsApproval; | ||
| if (typeof needsApproval === "boolean") { | ||
| requireApproval = needsApproval; | ||
| needsApprovalFn = void 0; | ||
| } else if (typeof needsApproval === "function") { | ||
| needsApprovalFn = needsApproval; | ||
| requireApproval = true; | ||
| } | ||
| } | ||
| const instanceNeedsApprovalFn = getNeedsApprovalFn(this.originalTool); | ||
| if (!needsApprovalFn && instanceNeedsApprovalFn) { | ||
| needsApprovalFn = instanceNeedsApprovalFn; | ||
| requireApproval = true; | ||
| } | ||
| const definition = { | ||
| type: "function", | ||
| description: this.originalTool.description, | ||
| requireApproval, | ||
| needsApprovalFn, | ||
| hasSuspendSchema: !!this.getSuspendSchema(), | ||
| execute: this.originalTool.execute ? this.createExecute( | ||
| this.originalTool, | ||
| { ...this.options, description: this.originalTool.description }, | ||
| this.logType | ||
| ) : void 0 | ||
| }; | ||
| return { | ||
| ...definition, | ||
| id: "id" in this.originalTool ? this.originalTool.id : void 0, | ||
| parameters: processedInputSchema ?? z.object({}), | ||
| outputSchema: processedOutputSchema, | ||
| strict: "strict" in this.originalTool ? this.originalTool.strict : void 0, | ||
| providerOptions: "providerOptions" in this.originalTool ? this.originalTool.providerOptions : void 0, | ||
| mcp: "mcp" in this.originalTool ? this.originalTool.mcp : void 0, | ||
| toModelOutput: "toModelOutput" in this.originalTool ? this.originalTool.toModelOutput : void 0, | ||
| transform: "transform" in this.originalTool ? this.originalTool.transform : void 0, | ||
| inputExamples: "inputExamples" in this.originalTool ? this.originalTool.inputExamples : void 0, | ||
| onInputStart: "onInputStart" in this.originalTool ? this.originalTool.onInputStart : void 0, | ||
| onInputDelta: "onInputDelta" in this.originalTool ? this.originalTool.onInputDelta : void 0, | ||
| onInputAvailable: "onInputAvailable" in this.originalTool ? this.originalTool.onInputAvailable : void 0, | ||
| onOutput: "onOutput" in this.originalTool ? this.originalTool.onOutput : void 0, | ||
| // Preserve tool-level background config so the agentic loop can pick it up | ||
| // from the converted CoreTool at dispatch time. | ||
| backgroundConfig: this.options.backgroundConfig | ||
| }; | ||
| } | ||
| }; | ||
| // src/utils.ts | ||
| var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); | ||
| function safeStringify(value, space) { | ||
| const stack = []; | ||
| return JSON.stringify( | ||
| value, | ||
| function(_key, val) { | ||
| if (typeof val === "bigint") return val.toString(); | ||
| if (val !== null && typeof val === "object") { | ||
| while (stack.length > 0 && stack[stack.length - 1] !== this) { | ||
| stack.pop(); | ||
| } | ||
| if (stack.includes(val)) return "[Circular]"; | ||
| stack.push(val); | ||
| } | ||
| return val; | ||
| }, | ||
| space | ||
| ); | ||
| } | ||
| function ensureSerializable(value) { | ||
| if (value === null || typeof value !== "object") return value; | ||
| try { | ||
| JSON.stringify(value); | ||
| return value; | ||
| } catch { | ||
| return JSON.parse(safeStringify(value)); | ||
| } | ||
| } | ||
| function isPlainObject(value) { | ||
| if (value === null || typeof value !== "object") return false; | ||
| const proto = Object.getPrototypeOf(value); | ||
| return proto === Object.prototype || proto === null; | ||
| } | ||
| function deepMerge(target, source) { | ||
| const output = { ...target }; | ||
| if (!source) return output; | ||
| Object.keys(source).forEach((key) => { | ||
| const targetValue = output[key]; | ||
| const sourceValue = source[key]; | ||
| if (isPlainObject(targetValue) && isPlainObject(sourceValue)) { | ||
| output[key] = deepMerge(targetValue, sourceValue); | ||
| } else if (sourceValue !== void 0) { | ||
| output[key] = sourceValue; | ||
| } | ||
| }); | ||
| return output; | ||
| } | ||
| function deepEqual(a, b) { | ||
| if (a === b) return true; | ||
| if (a == null || b == null) return a === b; | ||
| if (typeof a !== typeof b) return false; | ||
| if (Array.isArray(a) && Array.isArray(b)) { | ||
| if (a.length !== b.length) return false; | ||
| return a.every((item, index) => deepEqual(item, b[index])); | ||
| } | ||
| if (a instanceof Date && b instanceof Date) { | ||
| return a.getTime() === b.getTime(); | ||
| } | ||
| if (typeof a === "object" && typeof b === "object") { | ||
| const aObj = a; | ||
| const bObj = b; | ||
| const aKeys = Object.keys(aObj); | ||
| const bKeys = Object.keys(bObj); | ||
| if (aKeys.length !== bKeys.length) return false; | ||
| return aKeys.every((key) => Object.prototype.hasOwnProperty.call(bObj, key) && deepEqual(aObj[key], bObj[key])); | ||
| } | ||
| return false; | ||
| } | ||
| function generateEmptyFromSchema(schema) { | ||
| try { | ||
| const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema; | ||
| if (!parsedSchema || parsedSchema.type !== "object" || !parsedSchema.properties) return {}; | ||
| const obj = {}; | ||
| for (const [key, prop] of Object.entries( | ||
| parsedSchema.properties | ||
| )) { | ||
| if (prop.default !== void 0) { | ||
| obj[key] = typeof prop.default === "object" && prop.default !== null ? JSON.parse(JSON.stringify(prop.default)) : prop.default; | ||
| } else if (prop.type === "object" && prop.properties) { | ||
| obj[key] = generateEmptyFromSchema(prop); | ||
| } else if (prop.type === "object") { | ||
| obj[key] = {}; | ||
| } else if (prop.type === "string") { | ||
| obj[key] = ""; | ||
| } else if (prop.type === "array") { | ||
| obj[key] = []; | ||
| } else if (prop.type === "number" || prop.type === "integer") { | ||
| obj[key] = 0; | ||
| } else if (prop.type === "boolean") { | ||
| obj[key] = false; | ||
| } else { | ||
| obj[key] = null; | ||
| } | ||
| } | ||
| return obj; | ||
| } catch { | ||
| return {}; | ||
| } | ||
| } | ||
| async function* maskStreamTags(stream, tag, options = {}) { | ||
| const { onStart, onEnd, onMask } = options; | ||
| const openTag = `<${tag}>`; | ||
| const closeTag = `</${tag}>`; | ||
| let buffer = ""; | ||
| let fullContent = ""; | ||
| let isMasking = false; | ||
| let isBuffering = false; | ||
| const trimOutsideDelimiter = (text, delimiter, trim) => { | ||
| if (!text.includes(delimiter)) { | ||
| return text; | ||
| } | ||
| const parts = text.split(delimiter); | ||
| if (trim === `before-start`) { | ||
| return `${delimiter}${parts[1]}`; | ||
| } | ||
| return `${parts[0]}${delimiter}`; | ||
| }; | ||
| const startsWith = (text, pattern) => { | ||
| if (pattern.includes(openTag.substring(0, 3))) { | ||
| pattern = trimOutsideDelimiter(pattern, `<`, `before-start`); | ||
| } | ||
| return text.trim().startsWith(pattern.trim()); | ||
| }; | ||
| for await (const chunk of stream) { | ||
| fullContent += chunk; | ||
| if (isBuffering) buffer += chunk; | ||
| const chunkHasTag = startsWith(chunk, openTag); | ||
| const bufferHasTag = !chunkHasTag && isBuffering && startsWith(openTag, buffer); | ||
| let toYieldBeforeMaskedStartTag = ``; | ||
| if (!isMasking && (chunkHasTag || bufferHasTag)) { | ||
| isMasking = true; | ||
| isBuffering = false; | ||
| const taggedTextToMask = trimOutsideDelimiter(buffer, `<`, `before-start`); | ||
| if (taggedTextToMask !== buffer.trim()) { | ||
| toYieldBeforeMaskedStartTag = buffer.replace(taggedTextToMask, ``); | ||
| } | ||
| buffer = ""; | ||
| onStart?.(); | ||
| } | ||
| if (!isMasking && !isBuffering && startsWith(openTag, chunk) && chunk.trim() !== "") { | ||
| isBuffering = true; | ||
| buffer += chunk; | ||
| continue; | ||
| } | ||
| if (isBuffering && buffer && !startsWith(openTag, buffer)) { | ||
| yield buffer; | ||
| buffer = ""; | ||
| isBuffering = false; | ||
| continue; | ||
| } | ||
| if (isMasking && fullContent.includes(closeTag)) { | ||
| onMask?.(chunk); | ||
| onEnd?.(); | ||
| isMasking = false; | ||
| const lastFullContent = fullContent; | ||
| fullContent = ``; | ||
| const textUntilEndTag = trimOutsideDelimiter(lastFullContent, closeTag, "after-end"); | ||
| if (textUntilEndTag !== lastFullContent) { | ||
| yield lastFullContent.replace(textUntilEndTag, ``); | ||
| } | ||
| continue; | ||
| } | ||
| if (isMasking) { | ||
| onMask?.(chunk); | ||
| if (toYieldBeforeMaskedStartTag) { | ||
| yield toYieldBeforeMaskedStartTag; | ||
| } | ||
| continue; | ||
| } | ||
| yield chunk; | ||
| } | ||
| } | ||
| function resolveSerializedZodOutput(schema) { | ||
| return Function("z", `"use strict";return (${schema});`)(z); | ||
| } | ||
| function isZodType(value) { | ||
| return typeof value === "object" && value !== null && "_def" in value && "parse" in value && typeof value.parse === "function" && "safeParse" in value && typeof value.safeParse === "function"; | ||
| } | ||
| function createDeterministicId(input) { | ||
| return createHash("sha256").update(input).digest("hex").slice(0, 8); | ||
| } | ||
| function setVercelToolProperties(tool) { | ||
| const inputSchema = "inputSchema" in tool ? tool.inputSchema : convertVercelToolParameters(tool); | ||
| const toolId = !("id" in tool) ? tool.description ? `tool-${createDeterministicId(tool.description)}` : `tool-${Math.random().toString(36).substring(2, 9)}` : tool.id; | ||
| return { | ||
| ...tool, | ||
| id: toolId, | ||
| inputSchema | ||
| }; | ||
| } | ||
| function ensureToolProperties(tools) { | ||
| const toolsWithProperties = Object.keys(tools).reduce((acc, key) => { | ||
| const tool = tools?.[key]; | ||
| if (tool) { | ||
| if (typeof tool === "function" && !(tool instanceof Tool) && !isVercelTool(tool)) { | ||
| throw new MastraError({ | ||
| id: "TOOL_INVALID_FORMAT", | ||
| domain: ErrorDomain.TOOL, | ||
| category: ErrorCategory.USER, | ||
| text: `Tool "${key}" is not a valid tool format. Tools must be created using createTool() or be a valid Vercel AI SDK tool. Received a function.` | ||
| }); | ||
| } | ||
| if (isVercelTool(tool)) { | ||
| acc[key] = setVercelToolProperties(tool); | ||
| } else { | ||
| acc[key] = tool; | ||
| } | ||
| } | ||
| return acc; | ||
| }, {}); | ||
| return toolsWithProperties; | ||
| } | ||
| function convertVercelToolParameters(tool) { | ||
| let schema = tool.parameters ?? z.object({}); | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return isZodType(schema) ? schema : resolveSerializedZodOutput(jsonSchemaToZod(schema)); | ||
| } | ||
| function makeCoreTool(originalTool, options, logType, autoResumeSuspendedTools, backgroundTaskEnabled) { | ||
| return new CoreToolBuilder({ | ||
| originalTool, | ||
| options, | ||
| logType, | ||
| autoResumeSuspendedTools, | ||
| backgroundTaskEnabled | ||
| }).build(); | ||
| } | ||
| function makeCoreToolV5(originalTool, options, logType, autoResumeSuspendedTools, backgroundTaskEnabled) { | ||
| return new CoreToolBuilder({ | ||
| originalTool, | ||
| options, | ||
| logType, | ||
| autoResumeSuspendedTools, | ||
| backgroundTaskEnabled | ||
| }).buildV5(); | ||
| } | ||
| function createMastraProxy({ mastra, logger }) { | ||
| return new Proxy(mastra, { | ||
| get(target, prop) { | ||
| const hasProp = Reflect.has(target, prop); | ||
| if (hasProp) { | ||
| const value = Reflect.get(target, prop); | ||
| const isFunction = typeof value === "function"; | ||
| if (isFunction) { | ||
| return value.bind(target); | ||
| } | ||
| return value; | ||
| } | ||
| if (prop === "logger") { | ||
| logger.warn("Please use 'getLogger' instead, logger is deprecated"); | ||
| return Reflect.apply(target.getLogger, target, []); | ||
| } | ||
| if (prop === "storage") { | ||
| logger.warn("Please use 'getStorage' instead, storage is deprecated"); | ||
| return Reflect.get(target, "storage"); | ||
| } | ||
| if (prop === "agents") { | ||
| logger.warn("Please use 'listAgents' instead, agents is deprecated"); | ||
| return Reflect.apply(target.listAgents, target, []); | ||
| } | ||
| if (prop === "tts") { | ||
| logger.warn("Please use 'getTTS' instead, tts is deprecated"); | ||
| return Reflect.apply(target.getTTS, target, []); | ||
| } | ||
| if (prop === "vectors") { | ||
| logger.warn("Please use 'getVectors' instead, vectors is deprecated"); | ||
| return Reflect.apply(target.getVectors, target, []); | ||
| } | ||
| if (prop === "memory") { | ||
| logger.warn("Please use 'getMemory' instead, memory is deprecated"); | ||
| return Reflect.get(target, "memory"); | ||
| } | ||
| return Reflect.get(target, prop); | ||
| } | ||
| }); | ||
| } | ||
| function checkEvalStorageFields(traceObject, logger) { | ||
| const missingFields = []; | ||
| if (!traceObject.input) missingFields.push("input"); | ||
| if (!traceObject.output) missingFields.push("output"); | ||
| if (!traceObject.agentName) missingFields.push("agent_name"); | ||
| if (!traceObject.metricName) missingFields.push("metric_name"); | ||
| if (!traceObject.instructions) missingFields.push("instructions"); | ||
| if (!traceObject.globalRunId) missingFields.push("global_run_id"); | ||
| if (!traceObject.runId) missingFields.push("run_id"); | ||
| if (missingFields.length > 0) { | ||
| if (logger) { | ||
| logger.warn("Skipping evaluation storage due to missing required fields", { | ||
| missingFields, | ||
| runId: traceObject.runId, | ||
| agentName: traceObject.agentName | ||
| }); | ||
| } else { | ||
| console.warn("Skipping evaluation storage due to missing required fields", { | ||
| missingFields, | ||
| runId: traceObject.runId, | ||
| agentName: traceObject.agentName | ||
| }); | ||
| } | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| function detectSingleMessageCharacteristics(message) { | ||
| if (typeof message === "object" && message !== null && (message.role === "function" || // UI-only role | ||
| message.role === "data" || // UI-only role | ||
| "toolInvocations" in message || // UI-specific field | ||
| "parts" in message || // UI-specific field | ||
| "experimental_attachments" in message)) { | ||
| return "has-ui-specific-parts"; | ||
| } else if (typeof message === "object" && message !== null && "content" in message && (Array.isArray(message.content) || // Core messages can have array content | ||
| "experimental_providerMetadata" in message || "providerOptions" in message)) { | ||
| return "has-core-specific-parts"; | ||
| } else if (typeof message === "object" && message !== null && "role" in message && "content" in message && typeof message.content === "string" && ["system", "user", "assistant", "tool"].includes(message.role)) { | ||
| return "message"; | ||
| } else { | ||
| return "other"; | ||
| } | ||
| } | ||
| function isUiMessage(message) { | ||
| return detectSingleMessageCharacteristics(message) === `has-ui-specific-parts`; | ||
| } | ||
| function isCoreMessage(message) { | ||
| return [`has-core-specific-parts`, `message`].includes(detectSingleMessageCharacteristics(message)); | ||
| } | ||
| var SQL_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/; | ||
| function parseSqlIdentifier(name, kind = "identifier") { | ||
| if (!SQL_IDENTIFIER_PATTERN.test(name) || name.length > 63) { | ||
| throw new Error( | ||
| `Invalid ${kind}: ${name}. Must start with a letter or underscore, contain only letters, numbers, or underscores, and be at most 63 characters long.` | ||
| ); | ||
| } | ||
| return name; | ||
| } | ||
| function parseFieldKey(key) { | ||
| if (!key) throw new Error("Field key cannot be empty"); | ||
| const segments = key.split("."); | ||
| for (const segment of segments) { | ||
| if (!SQL_IDENTIFIER_PATTERN.test(segment) || segment.length > 63) { | ||
| throw new Error(`Invalid field key segment: ${segment} in ${key}`); | ||
| } | ||
| } | ||
| return key; | ||
| } | ||
| function omitKeys(obj, keysToOmit) { | ||
| return Object.fromEntries(Object.entries(obj).filter(([key]) => !keysToOmit.includes(key))); | ||
| } | ||
| function selectFields(obj, fields) { | ||
| if (!obj || typeof obj !== "object") { | ||
| return obj; | ||
| } | ||
| const result = {}; | ||
| for (const field of fields) { | ||
| const value = getNestedValue(obj, field); | ||
| if (value !== void 0) { | ||
| setNestedValue(result, field, value); | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function getNestedValue(obj, path) { | ||
| return path.split(".").reduce((current, key) => { | ||
| return current && typeof current === "object" ? current[key] : void 0; | ||
| }, obj); | ||
| } | ||
| function setNestedValue(obj, path, value) { | ||
| const keys = path.split("."); | ||
| const lastKey = keys.pop(); | ||
| if (!lastKey) return; | ||
| for (const key of keys) { | ||
| if (key === "__proto__" || key === "constructor" || key === "prototype") { | ||
| return; | ||
| } | ||
| } | ||
| if (lastKey === "__proto__" || lastKey === "constructor" || lastKey === "prototype") { | ||
| return; | ||
| } | ||
| let current = obj; | ||
| for (const key of keys) { | ||
| const existing = Object.prototype.hasOwnProperty.call(current, key) ? current[key] : void 0; | ||
| if (existing === null || typeof existing !== "object") { | ||
| const container = /* @__PURE__ */ Object.create(null); | ||
| Object.defineProperty(current, key, { value: container, writable: true, enumerable: true, configurable: true }); | ||
| } | ||
| current = current[key]; | ||
| } | ||
| Object.defineProperty(current, lastKey, { value, writable: true, enumerable: true, configurable: true }); | ||
| } | ||
| var removeUndefinedValues = (obj) => { | ||
| return Object.fromEntries(Object.entries(obj).filter(([_, value]) => value !== void 0)); | ||
| }; | ||
| export { ToolStream, checkEvalStorageFields, createMastraProxy, deepEqual, deepMerge, delay, ensureSerializable, ensureToolProperties, generateEmptyFromSchema, getNestedValue, isCoreMessage, isUiMessage, isZodType, makeCoreTool, makeCoreToolV5, maskStreamTags, noopObserve, omitKeys, parseFieldKey, parseSqlIdentifier, removeUndefinedValues, resolveSerializedZodOutput, safeStringify, selectFields, setNestedValue }; | ||
| //# sourceMappingURL=chunk-M2TW4P2L.js.map | ||
| //# sourceMappingURL=chunk-M2TW4P2L.js.map |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunkBP67LMWW_cjs = require('./chunk-BP67LMWW.cjs'); | ||
| var chunkXB4FLS7A_cjs = require('./chunk-XB4FLS7A.cjs'); | ||
| var chunkCMKSC37Z_cjs = require('./chunk-CMKSC37Z.cjs'); | ||
| var chunkSZ2THGT4_cjs = require('./chunk-SZ2THGT4.cjs'); | ||
| var chunkLP4WZA6D_cjs = require('./chunk-LP4WZA6D.cjs'); | ||
| var chunkWSD4JNMB_cjs = require('./chunk-WSD4JNMB.cjs'); | ||
| var chunkI4YELKDU_cjs = require('./chunk-I4YELKDU.cjs'); | ||
| var chunkXSOONORA_cjs = require('./chunk-XSOONORA.cjs'); | ||
| var schemaCompat = require('@mastra/schema-compat'); | ||
| var crypto = require('crypto'); | ||
| // src/stream/aisdk/v4/usage.ts | ||
| function convertV4Usage(usage) { | ||
| if (!usage) { | ||
| return {}; | ||
| } | ||
| return { | ||
| inputTokens: usage.promptTokens, | ||
| outputTokens: usage.completionTokens | ||
| }; | ||
| } | ||
| // src/llm/model/model.ts | ||
| var MastraLLMV1 = class extends chunkWSD4JNMB_cjs.MastraBase { | ||
| #model; | ||
| #mastra; | ||
| #options; | ||
| constructor({ model, mastra, options }) { | ||
| super({ name: "aisdk" }); | ||
| this.#model = model; | ||
| this.#options = options; | ||
| if (mastra) { | ||
| this.#mastra = mastra; | ||
| if (mastra.getLogger()) { | ||
| this.__setLogger(this.#mastra.getLogger()); | ||
| } | ||
| } | ||
| } | ||
| __registerPrimitives(p) { | ||
| if (p.logger) { | ||
| this.__setLogger(p.logger); | ||
| } | ||
| } | ||
| __registerMastra(p) { | ||
| this.#mastra = p; | ||
| } | ||
| getProvider() { | ||
| return this.#model.provider; | ||
| } | ||
| getModelId() { | ||
| return this.#model.modelId; | ||
| } | ||
| getModel() { | ||
| return this.#model; | ||
| } | ||
| _applySchemaCompat(schema) { | ||
| const model = this.#model; | ||
| const schemaCompatLayers = []; | ||
| if (model) { | ||
| const modelInfo = { | ||
| modelId: model.modelId, | ||
| supportsStructuredOutputs: model.supportsStructuredOutputs ?? false, | ||
| provider: model.provider | ||
| }; | ||
| schemaCompatLayers.push( | ||
| new schemaCompat.OpenAIReasoningSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.OpenAISchemaCompatLayer(modelInfo), | ||
| new schemaCompat.GoogleSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.AnthropicSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.DeepSeekSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.MetaSchemaCompatLayer(modelInfo) | ||
| ); | ||
| } | ||
| return schemaCompat.applyCompatLayer({ | ||
| schema, | ||
| compatLayers: schemaCompatLayers, | ||
| mode: "aiSdkSchema" | ||
| }); | ||
| } | ||
| async __text({ | ||
| runId, | ||
| messages, | ||
| maxSteps = 5, | ||
| tools = {}, | ||
| temperature, | ||
| toolChoice = "auto", | ||
| onStepFinish, | ||
| experimental_output, | ||
| threadId, | ||
| resourceId, | ||
| requestContext, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = chunkSZ2THGT4_cjs.resolveObservabilityContext(rest); | ||
| this.logger.debug("Generating text", { | ||
| runId, | ||
| messages, | ||
| maxSteps, | ||
| threadId, | ||
| resourceId, | ||
| tools: Object.keys(tools) | ||
| }); | ||
| let schema = void 0; | ||
| if (experimental_output) { | ||
| this.logger.debug("Using experimental output", { | ||
| runId | ||
| }); | ||
| if (chunkBP67LMWW_cjs.isZodType(experimental_output)) { | ||
| schema = experimental_output; | ||
| if (chunkCMKSC37Z_cjs.isZodArray(schema)) { | ||
| schema = chunkCMKSC37Z_cjs.getZodDef(schema).type; | ||
| } | ||
| const standardSchema = chunkXB4FLS7A_cjs.toStandardSchema(schema); | ||
| const jsonSchemaToUse = chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(standardSchema); | ||
| schema = schemaCompat.jsonSchema(jsonSchemaToUse); | ||
| } else { | ||
| schema = schemaCompat.jsonSchema(experimental_output); | ||
| } | ||
| } | ||
| if (tools && Object.keys(tools).length > 0) { | ||
| for (const tool of Object.values(tools)) { | ||
| if (tool.parameters) { | ||
| if ("validate" in tool.parameters) { | ||
| tool.parameters = tool.parameters; | ||
| } else if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(tool.parameters)) { | ||
| tool.parameters = schemaCompat.jsonSchema(chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(tool.parameters)); | ||
| } else { | ||
| tool.parameters = schemaCompat.jsonSchema(tool.parameters); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages, | ||
| schema | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: false | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| const argsForExecute = { | ||
| ...rest, | ||
| messages, | ||
| model, | ||
| temperature, | ||
| tools: { | ||
| ...tools | ||
| }, | ||
| toolChoice, | ||
| maxSteps, | ||
| onStepFinish: async (props) => { | ||
| try { | ||
| await onStepFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_TEXT_ON_STEP_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| finishReason: props?.finishReason, | ||
| toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "", | ||
| toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Text step change", { | ||
| text: props?.text, | ||
| toolCalls: props?.toolCalls, | ||
| toolResults: props?.toolResults, | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage, | ||
| runId | ||
| }); | ||
| const remainingTokens = parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"] ?? "", 10); | ||
| if (!isNaN(remainingTokens) && remainingTokens > 0 && remainingTokens < 2e3) { | ||
| this.logger.warn("Rate limit approaching, waiting 10 seconds", { runId, remainingTokens }); | ||
| const rateLimitSpan = llmSpan?.createChildSpan({ | ||
| name: "rate-limit-sleep", | ||
| type: "generic" /* GENERIC */, | ||
| metadata: { remainingTokens, delayMs: 1e4 } | ||
| }); | ||
| await chunkBP67LMWW_cjs.delay(10 * 1e3); | ||
| rateLimitSpan?.end(); | ||
| } | ||
| }, | ||
| experimental_output: schema ? chunkI4YELKDU_cjs.output_exports.object({ | ||
| schema | ||
| }) : void 0 | ||
| }; | ||
| try { | ||
| const result = await chunkLP4WZA6D_cjs.executeWithContext({ | ||
| span: llmSpan, | ||
| fn: () => chunkI4YELKDU_cjs.generateText(argsForExecute) | ||
| }); | ||
| if (schema && result.finishReason === "stop") { | ||
| result.object = result.experimental_output; | ||
| } | ||
| llmSpan?.end({ | ||
| output: { | ||
| text: result.text, | ||
| object: result.object, | ||
| reasoning: result.reasoningDetails, | ||
| reasoningText: result.reasoning, | ||
| files: result.files, | ||
| sources: result.sources, | ||
| toolCalls: result.toolCalls, | ||
| warnings: result.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: result.finishReason, | ||
| responseId: result.response?.id, | ||
| responseModel: result.response?.modelId, | ||
| usage: convertV4Usage(result.usage) | ||
| } | ||
| }); | ||
| return result; | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_GENERATE_TEXT_AI_SDK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Generate text failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| async __textObject({ | ||
| messages, | ||
| structuredOutput, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| requestContext, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = chunkSZ2THGT4_cjs.resolveObservabilityContext(rest); | ||
| this.logger.debug("Generating text object", { runId }); | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature: rest.temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: false | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| try { | ||
| let output = "object"; | ||
| if (chunkCMKSC37Z_cjs.isZodArray(structuredOutput)) { | ||
| output = "array"; | ||
| const zodDef = chunkCMKSC37Z_cjs.getZodDef(structuredOutput); | ||
| if ("element" in zodDef) { | ||
| structuredOutput = zodDef.element; | ||
| } else { | ||
| structuredOutput = zodDef.type; | ||
| } | ||
| } | ||
| const processedSchema = this._applySchemaCompat(structuredOutput); | ||
| llmSpan?.update({ | ||
| input: { | ||
| messages, | ||
| schema: processedSchema | ||
| } | ||
| }); | ||
| const argsForExecute = { | ||
| ...rest, | ||
| messages, | ||
| model, | ||
| output, | ||
| schema: processedSchema | ||
| }; | ||
| try { | ||
| const result = await chunkI4YELKDU_cjs.generateObject(argsForExecute); | ||
| llmSpan?.end({ | ||
| output: { | ||
| object: result.object, | ||
| warnings: result.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: result.finishReason, | ||
| responseId: result.response?.id, | ||
| responseModel: result.response?.modelId, | ||
| usage: convertV4Usage(result.usage) | ||
| } | ||
| }); | ||
| return result; | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_GENERATE_OBJECT_AI_SDK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Generate object failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } catch (e) { | ||
| if (e instanceof chunkXSOONORA_cjs.MastraError) { | ||
| throw e; | ||
| } | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_GENERATE_OBJECT_AI_SDK_SCHEMA_CONVERSION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Generate object schema conversion failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| __stream({ | ||
| messages, | ||
| onStepFinish, | ||
| onFinish, | ||
| maxSteps = 5, | ||
| tools = {}, | ||
| runId, | ||
| temperature, | ||
| toolChoice = "auto", | ||
| experimental_output, | ||
| threadId, | ||
| resourceId, | ||
| requestContext, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = chunkSZ2THGT4_cjs.resolveObservabilityContext(rest); | ||
| let schema; | ||
| if (experimental_output) { | ||
| if (typeof experimental_output.parse === "function") { | ||
| schema = experimental_output; | ||
| if (chunkCMKSC37Z_cjs.isZodArray(schema)) { | ||
| schema = chunkCMKSC37Z_cjs.getZodDef(schema).type; | ||
| } | ||
| } else { | ||
| schema = schemaCompat.jsonSchema(experimental_output); | ||
| } | ||
| } | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: true | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| if (llmSpan) { | ||
| chunkLP4WZA6D_cjs.executeWithContextSync({ | ||
| span: llmSpan, | ||
| fn: () => this.logger.debug("Streaming text", { | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| messages, | ||
| maxSteps, | ||
| tools: Object.keys(tools || {}) | ||
| }) | ||
| }); | ||
| } | ||
| if (tools && Object.keys(tools).length > 0) { | ||
| for (const tool of Object.values(tools)) { | ||
| if (tool.parameters) { | ||
| if ("validate" in tool.parameters) { | ||
| tool.parameters = tool.parameters; | ||
| } else if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(tool.parameters)) { | ||
| tool.parameters = schemaCompat.jsonSchema(chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(tool.parameters)); | ||
| } else { | ||
| tool.parameters = schemaCompat.jsonSchema(tool.parameters); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| const argsForExecute = { | ||
| model, | ||
| temperature, | ||
| tools: { | ||
| ...tools | ||
| }, | ||
| maxSteps, | ||
| toolChoice, | ||
| onStepFinish: async (props) => { | ||
| try { | ||
| await onStepFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_ON_STEP_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| finishReason: props?.finishReason, | ||
| toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "", | ||
| toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.trackException(mastraError); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Stream step change", { | ||
| text: props?.text, | ||
| toolCalls: props?.toolCalls, | ||
| toolResults: props?.toolResults, | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage, | ||
| runId | ||
| }); | ||
| const remainingTokens = parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"] ?? "", 10); | ||
| if (!isNaN(remainingTokens) && remainingTokens > 0 && remainingTokens < 2e3) { | ||
| this.logger.warn("Rate limit approaching, waiting 10 seconds", { runId, remainingTokens }); | ||
| const rateLimitSpan = llmSpan?.createChildSpan({ | ||
| name: "rate-limit-sleep", | ||
| type: "generic" /* GENERIC */, | ||
| metadata: { remainingTokens, delayMs: 1e4 } | ||
| }); | ||
| await chunkBP67LMWW_cjs.delay(10 * 1e3); | ||
| rateLimitSpan?.end(); | ||
| } | ||
| }, | ||
| onFinish: async (props) => { | ||
| llmSpan?.end({ | ||
| output: { | ||
| text: props?.text, | ||
| reasoning: props?.reasoningDetails, | ||
| reasoningText: props?.reasoning, | ||
| files: props?.files, | ||
| sources: props?.sources, | ||
| toolCalls: props?.toolCalls, | ||
| warnings: props?.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: props?.finishReason, | ||
| usage: convertV4Usage(props?.usage) | ||
| } | ||
| }); | ||
| try { | ||
| await onFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_ON_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| finishReason: props?.finishReason, | ||
| toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "", | ||
| toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| llmSpan?.error({ error: mastraError }); | ||
| this.logger.trackException(mastraError); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Stream finished", { | ||
| text: props?.text, | ||
| toolCalls: props?.toolCalls, | ||
| toolResults: props?.toolResults, | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage, | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }); | ||
| }, | ||
| onError: ({ error }) => { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_TEXT_AI_SDK_STREAMING_ERROR", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| error | ||
| ); | ||
| this.logger.error("Stream text error", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| }, | ||
| ...rest, | ||
| messages, | ||
| experimental_output: schema ? chunkI4YELKDU_cjs.output_exports.object({ | ||
| schema | ||
| }) : void 0 | ||
| }; | ||
| try { | ||
| return chunkLP4WZA6D_cjs.executeWithContextSync({ span: llmSpan, fn: () => chunkI4YELKDU_cjs.streamText(argsForExecute) }); | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_TEXT_AI_SDK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Stream text failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| __streamObject({ | ||
| messages, | ||
| runId, | ||
| requestContext, | ||
| threadId, | ||
| resourceId, | ||
| onFinish, | ||
| structuredOutput, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = chunkSZ2THGT4_cjs.resolveObservabilityContext(rest); | ||
| this.logger.debug("Streaming structured output", { | ||
| runId, | ||
| messages | ||
| }); | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature: rest.temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: true | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| try { | ||
| let output = "object"; | ||
| if (chunkCMKSC37Z_cjs.isZodArray(structuredOutput)) { | ||
| output = "array"; | ||
| structuredOutput = chunkCMKSC37Z_cjs.getZodDef(structuredOutput).type; | ||
| } | ||
| const processedSchema = this._applySchemaCompat(structuredOutput); | ||
| llmSpan?.update({ | ||
| input: { | ||
| messages, | ||
| schema: processedSchema | ||
| } | ||
| }); | ||
| const argsForExecute = { | ||
| ...rest, | ||
| model, | ||
| onFinish: async (props) => { | ||
| llmSpan?.end({ | ||
| output: { | ||
| text: props?.text, | ||
| object: props?.object, | ||
| reasoning: props?.reasoningDetails, | ||
| reasoningText: props?.reasoning, | ||
| files: props?.files, | ||
| sources: props?.sources, | ||
| warnings: props?.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage | ||
| } | ||
| }); | ||
| try { | ||
| await onFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_ON_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| toolCalls: "", | ||
| toolResults: "", | ||
| finishReason: "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.trackException(mastraError); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Object stream finished", { | ||
| usage: props?.usage, | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }); | ||
| }, | ||
| onError: ({ error }) => { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_AI_SDK_STREAMING_ERROR", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| error | ||
| ); | ||
| this.logger.error("Stream object error", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| }, | ||
| messages, | ||
| output, | ||
| schema: processedSchema | ||
| }; | ||
| try { | ||
| return chunkI4YELKDU_cjs.streamObject(argsForExecute); | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_AI_SDK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Stream object failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } catch (e) { | ||
| if (e instanceof chunkXSOONORA_cjs.MastraError) { | ||
| llmSpan?.error({ error: e }); | ||
| throw e; | ||
| } | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_AI_SDK_SCHEMA_CONVERSION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Stream object schema conversion failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| convertToMessages(messages) { | ||
| if (Array.isArray(messages)) { | ||
| return messages.map((m) => { | ||
| if (typeof m === "string") { | ||
| return { | ||
| role: "user", | ||
| content: m | ||
| }; | ||
| } | ||
| return m; | ||
| }); | ||
| } | ||
| return [ | ||
| { | ||
| role: "user", | ||
| content: messages | ||
| } | ||
| ]; | ||
| } | ||
| async generate(messages, args) { | ||
| const msgs = this.convertToMessages(messages); | ||
| const { output, ...rest } = args ?? {}; | ||
| if (!output) { | ||
| return await this.__text({ | ||
| messages: msgs, | ||
| ...rest | ||
| }); | ||
| } | ||
| return await this.__textObject({ | ||
| messages: msgs, | ||
| structuredOutput: output, | ||
| ...rest | ||
| }); | ||
| } | ||
| stream(messages, args) { | ||
| const msgs = this.convertToMessages(messages); | ||
| const { output, ...rest } = args ?? {}; | ||
| if (!output) { | ||
| const { | ||
| maxSteps = 5, | ||
| onFinish: onFinish2, | ||
| ...streamRest | ||
| } = rest; | ||
| return this.__stream({ | ||
| messages: msgs, | ||
| maxSteps, | ||
| onFinish: onFinish2, | ||
| ...streamRest | ||
| }); | ||
| } | ||
| const { onFinish, ...objectRest } = rest; | ||
| return this.__streamObject({ | ||
| messages: msgs, | ||
| structuredOutput: output, | ||
| onFinish, | ||
| ...objectRest | ||
| }); | ||
| } | ||
| }; | ||
| function createStreamFromGenerateResult(result) { | ||
| return new ReadableStream({ | ||
| start(controller) { | ||
| controller.enqueue({ type: "stream-start", warnings: result.warnings }); | ||
| controller.enqueue({ | ||
| type: "response-metadata", | ||
| id: result.response?.id, | ||
| modelId: result.response?.modelId, | ||
| timestamp: result.response?.timestamp | ||
| }); | ||
| const toolCallMeta = {}; | ||
| for (const message of result.content) { | ||
| if (message.type === "tool-call") { | ||
| const toolCall = message; | ||
| toolCallMeta[toolCall.toolCallId] = { providerExecuted: toolCall.providerExecuted }; | ||
| controller.enqueue({ | ||
| type: "tool-input-start", | ||
| id: toolCall.toolCallId, | ||
| toolName: toolCall.toolName, | ||
| providerExecuted: toolCall.providerExecuted, | ||
| dynamic: toolCall.dynamic, | ||
| providerMetadata: toolCall.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "tool-input-delta", | ||
| id: toolCall.toolCallId, | ||
| delta: toolCall.input, | ||
| providerMetadata: toolCall.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "tool-input-end", | ||
| id: toolCall.toolCallId, | ||
| providerMetadata: toolCall.providerMetadata | ||
| }); | ||
| controller.enqueue(toolCall); | ||
| } else if (message.type === "tool-result") { | ||
| const toolResult = message; | ||
| const meta = toolCallMeta[toolResult.toolCallId]; | ||
| if (meta?.providerExecuted) { | ||
| controller.enqueue({ ...toolResult, providerExecuted: meta.providerExecuted }); | ||
| } else { | ||
| controller.enqueue(message); | ||
| } | ||
| } else if (message.type === "text") { | ||
| const text = message; | ||
| const id = `msg_${crypto.randomUUID()}`; | ||
| controller.enqueue({ | ||
| type: "text-start", | ||
| id, | ||
| providerMetadata: text.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "text-delta", | ||
| id, | ||
| delta: text.text | ||
| }); | ||
| controller.enqueue({ | ||
| type: "text-end", | ||
| id | ||
| }); | ||
| } else if (message.type === "reasoning") { | ||
| const id = `reasoning_${crypto.randomUUID()}`; | ||
| const reasoning = message; | ||
| controller.enqueue({ | ||
| type: "reasoning-start", | ||
| id, | ||
| providerMetadata: reasoning.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "reasoning-delta", | ||
| id, | ||
| delta: reasoning.text, | ||
| providerMetadata: reasoning.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "reasoning-end", | ||
| id, | ||
| providerMetadata: reasoning.providerMetadata | ||
| }); | ||
| } else if (message.type === "file") { | ||
| const file = message; | ||
| controller.enqueue({ | ||
| type: "file", | ||
| mediaType: file.mediaType, | ||
| data: file.data | ||
| }); | ||
| } else if (message.type === "source") { | ||
| const source = message; | ||
| if (source.sourceType === "url") { | ||
| controller.enqueue({ | ||
| type: "source", | ||
| id: source.id, | ||
| sourceType: "url", | ||
| url: source.url, | ||
| title: source.title, | ||
| providerMetadata: source.providerMetadata | ||
| }); | ||
| } else { | ||
| controller.enqueue({ | ||
| type: "source", | ||
| id: source.id, | ||
| sourceType: "document", | ||
| mediaType: source.mediaType, | ||
| filename: source.filename, | ||
| title: source.title, | ||
| providerMetadata: source.providerMetadata | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| controller.enqueue({ | ||
| type: "finish", | ||
| finishReason: result.finishReason, | ||
| usage: result.usage, | ||
| providerMetadata: result.providerMetadata | ||
| }); | ||
| controller.close(); | ||
| } | ||
| }); | ||
| } | ||
| // src/llm/model/aisdk/v5/model.ts | ||
| function applyStrictForV2(options) { | ||
| if (!options.tools?.length) { | ||
| return options; | ||
| } | ||
| let hasStrictTool = false; | ||
| const sanitizedTools = options.tools.map((tool) => { | ||
| if (tool.type !== "function" || !("strict" in tool)) { | ||
| return tool; | ||
| } | ||
| if (tool.strict === true) { | ||
| hasStrictTool = true; | ||
| } | ||
| const { strict: _strict, ...rest } = tool; | ||
| return rest; | ||
| }); | ||
| let result = { | ||
| ...options, | ||
| tools: sanitizedTools | ||
| }; | ||
| if (hasStrictTool) { | ||
| const existingOpenai = options.providerOptions?.openai ?? {}; | ||
| if (existingOpenai.strictJsonSchema == null) { | ||
| result = { | ||
| ...result, | ||
| providerOptions: { | ||
| ...options.providerOptions, | ||
| openai: { | ||
| ...existingOpenai, | ||
| strictJsonSchema: true | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| var AISDKV5LanguageModel = class { | ||
| /** | ||
| * The language model must specify which language model interface version it implements. | ||
| */ | ||
| specificationVersion = "v2"; | ||
| /** | ||
| * Name of the provider for logging purposes. | ||
| */ | ||
| provider; | ||
| /** | ||
| * Provider-specific model ID for logging purposes. | ||
| */ | ||
| modelId; | ||
| gatewayId; | ||
| /** | ||
| * Supported URL patterns by media type for the provider. | ||
| * | ||
| * The keys are media type patterns or full media types (e.g. `*\/*` for everything, `audio/*`, `video/*`, or `application/pdf`). | ||
| * and the values are arrays of regular expressions that match the URL paths. | ||
| * The matching should be against lower-case URLs. | ||
| * Matched URLs are supported natively by the model and are not downloaded. | ||
| * @returns A map of supported URL patterns by media type (as a promise or a plain object). | ||
| */ | ||
| supportedUrls; | ||
| #model; | ||
| constructor(config) { | ||
| this.#model = config; | ||
| this.provider = this.#model.provider; | ||
| this.modelId = this.#model.modelId; | ||
| this.gatewayId = config.gatewayId; | ||
| this.supportedUrls = this.#model.supportedUrls; | ||
| } | ||
| async doGenerate(options) { | ||
| const result = await this.#model.doGenerate(applyStrictForV2(options)); | ||
| return { | ||
| ...result, | ||
| request: result.request, | ||
| response: result.response, | ||
| stream: createStreamFromGenerateResult(result) | ||
| }; | ||
| } | ||
| async doStream(options) { | ||
| return await this.#model.doStream(applyStrictForV2(options)); | ||
| } | ||
| /** | ||
| * Custom serialization for tracing/observability spans. | ||
| * `#model` is already a true JS private field and not enumerable, so | ||
| * the wrapped provider SDK client can't leak. This method makes the | ||
| * safe shape explicit and avoids walking `supportedUrls` (a | ||
| * PromiseLike / regex map that isn't useful in spans). | ||
| */ | ||
| serializeForSpan() { | ||
| return { | ||
| specificationVersion: this.specificationVersion, | ||
| modelId: this.modelId, | ||
| provider: this.provider, | ||
| gatewayId: this.gatewayId | ||
| }; | ||
| } | ||
| }; | ||
| exports.AISDKV5LanguageModel = AISDKV5LanguageModel; | ||
| exports.MastraLLMV1 = MastraLLMV1; | ||
| exports.createStreamFromGenerateResult = createStreamFromGenerateResult; | ||
| //# sourceMappingURL=chunk-PXCR3FNM.cjs.map | ||
| //# sourceMappingURL=chunk-PXCR3FNM.cjs.map |
Sorry, the diff of this file is too big to display
| import { VersionedStorageDomain, normalizePerPage, calculatePagination, FilesystemVersionedHelpers } from './chunk-SKZRHFF3.js'; | ||
| import { deepEqual } from './chunk-M2TW4P2L.js'; | ||
| // src/storage/domains/mcp-clients/base.ts | ||
| var MCPClientsStorage = class extends VersionedStorageDomain { | ||
| listKey = "mcpClients"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "mcpClientId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "MCP_CLIENTS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-clients/inmemory.ts | ||
| var InMemoryMCPClientsStorage = class extends MCPClientsStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.mcpClients.clear(); | ||
| this.db.mcpClientVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // MCP Client CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const config = this.db.mcpClients.get(id); | ||
| return config ? this.deepCopyConfig(config) : null; | ||
| } | ||
| async create(input) { | ||
| const { mcpClient } = input; | ||
| if (this.db.mcpClients.has(mcpClient.id)) { | ||
| throw new Error(`MCP client with id ${mcpClient.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newConfig = { | ||
| id: mcpClient.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpClient.authorId, | ||
| metadata: mcpClient.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.mcpClients.set(mcpClient.id, newConfig); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpClientId: mcpClient.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyConfig(newConfig); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingConfig = this.db.mcpClients.get(id); | ||
| if (!existingConfig) { | ||
| throw new Error(`MCP client with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedConfig = { | ||
| ...existingConfig, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingConfig.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpClients.set(id, updatedConfig); | ||
| return this.deepCopyConfig(updatedConfig); | ||
| } | ||
| async delete(id) { | ||
| this.db.mcpClients.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let configs = Array.from(this.db.mcpClients.values()); | ||
| if (status) { | ||
| configs = configs.filter((config) => config.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| configs = configs.filter((config) => config.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| configs = configs.filter((config) => { | ||
| if (!config.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedConfigs = this.sortConfigs(configs, field, direction); | ||
| const clonedConfigs = sortedConfigs.map((config) => this.deepCopyConfig(config)); | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| mcpClients: clonedConfigs.slice(offset, offset + perPage), | ||
| total: clonedConfigs.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedConfigs.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // MCP Client Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.mcpClientVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.mcpClientVersions.values()) { | ||
| if (version2.mcpClientId === input.mcpClientId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for MCP client ${input.mcpClientId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpClientVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.mcpClientVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(mcpClientId, versionNumber) { | ||
| for (const version of this.db.mcpClientVersions.values()) { | ||
| if (version.mcpClientId === mcpClientId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(mcpClientId) { | ||
| let latest = null; | ||
| for (const version of this.db.mcpClientVersions.values()) { | ||
| if (version.mcpClientId === mcpClientId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { mcpClientId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.mcpClientVersions.values()).filter((v) => v.mcpClientId === mcpClientId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.mcpClientVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.mcpClientVersions.entries()) { | ||
| if (version.mcpClientId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.mcpClientVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(mcpClientId) { | ||
| let count = 0; | ||
| for (const version of this.db.mcpClientVersions.values()) { | ||
| if (version.mcpClientId === mcpClientId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyConfig(config) { | ||
| return { | ||
| ...config, | ||
| metadata: config.metadata ? { ...config.metadata } : config.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| servers: version.servers ? JSON.parse(JSON.stringify(version.servers)) : version.servers, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortConfigs(configs, field, direction) { | ||
| return configs.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-clients/filesystem.ts | ||
| var FilesystemMCPClientsStorage = class extends MCPClientsStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "mcp-clients.json", | ||
| parentIdField: "mcpClientId", | ||
| name: "FilesystemMCPClientsStorage", | ||
| versionMetadataFields: ["id", "mcpClientId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { mcpClient } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: mcpClient.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpClient.authorId, | ||
| metadata: mcpClient.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(mcpClient.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpClientId: mcpClient.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "mcpClients", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(mcpClientId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(mcpClientId, versionNumber); | ||
| } | ||
| async getLatestVersion(mcpClientId) { | ||
| return this.helpers.getLatestVersion(mcpClientId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "mcpClientId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(mcpClientId) { | ||
| return this.helpers.countVersions(mcpClientId); | ||
| } | ||
| }; | ||
| export { FilesystemMCPClientsStorage, InMemoryMCPClientsStorage, MCPClientsStorage }; | ||
| //# sourceMappingURL=chunk-Q4AIRH5U.js.map | ||
| //# sourceMappingURL=chunk-Q4AIRH5U.js.map |
| {"version":3,"sources":["../src/storage/domains/mcp-clients/base.ts","../src/storage/domains/mcp-clients/inmemory.ts","../src/storage/domains/mcp-clients/filesystem.ts"],"names":["version"],"mappings":"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","file":"chunk-Q4AIRH5U.js","sourcesContent":["import type {\n StorageMCPClientType,\n StorageMCPClientSnapshotType,\n StorageResolvedMCPClientType,\n StorageCreateMCPClientInput,\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput,\n StorageListMCPClientsOutput,\n StorageListMCPClientsResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// MCP Client Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of an MCP client's content.\n * Client fields are top-level on the version row (no nested snapshot object).\n */\nexport interface MCPClientVersion extends StorageMCPClientSnapshotType, VersionBase {\n /** ID of the MCP client this version belongs to */\n mcpClientId: string;\n}\n\n/**\n * Input for creating a new MCP client version.\n * Client fields are top-level (no nested snapshot object).\n */\nexport interface CreateMCPClientVersionInput extends StorageMCPClientSnapshotType, CreateVersionInputBase {\n /** ID of the MCP client this version belongs to */\n mcpClientId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type MCPClientVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type MCPClientVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing MCP client versions with pagination and sorting.\n */\nexport interface ListMCPClientVersionsInput extends ListVersionsInputBase {\n /** ID of the MCP client to list versions for */\n mcpClientId: string;\n}\n\n/**\n * Output for listing MCP client versions with pagination info.\n */\nexport interface ListMCPClientVersionsOutput extends ListVersionsOutputBase<MCPClientVersion> {}\n\n// ============================================================================\n// MCPClientsStorage Base Class\n// ============================================================================\n\nexport abstract class MCPClientsStorage extends VersionedStorageDomain<\n StorageMCPClientType,\n StorageMCPClientSnapshotType,\n StorageResolvedMCPClientType,\n MCPClientVersion,\n CreateMCPClientVersionInput,\n ListMCPClientVersionsInput,\n ListMCPClientVersionsOutput,\n { mcpClient: StorageCreateMCPClientInput },\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput | undefined,\n StorageListMCPClientsOutput,\n StorageListMCPClientsResolvedOutput\n> {\n protected readonly listKey = 'mcpClients';\n protected readonly versionMetadataFields = [\n 'id',\n 'mcpClientId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof MCPClientVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'MCP_CLIENTS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageMCPClientType,\n StorageCreateMCPClientInput,\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput,\n StorageListMCPClientsOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n MCPClientVersion,\n CreateMCPClientVersionInput,\n ListMCPClientVersionsInput,\n ListMCPClientVersionsOutput,\n MCPClientVersionOrderBy,\n MCPClientVersionSortDirection,\n} from './base';\nimport { MCPClientsStorage } from './base';\n\nexport class InMemoryMCPClientsStorage extends MCPClientsStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.mcpClients.clear();\n this.db.mcpClientVersions.clear();\n }\n\n // ==========================================================================\n // MCP Client CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageMCPClientType | null> {\n const config = this.db.mcpClients.get(id);\n return config ? this.deepCopyConfig(config) : null;\n }\n\n async create(input: { mcpClient: StorageCreateMCPClientInput }): Promise<StorageMCPClientType> {\n const { mcpClient } = input;\n\n if (this.db.mcpClients.has(mcpClient.id)) {\n throw new Error(`MCP client with id ${mcpClient.id} already exists`);\n }\n\n const now = new Date();\n const newConfig: StorageMCPClientType = {\n id: mcpClient.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpClient.authorId,\n metadata: mcpClient.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.mcpClients.set(mcpClient.id, newConfig);\n\n // Extract config fields from the flat input (everything except record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpClientId: mcpClient.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin record\n return this.deepCopyConfig(newConfig);\n }\n\n async update(input: StorageUpdateMCPClientInput): Promise<StorageMCPClientType> {\n const { id, ...updates } = input;\n\n const existingConfig = this.db.mcpClients.get(id);\n if (!existingConfig) {\n throw new Error(`MCP client with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the record\n const updatedConfig: StorageMCPClientType = {\n ...existingConfig,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageMCPClientType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingConfig.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated record\n this.db.mcpClients.set(id, updatedConfig);\n return this.deepCopyConfig(updatedConfig);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.mcpClients.delete(id);\n // Also delete all versions for this client\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListMCPClientsInput): Promise<StorageListMCPClientsOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all MCP clients and apply filters\n let configs = Array.from(this.db.mcpClients.values());\n\n // Filter by status\n if (status) {\n configs = configs.filter(config => config.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n configs = configs.filter(config => config.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n configs = configs.filter(config => {\n if (!config.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata![key], value));\n });\n }\n\n // Sort filtered configs\n const sortedConfigs = this.sortConfigs(configs, field, direction);\n\n // Deep clone to avoid mutation\n const clonedConfigs = sortedConfigs.map(config => this.deepCopyConfig(config));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n mcpClients: clonedConfigs.slice(offset, offset + perPage),\n total: clonedConfigs.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedConfigs.length,\n };\n }\n\n // ==========================================================================\n // MCP Client Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateMCPClientVersionInput): Promise<MCPClientVersion> {\n // Check if version with this ID already exists\n if (this.db.mcpClientVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (mcpClientId, versionNumber) pair\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === input.mcpClientId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for MCP client ${input.mcpClientId}`);\n }\n }\n\n const version: MCPClientVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.mcpClientVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<MCPClientVersion | null> {\n const version = this.db.mcpClientVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(mcpClientId: string, versionNumber: number): Promise<MCPClientVersion | null> {\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === mcpClientId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(mcpClientId: string): Promise<MCPClientVersion | null> {\n let latest: MCPClientVersion | null = null;\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === mcpClientId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListMCPClientVersionsInput): Promise<ListMCPClientVersionsOutput> {\n const { mcpClientId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by mcpClientId\n let versions = Array.from(this.db.mcpClientVersions.values()).filter(v => v.mcpClientId === mcpClientId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.mcpClientVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.mcpClientVersions.entries()) {\n if (version.mcpClientId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.mcpClientVersions.delete(id);\n }\n }\n\n async countVersions(mcpClientId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === mcpClientId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyConfig(config: StorageMCPClientType): StorageMCPClientType {\n return {\n ...config,\n metadata: config.metadata ? { ...config.metadata } : config.metadata,\n };\n }\n\n private deepCopyVersion(version: MCPClientVersion): MCPClientVersion {\n return {\n ...version,\n servers: version.servers ? JSON.parse(JSON.stringify(version.servers)) : version.servers,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortConfigs(\n configs: StorageMCPClientType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageMCPClientType[] {\n return configs.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: MCPClientVersion[],\n field: MCPClientVersionOrderBy,\n direction: MCPClientVersionSortDirection,\n ): MCPClientVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageMCPClientType,\n StorageCreateMCPClientInput,\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput,\n StorageListMCPClientsOutput,\n} from '../../types';\nimport type {\n MCPClientVersion,\n CreateMCPClientVersionInput,\n ListMCPClientVersionsInput,\n ListMCPClientVersionsOutput,\n} from './base';\nimport { MCPClientsStorage } from './base';\n\nexport class FilesystemMCPClientsStorage extends MCPClientsStorage {\n private helpers: FilesystemVersionedHelpers<StorageMCPClientType, MCPClientVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'mcp-clients.json',\n parentIdField: 'mcpClientId',\n name: 'FilesystemMCPClientsStorage',\n versionMetadataFields: ['id', 'mcpClientId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageMCPClientType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { mcpClient: StorageCreateMCPClientInput }): Promise<StorageMCPClientType> {\n const { mcpClient } = input;\n const now = new Date();\n const entity: StorageMCPClientType = {\n id: mcpClient.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpClient.authorId,\n metadata: mcpClient.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(mcpClient.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpClientId: mcpClient.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateMCPClientVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateMCPClientInput): Promise<StorageMCPClientType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListMCPClientsInput): Promise<StorageListMCPClientsOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'mcpClients',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListMCPClientsOutput;\n }\n\n async createVersion(input: CreateMCPClientVersionInput): Promise<MCPClientVersion> {\n return this.helpers.createVersion(input as MCPClientVersion);\n }\n\n async getVersion(id: string): Promise<MCPClientVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(mcpClientId: string, versionNumber: number): Promise<MCPClientVersion | null> {\n return this.helpers.getVersionByNumber(mcpClientId, versionNumber);\n }\n\n async getLatestVersion(mcpClientId: string): Promise<MCPClientVersion | null> {\n return this.helpers.getLatestVersion(mcpClientId);\n }\n\n async listVersions(input: ListMCPClientVersionsInput): Promise<ListMCPClientVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'mcpClientId');\n return result as ListMCPClientVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(mcpClientId: string): Promise<number> {\n return this.helpers.countVersions(mcpClientId);\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { SignalProvider, TaskStateProcessor, taskCheckTool, taskCompleteTool, taskUpdateTool, taskWriteTool } from './chunk-PQ5PN4TW.js'; | ||
| // src/signals/task-signal-provider.ts | ||
| var TaskSignalProvider = class extends SignalProvider { | ||
| id = "task-signals"; | ||
| #processor = new TaskStateProcessor(); | ||
| getInputProcessors() { | ||
| return [this.#processor]; | ||
| } | ||
| getTools() { | ||
| return { | ||
| task_write: taskWriteTool, | ||
| task_update: taskUpdateTool, | ||
| task_complete: taskCompleteTool, | ||
| task_check: taskCheckTool | ||
| }; | ||
| } | ||
| }; | ||
| export { TaskSignalProvider }; | ||
| //# sourceMappingURL=chunk-SBQZFH46.js.map | ||
| //# sourceMappingURL=chunk-SBQZFH46.js.map |
| {"version":3,"sources":["../src/signals/task-signal-provider.ts"],"names":[],"mappings":";;;AA0CO,IAAM,kBAAA,GAAN,cAAiC,cAAA,CAA+B;AAAA,EAC5D,EAAA,GAAK,cAAA;AAAA,EAEL,UAAA,GAAa,IAAI,kBAAA,EAAmB;AAAA,EAE7C,kBAAA,GAAiD;AAC/C,IAAA,OAAO,CAAC,KAAK,UAAU,CAAA;AAAA,EACzB;AAAA,EAEA,QAAA,GAAW;AACT,IAAA,OAAO;AAAA,MACL,UAAA,EAAY,aAAA;AAAA,MACZ,WAAA,EAAa,cAAA;AAAA,MACb,aAAA,EAAe,gBAAA;AAAA,MACf,UAAA,EAAY;AAAA,KACd;AAAA,EACF;AACF","file":"chunk-SBQZFH46.js","sourcesContent":["import type { InputProcessorOrWorkflow } from '../processors';\nimport { TaskStateProcessor } from '../tools/builtin/task-state-processor';\nimport { taskCheckTool, taskCompleteTool, taskUpdateTool, taskWriteTool } from '../tools/builtin/task-tools';\n\nimport { SignalProvider } from './signal-provider';\n\n/**\n * Bundles the built-in task tools and the {@link TaskStateProcessor} behind a\n * single agent registration.\n *\n * The task list is held in the thread-scoped `tasks` storage domain (the\n * TaskStore) and projected onto the agent state-signal lane by\n * `TaskStateProcessor`. Wiring task tracking by hand means registering all four\n * task tools **and** the processor, and keeping them in sync — forget the\n * processor and the tools work for a single turn but silently lose the list\n * across turns. This provider wires both together so that cannot happen.\n *\n * Task tracking requires a memory-backed thread (`threadId` + `resourceId`) and\n * a Mastra `storage` instance (the `tasks` domain is always wired in-memory by\n * default). Without memory the tools no-op and report that task tracking\n * requires agent memory.\n *\n * @example\n * ```ts\n * import { Agent } from '@mastra/core/agent';\n * import { TaskSignalProvider } from '@mastra/core/signals';\n *\n * const agent = new Agent({\n * name: 'coder',\n * instructions: '...',\n * model,\n * memory,\n * signals: [new TaskSignalProvider()],\n * });\n * ```\n *\n * The Agent automatically merges the tools into its toolset and registers the\n * processor on its input-processor chain (which propagates the Mastra instance\n * so the processor can resolve the TaskStore).\n *\n * @experimental Agent signals are experimental and may change in a future release.\n */\nexport class TaskSignalProvider extends SignalProvider<'task-signals'> {\n readonly id = 'task-signals';\n\n readonly #processor = new TaskStateProcessor();\n\n getInputProcessors(): InputProcessorOrWorkflow[] {\n return [this.#processor];\n }\n\n getTools() {\n return {\n task_write: taskWriteTool,\n task_update: taskUpdateTool,\n task_complete: taskCompleteTool,\n task_check: taskCheckTool,\n };\n }\n}\n"]} |
| import { isZodType, delay } from './chunk-M2TW4P2L.js'; | ||
| import { toStandardSchema, standardSchemaToJSONSchema, isStandardSchemaWithJSON } from './chunk-6SRTDZ7S.js'; | ||
| import { isZodArray, getZodDef } from './chunk-TBHKQLPL.js'; | ||
| import { resolveObservabilityContext } from './chunk-JPUBRZLW.js'; | ||
| import { executeWithContext, executeWithContextSync } from './chunk-DEQCJWZZ.js'; | ||
| import { MastraBase } from './chunk-77VL4DNS.js'; | ||
| import { output_exports, generateText, generateObject, streamText, streamObject } from './chunk-D23QKBCZ.js'; | ||
| import { MastraError, ErrorCategory, ErrorDomain } from './chunk-M7RBQNFP.js'; | ||
| import { OpenAIReasoningSchemaCompatLayer, OpenAISchemaCompatLayer, GoogleSchemaCompatLayer, AnthropicSchemaCompatLayer, DeepSeekSchemaCompatLayer, MetaSchemaCompatLayer, applyCompatLayer, jsonSchema } from '@mastra/schema-compat'; | ||
| import { randomUUID } from 'crypto'; | ||
| // src/stream/aisdk/v4/usage.ts | ||
| function convertV4Usage(usage) { | ||
| if (!usage) { | ||
| return {}; | ||
| } | ||
| return { | ||
| inputTokens: usage.promptTokens, | ||
| outputTokens: usage.completionTokens | ||
| }; | ||
| } | ||
| // src/llm/model/model.ts | ||
| var MastraLLMV1 = class extends MastraBase { | ||
| #model; | ||
| #mastra; | ||
| #options; | ||
| constructor({ model, mastra, options }) { | ||
| super({ name: "aisdk" }); | ||
| this.#model = model; | ||
| this.#options = options; | ||
| if (mastra) { | ||
| this.#mastra = mastra; | ||
| if (mastra.getLogger()) { | ||
| this.__setLogger(this.#mastra.getLogger()); | ||
| } | ||
| } | ||
| } | ||
| __registerPrimitives(p) { | ||
| if (p.logger) { | ||
| this.__setLogger(p.logger); | ||
| } | ||
| } | ||
| __registerMastra(p) { | ||
| this.#mastra = p; | ||
| } | ||
| getProvider() { | ||
| return this.#model.provider; | ||
| } | ||
| getModelId() { | ||
| return this.#model.modelId; | ||
| } | ||
| getModel() { | ||
| return this.#model; | ||
| } | ||
| _applySchemaCompat(schema) { | ||
| const model = this.#model; | ||
| const schemaCompatLayers = []; | ||
| if (model) { | ||
| const modelInfo = { | ||
| modelId: model.modelId, | ||
| supportsStructuredOutputs: model.supportsStructuredOutputs ?? false, | ||
| provider: model.provider | ||
| }; | ||
| schemaCompatLayers.push( | ||
| new OpenAIReasoningSchemaCompatLayer(modelInfo), | ||
| new OpenAISchemaCompatLayer(modelInfo), | ||
| new GoogleSchemaCompatLayer(modelInfo), | ||
| new AnthropicSchemaCompatLayer(modelInfo), | ||
| new DeepSeekSchemaCompatLayer(modelInfo), | ||
| new MetaSchemaCompatLayer(modelInfo) | ||
| ); | ||
| } | ||
| return applyCompatLayer({ | ||
| schema, | ||
| compatLayers: schemaCompatLayers, | ||
| mode: "aiSdkSchema" | ||
| }); | ||
| } | ||
| async __text({ | ||
| runId, | ||
| messages, | ||
| maxSteps = 5, | ||
| tools = {}, | ||
| temperature, | ||
| toolChoice = "auto", | ||
| onStepFinish, | ||
| experimental_output, | ||
| threadId, | ||
| resourceId, | ||
| requestContext, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = resolveObservabilityContext(rest); | ||
| this.logger.debug("Generating text", { | ||
| runId, | ||
| messages, | ||
| maxSteps, | ||
| threadId, | ||
| resourceId, | ||
| tools: Object.keys(tools) | ||
| }); | ||
| let schema = void 0; | ||
| if (experimental_output) { | ||
| this.logger.debug("Using experimental output", { | ||
| runId | ||
| }); | ||
| if (isZodType(experimental_output)) { | ||
| schema = experimental_output; | ||
| if (isZodArray(schema)) { | ||
| schema = getZodDef(schema).type; | ||
| } | ||
| const standardSchema = toStandardSchema(schema); | ||
| const jsonSchemaToUse = standardSchemaToJSONSchema(standardSchema); | ||
| schema = jsonSchema(jsonSchemaToUse); | ||
| } else { | ||
| schema = jsonSchema(experimental_output); | ||
| } | ||
| } | ||
| if (tools && Object.keys(tools).length > 0) { | ||
| for (const tool of Object.values(tools)) { | ||
| if (tool.parameters) { | ||
| if ("validate" in tool.parameters) { | ||
| tool.parameters = tool.parameters; | ||
| } else if (isStandardSchemaWithJSON(tool.parameters)) { | ||
| tool.parameters = jsonSchema(standardSchemaToJSONSchema(tool.parameters)); | ||
| } else { | ||
| tool.parameters = jsonSchema(tool.parameters); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages, | ||
| schema | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: false | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| const argsForExecute = { | ||
| ...rest, | ||
| messages, | ||
| model, | ||
| temperature, | ||
| tools: { | ||
| ...tools | ||
| }, | ||
| toolChoice, | ||
| maxSteps, | ||
| onStepFinish: async (props) => { | ||
| try { | ||
| await onStepFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_TEXT_ON_STEP_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| finishReason: props?.finishReason, | ||
| toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "", | ||
| toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Text step change", { | ||
| text: props?.text, | ||
| toolCalls: props?.toolCalls, | ||
| toolResults: props?.toolResults, | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage, | ||
| runId | ||
| }); | ||
| const remainingTokens = parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"] ?? "", 10); | ||
| if (!isNaN(remainingTokens) && remainingTokens > 0 && remainingTokens < 2e3) { | ||
| this.logger.warn("Rate limit approaching, waiting 10 seconds", { runId, remainingTokens }); | ||
| const rateLimitSpan = llmSpan?.createChildSpan({ | ||
| name: "rate-limit-sleep", | ||
| type: "generic" /* GENERIC */, | ||
| metadata: { remainingTokens, delayMs: 1e4 } | ||
| }); | ||
| await delay(10 * 1e3); | ||
| rateLimitSpan?.end(); | ||
| } | ||
| }, | ||
| experimental_output: schema ? output_exports.object({ | ||
| schema | ||
| }) : void 0 | ||
| }; | ||
| try { | ||
| const result = await executeWithContext({ | ||
| span: llmSpan, | ||
| fn: () => generateText(argsForExecute) | ||
| }); | ||
| if (schema && result.finishReason === "stop") { | ||
| result.object = result.experimental_output; | ||
| } | ||
| llmSpan?.end({ | ||
| output: { | ||
| text: result.text, | ||
| object: result.object, | ||
| reasoning: result.reasoningDetails, | ||
| reasoningText: result.reasoning, | ||
| files: result.files, | ||
| sources: result.sources, | ||
| toolCalls: result.toolCalls, | ||
| warnings: result.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: result.finishReason, | ||
| responseId: result.response?.id, | ||
| responseModel: result.response?.modelId, | ||
| usage: convertV4Usage(result.usage) | ||
| } | ||
| }); | ||
| return result; | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_GENERATE_TEXT_AI_SDK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Generate text failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| async __textObject({ | ||
| messages, | ||
| structuredOutput, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| requestContext, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = resolveObservabilityContext(rest); | ||
| this.logger.debug("Generating text object", { runId }); | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature: rest.temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: false | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| try { | ||
| let output = "object"; | ||
| if (isZodArray(structuredOutput)) { | ||
| output = "array"; | ||
| const zodDef = getZodDef(structuredOutput); | ||
| if ("element" in zodDef) { | ||
| structuredOutput = zodDef.element; | ||
| } else { | ||
| structuredOutput = zodDef.type; | ||
| } | ||
| } | ||
| const processedSchema = this._applySchemaCompat(structuredOutput); | ||
| llmSpan?.update({ | ||
| input: { | ||
| messages, | ||
| schema: processedSchema | ||
| } | ||
| }); | ||
| const argsForExecute = { | ||
| ...rest, | ||
| messages, | ||
| model, | ||
| output, | ||
| schema: processedSchema | ||
| }; | ||
| try { | ||
| const result = await generateObject(argsForExecute); | ||
| llmSpan?.end({ | ||
| output: { | ||
| object: result.object, | ||
| warnings: result.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: result.finishReason, | ||
| responseId: result.response?.id, | ||
| responseModel: result.response?.modelId, | ||
| usage: convertV4Usage(result.usage) | ||
| } | ||
| }); | ||
| return result; | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_GENERATE_OBJECT_AI_SDK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Generate object failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } catch (e) { | ||
| if (e instanceof MastraError) { | ||
| throw e; | ||
| } | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_GENERATE_OBJECT_AI_SDK_SCHEMA_CONVERSION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Generate object schema conversion failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| __stream({ | ||
| messages, | ||
| onStepFinish, | ||
| onFinish, | ||
| maxSteps = 5, | ||
| tools = {}, | ||
| runId, | ||
| temperature, | ||
| toolChoice = "auto", | ||
| experimental_output, | ||
| threadId, | ||
| resourceId, | ||
| requestContext, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = resolveObservabilityContext(rest); | ||
| let schema; | ||
| if (experimental_output) { | ||
| if (typeof experimental_output.parse === "function") { | ||
| schema = experimental_output; | ||
| if (isZodArray(schema)) { | ||
| schema = getZodDef(schema).type; | ||
| } | ||
| } else { | ||
| schema = jsonSchema(experimental_output); | ||
| } | ||
| } | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: true | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| if (llmSpan) { | ||
| executeWithContextSync({ | ||
| span: llmSpan, | ||
| fn: () => this.logger.debug("Streaming text", { | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| messages, | ||
| maxSteps, | ||
| tools: Object.keys(tools || {}) | ||
| }) | ||
| }); | ||
| } | ||
| if (tools && Object.keys(tools).length > 0) { | ||
| for (const tool of Object.values(tools)) { | ||
| if (tool.parameters) { | ||
| if ("validate" in tool.parameters) { | ||
| tool.parameters = tool.parameters; | ||
| } else if (isStandardSchemaWithJSON(tool.parameters)) { | ||
| tool.parameters = jsonSchema(standardSchemaToJSONSchema(tool.parameters)); | ||
| } else { | ||
| tool.parameters = jsonSchema(tool.parameters); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| const argsForExecute = { | ||
| model, | ||
| temperature, | ||
| tools: { | ||
| ...tools | ||
| }, | ||
| maxSteps, | ||
| toolChoice, | ||
| onStepFinish: async (props) => { | ||
| try { | ||
| await onStepFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_ON_STEP_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| finishReason: props?.finishReason, | ||
| toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "", | ||
| toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.trackException(mastraError); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Stream step change", { | ||
| text: props?.text, | ||
| toolCalls: props?.toolCalls, | ||
| toolResults: props?.toolResults, | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage, | ||
| runId | ||
| }); | ||
| const remainingTokens = parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"] ?? "", 10); | ||
| if (!isNaN(remainingTokens) && remainingTokens > 0 && remainingTokens < 2e3) { | ||
| this.logger.warn("Rate limit approaching, waiting 10 seconds", { runId, remainingTokens }); | ||
| const rateLimitSpan = llmSpan?.createChildSpan({ | ||
| name: "rate-limit-sleep", | ||
| type: "generic" /* GENERIC */, | ||
| metadata: { remainingTokens, delayMs: 1e4 } | ||
| }); | ||
| await delay(10 * 1e3); | ||
| rateLimitSpan?.end(); | ||
| } | ||
| }, | ||
| onFinish: async (props) => { | ||
| llmSpan?.end({ | ||
| output: { | ||
| text: props?.text, | ||
| reasoning: props?.reasoningDetails, | ||
| reasoningText: props?.reasoning, | ||
| files: props?.files, | ||
| sources: props?.sources, | ||
| toolCalls: props?.toolCalls, | ||
| warnings: props?.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: props?.finishReason, | ||
| usage: convertV4Usage(props?.usage) | ||
| } | ||
| }); | ||
| try { | ||
| await onFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_ON_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| finishReason: props?.finishReason, | ||
| toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "", | ||
| toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| llmSpan?.error({ error: mastraError }); | ||
| this.logger.trackException(mastraError); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Stream finished", { | ||
| text: props?.text, | ||
| toolCalls: props?.toolCalls, | ||
| toolResults: props?.toolResults, | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage, | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }); | ||
| }, | ||
| onError: ({ error }) => { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_TEXT_AI_SDK_STREAMING_ERROR", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| error | ||
| ); | ||
| this.logger.error("Stream text error", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| }, | ||
| ...rest, | ||
| messages, | ||
| experimental_output: schema ? output_exports.object({ | ||
| schema | ||
| }) : void 0 | ||
| }; | ||
| try { | ||
| return executeWithContextSync({ span: llmSpan, fn: () => streamText(argsForExecute) }); | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_TEXT_AI_SDK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Stream text failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| __streamObject({ | ||
| messages, | ||
| runId, | ||
| requestContext, | ||
| threadId, | ||
| resourceId, | ||
| onFinish, | ||
| structuredOutput, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = resolveObservabilityContext(rest); | ||
| this.logger.debug("Streaming structured output", { | ||
| runId, | ||
| messages | ||
| }); | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature: rest.temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: true | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| try { | ||
| let output = "object"; | ||
| if (isZodArray(structuredOutput)) { | ||
| output = "array"; | ||
| structuredOutput = getZodDef(structuredOutput).type; | ||
| } | ||
| const processedSchema = this._applySchemaCompat(structuredOutput); | ||
| llmSpan?.update({ | ||
| input: { | ||
| messages, | ||
| schema: processedSchema | ||
| } | ||
| }); | ||
| const argsForExecute = { | ||
| ...rest, | ||
| model, | ||
| onFinish: async (props) => { | ||
| llmSpan?.end({ | ||
| output: { | ||
| text: props?.text, | ||
| object: props?.object, | ||
| reasoning: props?.reasoningDetails, | ||
| reasoningText: props?.reasoning, | ||
| files: props?.files, | ||
| sources: props?.sources, | ||
| warnings: props?.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage | ||
| } | ||
| }); | ||
| try { | ||
| await onFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_ON_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| toolCalls: "", | ||
| toolResults: "", | ||
| finishReason: "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.trackException(mastraError); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Object stream finished", { | ||
| usage: props?.usage, | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }); | ||
| }, | ||
| onError: ({ error }) => { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_AI_SDK_STREAMING_ERROR", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| error | ||
| ); | ||
| this.logger.error("Stream object error", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| }, | ||
| messages, | ||
| output, | ||
| schema: processedSchema | ||
| }; | ||
| try { | ||
| return streamObject(argsForExecute); | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_AI_SDK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Stream object failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } catch (e) { | ||
| if (e instanceof MastraError) { | ||
| llmSpan?.error({ error: e }); | ||
| throw e; | ||
| } | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_AI_SDK_SCHEMA_CONVERSION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Stream object schema conversion failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| convertToMessages(messages) { | ||
| if (Array.isArray(messages)) { | ||
| return messages.map((m) => { | ||
| if (typeof m === "string") { | ||
| return { | ||
| role: "user", | ||
| content: m | ||
| }; | ||
| } | ||
| return m; | ||
| }); | ||
| } | ||
| return [ | ||
| { | ||
| role: "user", | ||
| content: messages | ||
| } | ||
| ]; | ||
| } | ||
| async generate(messages, args) { | ||
| const msgs = this.convertToMessages(messages); | ||
| const { output, ...rest } = args ?? {}; | ||
| if (!output) { | ||
| return await this.__text({ | ||
| messages: msgs, | ||
| ...rest | ||
| }); | ||
| } | ||
| return await this.__textObject({ | ||
| messages: msgs, | ||
| structuredOutput: output, | ||
| ...rest | ||
| }); | ||
| } | ||
| stream(messages, args) { | ||
| const msgs = this.convertToMessages(messages); | ||
| const { output, ...rest } = args ?? {}; | ||
| if (!output) { | ||
| const { | ||
| maxSteps = 5, | ||
| onFinish: onFinish2, | ||
| ...streamRest | ||
| } = rest; | ||
| return this.__stream({ | ||
| messages: msgs, | ||
| maxSteps, | ||
| onFinish: onFinish2, | ||
| ...streamRest | ||
| }); | ||
| } | ||
| const { onFinish, ...objectRest } = rest; | ||
| return this.__streamObject({ | ||
| messages: msgs, | ||
| structuredOutput: output, | ||
| onFinish, | ||
| ...objectRest | ||
| }); | ||
| } | ||
| }; | ||
| function createStreamFromGenerateResult(result) { | ||
| return new ReadableStream({ | ||
| start(controller) { | ||
| controller.enqueue({ type: "stream-start", warnings: result.warnings }); | ||
| controller.enqueue({ | ||
| type: "response-metadata", | ||
| id: result.response?.id, | ||
| modelId: result.response?.modelId, | ||
| timestamp: result.response?.timestamp | ||
| }); | ||
| const toolCallMeta = {}; | ||
| for (const message of result.content) { | ||
| if (message.type === "tool-call") { | ||
| const toolCall = message; | ||
| toolCallMeta[toolCall.toolCallId] = { providerExecuted: toolCall.providerExecuted }; | ||
| controller.enqueue({ | ||
| type: "tool-input-start", | ||
| id: toolCall.toolCallId, | ||
| toolName: toolCall.toolName, | ||
| providerExecuted: toolCall.providerExecuted, | ||
| dynamic: toolCall.dynamic, | ||
| providerMetadata: toolCall.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "tool-input-delta", | ||
| id: toolCall.toolCallId, | ||
| delta: toolCall.input, | ||
| providerMetadata: toolCall.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "tool-input-end", | ||
| id: toolCall.toolCallId, | ||
| providerMetadata: toolCall.providerMetadata | ||
| }); | ||
| controller.enqueue(toolCall); | ||
| } else if (message.type === "tool-result") { | ||
| const toolResult = message; | ||
| const meta = toolCallMeta[toolResult.toolCallId]; | ||
| if (meta?.providerExecuted) { | ||
| controller.enqueue({ ...toolResult, providerExecuted: meta.providerExecuted }); | ||
| } else { | ||
| controller.enqueue(message); | ||
| } | ||
| } else if (message.type === "text") { | ||
| const text = message; | ||
| const id = `msg_${randomUUID()}`; | ||
| controller.enqueue({ | ||
| type: "text-start", | ||
| id, | ||
| providerMetadata: text.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "text-delta", | ||
| id, | ||
| delta: text.text | ||
| }); | ||
| controller.enqueue({ | ||
| type: "text-end", | ||
| id | ||
| }); | ||
| } else if (message.type === "reasoning") { | ||
| const id = `reasoning_${randomUUID()}`; | ||
| const reasoning = message; | ||
| controller.enqueue({ | ||
| type: "reasoning-start", | ||
| id, | ||
| providerMetadata: reasoning.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "reasoning-delta", | ||
| id, | ||
| delta: reasoning.text, | ||
| providerMetadata: reasoning.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "reasoning-end", | ||
| id, | ||
| providerMetadata: reasoning.providerMetadata | ||
| }); | ||
| } else if (message.type === "file") { | ||
| const file = message; | ||
| controller.enqueue({ | ||
| type: "file", | ||
| mediaType: file.mediaType, | ||
| data: file.data | ||
| }); | ||
| } else if (message.type === "source") { | ||
| const source = message; | ||
| if (source.sourceType === "url") { | ||
| controller.enqueue({ | ||
| type: "source", | ||
| id: source.id, | ||
| sourceType: "url", | ||
| url: source.url, | ||
| title: source.title, | ||
| providerMetadata: source.providerMetadata | ||
| }); | ||
| } else { | ||
| controller.enqueue({ | ||
| type: "source", | ||
| id: source.id, | ||
| sourceType: "document", | ||
| mediaType: source.mediaType, | ||
| filename: source.filename, | ||
| title: source.title, | ||
| providerMetadata: source.providerMetadata | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| controller.enqueue({ | ||
| type: "finish", | ||
| finishReason: result.finishReason, | ||
| usage: result.usage, | ||
| providerMetadata: result.providerMetadata | ||
| }); | ||
| controller.close(); | ||
| } | ||
| }); | ||
| } | ||
| // src/llm/model/aisdk/v5/model.ts | ||
| function applyStrictForV2(options) { | ||
| if (!options.tools?.length) { | ||
| return options; | ||
| } | ||
| let hasStrictTool = false; | ||
| const sanitizedTools = options.tools.map((tool) => { | ||
| if (tool.type !== "function" || !("strict" in tool)) { | ||
| return tool; | ||
| } | ||
| if (tool.strict === true) { | ||
| hasStrictTool = true; | ||
| } | ||
| const { strict: _strict, ...rest } = tool; | ||
| return rest; | ||
| }); | ||
| let result = { | ||
| ...options, | ||
| tools: sanitizedTools | ||
| }; | ||
| if (hasStrictTool) { | ||
| const existingOpenai = options.providerOptions?.openai ?? {}; | ||
| if (existingOpenai.strictJsonSchema == null) { | ||
| result = { | ||
| ...result, | ||
| providerOptions: { | ||
| ...options.providerOptions, | ||
| openai: { | ||
| ...existingOpenai, | ||
| strictJsonSchema: true | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| var AISDKV5LanguageModel = class { | ||
| /** | ||
| * The language model must specify which language model interface version it implements. | ||
| */ | ||
| specificationVersion = "v2"; | ||
| /** | ||
| * Name of the provider for logging purposes. | ||
| */ | ||
| provider; | ||
| /** | ||
| * Provider-specific model ID for logging purposes. | ||
| */ | ||
| modelId; | ||
| gatewayId; | ||
| /** | ||
| * Supported URL patterns by media type for the provider. | ||
| * | ||
| * The keys are media type patterns or full media types (e.g. `*\/*` for everything, `audio/*`, `video/*`, or `application/pdf`). | ||
| * and the values are arrays of regular expressions that match the URL paths. | ||
| * The matching should be against lower-case URLs. | ||
| * Matched URLs are supported natively by the model and are not downloaded. | ||
| * @returns A map of supported URL patterns by media type (as a promise or a plain object). | ||
| */ | ||
| supportedUrls; | ||
| #model; | ||
| constructor(config) { | ||
| this.#model = config; | ||
| this.provider = this.#model.provider; | ||
| this.modelId = this.#model.modelId; | ||
| this.gatewayId = config.gatewayId; | ||
| this.supportedUrls = this.#model.supportedUrls; | ||
| } | ||
| async doGenerate(options) { | ||
| const result = await this.#model.doGenerate(applyStrictForV2(options)); | ||
| return { | ||
| ...result, | ||
| request: result.request, | ||
| response: result.response, | ||
| stream: createStreamFromGenerateResult(result) | ||
| }; | ||
| } | ||
| async doStream(options) { | ||
| return await this.#model.doStream(applyStrictForV2(options)); | ||
| } | ||
| /** | ||
| * Custom serialization for tracing/observability spans. | ||
| * `#model` is already a true JS private field and not enumerable, so | ||
| * the wrapped provider SDK client can't leak. This method makes the | ||
| * safe shape explicit and avoids walking `supportedUrls` (a | ||
| * PromiseLike / regex map that isn't useful in spans). | ||
| */ | ||
| serializeForSpan() { | ||
| return { | ||
| specificationVersion: this.specificationVersion, | ||
| modelId: this.modelId, | ||
| provider: this.provider, | ||
| gatewayId: this.gatewayId | ||
| }; | ||
| } | ||
| }; | ||
| export { AISDKV5LanguageModel, MastraLLMV1, createStreamFromGenerateResult }; | ||
| //# sourceMappingURL=chunk-SGGND6WL.js.map | ||
| //# sourceMappingURL=chunk-SGGND6WL.js.map |
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunkA45A2T7R_cjs = require('./chunk-A45A2T7R.cjs'); | ||
| var chunk6QR4RQID_cjs = require('./chunk-6QR4RQID.cjs'); | ||
| var chunkXSOONORA_cjs = require('./chunk-XSOONORA.cjs'); | ||
| // src/llm/model/gateways/netlify.ts | ||
| var NetlifyGateway = class extends chunkA45A2T7R_cjs.MastraModelGateway { | ||
| id = "netlify"; | ||
| name = "Netlify AI Gateway"; | ||
| tokenCache = new chunk6QR4RQID_cjs.InMemoryServerCache(); | ||
| async fetchProviders() { | ||
| const response = await fetch("https://api.netlify.com/api/v1/ai-gateway/providers"); | ||
| if (!response.ok) { | ||
| throw new Error(`Failed to fetch from Netlify: ${response.statusText}`); | ||
| } | ||
| const data = await response.json(); | ||
| const config = { | ||
| apiKeyEnvVar: ["NETLIFY_TOKEN", "NETLIFY_SITE_ID"], | ||
| apiKeyHeader: "Authorization", | ||
| name: `Netlify`, | ||
| gateway: `netlify`, | ||
| models: [], | ||
| docUrl: "https://docs.netlify.com/build/ai-gateway/overview/" | ||
| }; | ||
| for (const [providerId, provider] of Object.entries(data.providers)) { | ||
| for (const model of provider.models) { | ||
| config.models.push(`${providerId}/${model}`); | ||
| } | ||
| } | ||
| return { netlify: config }; | ||
| } | ||
| async buildUrl(routerId, envVars) { | ||
| const siteId = envVars?.["NETLIFY_SITE_ID"] || process.env["NETLIFY_SITE_ID"]; | ||
| const netlifyToken = envVars?.["NETLIFY_TOKEN"] || process.env["NETLIFY_TOKEN"]; | ||
| if (!netlifyToken) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_TOKEN", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_TOKEN environment variable required for model: ${routerId}` | ||
| }); | ||
| } | ||
| if (!siteId) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_SITE_ID", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_SITE_ID environment variable required for model: ${routerId}` | ||
| }); | ||
| } | ||
| try { | ||
| const tokenData = await this.getOrFetchToken(siteId, netlifyToken); | ||
| return tokenData.url.endsWith(`/`) ? tokenData.url.substring(0, tokenData.url.length - 1) : tokenData.url; | ||
| } catch (error) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "NETLIFY_GATEWAY_TOKEN_ERROR", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Failed to get Netlify AI Gateway token for model ${routerId}: ${error instanceof Error ? error.message : String(error)}` | ||
| }); | ||
| } | ||
| } | ||
| /** | ||
| * Get cached token or fetch a new site-specific AI Gateway token from Netlify | ||
| */ | ||
| async getOrFetchToken(siteId, netlifyToken) { | ||
| const cacheKey = `netlify-token:${siteId}:${netlifyToken}`; | ||
| const cached = await this.tokenCache.get(cacheKey); | ||
| if (cached && cached.expiresAt > Date.now() / 1e3 + 60) { | ||
| return { token: cached.token, url: cached.url }; | ||
| } | ||
| const response = await fetch(`https://api.netlify.com/api/v1/sites/${siteId}/ai-gateway/token`, { | ||
| method: "GET", | ||
| headers: { | ||
| Authorization: `Bearer ${netlifyToken}` | ||
| } | ||
| }); | ||
| if (!response.ok) { | ||
| const error = await response.text(); | ||
| throw new Error(`Failed to get Netlify AI Gateway token: ${response.status} ${error}`); | ||
| } | ||
| const tokenResponse = await response.json(); | ||
| await this.tokenCache.set(cacheKey, { | ||
| token: tokenResponse.token, | ||
| url: tokenResponse.url, | ||
| expiresAt: tokenResponse.expires_at | ||
| }); | ||
| return { token: tokenResponse.token, url: tokenResponse.url }; | ||
| } | ||
| /** | ||
| * Get cached token or fetch a new site-specific AI Gateway token from Netlify | ||
| */ | ||
| async getApiKey(modelId) { | ||
| const siteId = process.env["NETLIFY_SITE_ID"]; | ||
| const netlifyToken = process.env["NETLIFY_TOKEN"]; | ||
| if (!netlifyToken) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_TOKEN", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_TOKEN environment variable required for model: ${modelId}` | ||
| }); | ||
| } | ||
| if (!siteId) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_SITE_ID", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_SITE_ID environment variable required for model: ${modelId}` | ||
| }); | ||
| } | ||
| try { | ||
| return (await this.getOrFetchToken(siteId, netlifyToken)).token; | ||
| } catch (error) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "NETLIFY_GATEWAY_TOKEN_ERROR", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Failed to get Netlify AI Gateway token for model ${modelId}: ${error instanceof Error ? error.message : String(error)}` | ||
| }); | ||
| } | ||
| } | ||
| async resolveLanguageModel({ | ||
| modelId, | ||
| providerId, | ||
| apiKey, | ||
| headers | ||
| }) { | ||
| const baseURL = await this.buildUrl(`${providerId}/${modelId}`); | ||
| const mastraHeaders = { "User-Agent": chunkA45A2T7R_cjs.MASTRA_USER_AGENT, ...headers }; | ||
| switch (providerId) { | ||
| case "openai": | ||
| return chunkA45A2T7R_cjs.createOpenAI({ apiKey, baseURL, headers: mastraHeaders }).responses(modelId); | ||
| case "gemini": | ||
| return chunkA45A2T7R_cjs.createGoogleGenerativeAI({ | ||
| baseURL: `${baseURL}/v1beta/`, | ||
| apiKey, | ||
| headers: { | ||
| "user-agent": "google-genai-sdk/", | ||
| ...mastraHeaders | ||
| } | ||
| }).chat(modelId); | ||
| case "anthropic": | ||
| return chunkA45A2T7R_cjs.createAnthropic({ | ||
| apiKey, | ||
| baseURL: `${baseURL}/v1/`, | ||
| headers: { | ||
| "anthropic-version": "2023-06-01", | ||
| ...mastraHeaders | ||
| } | ||
| })(modelId); | ||
| default: | ||
| return chunkA45A2T7R_cjs.createOpenAICompatible({ | ||
| name: providerId, | ||
| apiKey, | ||
| baseURL, | ||
| headers: mastraHeaders, | ||
| supportsStructuredOutputs: true | ||
| }).chatModel(modelId); | ||
| } | ||
| } | ||
| }; | ||
| exports.NetlifyGateway = NetlifyGateway; | ||
| //# sourceMappingURL=chunk-VIRV756L.cjs.map | ||
| //# sourceMappingURL=chunk-VIRV756L.cjs.map |
| {"version":3,"sources":["../src/llm/model/gateways/netlify.ts"],"names":["MastraModelGateway","InMemoryServerCache","MastraError","MASTRA_USER_AGENT","createOpenAI","createGoogleGenerativeAI","createAnthropic","createOpenAICompatible"],"mappings":"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","file":"chunk-VIRV756L.cjs","sourcesContent":["import { createAnthropic } from '@ai-sdk/anthropic-v6';\nimport { createGoogleGenerativeAI } from '@ai-sdk/google-v6';\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible-v5';\nimport { createOpenAI } from '@ai-sdk/openai-v6';\nimport { InMemoryServerCache } from '../../../cache/inmemory.js';\nimport { MastraError } from '../../../error/index.js';\nimport { MastraModelGateway } from './base.js';\nimport type { ProviderConfig, GatewayLanguageModel } from './base.js';\nimport { MASTRA_USER_AGENT } from './constants.js';\n\ninterface NetlifyProviderResponse {\n token_env_var: string;\n url_env_var: string;\n models: string[];\n}\ninterface NetlifyResponse {\n providers: Record<string, NetlifyProviderResponse>;\n}\n\ninterface NetlifyTokenResponse {\n token: string;\n url: string;\n expires_at: number;\n}\n\ninterface CachedToken {\n token: string;\n url: string;\n expiresAt: number;\n}\n\ninterface TokenData {\n token: string;\n url: string;\n}\n\nexport class NetlifyGateway extends MastraModelGateway {\n readonly id = 'netlify';\n readonly name = 'Netlify AI Gateway';\n private tokenCache = new InMemoryServerCache();\n\n async fetchProviders(): Promise<Record<string, ProviderConfig>> {\n const response = await fetch('https://api.netlify.com/api/v1/ai-gateway/providers');\n if (!response.ok) {\n throw new Error(`Failed to fetch from Netlify: ${response.statusText}`);\n }\n const data = (await response.json()) as NetlifyResponse;\n const config: ProviderConfig = {\n apiKeyEnvVar: ['NETLIFY_TOKEN', 'NETLIFY_SITE_ID'],\n apiKeyHeader: 'Authorization',\n name: `Netlify`,\n gateway: `netlify`,\n models: [],\n docUrl: 'https://docs.netlify.com/build/ai-gateway/overview/',\n };\n // Convert Netlify format to our standard format\n for (const [providerId, provider] of Object.entries(data.providers)) {\n for (const model of provider.models) {\n config.models.push(`${providerId}/${model}`);\n }\n }\n // Return with gateway ID as key - registry generator will detect this and avoid doubling the prefix\n return { netlify: config };\n }\n\n async buildUrl(routerId: string, envVars?: typeof process.env): Promise<string> {\n // Check for Netlify site ID first (for token exchange)\n const siteId = envVars?.['NETLIFY_SITE_ID'] || process.env['NETLIFY_SITE_ID'];\n const netlifyToken = envVars?.['NETLIFY_TOKEN'] || process.env['NETLIFY_TOKEN'];\n\n if (!netlifyToken) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_TOKEN',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_TOKEN environment variable required for model: ${routerId}`,\n });\n }\n\n if (!siteId) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_SITE_ID',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_SITE_ID environment variable required for model: ${routerId}`,\n });\n }\n\n try {\n const tokenData = await this.getOrFetchToken(siteId, netlifyToken);\n return tokenData.url.endsWith(`/`) ? tokenData.url.substring(0, tokenData.url.length - 1) : tokenData.url;\n } catch (error) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_TOKEN_ERROR',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Failed to get Netlify AI Gateway token for model ${routerId}: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n\n /**\n * Get cached token or fetch a new site-specific AI Gateway token from Netlify\n */\n private async getOrFetchToken(siteId: string, netlifyToken: string): Promise<TokenData> {\n const cacheKey = `netlify-token:${siteId}:${netlifyToken}`;\n\n // Check cache first\n const cached = (await this.tokenCache.get(cacheKey)) as CachedToken | undefined;\n if (cached && cached.expiresAt > Date.now() / 1000 + 60) {\n // Return cached token if it won't expire in the next minute\n return { token: cached.token, url: cached.url };\n }\n\n // Fetch new token\n const response = await fetch(`https://api.netlify.com/api/v1/sites/${siteId}/ai-gateway/token`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${netlifyToken}`,\n },\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Failed to get Netlify AI Gateway token: ${response.status} ${error}`);\n }\n\n const tokenResponse = (await response.json()) as NetlifyTokenResponse;\n\n // Cache the token - InMemoryServerCache will handle the TTL\n await this.tokenCache.set(cacheKey, {\n token: tokenResponse.token,\n url: tokenResponse.url,\n expiresAt: tokenResponse.expires_at,\n });\n\n return { token: tokenResponse.token, url: tokenResponse.url };\n }\n\n /**\n * Get cached token or fetch a new site-specific AI Gateway token from Netlify\n */\n async getApiKey(modelId: string): Promise<string> {\n const siteId = process.env['NETLIFY_SITE_ID'];\n const netlifyToken = process.env['NETLIFY_TOKEN'];\n\n if (!netlifyToken) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_TOKEN',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_TOKEN environment variable required for model: ${modelId}`,\n });\n }\n\n if (!siteId) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_SITE_ID',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_SITE_ID environment variable required for model: ${modelId}`,\n });\n }\n\n try {\n return (await this.getOrFetchToken(siteId, netlifyToken)).token;\n } catch (error) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_TOKEN_ERROR',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Failed to get Netlify AI Gateway token for model ${modelId}: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n\n async resolveLanguageModel({\n modelId,\n providerId,\n apiKey,\n headers,\n }: {\n modelId: string;\n providerId: string;\n apiKey: string;\n headers?: Record<string, string>;\n }): Promise<GatewayLanguageModel> {\n const baseURL = await this.buildUrl(`${providerId}/${modelId}`);\n\n const mastraHeaders = { 'User-Agent': MASTRA_USER_AGENT, ...headers };\n\n switch (providerId) {\n case 'openai':\n return createOpenAI({ apiKey, baseURL, headers: mastraHeaders }).responses(modelId);\n case 'gemini':\n return createGoogleGenerativeAI({\n baseURL: `${baseURL}/v1beta/`,\n apiKey,\n headers: {\n 'user-agent': 'google-genai-sdk/',\n ...mastraHeaders,\n },\n }).chat(modelId);\n case 'anthropic':\n return createAnthropic({\n apiKey,\n baseURL: `${baseURL}/v1/`,\n headers: {\n 'anthropic-version': '2023-06-01',\n ...mastraHeaders,\n },\n })(modelId);\n default:\n return createOpenAICompatible({\n name: providerId,\n apiKey,\n baseURL,\n headers: mastraHeaders,\n supportsStructuredOutputs: true,\n }).chatModel(modelId);\n }\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| export { MastraGateway } from './chunk-CXGM7OSM.js'; | ||
| //# sourceMappingURL=mastra-34ANSLN6.js.map | ||
| //# sourceMappingURL=mastra-34ANSLN6.js.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"mastra-34ANSLN6.js"} |
| 'use strict'; | ||
| var chunk5FCWY4Z3_cjs = require('./chunk-5FCWY4Z3.cjs'); | ||
| Object.defineProperty(exports, "MastraGateway", { | ||
| enumerable: true, | ||
| get: function () { return chunk5FCWY4Z3_cjs.MastraGateway; } | ||
| }); | ||
| //# sourceMappingURL=mastra-XSKDVDEO.cjs.map | ||
| //# sourceMappingURL=mastra-XSKDVDEO.cjs.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"mastra-XSKDVDEO.cjs"} |
| 'use strict'; | ||
| var chunkWFEGLWHX_cjs = require('./chunk-WFEGLWHX.cjs'); | ||
| Object.defineProperty(exports, "ModelsDevGateway", { | ||
| enumerable: true, | ||
| get: function () { return chunkWFEGLWHX_cjs.ModelsDevGateway; } | ||
| }); | ||
| //# sourceMappingURL=models-dev-2FIKRH25.cjs.map | ||
| //# sourceMappingURL=models-dev-2FIKRH25.cjs.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"models-dev-2FIKRH25.cjs"} |
| export { ModelsDevGateway } from './chunk-5VSJH776.js'; | ||
| //# sourceMappingURL=models-dev-WMBLPVEH.js.map | ||
| //# sourceMappingURL=models-dev-WMBLPVEH.js.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"models-dev-WMBLPVEH.js"} |
| export { NetlifyGateway } from './chunk-LVCGADQS.js'; | ||
| //# sourceMappingURL=netlify-3PWHCEFX.js.map | ||
| //# sourceMappingURL=netlify-3PWHCEFX.js.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"netlify-3PWHCEFX.js"} |
| 'use strict'; | ||
| var chunkVIRV756L_cjs = require('./chunk-VIRV756L.cjs'); | ||
| Object.defineProperty(exports, "NetlifyGateway", { | ||
| enumerable: true, | ||
| get: function () { return chunkVIRV756L_cjs.NetlifyGateway; } | ||
| }); | ||
| //# sourceMappingURL=netlify-RHVP5ZQM.cjs.map | ||
| //# sourceMappingURL=netlify-RHVP5ZQM.cjs.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"netlify-RHVP5ZQM.cjs"} |
| 'use strict'; | ||
| var chunk5FCWY4Z3_cjs = require('./chunk-5FCWY4Z3.cjs'); | ||
| Object.defineProperty(exports, "GatewayRegistry", { | ||
| enumerable: true, | ||
| get: function () { return chunk5FCWY4Z3_cjs.GatewayRegistry; } | ||
| }); | ||
| Object.defineProperty(exports, "PROVIDER_MODELS", { | ||
| enumerable: true, | ||
| get: function () { return chunk5FCWY4Z3_cjs.PROVIDER_MODELS; } | ||
| }); | ||
| Object.defineProperty(exports, "PROVIDER_REGISTRY", { | ||
| enumerable: true, | ||
| get: function () { return chunk5FCWY4Z3_cjs.PROVIDER_REGISTRY; } | ||
| }); | ||
| Object.defineProperty(exports, "getProviderConfig", { | ||
| enumerable: true, | ||
| get: function () { return chunk5FCWY4Z3_cjs.getProviderConfig; } | ||
| }); | ||
| Object.defineProperty(exports, "getRegisteredProviders", { | ||
| enumerable: true, | ||
| get: function () { return chunk5FCWY4Z3_cjs.getRegisteredProviders; } | ||
| }); | ||
| Object.defineProperty(exports, "isOfflineMode", { | ||
| enumerable: true, | ||
| get: function () { return chunk5FCWY4Z3_cjs.isOfflineMode; } | ||
| }); | ||
| Object.defineProperty(exports, "isProviderRegistered", { | ||
| enumerable: true, | ||
| get: function () { return chunk5FCWY4Z3_cjs.isProviderRegistered; } | ||
| }); | ||
| Object.defineProperty(exports, "isValidModelId", { | ||
| enumerable: true, | ||
| get: function () { return chunk5FCWY4Z3_cjs.isValidModelId; } | ||
| }); | ||
| Object.defineProperty(exports, "modelSupportsAttachments", { | ||
| enumerable: true, | ||
| get: function () { return chunk5FCWY4Z3_cjs.modelSupportsAttachments; } | ||
| }); | ||
| Object.defineProperty(exports, "parseModelString", { | ||
| enumerable: true, | ||
| get: function () { return chunk5FCWY4Z3_cjs.parseModelString; } | ||
| }); | ||
| //# sourceMappingURL=provider-registry-5U43NFLJ.cjs.map | ||
| //# sourceMappingURL=provider-registry-5U43NFLJ.cjs.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"provider-registry-5U43NFLJ.cjs"} |
| export { GatewayRegistry, PROVIDER_MODELS, PROVIDER_REGISTRY, getProviderConfig, getRegisteredProviders, isOfflineMode, isProviderRegistered, isValidModelId, modelSupportsAttachments, parseModelString } from './chunk-CXGM7OSM.js'; | ||
| //# sourceMappingURL=provider-registry-TEITX5SH.js.map | ||
| //# sourceMappingURL=provider-registry-TEITX5SH.js.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"provider-registry-TEITX5SH.js"} |
| import { shouldEnableGateway, getGatewayId } from './chunk-CXGM7OSM.js'; | ||
| import fs from 'fs/promises'; | ||
| import path from 'path'; | ||
| function hasAttachmentCapabilities(gateway) { | ||
| return "getAttachmentCapabilities" in gateway && typeof gateway.getAttachmentCapabilities === "function"; | ||
| } | ||
| async function atomicWriteFile(filePath, content, encoding = "utf-8") { | ||
| const randomSuffix = Math.random().toString(36).substring(2, 15); | ||
| const tempPath = `${filePath}.${process.pid}.${Date.now()}.${randomSuffix}.tmp`; | ||
| try { | ||
| await fs.writeFile(tempPath, content, encoding); | ||
| await fs.rename(tempPath, filePath); | ||
| } catch (error) { | ||
| try { | ||
| await fs.unlink(tempPath); | ||
| } catch { | ||
| } | ||
| throw error; | ||
| } | ||
| } | ||
| async function fetchProvidersFromGateways(gateways) { | ||
| const enabledGateways = []; | ||
| for (const gateway of gateways) { | ||
| if (shouldEnableGateway(gateway)) { | ||
| enabledGateways.push(gateway); | ||
| } | ||
| } | ||
| const allProviders = {}; | ||
| const allModels = {}; | ||
| const allAttachmentCapabilities = {}; | ||
| const failedGateways = []; | ||
| const maxRetries = 3; | ||
| for (const gateway of enabledGateways) { | ||
| let providers = null; | ||
| for (let attempt = 1; attempt <= maxRetries; attempt++) { | ||
| try { | ||
| providers = await gateway.fetchProviders(); | ||
| break; | ||
| } catch { | ||
| if (attempt < maxRetries) { | ||
| const delayMs = Math.min(1e3 * Math.pow(2, attempt - 1), 5e3); | ||
| await new Promise((resolve) => setTimeout(resolve, delayMs)); | ||
| } | ||
| } | ||
| } | ||
| if (!providers) { | ||
| failedGateways.push(getGatewayId(gateway)); | ||
| continue; | ||
| } | ||
| const gatewayId = getGatewayId(gateway); | ||
| const isProviderRegistry = gatewayId === "models.dev"; | ||
| const gatewayAttachmentCaps = hasAttachmentCapabilities(gateway) ? gateway.getAttachmentCapabilities() : void 0; | ||
| for (const [providerId, config] of Object.entries(providers)) { | ||
| const typeProviderId = isProviderRegistry ? providerId : providerId === gatewayId ? gatewayId : `${gatewayId}/${providerId}`; | ||
| allProviders[typeProviderId] = config; | ||
| allModels[typeProviderId] = config.models.sort(); | ||
| if (gatewayAttachmentCaps?.[providerId]) { | ||
| allAttachmentCapabilities[typeProviderId] = gatewayAttachmentCaps[providerId]; | ||
| } | ||
| } | ||
| } | ||
| return { | ||
| providers: allProviders, | ||
| models: allModels, | ||
| attachmentCapabilities: allAttachmentCapabilities, | ||
| failedGateways | ||
| }; | ||
| } | ||
| function generateTypesContent(models) { | ||
| const providerModelsEntries = Object.entries(models).map(([provider, modelList]) => { | ||
| const modelsList = modelList.map((m) => `'${m}'`); | ||
| const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(provider); | ||
| const providerKey = needsQuotes ? `'${provider}'` : provider; | ||
| const singleLine = ` readonly ${providerKey}: readonly [${modelsList.join(", ")}];`; | ||
| if (singleLine.length > 120) { | ||
| const formattedModels = modelList.map((m) => ` '${m}',`).join("\n"); | ||
| return ` readonly ${providerKey}: readonly [ | ||
| ${formattedModels} | ||
| ];`; | ||
| } | ||
| return singleLine; | ||
| }).join("\n"); | ||
| return `/** | ||
| * THIS FILE IS AUTO-GENERATED - DO NOT EDIT | ||
| * Generated from model gateway providers | ||
| */ | ||
| /** | ||
| * Provider models mapping type | ||
| * This is derived from the JSON data and provides type-safe access | ||
| */ | ||
| export type ProviderModelsMap = { | ||
| ${providerModelsEntries} | ||
| }; | ||
| /** | ||
| * Union type of all registered provider IDs | ||
| */ | ||
| export type Provider = keyof ProviderModelsMap; | ||
| /** | ||
| * Provider models mapping interface | ||
| */ | ||
| export interface ProviderModels { | ||
| [key: string]: string[]; | ||
| } | ||
| /** | ||
| * OpenAI-compatible model ID type | ||
| * Dynamically derived from ProviderModelsMap | ||
| * Full provider/model paths (e.g., "openai/gpt-4o", "anthropic/claude-3-5-sonnet-20241022") | ||
| */ | ||
| export type ModelRouterModelId = | ||
| | { | ||
| [P in Provider]: \`\${P}/\${ProviderModelsMap[P][number]}\`; | ||
| }[Provider] | ||
| | \`mastra/\${ProviderModelsMap['openrouter'][number]}\` | ||
| | (string & {}); | ||
| /** | ||
| * Extract the model part from a ModelRouterModelId for a specific provider | ||
| * Dynamically derived from ProviderModelsMap | ||
| * Example: ModelForProvider<'openai'> = 'gpt-4o' | 'gpt-4-turbo' | ... | ||
| */ | ||
| export type ModelForProvider<P extends Provider> = ProviderModelsMap[P][number]; | ||
| `; | ||
| } | ||
| async function writeRegistryFiles(jsonPath, typesPath, providers, models, attachmentCapabilities) { | ||
| const jsonDir = path.dirname(jsonPath); | ||
| const typesDir = path.dirname(typesPath); | ||
| await fs.mkdir(jsonDir, { recursive: true }); | ||
| await fs.mkdir(typesDir, { recursive: true }); | ||
| const registryData = { | ||
| providers, | ||
| models, | ||
| version: "1.0.0" | ||
| }; | ||
| await atomicWriteFile(jsonPath, JSON.stringify(registryData, null, 2), "utf-8"); | ||
| const typeContent = generateTypesContent(models); | ||
| await atomicWriteFile(typesPath, typeContent, "utf-8"); | ||
| if (attachmentCapabilities && Object.keys(attachmentCapabilities).length > 0) { | ||
| const capDir = path.join(jsonDir, "capabilities"); | ||
| await fs.mkdir(capDir, { recursive: true }); | ||
| try { | ||
| const existing = await fs.readdir(capDir); | ||
| for (const file of existing) { | ||
| if (file.endsWith(".json")) { | ||
| await fs.unlink(path.join(capDir, file)); | ||
| } | ||
| } | ||
| } catch { | ||
| } | ||
| for (const [provider, models2] of Object.entries(attachmentCapabilities)) { | ||
| const providerFile = path.join(capDir, `${provider}.json`); | ||
| await atomicWriteFile(providerFile, JSON.stringify({ attachment: models2 }, null, 2), "utf-8"); | ||
| } | ||
| } | ||
| } | ||
| export { atomicWriteFile, fetchProvidersFromGateways, generateTypesContent, writeRegistryFiles }; | ||
| //# sourceMappingURL=registry-generator-AXFE3YQ5.js.map | ||
| //# sourceMappingURL=registry-generator-AXFE3YQ5.js.map |
| {"version":3,"sources":["../src/llm/model/registry-generator.ts"],"names":["models"],"mappings":";;;;AAcA,SAAS,0BACP,OAAA,EAC4E;AAC5E,EAAA,OACE,2BAAA,IAA+B,OAAA,IAC/B,OAAQ,OAAA,CAAoD,yBAAA,KAA8B,UAAA;AAE9F;AAaA,eAAsB,eAAA,CACpB,QAAA,EACA,OAAA,EACA,QAAA,GAA2B,OAAA,EACZ;AAEf,EAAA,MAAM,YAAA,GAAe,KAAK,MAAA,EAAO,CAAE,SAAS,EAAE,CAAA,CAAE,SAAA,CAAU,CAAA,EAAG,EAAE,CAAA;AAC/D,EAAA,MAAM,QAAA,GAAW,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,OAAA,CAAQ,GAAG,CAAA,CAAA,EAAI,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,YAAY,CAAA,IAAA,CAAA;AAEzE,EAAA,IAAI;AAEF,IAAA,MAAM,EAAA,CAAG,SAAA,CAAU,QAAA,EAAU,OAAA,EAAS,QAAQ,CAAA;AAI9C,IAAA,MAAM,EAAA,CAAG,MAAA,CAAO,QAAA,EAAU,QAAQ,CAAA;AAAA,EACpC,SAAS,KAAA,EAAO;AAEd,IAAA,IAAI;AACF,MAAA,MAAM,EAAA,CAAG,OAAO,QAAQ,CAAA;AAAA,IAC1B,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,MAAM,KAAA;AAAA,EACR;AACF;AAUA,eAAsB,2BAA2B,QAAA,EAK9C;AACD,EAAA,MAAM,kBAAiD,EAAC;AAExD,EAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,IAAA,IAAI,mBAAA,CAAoB,OAAO,CAAA,EAAG;AAChC,MAAA,eAAA,CAAgB,KAAK,OAAO,CAAA;AAAA,IAC9B;AAAA,EACF;AAEA,EAAA,MAAM,eAA+C,EAAC;AACtD,EAAA,MAAM,YAAsC,EAAC;AAC7C,EAAA,MAAM,4BAAoD,EAAC;AAC3D,EAAA,MAAM,iBAA2B,EAAC;AAElC,EAAA,MAAM,UAAA,GAAa,CAAA;AAEnB,EAAA,KAAA,MAAW,WAAW,eAAA,EAAiB;AACrC,IAAA,IAAI,SAAA,GAAmD,IAAA;AAEvD,IAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,UAAA,EAAY,OAAA,EAAA,EAAW;AACtD,MAAA,IAAI;AACF,QAAA,SAAA,GAAY,MAAM,QAAQ,cAAA,EAAe;AACzC,QAAA;AAAA,MACF,CAAA,CAAA,MAAQ;AACN,QAAA,IAAI,UAAU,UAAA,EAAY;AACxB,UAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,GAAA,GAAO,IAAA,CAAK,IAAI,CAAA,EAAG,OAAA,GAAU,CAAC,CAAA,EAAG,GAAI,CAAA;AAC9D,UAAA,MAAM,IAAI,OAAA,CAAQ,CAAA,OAAA,KAAW,UAAA,CAAW,OAAA,EAAS,OAAO,CAAC,CAAA;AAAA,QAC3D;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,cAAA,CAAe,IAAA,CAAK,YAAA,CAAa,OAAO,CAAC,CAAA;AACzC,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,SAAA,GAAY,aAAa,OAAO,CAAA;AAEtC,IAAA,MAAM,qBAAqB,SAAA,KAAc,YAAA;AAGzC,IAAA,MAAM,wBAAwB,yBAAA,CAA0B,OAAO,CAAA,GAAI,OAAA,CAAQ,2BAA0B,GAAI,MAAA;AAEzG,IAAA,KAAA,MAAW,CAAC,UAAA,EAAY,MAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG;AAI5D,MAAA,MAAM,cAAA,GAAiB,qBACnB,UAAA,GACA,UAAA,KAAe,YACb,SAAA,GACA,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA;AAEhC,MAAA,YAAA,CAAa,cAAc,CAAA,GAAI,MAAA;AAE/B,MAAA,SAAA,CAAU,cAAc,CAAA,GAAI,MAAA,CAAO,MAAA,CAAO,IAAA,EAAK;AAG/C,MAAA,IAAI,qBAAA,GAAwB,UAAU,CAAA,EAAG;AACvC,QAAA,yBAAA,CAA0B,cAAc,CAAA,GAAI,qBAAA,CAAsB,UAAU,CAAA;AAAA,MAC9E;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,YAAA;AAAA,IACX,MAAA,EAAQ,SAAA;AAAA,IACR,sBAAA,EAAwB,yBAAA;AAAA,IACxB;AAAA,GACF;AACF;AAOO,SAAS,qBAAqB,MAAA,EAA0C;AAC7E,EAAA,MAAM,qBAAA,GAAwB,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,CAChD,IAAI,CAAC,CAAC,QAAA,EAAU,SAAS,CAAA,KAAM;AAC9B,IAAA,MAAM,aAAa,SAAA,CAAU,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AAI9C,IAAA,MAAM,WAAA,GAAc,CAAC,4BAAA,CAA6B,IAAA,CAAK,QAAQ,CAAA;AAC/D,IAAA,MAAM,WAAA,GAAc,WAAA,GAAc,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA,CAAA,GAAM,QAAA;AAGpD,IAAA,MAAM,aAAa,CAAA,WAAA,EAAc,WAAW,eAAe,UAAA,CAAW,IAAA,CAAK,IAAI,CAAC,CAAA,EAAA,CAAA;AAGhF,IAAA,IAAI,UAAA,CAAW,SAAS,GAAA,EAAK;AAC3B,MAAA,MAAM,eAAA,GAAkB,UAAU,GAAA,CAAI,CAAA,CAAA,KAAK,QAAQ,CAAC,CAAA,EAAA,CAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AACnE,MAAA,OAAO,cAAc,WAAW,CAAA;AAAA,EAAiB,eAAe;AAAA,IAAA,CAAA;AAAA,IAClE;AAEA,IAAA,OAAO,UAAA;AAAA,EACT,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,OAAO,CAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUP,qBAAqB;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAkCvB;AASA,eAAsB,kBAAA,CACpB,QAAA,EACA,SAAA,EACA,SAAA,EACA,QACA,sBAAA,EACe;AAEf,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,QAAQ,CAAA;AACrC,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA;AACvC,EAAA,MAAM,GAAG,KAAA,CAAM,OAAA,EAAS,EAAE,SAAA,EAAW,MAAM,CAAA;AAC3C,EAAA,MAAM,GAAG,KAAA,CAAM,QAAA,EAAU,EAAE,SAAA,EAAW,MAAM,CAAA;AAG5C,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,SAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA,EAAS;AAAA,GACX;AAEA,EAAA,MAAM,eAAA,CAAgB,UAAU,IAAA,CAAK,SAAA,CAAU,cAAc,IAAA,EAAM,CAAC,GAAG,OAAO,CAAA;AAG9E,EAAA,MAAM,WAAA,GAAc,qBAAqB,MAAM,CAAA;AAC/C,EAAA,MAAM,eAAA,CAAgB,SAAA,EAAW,WAAA,EAAa,OAAO,CAAA;AAGrD,EAAA,IAAI,0BAA0B,MAAA,CAAO,IAAA,CAAK,sBAAsB,CAAA,CAAE,SAAS,CAAA,EAAG;AAC5E,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,cAAc,CAAA;AAChD,IAAA,MAAM,GAAG,KAAA,CAAM,MAAA,EAAQ,EAAE,SAAA,EAAW,MAAM,CAAA;AAG1C,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,EAAA,CAAG,OAAA,CAAQ,MAAM,CAAA;AACxC,MAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,QAAA,IAAI,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,EAAG;AAC1B,UAAA,MAAM,GAAG,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,QACzC;AAAA,MACF;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,KAAA,MAAW,CAAC,QAAA,EAAUA,OAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,sBAAsB,CAAA,EAAG;AACvE,MAAA,MAAM,eAAe,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,CAAA,EAAG,QAAQ,CAAA,KAAA,CAAO,CAAA;AACzD,MAAA,MAAM,eAAA,CAAgB,YAAA,EAAc,IAAA,CAAK,SAAA,CAAU,EAAE,UAAA,EAAYA,OAAAA,EAAO,EAAG,IAAA,EAAM,CAAC,CAAA,EAAG,OAAO,CAAA;AAAA,IAC9F;AAAA,EACF;AACF","file":"registry-generator-AXFE3YQ5.js","sourcesContent":["/**\n * Shared provider registry generation logic\n * Used by both the CLI generation script and runtime refresh\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { AttachmentCapabilities, MastraModelGatewayInterface, ProviderConfig } from './gateways/base.js';\nimport { getGatewayId, shouldEnableGateway } from './gateways/index.js';\n\ninterface GatewayWithAttachmentCapabilities {\n getAttachmentCapabilities(): AttachmentCapabilities;\n}\n\nfunction hasAttachmentCapabilities(\n gateway: MastraModelGatewayInterface,\n): gateway is MastraModelGatewayInterface & GatewayWithAttachmentCapabilities {\n return (\n 'getAttachmentCapabilities' in gateway &&\n typeof (gateway as { getAttachmentCapabilities?: unknown }).getAttachmentCapabilities === 'function'\n );\n}\n\n/**\n * Write a file atomically using the write-to-temp-then-rename pattern.\n * This prevents file corruption when multiple processes write to the same file concurrently.\n *\n * The rename operation is atomic on POSIX systems when source and destination\n * are on the same filesystem.\n *\n * @param filePath - The target file path\n * @param content - The content to write\n * @param encoding - The encoding to use (default: 'utf-8')\n */\nexport async function atomicWriteFile(\n filePath: string,\n content: string,\n encoding: BufferEncoding = 'utf-8',\n): Promise<void> {\n // Create a unique temp file name using PID, timestamp, and random suffix to avoid collisions\n const randomSuffix = Math.random().toString(36).substring(2, 15);\n const tempPath = `${filePath}.${process.pid}.${Date.now()}.${randomSuffix}.tmp`;\n\n try {\n // Write to temp file first\n await fs.writeFile(tempPath, content, encoding);\n\n // Atomically rename temp file to target path\n // This is atomic on POSIX when both paths are on the same filesystem\n await fs.rename(tempPath, filePath);\n } catch (error) {\n // Clean up temp file if it exists\n try {\n await fs.unlink(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw error;\n }\n}\n\n/**\n * Fetch providers from all enabled gateways with silent retry logic.\n * Retries up to 3 times per gateway with exponential backoff. If all\n * retries are exhausted the gateway is silently skipped (no error logging)\n * since the bundled registry already contains all model data.\n * @param gateways - Array of gateway instances to fetch from\n * @returns Object containing providers and models records\n */\nexport async function fetchProvidersFromGateways(gateways: MastraModelGatewayInterface[]): Promise<{\n providers: Record<string, ProviderConfig>;\n models: Record<string, string[]>;\n attachmentCapabilities: AttachmentCapabilities;\n failedGateways: string[];\n}> {\n const enabledGateways: MastraModelGatewayInterface[] = [];\n\n for (const gateway of gateways) {\n if (shouldEnableGateway(gateway)) {\n enabledGateways.push(gateway);\n }\n }\n\n const allProviders: Record<string, ProviderConfig> = {};\n const allModels: Record<string, string[]> = {};\n const allAttachmentCapabilities: AttachmentCapabilities = {};\n const failedGateways: string[] = [];\n\n const maxRetries = 3;\n\n for (const gateway of enabledGateways) {\n let providers: Record<string, ProviderConfig> | null = null;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n providers = await gateway.fetchProviders();\n break;\n } catch {\n if (attempt < maxRetries) {\n const delayMs = Math.min(1000 * Math.pow(2, attempt - 1), 5000);\n await new Promise(resolve => setTimeout(resolve, delayMs));\n }\n }\n }\n\n if (!providers) {\n failedGateways.push(getGatewayId(gateway));\n continue;\n }\n\n const gatewayId = getGatewayId(gateway);\n // models.dev is a provider registry, not a true gateway - don't prefix its providers\n const isProviderRegistry = gatewayId === 'models.dev';\n\n // Collect attachment capabilities if the gateway exposes them\n const gatewayAttachmentCaps = hasAttachmentCapabilities(gateway) ? gateway.getAttachmentCapabilities() : undefined;\n\n for (const [providerId, config] of Object.entries(providers)) {\n // For true gateways, use gateway id as prefix (e.g., \"netlify/anthropic\")\n // Special case: if providerId matches gateway id, it's a unified gateway (e.g., azure-openai returning {azure-openai: {...}})\n // In this case, use just the gateway ID to avoid duplication (azure-openai, not azure-openai/azure-openai)\n const typeProviderId = isProviderRegistry\n ? providerId\n : providerId === gatewayId\n ? gatewayId\n : `${gatewayId}/${providerId}`;\n\n allProviders[typeProviderId] = config;\n // Sort models alphabetically for consistent ordering\n allModels[typeProviderId] = config.models.sort();\n\n // Merge attachment capabilities for this provider if available\n if (gatewayAttachmentCaps?.[providerId]) {\n allAttachmentCapabilities[typeProviderId] = gatewayAttachmentCaps[providerId];\n }\n }\n }\n\n return {\n providers: allProviders,\n models: allModels,\n attachmentCapabilities: allAttachmentCapabilities,\n failedGateways,\n };\n}\n\n/**\n * Generate TypeScript type definitions content\n * @param models - Record of provider IDs to model arrays\n * @returns Generated TypeScript type definitions as a string\n */\nexport function generateTypesContent(models: Record<string, string[]>): string {\n const providerModelsEntries = Object.entries(models)\n .map(([provider, modelList]) => {\n const modelsList = modelList.map(m => `'${m}'`);\n\n // Quote provider key if it's not a valid JavaScript identifier\n // Valid identifiers must start with a letter, underscore, or dollar sign\n const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(provider);\n const providerKey = needsQuotes ? `'${provider}'` : provider;\n\n // Format array based on length (prettier printWidth: 120)\n const singleLine = ` readonly ${providerKey}: readonly [${modelsList.join(', ')}];`;\n\n // If single line exceeds 120 chars, format as multi-line\n if (singleLine.length > 120) {\n const formattedModels = modelList.map(m => ` '${m}',`).join('\\n');\n return ` readonly ${providerKey}: readonly [\\n${formattedModels}\\n ];`;\n }\n\n return singleLine;\n })\n .join('\\n');\n\n return `/**\n * THIS FILE IS AUTO-GENERATED - DO NOT EDIT\n * Generated from model gateway providers\n */\n\n/**\n * Provider models mapping type\n * This is derived from the JSON data and provides type-safe access\n */\nexport type ProviderModelsMap = {\n${providerModelsEntries}\n};\n\n/**\n * Union type of all registered provider IDs\n */\nexport type Provider = keyof ProviderModelsMap;\n\n/**\n * Provider models mapping interface\n */\nexport interface ProviderModels {\n [key: string]: string[];\n}\n\n/**\n * OpenAI-compatible model ID type\n * Dynamically derived from ProviderModelsMap\n * Full provider/model paths (e.g., \"openai/gpt-4o\", \"anthropic/claude-3-5-sonnet-20241022\")\n */\nexport type ModelRouterModelId =\n | {\n [P in Provider]: \\`\\${P}/\\${ProviderModelsMap[P][number]}\\`;\n }[Provider]\n | \\`mastra/\\${ProviderModelsMap['openrouter'][number]}\\`\n | (string & {});\n\n/**\n * Extract the model part from a ModelRouterModelId for a specific provider\n * Dynamically derived from ProviderModelsMap\n * Example: ModelForProvider<'openai'> = 'gpt-4o' | 'gpt-4-turbo' | ...\n */\nexport type ModelForProvider<P extends Provider> = ProviderModelsMap[P][number];\n`;\n}\n\n/**\n * Write registry files to disk (JSON and .d.ts)\n * @param jsonPath - Path to write the JSON file\n * @param typesPath - Path to write the .d.ts file\n * @param providers - Provider configurations\n * @param models - Model lists by provider\n */\nexport async function writeRegistryFiles(\n jsonPath: string,\n typesPath: string,\n providers: Record<string, ProviderConfig>,\n models: Record<string, string[]>,\n attachmentCapabilities?: AttachmentCapabilities,\n): Promise<void> {\n // 0. Ensure directories exist\n const jsonDir = path.dirname(jsonPath);\n const typesDir = path.dirname(typesPath);\n await fs.mkdir(jsonDir, { recursive: true });\n await fs.mkdir(typesDir, { recursive: true });\n\n // 1. Write JSON file atomically to prevent corruption from concurrent writes\n const registryData = {\n providers,\n models,\n version: '1.0.0',\n };\n\n await atomicWriteFile(jsonPath, JSON.stringify(registryData, null, 2), 'utf-8');\n\n // 2. Generate .d.ts file with type-only declarations (also atomic)\n const typeContent = generateTypesContent(models);\n await atomicWriteFile(typesPath, typeContent, 'utf-8');\n\n // 3. Write per-provider capability files into a capabilities/ directory\n if (attachmentCapabilities && Object.keys(attachmentCapabilities).length > 0) {\n const capDir = path.join(jsonDir, 'capabilities');\n await fs.mkdir(capDir, { recursive: true });\n\n // Clean out stale provider files from previous runs\n try {\n const existing = await fs.readdir(capDir);\n for (const file of existing) {\n if (file.endsWith('.json')) {\n await fs.unlink(path.join(capDir, file));\n }\n }\n } catch {\n // Directory may not exist yet — ignore\n }\n\n for (const [provider, models] of Object.entries(attachmentCapabilities)) {\n const providerFile = path.join(capDir, `${provider}.json`);\n await atomicWriteFile(providerFile, JSON.stringify({ attachment: models }, null, 2), 'utf-8');\n }\n }\n}\n"]} |
| 'use strict'; | ||
| var chunk5FCWY4Z3_cjs = require('./chunk-5FCWY4Z3.cjs'); | ||
| var fs = require('fs/promises'); | ||
| var path = require('path'); | ||
| function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } | ||
| var fs__default = /*#__PURE__*/_interopDefault(fs); | ||
| var path__default = /*#__PURE__*/_interopDefault(path); | ||
| function hasAttachmentCapabilities(gateway) { | ||
| return "getAttachmentCapabilities" in gateway && typeof gateway.getAttachmentCapabilities === "function"; | ||
| } | ||
| async function atomicWriteFile(filePath, content, encoding = "utf-8") { | ||
| const randomSuffix = Math.random().toString(36).substring(2, 15); | ||
| const tempPath = `${filePath}.${process.pid}.${Date.now()}.${randomSuffix}.tmp`; | ||
| try { | ||
| await fs__default.default.writeFile(tempPath, content, encoding); | ||
| await fs__default.default.rename(tempPath, filePath); | ||
| } catch (error) { | ||
| try { | ||
| await fs__default.default.unlink(tempPath); | ||
| } catch { | ||
| } | ||
| throw error; | ||
| } | ||
| } | ||
| async function fetchProvidersFromGateways(gateways) { | ||
| const enabledGateways = []; | ||
| for (const gateway of gateways) { | ||
| if (chunk5FCWY4Z3_cjs.shouldEnableGateway(gateway)) { | ||
| enabledGateways.push(gateway); | ||
| } | ||
| } | ||
| const allProviders = {}; | ||
| const allModels = {}; | ||
| const allAttachmentCapabilities = {}; | ||
| const failedGateways = []; | ||
| const maxRetries = 3; | ||
| for (const gateway of enabledGateways) { | ||
| let providers = null; | ||
| for (let attempt = 1; attempt <= maxRetries; attempt++) { | ||
| try { | ||
| providers = await gateway.fetchProviders(); | ||
| break; | ||
| } catch { | ||
| if (attempt < maxRetries) { | ||
| const delayMs = Math.min(1e3 * Math.pow(2, attempt - 1), 5e3); | ||
| await new Promise((resolve) => setTimeout(resolve, delayMs)); | ||
| } | ||
| } | ||
| } | ||
| if (!providers) { | ||
| failedGateways.push(chunk5FCWY4Z3_cjs.getGatewayId(gateway)); | ||
| continue; | ||
| } | ||
| const gatewayId = chunk5FCWY4Z3_cjs.getGatewayId(gateway); | ||
| const isProviderRegistry = gatewayId === "models.dev"; | ||
| const gatewayAttachmentCaps = hasAttachmentCapabilities(gateway) ? gateway.getAttachmentCapabilities() : void 0; | ||
| for (const [providerId, config] of Object.entries(providers)) { | ||
| const typeProviderId = isProviderRegistry ? providerId : providerId === gatewayId ? gatewayId : `${gatewayId}/${providerId}`; | ||
| allProviders[typeProviderId] = config; | ||
| allModels[typeProviderId] = config.models.sort(); | ||
| if (gatewayAttachmentCaps?.[providerId]) { | ||
| allAttachmentCapabilities[typeProviderId] = gatewayAttachmentCaps[providerId]; | ||
| } | ||
| } | ||
| } | ||
| return { | ||
| providers: allProviders, | ||
| models: allModels, | ||
| attachmentCapabilities: allAttachmentCapabilities, | ||
| failedGateways | ||
| }; | ||
| } | ||
| function generateTypesContent(models) { | ||
| const providerModelsEntries = Object.entries(models).map(([provider, modelList]) => { | ||
| const modelsList = modelList.map((m) => `'${m}'`); | ||
| const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(provider); | ||
| const providerKey = needsQuotes ? `'${provider}'` : provider; | ||
| const singleLine = ` readonly ${providerKey}: readonly [${modelsList.join(", ")}];`; | ||
| if (singleLine.length > 120) { | ||
| const formattedModels = modelList.map((m) => ` '${m}',`).join("\n"); | ||
| return ` readonly ${providerKey}: readonly [ | ||
| ${formattedModels} | ||
| ];`; | ||
| } | ||
| return singleLine; | ||
| }).join("\n"); | ||
| return `/** | ||
| * THIS FILE IS AUTO-GENERATED - DO NOT EDIT | ||
| * Generated from model gateway providers | ||
| */ | ||
| /** | ||
| * Provider models mapping type | ||
| * This is derived from the JSON data and provides type-safe access | ||
| */ | ||
| export type ProviderModelsMap = { | ||
| ${providerModelsEntries} | ||
| }; | ||
| /** | ||
| * Union type of all registered provider IDs | ||
| */ | ||
| export type Provider = keyof ProviderModelsMap; | ||
| /** | ||
| * Provider models mapping interface | ||
| */ | ||
| export interface ProviderModels { | ||
| [key: string]: string[]; | ||
| } | ||
| /** | ||
| * OpenAI-compatible model ID type | ||
| * Dynamically derived from ProviderModelsMap | ||
| * Full provider/model paths (e.g., "openai/gpt-4o", "anthropic/claude-3-5-sonnet-20241022") | ||
| */ | ||
| export type ModelRouterModelId = | ||
| | { | ||
| [P in Provider]: \`\${P}/\${ProviderModelsMap[P][number]}\`; | ||
| }[Provider] | ||
| | \`mastra/\${ProviderModelsMap['openrouter'][number]}\` | ||
| | (string & {}); | ||
| /** | ||
| * Extract the model part from a ModelRouterModelId for a specific provider | ||
| * Dynamically derived from ProviderModelsMap | ||
| * Example: ModelForProvider<'openai'> = 'gpt-4o' | 'gpt-4-turbo' | ... | ||
| */ | ||
| export type ModelForProvider<P extends Provider> = ProviderModelsMap[P][number]; | ||
| `; | ||
| } | ||
| async function writeRegistryFiles(jsonPath, typesPath, providers, models, attachmentCapabilities) { | ||
| const jsonDir = path__default.default.dirname(jsonPath); | ||
| const typesDir = path__default.default.dirname(typesPath); | ||
| await fs__default.default.mkdir(jsonDir, { recursive: true }); | ||
| await fs__default.default.mkdir(typesDir, { recursive: true }); | ||
| const registryData = { | ||
| providers, | ||
| models, | ||
| version: "1.0.0" | ||
| }; | ||
| await atomicWriteFile(jsonPath, JSON.stringify(registryData, null, 2), "utf-8"); | ||
| const typeContent = generateTypesContent(models); | ||
| await atomicWriteFile(typesPath, typeContent, "utf-8"); | ||
| if (attachmentCapabilities && Object.keys(attachmentCapabilities).length > 0) { | ||
| const capDir = path__default.default.join(jsonDir, "capabilities"); | ||
| await fs__default.default.mkdir(capDir, { recursive: true }); | ||
| try { | ||
| const existing = await fs__default.default.readdir(capDir); | ||
| for (const file of existing) { | ||
| if (file.endsWith(".json")) { | ||
| await fs__default.default.unlink(path__default.default.join(capDir, file)); | ||
| } | ||
| } | ||
| } catch { | ||
| } | ||
| for (const [provider, models2] of Object.entries(attachmentCapabilities)) { | ||
| const providerFile = path__default.default.join(capDir, `${provider}.json`); | ||
| await atomicWriteFile(providerFile, JSON.stringify({ attachment: models2 }, null, 2), "utf-8"); | ||
| } | ||
| } | ||
| } | ||
| exports.atomicWriteFile = atomicWriteFile; | ||
| exports.fetchProvidersFromGateways = fetchProvidersFromGateways; | ||
| exports.generateTypesContent = generateTypesContent; | ||
| exports.writeRegistryFiles = writeRegistryFiles; | ||
| //# sourceMappingURL=registry-generator-YPGBZQ5K.cjs.map | ||
| //# sourceMappingURL=registry-generator-YPGBZQ5K.cjs.map |
| {"version":3,"sources":["../src/llm/model/registry-generator.ts"],"names":["fs","shouldEnableGateway","getGatewayId","path","models"],"mappings":"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","file":"registry-generator-YPGBZQ5K.cjs","sourcesContent":["/**\n * Shared provider registry generation logic\n * Used by both the CLI generation script and runtime refresh\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { AttachmentCapabilities, MastraModelGatewayInterface, ProviderConfig } from './gateways/base.js';\nimport { getGatewayId, shouldEnableGateway } from './gateways/index.js';\n\ninterface GatewayWithAttachmentCapabilities {\n getAttachmentCapabilities(): AttachmentCapabilities;\n}\n\nfunction hasAttachmentCapabilities(\n gateway: MastraModelGatewayInterface,\n): gateway is MastraModelGatewayInterface & GatewayWithAttachmentCapabilities {\n return (\n 'getAttachmentCapabilities' in gateway &&\n typeof (gateway as { getAttachmentCapabilities?: unknown }).getAttachmentCapabilities === 'function'\n );\n}\n\n/**\n * Write a file atomically using the write-to-temp-then-rename pattern.\n * This prevents file corruption when multiple processes write to the same file concurrently.\n *\n * The rename operation is atomic on POSIX systems when source and destination\n * are on the same filesystem.\n *\n * @param filePath - The target file path\n * @param content - The content to write\n * @param encoding - The encoding to use (default: 'utf-8')\n */\nexport async function atomicWriteFile(\n filePath: string,\n content: string,\n encoding: BufferEncoding = 'utf-8',\n): Promise<void> {\n // Create a unique temp file name using PID, timestamp, and random suffix to avoid collisions\n const randomSuffix = Math.random().toString(36).substring(2, 15);\n const tempPath = `${filePath}.${process.pid}.${Date.now()}.${randomSuffix}.tmp`;\n\n try {\n // Write to temp file first\n await fs.writeFile(tempPath, content, encoding);\n\n // Atomically rename temp file to target path\n // This is atomic on POSIX when both paths are on the same filesystem\n await fs.rename(tempPath, filePath);\n } catch (error) {\n // Clean up temp file if it exists\n try {\n await fs.unlink(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw error;\n }\n}\n\n/**\n * Fetch providers from all enabled gateways with silent retry logic.\n * Retries up to 3 times per gateway with exponential backoff. If all\n * retries are exhausted the gateway is silently skipped (no error logging)\n * since the bundled registry already contains all model data.\n * @param gateways - Array of gateway instances to fetch from\n * @returns Object containing providers and models records\n */\nexport async function fetchProvidersFromGateways(gateways: MastraModelGatewayInterface[]): Promise<{\n providers: Record<string, ProviderConfig>;\n models: Record<string, string[]>;\n attachmentCapabilities: AttachmentCapabilities;\n failedGateways: string[];\n}> {\n const enabledGateways: MastraModelGatewayInterface[] = [];\n\n for (const gateway of gateways) {\n if (shouldEnableGateway(gateway)) {\n enabledGateways.push(gateway);\n }\n }\n\n const allProviders: Record<string, ProviderConfig> = {};\n const allModels: Record<string, string[]> = {};\n const allAttachmentCapabilities: AttachmentCapabilities = {};\n const failedGateways: string[] = [];\n\n const maxRetries = 3;\n\n for (const gateway of enabledGateways) {\n let providers: Record<string, ProviderConfig> | null = null;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n providers = await gateway.fetchProviders();\n break;\n } catch {\n if (attempt < maxRetries) {\n const delayMs = Math.min(1000 * Math.pow(2, attempt - 1), 5000);\n await new Promise(resolve => setTimeout(resolve, delayMs));\n }\n }\n }\n\n if (!providers) {\n failedGateways.push(getGatewayId(gateway));\n continue;\n }\n\n const gatewayId = getGatewayId(gateway);\n // models.dev is a provider registry, not a true gateway - don't prefix its providers\n const isProviderRegistry = gatewayId === 'models.dev';\n\n // Collect attachment capabilities if the gateway exposes them\n const gatewayAttachmentCaps = hasAttachmentCapabilities(gateway) ? gateway.getAttachmentCapabilities() : undefined;\n\n for (const [providerId, config] of Object.entries(providers)) {\n // For true gateways, use gateway id as prefix (e.g., \"netlify/anthropic\")\n // Special case: if providerId matches gateway id, it's a unified gateway (e.g., azure-openai returning {azure-openai: {...}})\n // In this case, use just the gateway ID to avoid duplication (azure-openai, not azure-openai/azure-openai)\n const typeProviderId = isProviderRegistry\n ? providerId\n : providerId === gatewayId\n ? gatewayId\n : `${gatewayId}/${providerId}`;\n\n allProviders[typeProviderId] = config;\n // Sort models alphabetically for consistent ordering\n allModels[typeProviderId] = config.models.sort();\n\n // Merge attachment capabilities for this provider if available\n if (gatewayAttachmentCaps?.[providerId]) {\n allAttachmentCapabilities[typeProviderId] = gatewayAttachmentCaps[providerId];\n }\n }\n }\n\n return {\n providers: allProviders,\n models: allModels,\n attachmentCapabilities: allAttachmentCapabilities,\n failedGateways,\n };\n}\n\n/**\n * Generate TypeScript type definitions content\n * @param models - Record of provider IDs to model arrays\n * @returns Generated TypeScript type definitions as a string\n */\nexport function generateTypesContent(models: Record<string, string[]>): string {\n const providerModelsEntries = Object.entries(models)\n .map(([provider, modelList]) => {\n const modelsList = modelList.map(m => `'${m}'`);\n\n // Quote provider key if it's not a valid JavaScript identifier\n // Valid identifiers must start with a letter, underscore, or dollar sign\n const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(provider);\n const providerKey = needsQuotes ? `'${provider}'` : provider;\n\n // Format array based on length (prettier printWidth: 120)\n const singleLine = ` readonly ${providerKey}: readonly [${modelsList.join(', ')}];`;\n\n // If single line exceeds 120 chars, format as multi-line\n if (singleLine.length > 120) {\n const formattedModels = modelList.map(m => ` '${m}',`).join('\\n');\n return ` readonly ${providerKey}: readonly [\\n${formattedModels}\\n ];`;\n }\n\n return singleLine;\n })\n .join('\\n');\n\n return `/**\n * THIS FILE IS AUTO-GENERATED - DO NOT EDIT\n * Generated from model gateway providers\n */\n\n/**\n * Provider models mapping type\n * This is derived from the JSON data and provides type-safe access\n */\nexport type ProviderModelsMap = {\n${providerModelsEntries}\n};\n\n/**\n * Union type of all registered provider IDs\n */\nexport type Provider = keyof ProviderModelsMap;\n\n/**\n * Provider models mapping interface\n */\nexport interface ProviderModels {\n [key: string]: string[];\n}\n\n/**\n * OpenAI-compatible model ID type\n * Dynamically derived from ProviderModelsMap\n * Full provider/model paths (e.g., \"openai/gpt-4o\", \"anthropic/claude-3-5-sonnet-20241022\")\n */\nexport type ModelRouterModelId =\n | {\n [P in Provider]: \\`\\${P}/\\${ProviderModelsMap[P][number]}\\`;\n }[Provider]\n | \\`mastra/\\${ProviderModelsMap['openrouter'][number]}\\`\n | (string & {});\n\n/**\n * Extract the model part from a ModelRouterModelId for a specific provider\n * Dynamically derived from ProviderModelsMap\n * Example: ModelForProvider<'openai'> = 'gpt-4o' | 'gpt-4-turbo' | ...\n */\nexport type ModelForProvider<P extends Provider> = ProviderModelsMap[P][number];\n`;\n}\n\n/**\n * Write registry files to disk (JSON and .d.ts)\n * @param jsonPath - Path to write the JSON file\n * @param typesPath - Path to write the .d.ts file\n * @param providers - Provider configurations\n * @param models - Model lists by provider\n */\nexport async function writeRegistryFiles(\n jsonPath: string,\n typesPath: string,\n providers: Record<string, ProviderConfig>,\n models: Record<string, string[]>,\n attachmentCapabilities?: AttachmentCapabilities,\n): Promise<void> {\n // 0. Ensure directories exist\n const jsonDir = path.dirname(jsonPath);\n const typesDir = path.dirname(typesPath);\n await fs.mkdir(jsonDir, { recursive: true });\n await fs.mkdir(typesDir, { recursive: true });\n\n // 1. Write JSON file atomically to prevent corruption from concurrent writes\n const registryData = {\n providers,\n models,\n version: '1.0.0',\n };\n\n await atomicWriteFile(jsonPath, JSON.stringify(registryData, null, 2), 'utf-8');\n\n // 2. Generate .d.ts file with type-only declarations (also atomic)\n const typeContent = generateTypesContent(models);\n await atomicWriteFile(typesPath, typeContent, 'utf-8');\n\n // 3. Write per-provider capability files into a capabilities/ directory\n if (attachmentCapabilities && Object.keys(attachmentCapabilities).length > 0) {\n const capDir = path.join(jsonDir, 'capabilities');\n await fs.mkdir(capDir, { recursive: true });\n\n // Clean out stale provider files from previous runs\n try {\n const existing = await fs.readdir(capDir);\n for (const file of existing) {\n if (file.endsWith('.json')) {\n await fs.unlink(path.join(capDir, file));\n }\n }\n } catch {\n // Directory may not exist yet — ignore\n }\n\n for (const [provider, models] of Object.entries(attachmentCapabilities)) {\n const providerFile = path.join(capDir, `${provider}.json`);\n await atomicWriteFile(providerFile, JSON.stringify({ attachment: models }, null, 2), 'utf-8');\n }\n }\n}\n"]} |
| export { ProcessorRunner, ProcessorState } from './chunk-YNS26J6E.js'; | ||
| //# sourceMappingURL=runner-2DAIS6LW.js.map | ||
| //# sourceMappingURL=runner-2DAIS6LW.js.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"runner-2DAIS6LW.js"} |
| 'use strict'; | ||
| var chunkH3Y3YAMF_cjs = require('./chunk-H3Y3YAMF.cjs'); | ||
| Object.defineProperty(exports, "ProcessorRunner", { | ||
| enumerable: true, | ||
| get: function () { return chunkH3Y3YAMF_cjs.ProcessorRunner; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorState", { | ||
| enumerable: true, | ||
| get: function () { return chunkH3Y3YAMF_cjs.ProcessorState; } | ||
| }); | ||
| //# sourceMappingURL=runner-SYEQ4Z4B.cjs.map | ||
| //# sourceMappingURL=runner-SYEQ4Z4B.cjs.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"runner-SYEQ4Z4B.cjs"} |
| 'use strict'; | ||
| var chunkQJ3FDYCK_cjs = require('./chunk-QJ3FDYCK.cjs'); | ||
| var chunkDRYYU2XF_cjs = require('./chunk-DRYYU2XF.cjs'); | ||
| var zod = require('zod'); | ||
| var inputSchema = zod.z.object({ taskId: zod.z.string() }); | ||
| var attemptOutcomeSchema = zod.z.enum(["success", "retry", "cancelled", "timed_out"]); | ||
| var attemptOutputSchema = zod.z.object({ | ||
| taskId: zod.z.string(), | ||
| outcome: attemptOutcomeSchema, | ||
| result: zod.z.unknown().optional(), | ||
| error: zod.z.any().optional() | ||
| }); | ||
| var bodyIOSchema = zod.z.object({ | ||
| taskId: zod.z.string(), | ||
| done: zod.z.boolean().optional(), | ||
| result: zod.z.unknown().optional() | ||
| }); | ||
| var bodyOutputSchema = zod.z.object({ | ||
| taskId: zod.z.string(), | ||
| done: zod.z.boolean(), | ||
| result: zod.z.unknown().optional() | ||
| }); | ||
| var WORKFLOW_STATUS_TO_PERSIST = ["suspended", "pending", "paused", "waiting"]; | ||
| function buildBackgroundTaskWorkflow(manager) { | ||
| const runAttemptStep = chunkQJ3FDYCK_cjs.createStep2({ | ||
| id: "run-attempt", | ||
| inputSchema: bodyIOSchema, | ||
| outputSchema: attemptOutputSchema, | ||
| execute: async ({ inputData, abortSignal: workflowAbortSignal, suspend, resumeData }) => { | ||
| const { taskId } = inputData; | ||
| const storage = await manager.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task || task.status === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, outcome: "cancelled" }; | ||
| } | ||
| const ctx = manager.taskContexts.get(taskId); | ||
| const executor = ctx?.executor ?? manager.getStaticExecutor(task.toolName); | ||
| if (!executor) { | ||
| const errorInfo = { | ||
| message: `No executor registered for tool "${task.toolName}". Register the tool on Mastra (so workers can resolve it cross-process) or run the task in the same process as the producer.` | ||
| }; | ||
| await storage.updateTask(taskId, { status: "failed", error: errorInfo, completedAt: /* @__PURE__ */ new Date() }); | ||
| const failedTask = await storage.getTask(taskId); | ||
| if (failedTask) { | ||
| await manager.runLocalCompletionHooks(failedTask, "failed", { error: errorInfo }); | ||
| await manager.publishLifecycleEvent("task.failed", failedTask); | ||
| } | ||
| manager.deregisterTaskContext(taskId); | ||
| throw new Error(errorInfo.message); | ||
| } | ||
| const progressThrottleMs = manager.config.progressThrottleMs; | ||
| const shouldThrottleProgress = typeof progressThrottleMs === "number" && Number.isFinite(progressThrottleMs) && progressThrottleMs > 0; | ||
| let lastProgressEmitMs; | ||
| const onProgress = async (chunk) => { | ||
| if (shouldThrottleProgress) { | ||
| const now = Date.now(); | ||
| if (lastProgressEmitMs !== void 0 && now - lastProgressEmitMs < progressThrottleMs) return; | ||
| lastProgressEmitMs = now; | ||
| } | ||
| await manager.publishLifecycleEvent("task.output", { ...task, chunk }); | ||
| }; | ||
| const abortController = new AbortController(); | ||
| manager.activeAbortControllers.set(taskId, abortController); | ||
| const onWorkflowAbort = () => abortController.abort(new Error("Task cancelled")); | ||
| if (workflowAbortSignal.aborted) { | ||
| abortController.abort(new Error("Task cancelled")); | ||
| } else { | ||
| workflowAbortSignal.addEventListener("abort", onWorkflowAbort, { once: true }); | ||
| } | ||
| const timeoutHandle = setTimeout(() => { | ||
| abortController.abort(new Error(`Task timed out after ${task.timeoutMs}ms`)); | ||
| }, task.timeoutMs); | ||
| let pendingSuspend; | ||
| const wrappedSuspend = async (data, suspendOptions) => { | ||
| await storage.updateTask(taskId, { | ||
| status: "suspended", | ||
| suspendPayload: data, | ||
| suspendedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| const suspendedTask = await storage.getTask(taskId); | ||
| if (suspendedTask) { | ||
| await manager.runLocalSuspendHooks(suspendedTask); | ||
| await manager.publishLifecycleEvent("task.suspended", suspendedTask); | ||
| } | ||
| pendingSuspend = { data, suspendOptions }; | ||
| }; | ||
| try { | ||
| const result = await executor.execute(task.args, { | ||
| abortSignal: abortController.signal, | ||
| onProgress, | ||
| suspend: wrappedSuspend, | ||
| // On resume the runtime populates `resumeData`; undefined on | ||
| // the initial run. | ||
| resumeData | ||
| }); | ||
| if (pendingSuspend) { | ||
| return suspend(pendingSuspend.data, pendingSuspend.suspendOptions); | ||
| } | ||
| return { taskId, outcome: "success", result }; | ||
| } catch (error) { | ||
| const currentTask = await storage.getTask(taskId); | ||
| if (!currentTask || currentTask.status === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, outcome: "cancelled" }; | ||
| } | ||
| if (abortController.signal.aborted || error?.name === "AbortError" || error?.message === "Task cancelled" || error?.message?.startsWith("Task timed out after ")) { | ||
| return { taskId, outcome: "timed_out" }; | ||
| } | ||
| return { | ||
| taskId, | ||
| outcome: "retry", | ||
| error: { message: error?.message ?? "Unknown error", stack: error?.stack } | ||
| }; | ||
| } finally { | ||
| clearTimeout(timeoutHandle); | ||
| workflowAbortSignal.removeEventListener("abort", onWorkflowAbort); | ||
| manager.activeAbortControllers.delete(taskId); | ||
| } | ||
| } | ||
| }); | ||
| const classifyOutcomeStep = chunkQJ3FDYCK_cjs.createStep2({ | ||
| id: "classify-outcome", | ||
| inputSchema: attemptOutputSchema, | ||
| outputSchema: bodyOutputSchema, | ||
| execute: async ({ inputData }) => { | ||
| const { taskId, outcome, result, error } = inputData; | ||
| const storage = await manager.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task) return { taskId, done: true }; | ||
| if (outcome === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, done: true }; | ||
| } | ||
| if (outcome === "timed_out") { | ||
| const status = task.status; | ||
| if (status !== "timed_out" && status !== "cancelled") { | ||
| await storage.updateTask(taskId, { | ||
| status: "timed_out", | ||
| error: { message: `Task timed out after ${task.timeoutMs}ms` }, | ||
| completedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| const timedOutTask = await storage.getTask(taskId); | ||
| if (timedOutTask) await manager.publishLifecycleEvent("task.failed", timedOutTask); | ||
| } | ||
| return { taskId, done: true }; | ||
| } | ||
| if (outcome === "success") { | ||
| if (task.status === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, done: true }; | ||
| } | ||
| await storage.updateTask(taskId, { status: "completed", result, completedAt: /* @__PURE__ */ new Date() }); | ||
| const completedTask = await storage.getTask(taskId); | ||
| if (completedTask) { | ||
| await manager.runLocalCompletionHooks(completedTask, "completed", { result }); | ||
| await manager.publishLifecycleEvent("task.completed", completedTask); | ||
| } | ||
| return { taskId, done: true, result }; | ||
| } | ||
| if (task.retryCount < task.maxRetries) { | ||
| await storage.updateTask(taskId, { | ||
| retryCount: task.retryCount + 1, | ||
| error: void 0, | ||
| startedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| return { taskId, done: false }; | ||
| } | ||
| const errorInfo = error ?? { message: "Unknown error" }; | ||
| await storage.updateTask(taskId, { status: "failed", error: errorInfo, completedAt: /* @__PURE__ */ new Date() }); | ||
| const failedTask = await storage.getTask(taskId); | ||
| if (failedTask) { | ||
| await manager.runLocalCompletionHooks(failedTask, "failed", { error: errorInfo }); | ||
| await manager.publishLifecycleEvent("task.failed", failedTask); | ||
| } | ||
| const thrown = new Error(errorInfo.message); | ||
| if (errorInfo.stack) thrown.stack = errorInfo.stack; | ||
| throw thrown; | ||
| } | ||
| }); | ||
| const attemptBodyWorkflow = chunkQJ3FDYCK_cjs.createWorkflow2({ | ||
| id: `${chunkDRYYU2XF_cjs.BACKGROUND_TASK_WORKFLOW_ID}__attempt`, | ||
| inputSchema: bodyIOSchema, | ||
| outputSchema: bodyOutputSchema, | ||
| steps: [runAttemptStep, classifyOutcomeStep], | ||
| options: { | ||
| // `dountil` feeds the prior iteration's output back in as input. The | ||
| // body's actual entry point only needs `taskId`, but the loop's | ||
| // feedback shape includes `done`/`result`/etc. Skip validation rather | ||
| // than widen every step's input schema. | ||
| validateInputs: false, | ||
| shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus), | ||
| // Internal scheduler plumbing — hide workflow spans from exported | ||
| // traces. The task body itself runs as user code and keeps its own | ||
| // spans. | ||
| tracingPolicy: { | ||
| internal: 1 /* WORKFLOW */ | ||
| } | ||
| } | ||
| }).then(runAttemptStep).then(classifyOutcomeStep).commit(); | ||
| return chunkQJ3FDYCK_cjs.createWorkflow2({ | ||
| id: chunkDRYYU2XF_cjs.BACKGROUND_TASK_WORKFLOW_ID, | ||
| inputSchema, | ||
| outputSchema: bodyOutputSchema, | ||
| steps: [attemptBodyWorkflow], | ||
| options: { | ||
| shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus), | ||
| // Internal scheduler plumbing — see the inner workflow comment. | ||
| tracingPolicy: { | ||
| internal: 1 /* WORKFLOW */ | ||
| } | ||
| } | ||
| }).dountil(attemptBodyWorkflow, async ({ inputData }) => inputData?.done === true).commit(); | ||
| } | ||
| Object.defineProperty(exports, "BACKGROUND_TASK_WORKFLOW_ID", { | ||
| enumerable: true, | ||
| get: function () { return chunkDRYYU2XF_cjs.BACKGROUND_TASK_WORKFLOW_ID; } | ||
| }); | ||
| exports.buildBackgroundTaskWorkflow = buildBackgroundTaskWorkflow; | ||
| //# sourceMappingURL=workflow-Q6UPZITR.cjs.map | ||
| //# sourceMappingURL=workflow-Q6UPZITR.cjs.map |
| {"version":3,"sources":["../src/background-tasks/workflow.ts"],"names":["z","createStep","createWorkflow","BACKGROUND_TASK_WORKFLOW_ID"],"mappings":";;;;;;AAUA,IAAM,WAAA,GAAcA,MAAE,MAAA,CAAO,EAAE,QAAQA,KAAA,CAAE,MAAA,IAAU,CAAA;AAEnD,IAAM,oBAAA,GAAuBA,MAAE,IAAA,CAAK,CAAC,WAAW,OAAA,EAAS,WAAA,EAAa,WAAW,CAAC,CAAA;AAElF,IAAM,mBAAA,GAAsBA,MAAE,MAAA,CAAO;AAAA,EACnC,MAAA,EAAQA,MAAE,MAAA,EAAO;AAAA,EACjB,OAAA,EAAS,oBAAA;AAAA,EACT,MAAA,EAAQA,KAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC7B,KAAA,EAAOA,KAAA,CAAE,GAAA,EAAI,CAAE,QAAA;AACjB,CAAC,CAAA;AAED,IAAM,YAAA,GAAeA,MAAE,MAAA,CAAO;AAAA,EAC5B,MAAA,EAAQA,MAAE,MAAA,EAAO;AAAA,EACjB,IAAA,EAAMA,KAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC3B,MAAA,EAAQA,KAAA,CAAE,OAAA,EAAQ,CAAE,QAAA;AACtB,CAAC,CAAA;AAED,IAAM,gBAAA,GAAmBA,MAAE,MAAA,CAAO;AAAA,EAChC,MAAA,EAAQA,MAAE,MAAA,EAAO;AAAA,EACjB,IAAA,EAAMA,MAAE,OAAA,EAAQ;AAAA,EAChB,MAAA,EAAQA,KAAA,CAAE,OAAA,EAAQ,CAAE,QAAA;AACtB,CAAC,CAAA;AAED,IAAM,0BAAA,GAA6B,CAAC,WAAA,EAAa,SAAA,EAAW,UAAU,SAAS,CAAA;AAmBxE,SAAS,4BAA4B,OAAA,EAAgC;AAC1E,EAAA,MAAM,iBAAiBC,6BAAA,CAAW;AAAA,IAChC,EAAA,EAAI,aAAA;AAAA,IACJ,WAAA,EAAa,YAAA;AAAA,IACb,YAAA,EAAc,mBAAA;AAAA,IACd,OAAA,EAAS,OAAO,EAAE,SAAA,EAAW,aAAa,mBAAA,EAAqB,OAAA,EAAS,YAAW,KAAM;AACvF,MAAA,MAAM,EAAE,QAAO,GAAI,SAAA;AACnB,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,UAAA,EAAW;AACzC,MAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA;AACzC,MAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,MAAA,KAAW,WAAA,EAAa;AACxC,QAAA,OAAA,CAAQ,sBAAsB,MAAM,CAAA;AACpC,QAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,WAAA,EAAqB;AAAA,MACjD;AASA,MAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA;AAC3C,MAAA,MAAM,WAAW,GAAA,EAAK,QAAA,IAAY,OAAA,CAAQ,iBAAA,CAAkB,KAAK,QAAQ,CAAA;AACzE,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,MAAM,SAAA,GAAY;AAAA,UAChB,OAAA,EACE,CAAA,iCAAA,EAAoC,IAAA,CAAK,QAAQ,CAAA,6HAAA;AAAA,SAGrD;AACA,QAAA,MAAM,OAAA,CAAQ,UAAA,CAAW,MAAA,EAAQ,EAAE,MAAA,EAAQ,QAAA,EAAU,KAAA,EAAO,SAAA,EAAW,WAAA,kBAAa,IAAI,IAAA,EAAK,EAAG,CAAA;AAChG,QAAA,MAAM,UAAA,GAAa,MAAM,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA;AAC/C,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,MAAM,QAAQ,uBAAA,CAAwB,UAAA,EAAY,UAAU,EAAE,KAAA,EAAO,WAAW,CAAA;AAChF,UAAA,MAAM,OAAA,CAAQ,qBAAA,CAAsB,aAAA,EAAe,UAAU,CAAA;AAAA,QAC/D;AACA,QAAA,OAAA,CAAQ,sBAAsB,MAAM,CAAA;AACpC,QAAA,MAAM,IAAI,KAAA,CAAM,SAAA,CAAU,OAAO,CAAA;AAAA,MACnC;AAGA,MAAA,MAAM,kBAAA,GAAqB,QAAQ,MAAA,CAAO,kBAAA;AAC1C,MAAA,MAAM,sBAAA,GACJ,OAAO,kBAAA,KAAuB,QAAA,IAAY,OAAO,QAAA,CAAS,kBAAkB,KAAK,kBAAA,GAAqB,CAAA;AACxG,MAAA,IAAI,kBAAA;AACJ,MAAA,MAAM,UAAA,GAAa,OAAO,KAAA,KAAe;AACvC,QAAA,IAAI,sBAAA,EAAwB;AAC1B,UAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,UAAA,IAAI,kBAAA,KAAuB,MAAA,IAAa,GAAA,GAAM,kBAAA,GAAqB,kBAAA,EAAqB;AACxF,UAAA,kBAAA,GAAqB,GAAA;AAAA,QACvB;AACA,QAAA,MAAM,QAAQ,qBAAA,CAAsB,aAAA,EAAe,EAAE,GAAG,IAAA,EAAM,OAAO,CAAA;AAAA,MACvE,CAAA;AAEA,MAAA,MAAM,eAAA,GAAkB,IAAI,eAAA,EAAgB;AAC5C,MAAA,OAAA,CAAQ,sBAAA,CAAuB,GAAA,CAAI,MAAA,EAAQ,eAAe,CAAA;AAG1D,MAAA,MAAM,kBAAkB,MAAM,eAAA,CAAgB,MAAM,IAAI,KAAA,CAAM,gBAAgB,CAAC,CAAA;AAC/E,MAAA,IAAI,oBAAoB,OAAA,EAAS;AAC/B,QAAA,eAAA,CAAgB,KAAA,CAAM,IAAI,KAAA,CAAM,gBAAgB,CAAC,CAAA;AAAA,MACnD,CAAA,MAAO;AACL,QAAA,mBAAA,CAAoB,iBAAiB,OAAA,EAAS,eAAA,EAAiB,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,MAC/E;AACA,MAAA,MAAM,aAAA,GAAgB,WAAW,MAAM;AACrC,QAAA,eAAA,CAAgB,MAAM,IAAI,KAAA,CAAM,wBAAwB,IAAA,CAAK,SAAS,IAAI,CAAC,CAAA;AAAA,MAC7E,CAAA,EAAG,KAAK,SAAS,CAAA;AAYjB,MAAA,IAAI,cAAA;AACJ,MAAA,MAAM,cAAA,GAAiB,OAAO,IAAA,EAAgB,cAAA,KAAoC;AAChF,QAAA,MAAM,OAAA,CAAQ,WAAW,MAAA,EAAQ;AAAA,UAC/B,MAAA,EAAQ,WAAA;AAAA,UACR,cAAA,EAAgB,IAAA;AAAA,UAChB,WAAA,sBAAiB,IAAA;AAAK,SACvB,CAAA;AACD,QAAA,MAAM,aAAA,GAAgB,MAAM,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA;AAClD,QAAA,IAAI,aAAA,EAAe;AAKjB,UAAA,MAAM,OAAA,CAAQ,qBAAqB,aAAa,CAAA;AAChD,UAAA,MAAM,OAAA,CAAQ,qBAAA,CAAsB,gBAAA,EAAkB,aAAa,CAAA;AAAA,QACrE;AACA,QAAA,cAAA,GAAiB,EAAE,MAAM,cAAA,EAAe;AAAA,MAC1C,CAAA;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,OAAA,CAAQ,KAAK,IAAA,EAAM;AAAA,UAC/C,aAAa,eAAA,CAAgB,MAAA;AAAA,UAC7B,UAAA;AAAA,UACA,OAAA,EAAS,cAAA;AAAA;AAAA;AAAA,UAGT;AAAA,SACD,CAAA;AAED,QAAA,IAAI,cAAA,EAAgB;AAClB,UAAA,OAAO,OAAA,CAAQ,cAAA,CAAe,IAAA,EAAM,cAAA,CAAe,cAAgC,CAAA;AAAA,QACrF;AAEA,QAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAA,EAAoB,MAAA,EAAO;AAAA,MACvD,SAAS,KAAA,EAAY;AACnB,QAAA,MAAM,WAAA,GAAc,MAAM,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA;AAChD,QAAA,IAAI,CAAC,WAAA,IAAgB,WAAA,CAAY,MAAA,KAAoC,WAAA,EAAa;AAChF,UAAA,OAAA,CAAQ,sBAAsB,MAAM,CAAA;AACpC,UAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,WAAA,EAAqB;AAAA,QACjD;AAOA,QAAA,IACE,eAAA,CAAgB,MAAA,CAAO,OAAA,IACvB,KAAA,EAAO,IAAA,KAAS,YAAA,IAChB,KAAA,EAAO,OAAA,KAAY,gBAAA,IACnB,KAAA,EAAO,OAAA,EAAS,UAAA,CAAW,uBAAuB,CAAA,EAClD;AACA,UAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,WAAA,EAAqB;AAAA,QACjD;AAEA,QAAA,OAAO;AAAA,UACL,MAAA;AAAA,UACA,OAAA,EAAS,OAAA;AAAA,UACT,KAAA,EAAO,EAAE,OAAA,EAAS,KAAA,EAAO,WAAW,eAAA,EAAiB,KAAA,EAAO,OAAO,KAAA;AAAM,SAC3E;AAAA,MACF,CAAA,SAAE;AACA,QAAA,YAAA,CAAa,aAAa,CAAA;AAC1B,QAAA,mBAAA,CAAoB,mBAAA,CAAoB,SAAS,eAAe,CAAA;AAChE,QAAA,OAAA,CAAQ,sBAAA,CAAuB,OAAO,MAAM,CAAA;AAAA,MAC9C;AAAA,IACF;AAAA,GACD,CAAA;AAED,EAAA,MAAM,sBAAsBA,6BAAA,CAAW;AAAA,IACrC,EAAA,EAAI,kBAAA;AAAA,IACJ,WAAA,EAAa,mBAAA;AAAA,IACb,YAAA,EAAc,gBAAA;AAAA,IACd,OAAA,EAAS,OAAO,EAAE,SAAA,EAAU,KAAM;AAChC,MAAA,MAAM,EAAE,MAAA,EAAQ,OAAA,EAAS,MAAA,EAAQ,OAAM,GAAI,SAAA;AAC3C,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,UAAA,EAAW;AACzC,MAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA;AACzC,MAAA,IAAI,CAAC,IAAA,EAAM,OAAO,EAAE,MAAA,EAAQ,MAAM,IAAA,EAAK;AAEvC,MAAA,IAAI,YAAY,WAAA,EAAa;AAC3B,QAAA,OAAA,CAAQ,sBAAsB,MAAM,CAAA;AACpC,QAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,IAAA,EAAK;AAAA,MAC9B;AAEA,MAAA,IAAI,YAAY,WAAA,EAAa;AAC3B,QAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,QAAA,IAAI,MAAA,KAAW,WAAA,IAAe,MAAA,KAAW,WAAA,EAAa;AACpD,UAAA,MAAM,OAAA,CAAQ,WAAW,MAAA,EAAQ;AAAA,YAC/B,MAAA,EAAQ,WAAA;AAAA,YACR,OAAO,EAAE,OAAA,EAAS,CAAA,qBAAA,EAAwB,IAAA,CAAK,SAAS,CAAA,EAAA,CAAA,EAAK;AAAA,YAC7D,WAAA,sBAAiB,IAAA;AAAK,WACvB,CAAA;AACD,UAAA,MAAM,YAAA,GAAe,MAAM,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA;AACjD,UAAA,IAAI,YAAA,EAAc,MAAM,OAAA,CAAQ,qBAAA,CAAsB,eAAe,YAAY,CAAA;AAAA,QACnF;AACA,QAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,IAAA,EAAK;AAAA,MAC9B;AAEA,MAAA,IAAI,YAAY,SAAA,EAAW;AACzB,QAAA,IAAK,IAAA,CAAK,WAAoC,WAAA,EAAa;AACzD,UAAA,OAAA,CAAQ,sBAAsB,MAAM,CAAA;AACpC,UAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,IAAA,EAAK;AAAA,QAC9B;AACA,QAAA,MAAM,OAAA,CAAQ,UAAA,CAAW,MAAA,EAAQ,EAAE,MAAA,EAAQ,WAAA,EAAa,MAAA,EAAQ,WAAA,kBAAa,IAAI,IAAA,EAAK,EAAG,CAAA;AACzF,QAAA,MAAM,aAAA,GAAgB,MAAM,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA;AAClD,QAAA,IAAI,aAAA,EAAe;AACjB,UAAA,MAAM,QAAQ,uBAAA,CAAwB,aAAA,EAAe,WAAA,EAAa,EAAE,QAAQ,CAAA;AAC5E,UAAA,MAAM,OAAA,CAAQ,qBAAA,CAAsB,gBAAA,EAAkB,aAAa,CAAA;AAAA,QACrE;AACA,QAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,IAAA,EAAM,MAAA,EAAO;AAAA,MACtC;AAGA,MAAA,IAAI,IAAA,CAAK,UAAA,GAAa,IAAA,CAAK,UAAA,EAAY;AACrC,QAAA,MAAM,OAAA,CAAQ,WAAW,MAAA,EAAQ;AAAA,UAC/B,UAAA,EAAY,KAAK,UAAA,GAAa,CAAA;AAAA,UAC9B,KAAA,EAAO,MAAA;AAAA,UACP,SAAA,sBAAe,IAAA;AAAK,SACrB,CAAA;AACD,QAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAM;AAAA,MAC/B;AAKA,MAAA,MAAM,SAAA,GAAY,KAAA,IAAS,EAAE,OAAA,EAAS,eAAA,EAAgB;AACtD,MAAA,MAAM,OAAA,CAAQ,UAAA,CAAW,MAAA,EAAQ,EAAE,MAAA,EAAQ,QAAA,EAAU,KAAA,EAAO,SAAA,EAAW,WAAA,kBAAa,IAAI,IAAA,EAAK,EAAG,CAAA;AAChG,MAAA,MAAM,UAAA,GAAa,MAAM,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA;AAC/C,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,MAAM,QAAQ,uBAAA,CAAwB,UAAA,EAAY,UAAU,EAAE,KAAA,EAAO,WAAW,CAAA;AAChF,QAAA,MAAM,OAAA,CAAQ,qBAAA,CAAsB,aAAA,EAAe,UAAU,CAAA;AAAA,MAC/D;AACA,MAAA,MAAM,MAAA,GAAS,IAAI,KAAA,CAAM,SAAA,CAAU,OAAO,CAAA;AAC1C,MAAA,IAAI,SAAA,CAAU,KAAA,EAAO,MAAA,CAAO,KAAA,GAAQ,SAAA,CAAU,KAAA;AAC9C,MAAA,MAAM,MAAA;AAAA,IACR;AAAA,GACD,CAAA;AAED,EAAA,MAAM,sBAAsBC,iCAAA,CAAe;AAAA,IACzC,EAAA,EAAI,GAAGC,6CAA2B,CAAA,SAAA,CAAA;AAAA,IAClC,WAAA,EAAa,YAAA;AAAA,IACb,YAAA,EAAc,gBAAA;AAAA,IACd,KAAA,EAAO,CAAC,cAAA,EAAgB,mBAAmB,CAAA;AAAA,IAC3C,OAAA,EAAS;AAAA;AAAA;AAAA;AAAA;AAAA,MAKP,cAAA,EAAgB,KAAA;AAAA,MAChB,uBAAuB,CAAC,EAAE,gBAAe,KAAM,0BAAA,CAA2B,SAAS,cAAc,CAAA;AAAA;AAAA;AAAA;AAAA,MAIjG,aAAA,EAAe;AAAA,QACb,QAAA,EAAA,CAAA;AAAA;AACF;AACF,GACD,EACE,IAAA,CAAK,cAAc,EACnB,IAAA,CAAK,mBAAmB,EACxB,MAAA,EAAO;AAEV,EAAA,OAAOD,iCAAA,CAAe;AAAA,IACpB,EAAA,EAAIC,6CAAA;AAAA,IACJ,WAAA;AAAA,IACA,YAAA,EAAc,gBAAA;AAAA,IACd,KAAA,EAAO,CAAC,mBAAmB,CAAA;AAAA,IAC3B,OAAA,EAAS;AAAA,MACP,uBAAuB,CAAC,EAAE,gBAAe,KAAM,0BAAA,CAA2B,SAAS,cAAc,CAAA;AAAA;AAAA,MAEjG,aAAA,EAAe;AAAA,QACb,QAAA,EAAA,CAAA;AAAA;AACF;AACF,GACD,CAAA,CACE,OAAA,CAAQ,mBAAA,EAAqB,OAAO,EAAE,SAAA,EAAU,KAAM,SAAA,EAAW,IAAA,KAAS,IAAI,CAAA,CAC9E,MAAA,EAAO;AACZ","file":"workflow-Q6UPZITR.cjs","sourcesContent":["import { z } from 'zod';\nimport { InternalSpans } from '../observability';\nimport type { SuspendOptions } from '../workflows';\nimport { createStep, createWorkflow } from '../workflows/evented';\nimport type { BackgroundTaskManager } from './manager';\nimport type { BackgroundTaskStatus } from './types';\nimport { BACKGROUND_TASK_WORKFLOW_ID } from './workflow-id';\n\nexport { BACKGROUND_TASK_WORKFLOW_ID } from './workflow-id';\n\nconst inputSchema = z.object({ taskId: z.string() });\n\nconst attemptOutcomeSchema = z.enum(['success', 'retry', 'cancelled', 'timed_out']);\n\nconst attemptOutputSchema = z.object({\n taskId: z.string(),\n outcome: attemptOutcomeSchema,\n result: z.unknown().optional(),\n error: z.any().optional(),\n});\n\nconst bodyIOSchema = z.object({\n taskId: z.string(),\n done: z.boolean().optional(),\n result: z.unknown().optional(),\n});\n\nconst bodyOutputSchema = z.object({\n taskId: z.string(),\n done: z.boolean(),\n result: z.unknown().optional(),\n});\n\nconst WORKFLOW_STATUS_TO_PERSIST = ['suspended', 'pending', 'paused', 'waiting'];\n\n/**\n * Builds the per-task evented workflow that owns executor + retries.\n *\n * Shape: outer workflow runs an inner `[run-attempt, classify-outcome]`\n * workflow inside a `dountil` loop. `run-attempt` invokes the executor and\n * categorises the outcome; `classify-outcome` persists final state, advances\n * retry bookkeeping, and decides whether the loop is done. The dountil\n * predicate exits on `done === true`.\n *\n * The nested-workflow-as-loop-body path lives in\n * `processWorkflowEnd → processWorkflowLoop` and was fixed in PR #16312.\n * Suspend/resume routes through the runtime's nested-workflow auto-detect\n * (`processWorkflowStepRun` resume branch).\n *\n * Step bodies close over `manager` directly — the bg-tasks layer is the only\n * consumer of the `@internal` private fields.\n */\nexport function buildBackgroundTaskWorkflow(manager: BackgroundTaskManager) {\n const runAttemptStep = createStep({\n id: 'run-attempt',\n inputSchema: bodyIOSchema,\n outputSchema: attemptOutputSchema,\n execute: async ({ inputData, abortSignal: workflowAbortSignal, suspend, resumeData }) => {\n const { taskId } = inputData;\n const storage = await manager.getStorage();\n const task = await storage.getTask(taskId);\n if (!task || task.status === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, outcome: 'cancelled' as const };\n }\n\n // Resolve the executor. Two paths:\n // 1. Per-task `TaskContext` registered on the producer (in-process).\n // Carries closure-captured state (e.g. agent memory hooks) and\n // wins when present.\n // 2. Static executor registered by tool name. Used by remote workers\n // that received the dispatch via PubSub and don't have access to\n // the producer's per-task closure.\n const ctx = manager.taskContexts.get(taskId);\n const executor = ctx?.executor ?? manager.getStaticExecutor(task.toolName);\n if (!executor) {\n const errorInfo = {\n message:\n `No executor registered for tool \"${task.toolName}\". ` +\n `Register the tool on Mastra (so workers can resolve it cross-process) ` +\n `or run the task in the same process as the producer.`,\n };\n await storage.updateTask(taskId, { status: 'failed', error: errorInfo, completedAt: new Date() });\n const failedTask = await storage.getTask(taskId);\n if (failedTask) {\n await manager.runLocalCompletionHooks(failedTask, 'failed', { error: errorInfo });\n await manager.publishLifecycleEvent('task.failed', failedTask);\n }\n manager.deregisterTaskContext(taskId);\n throw new Error(errorInfo.message);\n }\n\n // Throttled progress publisher.\n const progressThrottleMs = manager.config.progressThrottleMs;\n const shouldThrottleProgress =\n typeof progressThrottleMs === 'number' && Number.isFinite(progressThrottleMs) && progressThrottleMs > 0;\n let lastProgressEmitMs: number | undefined;\n const onProgress = async (chunk: any) => {\n if (shouldThrottleProgress) {\n const now = Date.now();\n if (lastProgressEmitMs !== undefined && now - lastProgressEmitMs < progressThrottleMs!) return;\n lastProgressEmitMs = now;\n }\n await manager.publishLifecycleEvent('task.output', { ...task, chunk });\n };\n\n const abortController = new AbortController();\n manager.activeAbortControllers.set(taskId, abortController);\n // Wire the workflow's run-level abort signal into our local controller\n // so `workflow.getRun(taskId).cancel()` propagates to the executor.\n const onWorkflowAbort = () => abortController.abort(new Error('Task cancelled'));\n if (workflowAbortSignal.aborted) {\n abortController.abort(new Error('Task cancelled'));\n } else {\n workflowAbortSignal.addEventListener('abort', onWorkflowAbort, { once: true });\n }\n const timeoutHandle = setTimeout(() => {\n abortController.abort(new Error(`Task timed out after ${task.timeoutMs}ms`));\n }, task.timeoutMs);\n\n // Wrap the workflow runtime's `suspend` so we persist\n // `status: 'suspended'` + `suspendPayload`, fire the per-task\n // suspend hook (so the bg-task's `onResult` updates the agent's\n // message list), and publish the lifecycle event before\n // delegating. The runtime's `suspend` does not throw — it sets a\n // flag the step-executor reads after `execute` returns. We\n // capture the args here and call the runtime's suspend from the\n // step body after the executor returns, so `wrappedSuspend` can\n // safely run all its side effects synchronously inside the\n // tool's call.\n let pendingSuspend: { data?: unknown; suspendOptions?: SuspendOptions } | undefined;\n const wrappedSuspend = async (data?: unknown, suspendOptions?: SuspendOptions) => {\n await storage.updateTask(taskId, {\n status: 'suspended',\n suspendPayload: data,\n suspendedAt: new Date(),\n });\n const suspendedTask = await storage.getTask(taskId);\n if (suspendedTask) {\n // Suspend is non-terminal — DO NOT use `runLocalCompletionHooks`\n // here. That helper deregisters the task context in its `finally`\n // block, which would strand the resume call (the workflow step\n // body re-enters and looks up `manager.taskContexts.get(taskId)`).\n await manager.runLocalSuspendHooks(suspendedTask);\n await manager.publishLifecycleEvent('task.suspended', suspendedTask);\n }\n pendingSuspend = { data, suspendOptions };\n };\n\n try {\n const result = await executor.execute(task.args, {\n abortSignal: abortController.signal,\n onProgress,\n suspend: wrappedSuspend,\n // On resume the runtime populates `resumeData`; undefined on\n // the initial run.\n resumeData,\n });\n\n if (pendingSuspend) {\n return suspend(pendingSuspend.data, pendingSuspend.suspendOptions as SuspendOptions);\n }\n\n return { taskId, outcome: 'success' as const, result };\n } catch (error: any) {\n const currentTask = await storage.getTask(taskId);\n if (!currentTask || (currentTask.status as BackgroundTaskStatus) === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, outcome: 'cancelled' as const };\n }\n\n // Treat any aborted-signal exit as a timeout. The cancel path is\n // already handled by the storage-status check above, so if we reach\n // here with `signal.aborted`, it's the timeout abort. The\n // `AbortError` / message checks are belt-and-braces for executors\n // that throw their own abort error instead of propagating ours.\n if (\n abortController.signal.aborted ||\n error?.name === 'AbortError' ||\n error?.message === 'Task cancelled' ||\n error?.message?.startsWith('Task timed out after ')\n ) {\n return { taskId, outcome: 'timed_out' as const };\n }\n\n return {\n taskId,\n outcome: 'retry' as const,\n error: { message: error?.message ?? 'Unknown error', stack: error?.stack },\n };\n } finally {\n clearTimeout(timeoutHandle);\n workflowAbortSignal.removeEventListener('abort', onWorkflowAbort);\n manager.activeAbortControllers.delete(taskId);\n }\n },\n });\n\n const classifyOutcomeStep = createStep({\n id: 'classify-outcome',\n inputSchema: attemptOutputSchema,\n outputSchema: bodyOutputSchema,\n execute: async ({ inputData }) => {\n const { taskId, outcome, result, error } = inputData;\n const storage = await manager.getStorage();\n const task = await storage.getTask(taskId);\n if (!task) return { taskId, done: true };\n\n if (outcome === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, done: true };\n }\n\n if (outcome === 'timed_out') {\n const status = task.status as string;\n if (status !== 'timed_out' && status !== 'cancelled') {\n await storage.updateTask(taskId, {\n status: 'timed_out',\n error: { message: `Task timed out after ${task.timeoutMs}ms` },\n completedAt: new Date(),\n });\n const timedOutTask = await storage.getTask(taskId);\n if (timedOutTask) await manager.publishLifecycleEvent('task.failed', timedOutTask);\n }\n return { taskId, done: true };\n }\n\n if (outcome === 'success') {\n if ((task.status as BackgroundTaskStatus) === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, done: true };\n }\n await storage.updateTask(taskId, { status: 'completed', result, completedAt: new Date() });\n const completedTask = await storage.getTask(taskId);\n if (completedTask) {\n await manager.runLocalCompletionHooks(completedTask, 'completed', { result });\n await manager.publishLifecycleEvent('task.completed', completedTask);\n }\n return { taskId, done: true, result };\n }\n\n // outcome === 'retry'\n if (task.retryCount < task.maxRetries) {\n await storage.updateTask(taskId, {\n retryCount: task.retryCount + 1,\n error: undefined,\n startedAt: new Date(),\n });\n return { taskId, done: false };\n }\n\n // Retries exhausted: persist failure and throw so the workflow run ends\n // in `failed` rather than completing cleanly. Throw matches the prior\n // single-step behavior — workflow-run history stays accurate.\n const errorInfo = error ?? { message: 'Unknown error' };\n await storage.updateTask(taskId, { status: 'failed', error: errorInfo, completedAt: new Date() });\n const failedTask = await storage.getTask(taskId);\n if (failedTask) {\n await manager.runLocalCompletionHooks(failedTask, 'failed', { error: errorInfo });\n await manager.publishLifecycleEvent('task.failed', failedTask);\n }\n const thrown = new Error(errorInfo.message);\n if (errorInfo.stack) thrown.stack = errorInfo.stack;\n throw thrown;\n },\n });\n\n const attemptBodyWorkflow = createWorkflow({\n id: `${BACKGROUND_TASK_WORKFLOW_ID}__attempt`,\n inputSchema: bodyIOSchema,\n outputSchema: bodyOutputSchema,\n steps: [runAttemptStep, classifyOutcomeStep],\n options: {\n // `dountil` feeds the prior iteration's output back in as input. The\n // body's actual entry point only needs `taskId`, but the loop's\n // feedback shape includes `done`/`result`/etc. Skip validation rather\n // than widen every step's input schema.\n validateInputs: false,\n shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus),\n // Internal scheduler plumbing — hide workflow spans from exported\n // traces. The task body itself runs as user code and keeps its own\n // spans.\n tracingPolicy: {\n internal: InternalSpans.WORKFLOW,\n },\n },\n })\n .then(runAttemptStep)\n .then(classifyOutcomeStep)\n .commit();\n\n return createWorkflow({\n id: BACKGROUND_TASK_WORKFLOW_ID,\n inputSchema,\n outputSchema: bodyOutputSchema,\n steps: [attemptBodyWorkflow],\n options: {\n shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus),\n // Internal scheduler plumbing — see the inner workflow comment.\n tracingPolicy: {\n internal: InternalSpans.WORKFLOW,\n },\n },\n })\n .dountil(attemptBodyWorkflow, async ({ inputData }) => inputData?.done === true)\n .commit();\n}\n"]} |
| import { createStep2, createWorkflow2 } from './chunk-PQ5PN4TW.js'; | ||
| import { BACKGROUND_TASK_WORKFLOW_ID } from './chunk-GCIWBMEH.js'; | ||
| export { BACKGROUND_TASK_WORKFLOW_ID } from './chunk-GCIWBMEH.js'; | ||
| import { z } from 'zod'; | ||
| var inputSchema = z.object({ taskId: z.string() }); | ||
| var attemptOutcomeSchema = z.enum(["success", "retry", "cancelled", "timed_out"]); | ||
| var attemptOutputSchema = z.object({ | ||
| taskId: z.string(), | ||
| outcome: attemptOutcomeSchema, | ||
| result: z.unknown().optional(), | ||
| error: z.any().optional() | ||
| }); | ||
| var bodyIOSchema = z.object({ | ||
| taskId: z.string(), | ||
| done: z.boolean().optional(), | ||
| result: z.unknown().optional() | ||
| }); | ||
| var bodyOutputSchema = z.object({ | ||
| taskId: z.string(), | ||
| done: z.boolean(), | ||
| result: z.unknown().optional() | ||
| }); | ||
| var WORKFLOW_STATUS_TO_PERSIST = ["suspended", "pending", "paused", "waiting"]; | ||
| function buildBackgroundTaskWorkflow(manager) { | ||
| const runAttemptStep = createStep2({ | ||
| id: "run-attempt", | ||
| inputSchema: bodyIOSchema, | ||
| outputSchema: attemptOutputSchema, | ||
| execute: async ({ inputData, abortSignal: workflowAbortSignal, suspend, resumeData }) => { | ||
| const { taskId } = inputData; | ||
| const storage = await manager.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task || task.status === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, outcome: "cancelled" }; | ||
| } | ||
| const ctx = manager.taskContexts.get(taskId); | ||
| const executor = ctx?.executor ?? manager.getStaticExecutor(task.toolName); | ||
| if (!executor) { | ||
| const errorInfo = { | ||
| message: `No executor registered for tool "${task.toolName}". Register the tool on Mastra (so workers can resolve it cross-process) or run the task in the same process as the producer.` | ||
| }; | ||
| await storage.updateTask(taskId, { status: "failed", error: errorInfo, completedAt: /* @__PURE__ */ new Date() }); | ||
| const failedTask = await storage.getTask(taskId); | ||
| if (failedTask) { | ||
| await manager.runLocalCompletionHooks(failedTask, "failed", { error: errorInfo }); | ||
| await manager.publishLifecycleEvent("task.failed", failedTask); | ||
| } | ||
| manager.deregisterTaskContext(taskId); | ||
| throw new Error(errorInfo.message); | ||
| } | ||
| const progressThrottleMs = manager.config.progressThrottleMs; | ||
| const shouldThrottleProgress = typeof progressThrottleMs === "number" && Number.isFinite(progressThrottleMs) && progressThrottleMs > 0; | ||
| let lastProgressEmitMs; | ||
| const onProgress = async (chunk) => { | ||
| if (shouldThrottleProgress) { | ||
| const now = Date.now(); | ||
| if (lastProgressEmitMs !== void 0 && now - lastProgressEmitMs < progressThrottleMs) return; | ||
| lastProgressEmitMs = now; | ||
| } | ||
| await manager.publishLifecycleEvent("task.output", { ...task, chunk }); | ||
| }; | ||
| const abortController = new AbortController(); | ||
| manager.activeAbortControllers.set(taskId, abortController); | ||
| const onWorkflowAbort = () => abortController.abort(new Error("Task cancelled")); | ||
| if (workflowAbortSignal.aborted) { | ||
| abortController.abort(new Error("Task cancelled")); | ||
| } else { | ||
| workflowAbortSignal.addEventListener("abort", onWorkflowAbort, { once: true }); | ||
| } | ||
| const timeoutHandle = setTimeout(() => { | ||
| abortController.abort(new Error(`Task timed out after ${task.timeoutMs}ms`)); | ||
| }, task.timeoutMs); | ||
| let pendingSuspend; | ||
| const wrappedSuspend = async (data, suspendOptions) => { | ||
| await storage.updateTask(taskId, { | ||
| status: "suspended", | ||
| suspendPayload: data, | ||
| suspendedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| const suspendedTask = await storage.getTask(taskId); | ||
| if (suspendedTask) { | ||
| await manager.runLocalSuspendHooks(suspendedTask); | ||
| await manager.publishLifecycleEvent("task.suspended", suspendedTask); | ||
| } | ||
| pendingSuspend = { data, suspendOptions }; | ||
| }; | ||
| try { | ||
| const result = await executor.execute(task.args, { | ||
| abortSignal: abortController.signal, | ||
| onProgress, | ||
| suspend: wrappedSuspend, | ||
| // On resume the runtime populates `resumeData`; undefined on | ||
| // the initial run. | ||
| resumeData | ||
| }); | ||
| if (pendingSuspend) { | ||
| return suspend(pendingSuspend.data, pendingSuspend.suspendOptions); | ||
| } | ||
| return { taskId, outcome: "success", result }; | ||
| } catch (error) { | ||
| const currentTask = await storage.getTask(taskId); | ||
| if (!currentTask || currentTask.status === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, outcome: "cancelled" }; | ||
| } | ||
| if (abortController.signal.aborted || error?.name === "AbortError" || error?.message === "Task cancelled" || error?.message?.startsWith("Task timed out after ")) { | ||
| return { taskId, outcome: "timed_out" }; | ||
| } | ||
| return { | ||
| taskId, | ||
| outcome: "retry", | ||
| error: { message: error?.message ?? "Unknown error", stack: error?.stack } | ||
| }; | ||
| } finally { | ||
| clearTimeout(timeoutHandle); | ||
| workflowAbortSignal.removeEventListener("abort", onWorkflowAbort); | ||
| manager.activeAbortControllers.delete(taskId); | ||
| } | ||
| } | ||
| }); | ||
| const classifyOutcomeStep = createStep2({ | ||
| id: "classify-outcome", | ||
| inputSchema: attemptOutputSchema, | ||
| outputSchema: bodyOutputSchema, | ||
| execute: async ({ inputData }) => { | ||
| const { taskId, outcome, result, error } = inputData; | ||
| const storage = await manager.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task) return { taskId, done: true }; | ||
| if (outcome === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, done: true }; | ||
| } | ||
| if (outcome === "timed_out") { | ||
| const status = task.status; | ||
| if (status !== "timed_out" && status !== "cancelled") { | ||
| await storage.updateTask(taskId, { | ||
| status: "timed_out", | ||
| error: { message: `Task timed out after ${task.timeoutMs}ms` }, | ||
| completedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| const timedOutTask = await storage.getTask(taskId); | ||
| if (timedOutTask) await manager.publishLifecycleEvent("task.failed", timedOutTask); | ||
| } | ||
| return { taskId, done: true }; | ||
| } | ||
| if (outcome === "success") { | ||
| if (task.status === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, done: true }; | ||
| } | ||
| await storage.updateTask(taskId, { status: "completed", result, completedAt: /* @__PURE__ */ new Date() }); | ||
| const completedTask = await storage.getTask(taskId); | ||
| if (completedTask) { | ||
| await manager.runLocalCompletionHooks(completedTask, "completed", { result }); | ||
| await manager.publishLifecycleEvent("task.completed", completedTask); | ||
| } | ||
| return { taskId, done: true, result }; | ||
| } | ||
| if (task.retryCount < task.maxRetries) { | ||
| await storage.updateTask(taskId, { | ||
| retryCount: task.retryCount + 1, | ||
| error: void 0, | ||
| startedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| return { taskId, done: false }; | ||
| } | ||
| const errorInfo = error ?? { message: "Unknown error" }; | ||
| await storage.updateTask(taskId, { status: "failed", error: errorInfo, completedAt: /* @__PURE__ */ new Date() }); | ||
| const failedTask = await storage.getTask(taskId); | ||
| if (failedTask) { | ||
| await manager.runLocalCompletionHooks(failedTask, "failed", { error: errorInfo }); | ||
| await manager.publishLifecycleEvent("task.failed", failedTask); | ||
| } | ||
| const thrown = new Error(errorInfo.message); | ||
| if (errorInfo.stack) thrown.stack = errorInfo.stack; | ||
| throw thrown; | ||
| } | ||
| }); | ||
| const attemptBodyWorkflow = createWorkflow2({ | ||
| id: `${BACKGROUND_TASK_WORKFLOW_ID}__attempt`, | ||
| inputSchema: bodyIOSchema, | ||
| outputSchema: bodyOutputSchema, | ||
| steps: [runAttemptStep, classifyOutcomeStep], | ||
| options: { | ||
| // `dountil` feeds the prior iteration's output back in as input. The | ||
| // body's actual entry point only needs `taskId`, but the loop's | ||
| // feedback shape includes `done`/`result`/etc. Skip validation rather | ||
| // than widen every step's input schema. | ||
| validateInputs: false, | ||
| shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus), | ||
| // Internal scheduler plumbing — hide workflow spans from exported | ||
| // traces. The task body itself runs as user code and keeps its own | ||
| // spans. | ||
| tracingPolicy: { | ||
| internal: 1 /* WORKFLOW */ | ||
| } | ||
| } | ||
| }).then(runAttemptStep).then(classifyOutcomeStep).commit(); | ||
| return createWorkflow2({ | ||
| id: BACKGROUND_TASK_WORKFLOW_ID, | ||
| inputSchema, | ||
| outputSchema: bodyOutputSchema, | ||
| steps: [attemptBodyWorkflow], | ||
| options: { | ||
| shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus), | ||
| // Internal scheduler plumbing — see the inner workflow comment. | ||
| tracingPolicy: { | ||
| internal: 1 /* WORKFLOW */ | ||
| } | ||
| } | ||
| }).dountil(attemptBodyWorkflow, async ({ inputData }) => inputData?.done === true).commit(); | ||
| } | ||
| export { buildBackgroundTaskWorkflow }; | ||
| //# sourceMappingURL=workflow-XYGMHLZV.js.map | ||
| //# sourceMappingURL=workflow-XYGMHLZV.js.map |
| {"version":3,"sources":["../src/background-tasks/workflow.ts"],"names":["createStep","createWorkflow"],"mappings":"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","file":"workflow-XYGMHLZV.js","sourcesContent":["import { z } from 'zod';\nimport { InternalSpans } from '../observability';\nimport type { SuspendOptions } from '../workflows';\nimport { createStep, createWorkflow } from '../workflows/evented';\nimport type { BackgroundTaskManager } from './manager';\nimport type { BackgroundTaskStatus } from './types';\nimport { BACKGROUND_TASK_WORKFLOW_ID } from './workflow-id';\n\nexport { BACKGROUND_TASK_WORKFLOW_ID } from './workflow-id';\n\nconst inputSchema = z.object({ taskId: z.string() });\n\nconst attemptOutcomeSchema = z.enum(['success', 'retry', 'cancelled', 'timed_out']);\n\nconst attemptOutputSchema = z.object({\n taskId: z.string(),\n outcome: attemptOutcomeSchema,\n result: z.unknown().optional(),\n error: z.any().optional(),\n});\n\nconst bodyIOSchema = z.object({\n taskId: z.string(),\n done: z.boolean().optional(),\n result: z.unknown().optional(),\n});\n\nconst bodyOutputSchema = z.object({\n taskId: z.string(),\n done: z.boolean(),\n result: z.unknown().optional(),\n});\n\nconst WORKFLOW_STATUS_TO_PERSIST = ['suspended', 'pending', 'paused', 'waiting'];\n\n/**\n * Builds the per-task evented workflow that owns executor + retries.\n *\n * Shape: outer workflow runs an inner `[run-attempt, classify-outcome]`\n * workflow inside a `dountil` loop. `run-attempt` invokes the executor and\n * categorises the outcome; `classify-outcome` persists final state, advances\n * retry bookkeeping, and decides whether the loop is done. The dountil\n * predicate exits on `done === true`.\n *\n * The nested-workflow-as-loop-body path lives in\n * `processWorkflowEnd → processWorkflowLoop` and was fixed in PR #16312.\n * Suspend/resume routes through the runtime's nested-workflow auto-detect\n * (`processWorkflowStepRun` resume branch).\n *\n * Step bodies close over `manager` directly — the bg-tasks layer is the only\n * consumer of the `@internal` private fields.\n */\nexport function buildBackgroundTaskWorkflow(manager: BackgroundTaskManager) {\n const runAttemptStep = createStep({\n id: 'run-attempt',\n inputSchema: bodyIOSchema,\n outputSchema: attemptOutputSchema,\n execute: async ({ inputData, abortSignal: workflowAbortSignal, suspend, resumeData }) => {\n const { taskId } = inputData;\n const storage = await manager.getStorage();\n const task = await storage.getTask(taskId);\n if (!task || task.status === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, outcome: 'cancelled' as const };\n }\n\n // Resolve the executor. Two paths:\n // 1. Per-task `TaskContext` registered on the producer (in-process).\n // Carries closure-captured state (e.g. agent memory hooks) and\n // wins when present.\n // 2. Static executor registered by tool name. Used by remote workers\n // that received the dispatch via PubSub and don't have access to\n // the producer's per-task closure.\n const ctx = manager.taskContexts.get(taskId);\n const executor = ctx?.executor ?? manager.getStaticExecutor(task.toolName);\n if (!executor) {\n const errorInfo = {\n message:\n `No executor registered for tool \"${task.toolName}\". ` +\n `Register the tool on Mastra (so workers can resolve it cross-process) ` +\n `or run the task in the same process as the producer.`,\n };\n await storage.updateTask(taskId, { status: 'failed', error: errorInfo, completedAt: new Date() });\n const failedTask = await storage.getTask(taskId);\n if (failedTask) {\n await manager.runLocalCompletionHooks(failedTask, 'failed', { error: errorInfo });\n await manager.publishLifecycleEvent('task.failed', failedTask);\n }\n manager.deregisterTaskContext(taskId);\n throw new Error(errorInfo.message);\n }\n\n // Throttled progress publisher.\n const progressThrottleMs = manager.config.progressThrottleMs;\n const shouldThrottleProgress =\n typeof progressThrottleMs === 'number' && Number.isFinite(progressThrottleMs) && progressThrottleMs > 0;\n let lastProgressEmitMs: number | undefined;\n const onProgress = async (chunk: any) => {\n if (shouldThrottleProgress) {\n const now = Date.now();\n if (lastProgressEmitMs !== undefined && now - lastProgressEmitMs < progressThrottleMs!) return;\n lastProgressEmitMs = now;\n }\n await manager.publishLifecycleEvent('task.output', { ...task, chunk });\n };\n\n const abortController = new AbortController();\n manager.activeAbortControllers.set(taskId, abortController);\n // Wire the workflow's run-level abort signal into our local controller\n // so `workflow.getRun(taskId).cancel()` propagates to the executor.\n const onWorkflowAbort = () => abortController.abort(new Error('Task cancelled'));\n if (workflowAbortSignal.aborted) {\n abortController.abort(new Error('Task cancelled'));\n } else {\n workflowAbortSignal.addEventListener('abort', onWorkflowAbort, { once: true });\n }\n const timeoutHandle = setTimeout(() => {\n abortController.abort(new Error(`Task timed out after ${task.timeoutMs}ms`));\n }, task.timeoutMs);\n\n // Wrap the workflow runtime's `suspend` so we persist\n // `status: 'suspended'` + `suspendPayload`, fire the per-task\n // suspend hook (so the bg-task's `onResult` updates the agent's\n // message list), and publish the lifecycle event before\n // delegating. The runtime's `suspend` does not throw — it sets a\n // flag the step-executor reads after `execute` returns. We\n // capture the args here and call the runtime's suspend from the\n // step body after the executor returns, so `wrappedSuspend` can\n // safely run all its side effects synchronously inside the\n // tool's call.\n let pendingSuspend: { data?: unknown; suspendOptions?: SuspendOptions } | undefined;\n const wrappedSuspend = async (data?: unknown, suspendOptions?: SuspendOptions) => {\n await storage.updateTask(taskId, {\n status: 'suspended',\n suspendPayload: data,\n suspendedAt: new Date(),\n });\n const suspendedTask = await storage.getTask(taskId);\n if (suspendedTask) {\n // Suspend is non-terminal — DO NOT use `runLocalCompletionHooks`\n // here. That helper deregisters the task context in its `finally`\n // block, which would strand the resume call (the workflow step\n // body re-enters and looks up `manager.taskContexts.get(taskId)`).\n await manager.runLocalSuspendHooks(suspendedTask);\n await manager.publishLifecycleEvent('task.suspended', suspendedTask);\n }\n pendingSuspend = { data, suspendOptions };\n };\n\n try {\n const result = await executor.execute(task.args, {\n abortSignal: abortController.signal,\n onProgress,\n suspend: wrappedSuspend,\n // On resume the runtime populates `resumeData`; undefined on\n // the initial run.\n resumeData,\n });\n\n if (pendingSuspend) {\n return suspend(pendingSuspend.data, pendingSuspend.suspendOptions as SuspendOptions);\n }\n\n return { taskId, outcome: 'success' as const, result };\n } catch (error: any) {\n const currentTask = await storage.getTask(taskId);\n if (!currentTask || (currentTask.status as BackgroundTaskStatus) === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, outcome: 'cancelled' as const };\n }\n\n // Treat any aborted-signal exit as a timeout. The cancel path is\n // already handled by the storage-status check above, so if we reach\n // here with `signal.aborted`, it's the timeout abort. The\n // `AbortError` / message checks are belt-and-braces for executors\n // that throw their own abort error instead of propagating ours.\n if (\n abortController.signal.aborted ||\n error?.name === 'AbortError' ||\n error?.message === 'Task cancelled' ||\n error?.message?.startsWith('Task timed out after ')\n ) {\n return { taskId, outcome: 'timed_out' as const };\n }\n\n return {\n taskId,\n outcome: 'retry' as const,\n error: { message: error?.message ?? 'Unknown error', stack: error?.stack },\n };\n } finally {\n clearTimeout(timeoutHandle);\n workflowAbortSignal.removeEventListener('abort', onWorkflowAbort);\n manager.activeAbortControllers.delete(taskId);\n }\n },\n });\n\n const classifyOutcomeStep = createStep({\n id: 'classify-outcome',\n inputSchema: attemptOutputSchema,\n outputSchema: bodyOutputSchema,\n execute: async ({ inputData }) => {\n const { taskId, outcome, result, error } = inputData;\n const storage = await manager.getStorage();\n const task = await storage.getTask(taskId);\n if (!task) return { taskId, done: true };\n\n if (outcome === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, done: true };\n }\n\n if (outcome === 'timed_out') {\n const status = task.status as string;\n if (status !== 'timed_out' && status !== 'cancelled') {\n await storage.updateTask(taskId, {\n status: 'timed_out',\n error: { message: `Task timed out after ${task.timeoutMs}ms` },\n completedAt: new Date(),\n });\n const timedOutTask = await storage.getTask(taskId);\n if (timedOutTask) await manager.publishLifecycleEvent('task.failed', timedOutTask);\n }\n return { taskId, done: true };\n }\n\n if (outcome === 'success') {\n if ((task.status as BackgroundTaskStatus) === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, done: true };\n }\n await storage.updateTask(taskId, { status: 'completed', result, completedAt: new Date() });\n const completedTask = await storage.getTask(taskId);\n if (completedTask) {\n await manager.runLocalCompletionHooks(completedTask, 'completed', { result });\n await manager.publishLifecycleEvent('task.completed', completedTask);\n }\n return { taskId, done: true, result };\n }\n\n // outcome === 'retry'\n if (task.retryCount < task.maxRetries) {\n await storage.updateTask(taskId, {\n retryCount: task.retryCount + 1,\n error: undefined,\n startedAt: new Date(),\n });\n return { taskId, done: false };\n }\n\n // Retries exhausted: persist failure and throw so the workflow run ends\n // in `failed` rather than completing cleanly. Throw matches the prior\n // single-step behavior — workflow-run history stays accurate.\n const errorInfo = error ?? { message: 'Unknown error' };\n await storage.updateTask(taskId, { status: 'failed', error: errorInfo, completedAt: new Date() });\n const failedTask = await storage.getTask(taskId);\n if (failedTask) {\n await manager.runLocalCompletionHooks(failedTask, 'failed', { error: errorInfo });\n await manager.publishLifecycleEvent('task.failed', failedTask);\n }\n const thrown = new Error(errorInfo.message);\n if (errorInfo.stack) thrown.stack = errorInfo.stack;\n throw thrown;\n },\n });\n\n const attemptBodyWorkflow = createWorkflow({\n id: `${BACKGROUND_TASK_WORKFLOW_ID}__attempt`,\n inputSchema: bodyIOSchema,\n outputSchema: bodyOutputSchema,\n steps: [runAttemptStep, classifyOutcomeStep],\n options: {\n // `dountil` feeds the prior iteration's output back in as input. The\n // body's actual entry point only needs `taskId`, but the loop's\n // feedback shape includes `done`/`result`/etc. Skip validation rather\n // than widen every step's input schema.\n validateInputs: false,\n shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus),\n // Internal scheduler plumbing — hide workflow spans from exported\n // traces. The task body itself runs as user code and keeps its own\n // spans.\n tracingPolicy: {\n internal: InternalSpans.WORKFLOW,\n },\n },\n })\n .then(runAttemptStep)\n .then(classifyOutcomeStep)\n .commit();\n\n return createWorkflow({\n id: BACKGROUND_TASK_WORKFLOW_ID,\n inputSchema,\n outputSchema: bodyOutputSchema,\n steps: [attemptBodyWorkflow],\n options: {\n shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus),\n // Internal scheduler plumbing — see the inner workflow comment.\n tracingPolicy: {\n internal: InternalSpans.WORKFLOW,\n },\n },\n })\n .dountil(attemptBodyWorkflow, async ({ inputData }) => inputData?.done === true)\n .commit();\n}\n"]} |
| 'use strict'; | ||
| var chunkMQ4ZJ5UC_cjs = require('../../chunk-MQ4ZJ5UC.cjs'); | ||
| var chunk5FCWY4Z3_cjs = require('../../chunk-5FCWY4Z3.cjs'); | ||
@@ -66,3 +66,3 @@ // src/agent-builder/ee/types.ts | ||
| function splitRuntimeModelString(input) { | ||
| const providers = chunkMQ4ZJ5UC_cjs.getRegisteredProviders().sort((a, b) => b.length - a.length); | ||
| const providers = chunk5FCWY4Z3_cjs.getRegisteredProviders().sort((a, b) => b.length - a.length); | ||
| for (const providerId of providers) { | ||
@@ -75,3 +75,3 @@ const prefix = `${providerId}/`; | ||
| } | ||
| const parsed = chunkMQ4ZJ5UC_cjs.parseModelString(input); | ||
| const parsed = chunk5FCWY4Z3_cjs.parseModelString(input); | ||
| if (parsed.provider && parsed.modelId) { | ||
@@ -176,3 +176,3 @@ return { provider: parsed.provider, modelId: parsed.modelId }; | ||
| if ("kind" in entry && entry.kind === "custom") return true; | ||
| return chunkMQ4ZJ5UC_cjs.isProviderRegistered(entry.provider); | ||
| return chunk5FCWY4Z3_cjs.isProviderRegistered(entry.provider); | ||
| }); | ||
@@ -179,0 +179,0 @@ if (activeEntries.length === 0) return false; |
@@ -1,2 +0,2 @@ | ||
| import { isProviderRegistered, getRegisteredProviders, parseModelString } from '../../chunk-PL6DJRKR.js'; | ||
| import { isProviderRegistered, getRegisteredProviders, parseModelString } from '../../chunk-CXGM7OSM.js'; | ||
@@ -3,0 +3,0 @@ // src/agent-builder/ee/types.ts |
| 'use strict'; | ||
| var chunkOKPB3IMA_cjs = require('../chunk-OKPB3IMA.cjs'); | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkNPAGJ3HR_cjs = require('../chunk-NPAGJ3HR.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
@@ -10,49 +10,49 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkOKPB3IMA_cjs.AgentController; } | ||
| get: function () { return chunkNPAGJ3HR_cjs.AgentController; } | ||
| }); | ||
| Object.defineProperty(exports, "Session", { | ||
| enumerable: true, | ||
| get: function () { return chunkOKPB3IMA_cjs.Session; } | ||
| get: function () { return chunkNPAGJ3HR_cjs.Session; } | ||
| }); | ||
| Object.defineProperty(exports, "defaultDisplayState", { | ||
| enumerable: true, | ||
| get: function () { return chunkOKPB3IMA_cjs.defaultDisplayState; } | ||
| get: function () { return chunkNPAGJ3HR_cjs.defaultDisplayState; } | ||
| }); | ||
| Object.defineProperty(exports, "defaultOMProgressState", { | ||
| enumerable: true, | ||
| get: function () { return chunkOKPB3IMA_cjs.defaultOMProgressState; } | ||
| get: function () { return chunkNPAGJ3HR_cjs.defaultOMProgressState; } | ||
| }); | ||
| Object.defineProperty(exports, "parseSubagentMeta", { | ||
| enumerable: true, | ||
| get: function () { return chunkOKPB3IMA_cjs.parseSubagentMeta; } | ||
| get: function () { return chunkNPAGJ3HR_cjs.parseSubagentMeta; } | ||
| }); | ||
| Object.defineProperty(exports, "askUserTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.askUserTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.askUserTool; } | ||
| }); | ||
| Object.defineProperty(exports, "assignTaskIds", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.assignTaskIds; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.assignTaskIds; } | ||
| }); | ||
| Object.defineProperty(exports, "submitPlanTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.submitPlanTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.submitPlanTool; } | ||
| }); | ||
| Object.defineProperty(exports, "taskCheckTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.taskCheckTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.taskCheckTool; } | ||
| }); | ||
| Object.defineProperty(exports, "taskCompleteTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.taskCompleteTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.taskCompleteTool; } | ||
| }); | ||
| Object.defineProperty(exports, "taskUpdateTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.taskUpdateTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.taskUpdateTool; } | ||
| }); | ||
| Object.defineProperty(exports, "taskWriteTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.taskWriteTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.taskWriteTool; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,4 +0,4 @@ | ||
| export { AgentController, Session, defaultDisplayState, defaultOMProgressState, parseSubagentMeta } from '../chunk-QR3NJFL3.js'; | ||
| export { askUserTool, assignTaskIds, submitPlanTool, taskCheckTool, taskCompleteTool, taskUpdateTool, taskWriteTool } from '../chunk-MVA25X63.js'; | ||
| export { AgentController, Session, defaultDisplayState, defaultOMProgressState, parseSubagentMeta } from '../chunk-MRDQBJLU.js'; | ||
| export { askUserTool, assignTaskIds, submitPlanTool, taskCheckTool, taskCompleteTool, taskUpdateTool, taskWriteTool } from '../chunk-PQ5PN4TW.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
+21
-21
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkLZIIAAGJ_cjs = require('../chunk-LZIIAAGJ.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
| var chunkH3Y3YAMF_cjs = require('../chunk-H3Y3YAMF.cjs'); | ||
| var chunkDC5C6QMM_cjs = require('../chunk-DC5C6QMM.cjs'); | ||
@@ -11,75 +11,75 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.Agent; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.Agent; } | ||
| }); | ||
| Object.defineProperty(exports, "HEARTBEAT_SCHEDULE_PREFIX", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.HEARTBEAT_SCHEDULE_PREFIX; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.HEARTBEAT_SCHEDULE_PREFIX; } | ||
| }); | ||
| Object.defineProperty(exports, "HeartbeatInputSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.HeartbeatInputSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.HeartbeatInputSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "HeartbeatOutputSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.HeartbeatOutputSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.HeartbeatOutputSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "Heartbeats", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.Heartbeats; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.Heartbeats; } | ||
| }); | ||
| Object.defineProperty(exports, "SignalProvider", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SignalProvider; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SignalProvider; } | ||
| }); | ||
| Object.defineProperty(exports, "WebhookSignalProvider", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.WebhookSignalProvider; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.WebhookSignalProvider; } | ||
| }); | ||
| Object.defineProperty(exports, "agentConfig", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.agentConfig; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.agentConfig; } | ||
| }); | ||
| Object.defineProperty(exports, "assembleAgentFromFsEntry", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.assembleAgentFromFsEntry; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.assembleAgentFromFsEntry; } | ||
| }); | ||
| Object.defineProperty(exports, "isAgentCompatible", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.isAgentCompatible; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.isAgentCompatible; } | ||
| }); | ||
| Object.defineProperty(exports, "isDurableAgentLike", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.isDurableAgentLike; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.isDurableAgentLike; } | ||
| }); | ||
| Object.defineProperty(exports, "isSignalProvider", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.isSignalProvider; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.isSignalProvider; } | ||
| }); | ||
| Object.defineProperty(exports, "toHeartbeat", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.toHeartbeat; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.toHeartbeat; } | ||
| }); | ||
| Object.defineProperty(exports, "TripWire", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.TripWire; } | ||
| get: function () { return chunkH3Y3YAMF_cjs.TripWire; } | ||
| }); | ||
| Object.defineProperty(exports, "isSupportedLanguageModel", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.isSupportedLanguageModel; } | ||
| get: function () { return chunkH3Y3YAMF_cjs.isSupportedLanguageModel; } | ||
| }); | ||
| Object.defineProperty(exports, "resolveThreadIdFromArgs", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.resolveThreadIdFromArgs; } | ||
| get: function () { return chunkH3Y3YAMF_cjs.resolveThreadIdFromArgs; } | ||
| }); | ||
| Object.defineProperty(exports, "supportedLanguageModelSpecifications", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.supportedLanguageModelSpecifications; } | ||
| get: function () { return chunkH3Y3YAMF_cjs.supportedLanguageModelSpecifications; } | ||
| }); | ||
| Object.defineProperty(exports, "tryGenerateWithJsonFallback", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.tryGenerateWithJsonFallback; } | ||
| get: function () { return chunkH3Y3YAMF_cjs.tryGenerateWithJsonFallback; } | ||
| }); | ||
| Object.defineProperty(exports, "tryStreamWithJsonFallback", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.tryStreamWithJsonFallback; } | ||
| get: function () { return chunkH3Y3YAMF_cjs.tryStreamWithJsonFallback; } | ||
| }); | ||
@@ -86,0 +86,0 @@ Object.defineProperty(exports, "MessageList", { |
@@ -1,5 +0,5 @@ | ||
| export { Agent, HEARTBEAT_SCHEDULE_PREFIX, HeartbeatInputSchema, HeartbeatOutputSchema, Heartbeats, SignalProvider, WebhookSignalProvider, agentConfig, assembleAgentFromFsEntry, isAgentCompatible, isDurableAgentLike, isSignalProvider, toHeartbeat } from '../chunk-MVA25X63.js'; | ||
| export { TripWire, isSupportedLanguageModel, resolveThreadIdFromArgs, supportedLanguageModelSpecifications, tryGenerateWithJsonFallback, tryStreamWithJsonFallback } from '../chunk-HCSJNNEN.js'; | ||
| export { Agent, HEARTBEAT_SCHEDULE_PREFIX, HeartbeatInputSchema, HeartbeatOutputSchema, Heartbeats, SignalProvider, WebhookSignalProvider, agentConfig, assembleAgentFromFsEntry, isAgentCompatible, isDurableAgentLike, isSignalProvider, toHeartbeat } from '../chunk-PQ5PN4TW.js'; | ||
| export { TripWire, isSupportedLanguageModel, resolveThreadIdFromArgs, supportedLanguageModelSpecifications, tryGenerateWithJsonFallback, tryStreamWithJsonFallback } from '../chunk-YNS26J6E.js'; | ||
| export { MessageList, TypeDetector, aiV5ModelMessageToV2PromptMessage, convertMessages, createMessageSignal, createSignal, dataPartToSignal, isCreatedAgentSignal, isMastraSignalMessage, mastraDBMessageToSignal, resolveDeliveryAttributes, signalToDataPartFormat, signalToMastraDBMessage, signalToMessage, signalToXmlMarkup } from '../chunk-FDU3KNKR.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkBHNX447S_cjs = require('../chunk-BHNX447S.cjs'); | ||
| var chunkDRYYU2XF_cjs = require('../chunk-DRYYU2XF.cjs'); | ||
@@ -9,29 +9,29 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkBHNX447S_cjs.BACKGROUND_TASK_WORKFLOW_ID; } | ||
| get: function () { return chunkDRYYU2XF_cjs.BACKGROUND_TASK_WORKFLOW_ID; } | ||
| }); | ||
| Object.defineProperty(exports, "BackgroundTaskManager", { | ||
| enumerable: true, | ||
| get: function () { return chunkBHNX447S_cjs.BackgroundTaskManager; } | ||
| get: function () { return chunkDRYYU2XF_cjs.BackgroundTaskManager; } | ||
| }); | ||
| Object.defineProperty(exports, "backgroundOverrideJsonSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkBHNX447S_cjs.backgroundOverrideJsonSchema; } | ||
| get: function () { return chunkDRYYU2XF_cjs.backgroundOverrideJsonSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "backgroundOverrideZodSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkBHNX447S_cjs.backgroundOverrideZodSchema; } | ||
| get: function () { return chunkDRYYU2XF_cjs.backgroundOverrideZodSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "createBackgroundTask", { | ||
| enumerable: true, | ||
| get: function () { return chunkBHNX447S_cjs.createBackgroundTask; } | ||
| get: function () { return chunkDRYYU2XF_cjs.createBackgroundTask; } | ||
| }); | ||
| Object.defineProperty(exports, "generateBackgroundTaskSystemPrompt", { | ||
| enumerable: true, | ||
| get: function () { return chunkBHNX447S_cjs.generateBackgroundTaskSystemPrompt; } | ||
| get: function () { return chunkDRYYU2XF_cjs.generateBackgroundTaskSystemPrompt; } | ||
| }); | ||
| Object.defineProperty(exports, "resolveBackgroundConfig", { | ||
| enumerable: true, | ||
| get: function () { return chunkBHNX447S_cjs.resolveBackgroundConfig; } | ||
| get: function () { return chunkDRYYU2XF_cjs.resolveBackgroundConfig; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,3 +0,3 @@ | ||
| export { BACKGROUND_TASK_WORKFLOW_ID, BackgroundTaskManager, backgroundOverrideJsonSchema, backgroundOverrideZodSchema, createBackgroundTask, generateBackgroundTaskSystemPrompt, resolveBackgroundConfig } from '../chunk-MLZSPNYB.js'; | ||
| export { BACKGROUND_TASK_WORKFLOW_ID, BackgroundTaskManager, backgroundOverrideJsonSchema, backgroundOverrideZodSchema, createBackgroundTask, generateBackgroundTaskSystemPrompt, resolveBackgroundConfig } from '../chunk-GCIWBMEH.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
@@ -9,21 +9,21 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.AgentChannels; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.AgentChannels; } | ||
| }); | ||
| Object.defineProperty(exports, "ChatChannelProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ChatChannelProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ChatChannelProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "MastraStateAdapter", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MastraStateAdapter; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MastraStateAdapter; } | ||
| }); | ||
| Object.defineProperty(exports, "defaultTypingStatus", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.defaultTypingStatus; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.defaultTypingStatus; } | ||
| }); | ||
| Object.defineProperty(exports, "resolveWaitUntil", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.resolveWaitUntil; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.resolveWaitUntil; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,3 +0,3 @@ | ||
| export { AgentChannels, ChatChannelProcessor, MastraStateAdapter, defaultTypingStatus, resolveWaitUntil } from '../chunk-MVA25X63.js'; | ||
| export { AgentChannels, ChatChannelProcessor, MastraStateAdapter, defaultTypingStatus, resolveWaitUntil } from '../chunk-PQ5PN4TW.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkORIBHWNH_cjs = require('../chunk-ORIBHWNH.cjs'); | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunk7QFVYQT7_cjs = require('../chunk-7QFVYQT7.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
@@ -175,5 +175,5 @@ // src/coding-agent/prompt.ts | ||
| return [ | ||
| new chunkGSWZYCY4_cjs.StreamErrorRetryProcessor({ | ||
| new chunkQJ3FDYCK_cjs.StreamErrorRetryProcessor({ | ||
| matchers: [ | ||
| { match: chunkGSWZYCY4_cjs.isBadRequestError, maxRetries: 1, delayMs: 2e3 }, | ||
| { match: chunkQJ3FDYCK_cjs.isBadRequestError, maxRetries: 1, delayMs: 2e3 }, | ||
| { | ||
@@ -186,10 +186,10 @@ match: isECONNRESETError, | ||
| }), | ||
| new chunkGSWZYCY4_cjs.PrefillErrorHandler(), | ||
| new chunkGSWZYCY4_cjs.ProviderHistoryCompat() | ||
| new chunkQJ3FDYCK_cjs.PrefillErrorHandler(), | ||
| new chunkQJ3FDYCK_cjs.ProviderHistoryCompat() | ||
| ]; | ||
| } | ||
| function defaultWorkspace(basePath) { | ||
| return new chunkGSWZYCY4_cjs.Workspace({ | ||
| filesystem: new chunkGSWZYCY4_cjs.LocalFilesystem({ basePath }), | ||
| sandbox: new chunkGSWZYCY4_cjs.LocalSandbox({ workingDirectory: basePath }) | ||
| return new chunkQJ3FDYCK_cjs.Workspace({ | ||
| filesystem: new chunkQJ3FDYCK_cjs.LocalFilesystem({ basePath }), | ||
| sandbox: new chunkQJ3FDYCK_cjs.LocalSandbox({ workingDirectory: basePath }) | ||
| }); | ||
@@ -200,7 +200,7 @@ } | ||
| const workspace = "workspace" in config ? config.workspace : defaultWorkspace(basePath ?? process.cwd()); | ||
| const resolvedGoal = goal ? { ...goal, prompt: goal.prompt ?? chunkGSWZYCY4_cjs.DEFAULT_GOAL_JUDGE_PROMPT } : void 0; | ||
| return new chunkGSWZYCY4_cjs.Agent({ | ||
| const resolvedGoal = goal ? { ...goal, prompt: goal.prompt ?? chunkQJ3FDYCK_cjs.DEFAULT_GOAL_JUDGE_PROMPT } : void 0; | ||
| return new chunkQJ3FDYCK_cjs.Agent({ | ||
| ...rest, | ||
| workspace, | ||
| signals: signals ?? [new chunkORIBHWNH_cjs.TaskSignalProvider()], | ||
| signals: signals ?? [new chunk7QFVYQT7_cjs.TaskSignalProvider()], | ||
| errorProcessors: errorProcessors ?? defaultErrorProcessors(), | ||
@@ -207,0 +207,0 @@ ...resolvedGoal ? { goal: resolvedGoal } : {} |
@@ -1,3 +0,3 @@ | ||
| import { TaskSignalProvider } from '../chunk-T27PG4IC.js'; | ||
| import { Agent, DEFAULT_GOAL_JUDGE_PROMPT, Workspace, LocalSandbox, LocalFilesystem, StreamErrorRetryProcessor, PrefillErrorHandler, ProviderHistoryCompat, isBadRequestError } from '../chunk-MVA25X63.js'; | ||
| import { TaskSignalProvider } from '../chunk-SBQZFH46.js'; | ||
| import { Agent, DEFAULT_GOAL_JUDGE_PROMPT, Workspace, LocalSandbox, LocalFilesystem, StreamErrorRetryProcessor, PrefillErrorHandler, ProviderHistoryCompat, isBadRequestError } from '../chunk-PQ5PN4TW.js'; | ||
@@ -4,0 +4,0 @@ // src/coding-agent/prompt.ts |
+20
-20
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkPVH4I7QG_cjs = require('../chunk-PVH4I7QG.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
| var chunkYLFDILPM_cjs = require('../chunk-YLFDILPM.cjs'); | ||
@@ -10,73 +10,73 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.Dataset; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.Dataset; } | ||
| }); | ||
| Object.defineProperty(exports, "DatasetsManager", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.DatasetsManager; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.DatasetsManager; } | ||
| }); | ||
| Object.defineProperty(exports, "TOOL_MOCK_EXHAUSTED", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.TOOL_MOCK_EXHAUSTED; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.TOOL_MOCK_EXHAUSTED; } | ||
| }); | ||
| Object.defineProperty(exports, "TOOL_MOCK_MISMATCH", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.TOOL_MOCK_MISMATCH; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.TOOL_MOCK_MISMATCH; } | ||
| }); | ||
| Object.defineProperty(exports, "ToolMockMatcher", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ToolMockMatcher; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ToolMockMatcher; } | ||
| }); | ||
| Object.defineProperty(exports, "compareExperiments", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.compareExperiments; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.compareExperiments; } | ||
| }); | ||
| Object.defineProperty(exports, "computeMean", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.computeMean; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.computeMean; } | ||
| }); | ||
| Object.defineProperty(exports, "computeScorerStats", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.computeScorerStats; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.computeScorerStats; } | ||
| }); | ||
| Object.defineProperty(exports, "executeTarget", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.executeTarget; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.executeTarget; } | ||
| }); | ||
| Object.defineProperty(exports, "isRegression", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.isRegression; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.isRegression; } | ||
| }); | ||
| Object.defineProperty(exports, "resolveScorers", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.resolveScorers; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.resolveScorers; } | ||
| }); | ||
| Object.defineProperty(exports, "runExperiment", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.runExperiment; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.runExperiment; } | ||
| }); | ||
| Object.defineProperty(exports, "runScorersForItem", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.runScorersForItem; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.runScorersForItem; } | ||
| }); | ||
| Object.defineProperty(exports, "SchemaUpdateValidationError", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.SchemaUpdateValidationError; } | ||
| get: function () { return chunkYLFDILPM_cjs.SchemaUpdateValidationError; } | ||
| }); | ||
| Object.defineProperty(exports, "SchemaValidationError", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.SchemaValidationError; } | ||
| get: function () { return chunkYLFDILPM_cjs.SchemaValidationError; } | ||
| }); | ||
| Object.defineProperty(exports, "SchemaValidator", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.SchemaValidator; } | ||
| get: function () { return chunkYLFDILPM_cjs.SchemaValidator; } | ||
| }); | ||
| Object.defineProperty(exports, "createValidator", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.createValidator; } | ||
| get: function () { return chunkYLFDILPM_cjs.createValidator; } | ||
| }); | ||
| Object.defineProperty(exports, "getSchemaValidator", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.getSchemaValidator; } | ||
| get: function () { return chunkYLFDILPM_cjs.getSchemaValidator; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,4 +0,4 @@ | ||
| export { Dataset, DatasetsManager, TOOL_MOCK_EXHAUSTED, TOOL_MOCK_MISMATCH, ToolMockMatcher, compareExperiments, computeMean, computeScorerStats, executeTarget, isRegression, resolveScorers, runExperiment, runScorersForItem } from '../chunk-MVA25X63.js'; | ||
| export { SchemaUpdateValidationError, SchemaValidationError, SchemaValidator, createValidator, getSchemaValidator } from '../chunk-BXKPCDLM.js'; | ||
| export { Dataset, DatasetsManager, TOOL_MOCK_EXHAUSTED, TOOL_MOCK_MISMATCH, ToolMockMatcher, compareExperiments, computeMean, computeScorerStats, executeTarget, isRegression, resolveScorers, runExperiment, runScorersForItem } from '../chunk-PQ5PN4TW.js'; | ||
| export { SchemaUpdateValidationError, SchemaValidationError, SchemaValidator, createValidator, getSchemaValidator } from '../chunk-RIIPXHAY.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
| var chunkTLSDQS6O_cjs = require('../chunk-TLSDQS6O.cjs'); | ||
@@ -11,15 +11,15 @@ var chunk3I6MKYQG_cjs = require('../chunk-3I6MKYQG.cjs'); | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MastraScorer; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MastraScorer; } | ||
| }); | ||
| Object.defineProperty(exports, "createScorer", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createScorer; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createScorer; } | ||
| }); | ||
| Object.defineProperty(exports, "filterRun", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.filterRun; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.filterRun; } | ||
| }); | ||
| Object.defineProperty(exports, "runEvals", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.runEvals; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.runEvals; } | ||
| }); | ||
@@ -26,0 +26,0 @@ Object.defineProperty(exports, "collectToolMocks", { |
@@ -1,2 +0,2 @@ | ||
| export { MastraScorer, createScorer, filterRun, runEvals } from '../chunk-MVA25X63.js'; | ||
| export { MastraScorer, createScorer, filterRun, runEvals } from '../chunk-PQ5PN4TW.js'; | ||
| export { collectToolMocks } from '../chunk-T24H2ARG.js'; | ||
@@ -3,0 +3,0 @@ export { extractTrajectory, extractTrajectoryFromTrace, extractWorkflowTrajectory, listScoresResponseSchema, saveScorePayloadSchema, scoreResultSchema, scoreRowDataSchema, scoringEntityTypeSchema, scoringExtractStepResultSchema, scoringHookInputSchema, scoringInputSchema, scoringInputWithExtractStepResultAndAnalyzeStepResultSchema, scoringInputWithExtractStepResultAndScoreAndReasonSchema, scoringInputWithExtractStepResultSchema, scoringPromptsSchema, scoringSourceSchema, scoringValueSchema } from '../chunk-PUHREAKR.js'; |
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../../chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../../chunk-QJ3FDYCK.cjs'); | ||
| var chunk3I6MKYQG_cjs = require('../../chunk-3I6MKYQG.cjs'); | ||
@@ -237,3 +237,3 @@ var chunkLP4WZA6D_cjs = require('../../chunk-LP4WZA6D.cjs'); | ||
| // src/evals/scoreTraces/scoreTracesWorkflow.ts | ||
| var getTraceStep = chunkGSWZYCY4_cjs.createStep2({ | ||
| var getTraceStep = chunkQJ3FDYCK_cjs.createStep2({ | ||
| id: "__process-trace-scoring", | ||
@@ -433,3 +433,3 @@ inputSchema: v4.z.object({ | ||
| } | ||
| var scoreTracesWorkflow = chunkGSWZYCY4_cjs.createWorkflow2({ | ||
| var scoreTracesWorkflow = chunkQJ3FDYCK_cjs.createWorkflow2({ | ||
| id: "__batch-scoring-traces", | ||
@@ -436,0 +436,0 @@ inputSchema: v4.z.object({ |
@@ -1,2 +0,2 @@ | ||
| import { createStep2, createWorkflow2 } from '../../chunk-MVA25X63.js'; | ||
| import { createStep2, createWorkflow2 } from '../../chunk-PQ5PN4TW.js'; | ||
| import { saveScorePayloadSchema } from '../../chunk-PUHREAKR.js'; | ||
@@ -3,0 +3,0 @@ import { getEntityTypeForSpan } from '../../chunk-DEQCJWZZ.js'; |
+15
-15
| 'use strict'; | ||
| var chunkOKPB3IMA_cjs = require('../chunk-OKPB3IMA.cjs'); | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkNPAGJ3HR_cjs = require('../chunk-NPAGJ3HR.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
| // src/harness/index.ts | ||
| var Harness = chunkOKPB3IMA_cjs.AgentController; | ||
| var Harness = chunkNPAGJ3HR_cjs.AgentController; | ||
| Object.defineProperty(exports, "AgentController", { | ||
| enumerable: true, | ||
| get: function () { return chunkOKPB3IMA_cjs.AgentController; } | ||
| get: function () { return chunkNPAGJ3HR_cjs.AgentController; } | ||
| }); | ||
| Object.defineProperty(exports, "Session", { | ||
| enumerable: true, | ||
| get: function () { return chunkOKPB3IMA_cjs.Session; } | ||
| get: function () { return chunkNPAGJ3HR_cjs.Session; } | ||
| }); | ||
| Object.defineProperty(exports, "defaultDisplayState", { | ||
| enumerable: true, | ||
| get: function () { return chunkOKPB3IMA_cjs.defaultDisplayState; } | ||
| get: function () { return chunkNPAGJ3HR_cjs.defaultDisplayState; } | ||
| }); | ||
| Object.defineProperty(exports, "defaultOMProgressState", { | ||
| enumerable: true, | ||
| get: function () { return chunkOKPB3IMA_cjs.defaultOMProgressState; } | ||
| get: function () { return chunkNPAGJ3HR_cjs.defaultOMProgressState; } | ||
| }); | ||
| Object.defineProperty(exports, "parseSubagentMeta", { | ||
| enumerable: true, | ||
| get: function () { return chunkOKPB3IMA_cjs.parseSubagentMeta; } | ||
| get: function () { return chunkNPAGJ3HR_cjs.parseSubagentMeta; } | ||
| }); | ||
| Object.defineProperty(exports, "askUserTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.askUserTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.askUserTool; } | ||
| }); | ||
| Object.defineProperty(exports, "assignTaskIds", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.assignTaskIds; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.assignTaskIds; } | ||
| }); | ||
| Object.defineProperty(exports, "submitPlanTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.submitPlanTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.submitPlanTool; } | ||
| }); | ||
| Object.defineProperty(exports, "taskCheckTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.taskCheckTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.taskCheckTool; } | ||
| }); | ||
| Object.defineProperty(exports, "taskCompleteTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.taskCompleteTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.taskCompleteTool; } | ||
| }); | ||
| Object.defineProperty(exports, "taskUpdateTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.taskUpdateTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.taskUpdateTool; } | ||
| }); | ||
| Object.defineProperty(exports, "taskWriteTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.taskWriteTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.taskWriteTool; } | ||
| }); | ||
@@ -57,0 +57,0 @@ exports.Harness = Harness; |
@@ -1,4 +0,4 @@ | ||
| import { AgentController } from '../chunk-QR3NJFL3.js'; | ||
| export { AgentController, Session, defaultDisplayState, defaultOMProgressState, parseSubagentMeta } from '../chunk-QR3NJFL3.js'; | ||
| export { askUserTool, assignTaskIds, submitPlanTool, taskCheckTool, taskCompleteTool, taskUpdateTool, taskWriteTool } from '../chunk-MVA25X63.js'; | ||
| import { AgentController } from '../chunk-MRDQBJLU.js'; | ||
| export { AgentController, Session, defaultDisplayState, defaultOMProgressState, parseSubagentMeta } from '../chunk-MRDQBJLU.js'; | ||
| export { askUserTool, assignTaskIds, submitPlanTool, taskCheckTool, taskCompleteTool, taskUpdateTool, taskWriteTool } from '../chunk-PQ5PN4TW.js'; | ||
@@ -5,0 +5,0 @@ // src/harness/index.ts |
+2
-2
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('./chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('./chunk-QJ3FDYCK.cjs'); | ||
@@ -9,5 +9,5 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.Mastra; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.Mastra; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
+1
-1
@@ -1,3 +0,3 @@ | ||
| export { Mastra } from './chunk-MVA25X63.js'; | ||
| export { Mastra } from './chunk-PQ5PN4TW.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
+23
-23
| 'use strict'; | ||
| var chunk4THHYWDP_cjs = require('../chunk-4THHYWDP.cjs'); | ||
| var chunk6HOXSACA_cjs = require('../chunk-6HOXSACA.cjs'); | ||
| var chunkMQ4ZJ5UC_cjs = require('../chunk-MQ4ZJ5UC.cjs'); | ||
| var chunkYTZZBZ5Q_cjs = require('../chunk-YTZZBZ5Q.cjs'); | ||
| var chunkS5VPX3LQ_cjs = require('../chunk-S5VPX3LQ.cjs'); | ||
| var chunk6OAFM3KL_cjs = require('../chunk-6OAFM3KL.cjs'); | ||
| var chunk2PXTHATK_cjs = require('../chunk-2PXTHATK.cjs'); | ||
| var chunkOYARTFJQ_cjs = require('../chunk-OYARTFJQ.cjs'); | ||
| var chunk5FCWY4Z3_cjs = require('../chunk-5FCWY4Z3.cjs'); | ||
| var chunkWFEGLWHX_cjs = require('../chunk-WFEGLWHX.cjs'); | ||
| var chunkVIRV756L_cjs = require('../chunk-VIRV756L.cjs'); | ||
| var chunkA45A2T7R_cjs = require('../chunk-A45A2T7R.cjs'); | ||
@@ -14,69 +14,69 @@ | ||
| enumerable: true, | ||
| get: function () { return chunk4THHYWDP_cjs.EMBEDDING_MODELS; } | ||
| get: function () { return chunk2PXTHATK_cjs.EMBEDDING_MODELS; } | ||
| }); | ||
| Object.defineProperty(exports, "ModelRouterEmbeddingModel", { | ||
| enumerable: true, | ||
| get: function () { return chunk4THHYWDP_cjs.ModelRouterEmbeddingModel; } | ||
| get: function () { return chunk2PXTHATK_cjs.ModelRouterEmbeddingModel; } | ||
| }); | ||
| Object.defineProperty(exports, "ModelRouterLanguageModel", { | ||
| enumerable: true, | ||
| get: function () { return chunk4THHYWDP_cjs.ModelRouterLanguageModel; } | ||
| get: function () { return chunk2PXTHATK_cjs.ModelRouterLanguageModel; } | ||
| }); | ||
| Object.defineProperty(exports, "resolveModelAuth", { | ||
| enumerable: true, | ||
| get: function () { return chunk4THHYWDP_cjs.resolveModelAuth; } | ||
| get: function () { return chunk2PXTHATK_cjs.resolveModelAuth; } | ||
| }); | ||
| Object.defineProperty(exports, "resolveModelConfig", { | ||
| enumerable: true, | ||
| get: function () { return chunk4THHYWDP_cjs.resolveModelConfig; } | ||
| get: function () { return chunk2PXTHATK_cjs.resolveModelConfig; } | ||
| }); | ||
| Object.defineProperty(exports, "AzureOpenAIGateway", { | ||
| enumerable: true, | ||
| get: function () { return chunk6HOXSACA_cjs.AzureOpenAIGateway; } | ||
| get: function () { return chunkOYARTFJQ_cjs.AzureOpenAIGateway; } | ||
| }); | ||
| Object.defineProperty(exports, "defaultGateways", { | ||
| enumerable: true, | ||
| get: function () { return chunk6HOXSACA_cjs.defaultGateways; } | ||
| get: function () { return chunkOYARTFJQ_cjs.defaultGateways; } | ||
| }); | ||
| Object.defineProperty(exports, "GatewayRegistry", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.GatewayRegistry; } | ||
| get: function () { return chunk5FCWY4Z3_cjs.GatewayRegistry; } | ||
| }); | ||
| Object.defineProperty(exports, "MastraGateway", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.MastraGateway; } | ||
| get: function () { return chunk5FCWY4Z3_cjs.MastraGateway; } | ||
| }); | ||
| Object.defineProperty(exports, "PROVIDER_REGISTRY", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.PROVIDER_REGISTRY; } | ||
| get: function () { return chunk5FCWY4Z3_cjs.PROVIDER_REGISTRY; } | ||
| }); | ||
| Object.defineProperty(exports, "getProviderConfig", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.getProviderConfig; } | ||
| get: function () { return chunk5FCWY4Z3_cjs.getProviderConfig; } | ||
| }); | ||
| Object.defineProperty(exports, "modelSupportsAttachments", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.modelSupportsAttachments; } | ||
| get: function () { return chunk5FCWY4Z3_cjs.modelSupportsAttachments; } | ||
| }); | ||
| Object.defineProperty(exports, "parseModelString", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.parseModelString; } | ||
| get: function () { return chunk5FCWY4Z3_cjs.parseModelString; } | ||
| }); | ||
| Object.defineProperty(exports, "ModelsDevGateway", { | ||
| enumerable: true, | ||
| get: function () { return chunkYTZZBZ5Q_cjs.ModelsDevGateway; } | ||
| get: function () { return chunkWFEGLWHX_cjs.ModelsDevGateway; } | ||
| }); | ||
| Object.defineProperty(exports, "NetlifyGateway", { | ||
| enumerable: true, | ||
| get: function () { return chunkS5VPX3LQ_cjs.NetlifyGateway; } | ||
| get: function () { return chunkVIRV756L_cjs.NetlifyGateway; } | ||
| }); | ||
| Object.defineProperty(exports, "GATEWAY_AUTH_HEADER", { | ||
| enumerable: true, | ||
| get: function () { return chunk6OAFM3KL_cjs.GATEWAY_AUTH_HEADER; } | ||
| get: function () { return chunkA45A2T7R_cjs.GATEWAY_AUTH_HEADER; } | ||
| }); | ||
| Object.defineProperty(exports, "MastraModelGateway", { | ||
| enumerable: true, | ||
| get: function () { return chunk6OAFM3KL_cjs.MastraModelGateway; } | ||
| get: function () { return chunkA45A2T7R_cjs.MastraModelGateway; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,8 +0,8 @@ | ||
| export { EMBEDDING_MODELS, ModelRouterEmbeddingModel, ModelRouterLanguageModel, resolveModelAuth, resolveModelConfig } from '../chunk-4VYRSIOP.js'; | ||
| export { AzureOpenAIGateway, defaultGateways } from '../chunk-N2QTYNXV.js'; | ||
| export { GatewayRegistry, MastraGateway, PROVIDER_REGISTRY, getProviderConfig, modelSupportsAttachments, parseModelString } from '../chunk-PL6DJRKR.js'; | ||
| export { ModelsDevGateway } from '../chunk-WPYY4VSL.js'; | ||
| export { NetlifyGateway } from '../chunk-RZKMXUCM.js'; | ||
| export { GATEWAY_AUTH_HEADER, MastraModelGateway } from '../chunk-XM3ZHT2Q.js'; | ||
| export { EMBEDDING_MODELS, ModelRouterEmbeddingModel, ModelRouterLanguageModel, resolveModelAuth, resolveModelConfig } from '../chunk-ORABIARW.js'; | ||
| export { AzureOpenAIGateway, defaultGateways } from '../chunk-PS2LUACH.js'; | ||
| export { GatewayRegistry, MastraGateway, PROVIDER_REGISTRY, getProviderConfig, modelSupportsAttachments, parseModelString } from '../chunk-CXGM7OSM.js'; | ||
| export { ModelsDevGateway } from '../chunk-5VSJH776.js'; | ||
| export { NetlifyGateway } from '../chunk-LVCGADQS.js'; | ||
| export { GATEWAY_AUTH_HEADER, MastraModelGateway } from '../chunk-BQXT5IMT.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
+14
-14
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
@@ -9,53 +9,53 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createScorer; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createScorer; } | ||
| }); | ||
| Object.defineProperty(exports, "formatCheckFeedback", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.formatCheckFeedback; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.formatCheckFeedback; } | ||
| }); | ||
| Object.defineProperty(exports, "formatCompletionFeedback", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.formatCompletionFeedback; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.formatCompletionFeedback; } | ||
| }); | ||
| Object.defineProperty(exports, "formatStreamCompletionFeedback", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.formatStreamCompletionFeedback; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.formatStreamCompletionFeedback; } | ||
| }); | ||
| Object.defineProperty(exports, "formatValidationFeedback", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.formatValidationFeedback; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.formatValidationFeedback; } | ||
| }); | ||
| Object.defineProperty(exports, "generateFinalResult", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.generateFinalResult; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.generateFinalResult; } | ||
| }); | ||
| Object.defineProperty(exports, "generateStructuredFinalResult", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.generateStructuredFinalResult; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.generateStructuredFinalResult; } | ||
| }); | ||
| Object.defineProperty(exports, "loop", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.loop; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.loop; } | ||
| }); | ||
| Object.defineProperty(exports, "runChecks", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.runChecks; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.runChecks; } | ||
| }); | ||
| Object.defineProperty(exports, "runCompletionScorers", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.runCompletionScorers; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.runCompletionScorers; } | ||
| }); | ||
| Object.defineProperty(exports, "runDefaultCompletionCheck", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.runDefaultCompletionCheck; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.runDefaultCompletionCheck; } | ||
| }); | ||
| Object.defineProperty(exports, "runStreamCompletionScorers", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.runStreamCompletionScorers; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.runStreamCompletionScorers; } | ||
| }); | ||
| Object.defineProperty(exports, "runValidation", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.runValidation; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.runValidation; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,3 +0,3 @@ | ||
| export { createScorer, formatCheckFeedback, formatCompletionFeedback, formatStreamCompletionFeedback, formatValidationFeedback, generateFinalResult, generateStructuredFinalResult, loop, runChecks, runCompletionScorers, runDefaultCompletionCheck, runStreamCompletionScorers, runValidation } from '../chunk-MVA25X63.js'; | ||
| export { createScorer, formatCheckFeedback, formatCompletionFeedback, formatStreamCompletionFeedback, formatValidationFeedback, generateFinalResult, generateStructuredFinalResult, loop, runChecks, runCompletionScorers, runDefaultCompletionCheck, runStreamCompletionScorers, runValidation } from '../chunk-PQ5PN4TW.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
@@ -9,5 +9,5 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.Mastra; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.Mastra; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,3 +0,3 @@ | ||
| export { Mastra } from '../chunk-MVA25X63.js'; | ||
| export { Mastra } from '../chunk-PQ5PN4TW.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
+19
-19
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
| var chunkCAGRA5LK_cjs = require('../chunk-CAGRA5LK.cjs'); | ||
@@ -10,71 +10,71 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MastraMemory; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MastraMemory; } | ||
| }); | ||
| Object.defineProperty(exports, "MemoryProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MemoryProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MemoryProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "MockMemory", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MockMemory; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MockMemory; } | ||
| }); | ||
| Object.defineProperty(exports, "SET_WORKING_MEMORY_TOOL_NAME", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SET_WORKING_MEMORY_TOOL_NAME; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SET_WORKING_MEMORY_TOOL_NAME; } | ||
| }); | ||
| Object.defineProperty(exports, "SYSTEM_REMINDER_END_TAG", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SYSTEM_REMINDER_END_TAG; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SYSTEM_REMINDER_END_TAG; } | ||
| }); | ||
| Object.defineProperty(exports, "SYSTEM_REMINDER_START_TAG", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SYSTEM_REMINDER_START_TAG; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SYSTEM_REMINDER_START_TAG; } | ||
| }); | ||
| Object.defineProperty(exports, "UPDATE_WORKING_MEMORY_TOOL_NAME", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.UPDATE_WORKING_MEMORY_TOOL_NAME; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.UPDATE_WORKING_MEMORY_TOOL_NAME; } | ||
| }); | ||
| Object.defineProperty(exports, "WORKING_MEMORY_END_TAG", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.WORKING_MEMORY_END_TAG; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.WORKING_MEMORY_END_TAG; } | ||
| }); | ||
| Object.defineProperty(exports, "WORKING_MEMORY_START_TAG", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.WORKING_MEMORY_START_TAG; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.WORKING_MEMORY_START_TAG; } | ||
| }); | ||
| Object.defineProperty(exports, "WORKING_MEMORY_TOOL_NAMES", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.WORKING_MEMORY_TOOL_NAMES; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.WORKING_MEMORY_TOOL_NAMES; } | ||
| }); | ||
| Object.defineProperty(exports, "extractWorkingMemoryContent", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.extractWorkingMemoryContent; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.extractWorkingMemoryContent; } | ||
| }); | ||
| Object.defineProperty(exports, "extractWorkingMemoryTags", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.extractWorkingMemoryTags; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.extractWorkingMemoryTags; } | ||
| }); | ||
| Object.defineProperty(exports, "filterSystemReminderMessages", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.filterSystemReminderMessages; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.filterSystemReminderMessages; } | ||
| }); | ||
| Object.defineProperty(exports, "isSystemReminderMessage", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.isSystemReminderMessage; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.isSystemReminderMessage; } | ||
| }); | ||
| Object.defineProperty(exports, "isWorkingMemoryToolName", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.isWorkingMemoryToolName; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.isWorkingMemoryToolName; } | ||
| }); | ||
| Object.defineProperty(exports, "memoryDefaultOptions", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.memoryDefaultOptions; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.memoryDefaultOptions; } | ||
| }); | ||
| Object.defineProperty(exports, "removeSystemReminderTags", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.removeSystemReminderTags; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.removeSystemReminderTags; } | ||
| }); | ||
| Object.defineProperty(exports, "removeWorkingMemoryTags", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.removeWorkingMemoryTags; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.removeWorkingMemoryTags; } | ||
| }); | ||
@@ -81,0 +81,0 @@ Object.defineProperty(exports, "getThreadOMMetadata", { |
@@ -1,4 +0,4 @@ | ||
| export { MastraMemory, MemoryProcessor, MockMemory, SET_WORKING_MEMORY_TOOL_NAME, SYSTEM_REMINDER_END_TAG, SYSTEM_REMINDER_START_TAG, UPDATE_WORKING_MEMORY_TOOL_NAME, WORKING_MEMORY_END_TAG, WORKING_MEMORY_START_TAG, WORKING_MEMORY_TOOL_NAMES, extractWorkingMemoryContent, extractWorkingMemoryTags, filterSystemReminderMessages, isSystemReminderMessage, isWorkingMemoryToolName, memoryDefaultOptions, removeSystemReminderTags, removeWorkingMemoryTags } from '../chunk-MVA25X63.js'; | ||
| export { MastraMemory, MemoryProcessor, MockMemory, SET_WORKING_MEMORY_TOOL_NAME, SYSTEM_REMINDER_END_TAG, SYSTEM_REMINDER_START_TAG, UPDATE_WORKING_MEMORY_TOOL_NAME, WORKING_MEMORY_END_TAG, WORKING_MEMORY_START_TAG, WORKING_MEMORY_TOOL_NAMES, extractWorkingMemoryContent, extractWorkingMemoryTags, filterSystemReminderMessages, isSystemReminderMessage, isWorkingMemoryToolName, memoryDefaultOptions, removeSystemReminderTags, removeWorkingMemoryTags } from '../chunk-PQ5PN4TW.js'; | ||
| export { getThreadOMMetadata, isObservationalMemoryEnabled, parseMemoryRequestContext, setThreadOMMetadata } from '../chunk-D44RUAWR.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkPVH4I7QG_cjs = require('../chunk-PVH4I7QG.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
| var chunkYLFDILPM_cjs = require('../chunk-YLFDILPM.cjs'); | ||
| var chunkDZ44ZU2T_cjs = require('../chunk-DZ44ZU2T.cjs'); | ||
@@ -38,3 +38,3 @@ var v4 = require('zod/v4'); | ||
| if (agent && resourceId && !notification.deliveredSignalId) { | ||
| const signal = chunkPVH4I7QG_cjs.createNotificationSignal({ ...notification, status: "delivered" }); | ||
| const signal = chunkYLFDILPM_cjs.createNotificationSignal({ ...notification, status: "delivered" }); | ||
| const result = agent.sendSignal(signal, { | ||
@@ -134,47 +134,47 @@ resourceId, | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.defaultNotificationDeliveryDecision; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.defaultNotificationDeliveryDecision; } | ||
| }); | ||
| Object.defineProperty(exports, "resolveNotificationDeliveryDecision", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.resolveNotificationDeliveryDecision; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.resolveNotificationDeliveryDecision; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryNotificationsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.InMemoryNotificationsStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.InMemoryNotificationsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "NotificationsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.NotificationsStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.NotificationsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "createNotificationSignal", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.createNotificationSignal; } | ||
| get: function () { return chunkYLFDILPM_cjs.createNotificationSignal; } | ||
| }); | ||
| Object.defineProperty(exports, "createNotificationSummarySignal", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.createNotificationSummarySignal; } | ||
| get: function () { return chunkYLFDILPM_cjs.createNotificationSummarySignal; } | ||
| }); | ||
| Object.defineProperty(exports, "dispatchDueNotifications", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.dispatchDueNotifications; } | ||
| get: function () { return chunkYLFDILPM_cjs.dispatchDueNotifications; } | ||
| }); | ||
| Object.defineProperty(exports, "notificationSignalAttributes", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.notificationSignalAttributes; } | ||
| get: function () { return chunkYLFDILPM_cjs.notificationSignalAttributes; } | ||
| }); | ||
| Object.defineProperty(exports, "notificationSignalMetadata", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.notificationSignalMetadata; } | ||
| get: function () { return chunkYLFDILPM_cjs.notificationSignalMetadata; } | ||
| }); | ||
| Object.defineProperty(exports, "notificationSummaryContents", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.notificationSummaryContents; } | ||
| get: function () { return chunkYLFDILPM_cjs.notificationSummaryContents; } | ||
| }); | ||
| Object.defineProperty(exports, "notificationSummarySignalMetadata", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.notificationSummarySignalMetadata; } | ||
| get: function () { return chunkYLFDILPM_cjs.notificationSummarySignalMetadata; } | ||
| }); | ||
| Object.defineProperty(exports, "summarizeNotifications", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.summarizeNotifications; } | ||
| get: function () { return chunkYLFDILPM_cjs.summarizeNotifications; } | ||
| }); | ||
@@ -181,0 +181,0 @@ exports.createNotificationInboxTool = createNotificationInboxTool; |
@@ -1,4 +0,4 @@ | ||
| export { defaultNotificationDeliveryDecision, resolveNotificationDeliveryDecision } from '../chunk-MVA25X63.js'; | ||
| import { createNotificationSignal } from '../chunk-BXKPCDLM.js'; | ||
| export { InMemoryNotificationsStorage, NotificationsStorage, createNotificationSignal, createNotificationSummarySignal, dispatchDueNotifications, notificationSignalAttributes, notificationSignalMetadata, notificationSummaryContents, notificationSummarySignalMetadata, summarizeNotifications } from '../chunk-BXKPCDLM.js'; | ||
| export { defaultNotificationDeliveryDecision, resolveNotificationDeliveryDecision } from '../chunk-PQ5PN4TW.js'; | ||
| import { createNotificationSignal } from '../chunk-RIIPXHAY.js'; | ||
| export { InMemoryNotificationsStorage, NotificationsStorage, createNotificationSignal, createNotificationSummarySignal, dispatchDueNotifications, notificationSignalAttributes, notificationSignalMetadata, notificationSummaryContents, notificationSummarySignalMetadata, summarizeNotifications } from '../chunk-RIIPXHAY.js'; | ||
| import { createTool } from '../chunk-VLJMDX6T.js'; | ||
@@ -5,0 +5,0 @@ import { z } from 'zod/v4'; |
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
| var v4 = require('zod/v4'); | ||
@@ -70,3 +70,3 @@ | ||
| createProcessor(config) { | ||
| return new chunkGSWZYCY4_cjs.UnicodeNormalizer(config); | ||
| return new chunkQJ3FDYCK_cjs.UnicodeNormalizer(config); | ||
| } | ||
@@ -87,3 +87,3 @@ }; | ||
| createProcessor(config) { | ||
| return new chunkGSWZYCY4_cjs.TokenLimiterProcessor( | ||
| return new chunkQJ3FDYCK_cjs.TokenLimiterProcessor( | ||
| config | ||
@@ -106,3 +106,3 @@ ); | ||
| createProcessor(config) { | ||
| return new chunkGSWZYCY4_cjs.ToolCallFilter(config); | ||
| return new chunkQJ3FDYCK_cjs.ToolCallFilter(config); | ||
| } | ||
@@ -123,3 +123,3 @@ }; | ||
| createProcessor(config) { | ||
| return new chunkGSWZYCY4_cjs.BatchPartsProcessor(config); | ||
| return new chunkQJ3FDYCK_cjs.BatchPartsProcessor(config); | ||
| } | ||
@@ -146,3 +146,3 @@ }; | ||
| createProcessor(config) { | ||
| return new chunkGSWZYCY4_cjs.ModerationProcessor(config); | ||
| return new chunkQJ3FDYCK_cjs.ModerationProcessor(config); | ||
| } | ||
@@ -168,3 +168,3 @@ }; | ||
| createProcessor(config) { | ||
| return new chunkGSWZYCY4_cjs.PromptInjectionDetector(config); | ||
| return new chunkQJ3FDYCK_cjs.PromptInjectionDetector(config); | ||
| } | ||
@@ -192,3 +192,3 @@ }; | ||
| createProcessor(config) { | ||
| return new chunkGSWZYCY4_cjs.PIIDetector(config); | ||
| return new chunkQJ3FDYCK_cjs.PIIDetector(config); | ||
| } | ||
@@ -216,3 +216,3 @@ }; | ||
| createProcessor(config) { | ||
| return new chunkGSWZYCY4_cjs.LanguageDetector(config); | ||
| return new chunkQJ3FDYCK_cjs.LanguageDetector(config); | ||
| } | ||
@@ -238,3 +238,3 @@ }; | ||
| createProcessor(config) { | ||
| return new chunkGSWZYCY4_cjs.SystemPromptScrubber(config); | ||
| return new chunkQJ3FDYCK_cjs.SystemPromptScrubber(config); | ||
| } | ||
@@ -241,0 +241,0 @@ }; |
@@ -1,2 +0,2 @@ | ||
| import { UnicodeNormalizer, TokenLimiterProcessor, ToolCallFilter, BatchPartsProcessor, ModerationProcessor, PromptInjectionDetector, PIIDetector, LanguageDetector, SystemPromptScrubber } from '../chunk-MVA25X63.js'; | ||
| import { UnicodeNormalizer, TokenLimiterProcessor, ToolCallFilter, BatchPartsProcessor, ModerationProcessor, PromptInjectionDetector, PIIDetector, LanguageDetector, SystemPromptScrubber } from '../chunk-PQ5PN4TW.js'; | ||
| import { z } from 'zod/v4'; | ||
@@ -3,0 +3,0 @@ |
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkLZIIAAGJ_cjs = require('../chunk-LZIIAAGJ.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
| var chunkH3Y3YAMF_cjs = require('../chunk-H3Y3YAMF.cjs'); | ||
@@ -10,229 +10,229 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.AgentsMDInjector; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.AgentsMDInjector; } | ||
| }); | ||
| Object.defineProperty(exports, "BaseProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.BaseProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.BaseProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "BatchPartsProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.BatchPartsProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.BatchPartsProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "CostGuardProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.CostGuardProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.CostGuardProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "DEFAULT_RESPONSE_CACHE_TTL_SECONDS", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.DEFAULT_RESPONSE_CACHE_TTL_SECONDS; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.DEFAULT_RESPONSE_CACHE_TTL_SECONDS; } | ||
| }); | ||
| Object.defineProperty(exports, "FilePartSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.FilePartSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.FilePartSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "ImagePartSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ImagePartSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ImagePartSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "LanguageDetector", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.LanguageDetector; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.LanguageDetector; } | ||
| }); | ||
| Object.defineProperty(exports, "MessageContentSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MessageContentSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MessageContentSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "MessageHistory", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MessageHistory; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MessageHistory; } | ||
| }); | ||
| Object.defineProperty(exports, "MessagePartSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MessagePartSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MessagePartSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "ModerationProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ModerationProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ModerationProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "PIIDetector", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.PIIDetector; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.PIIDetector; } | ||
| }); | ||
| Object.defineProperty(exports, "PrefillErrorHandler", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.PrefillErrorHandler; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.PrefillErrorHandler; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorInputPhaseSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ProcessorInputPhaseSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ProcessorInputPhaseSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorInputStepPhaseSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ProcessorInputStepPhaseSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ProcessorInputStepPhaseSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorMessageContentSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ProcessorMessageContentSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ProcessorMessageContentSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorMessageSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ProcessorMessageSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ProcessorMessageSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorOutputResultPhaseSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ProcessorOutputResultPhaseSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ProcessorOutputResultPhaseSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorOutputStepPhaseSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ProcessorOutputStepPhaseSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ProcessorOutputStepPhaseSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorOutputStreamPhaseSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ProcessorOutputStreamPhaseSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ProcessorOutputStreamPhaseSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorStepInputSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ProcessorStepInputSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ProcessorStepInputSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorStepOutputSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ProcessorStepOutputSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ProcessorStepOutputSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorStepSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ProcessorStepSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ProcessorStepSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "PromptInjectionDetector", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.PromptInjectionDetector; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.PromptInjectionDetector; } | ||
| }); | ||
| Object.defineProperty(exports, "ProviderHistoryCompat", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ProviderHistoryCompat; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ProviderHistoryCompat; } | ||
| }); | ||
| Object.defineProperty(exports, "RESPONSE_CACHE_CONTEXT_KEY", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.RESPONSE_CACHE_CONTEXT_KEY; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.RESPONSE_CACHE_CONTEXT_KEY; } | ||
| }); | ||
| Object.defineProperty(exports, "ReasoningPartSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ReasoningPartSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ReasoningPartSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "RegexFilterProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.RegexFilterProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.RegexFilterProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "ResponseCache", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ResponseCache; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ResponseCache; } | ||
| }); | ||
| Object.defineProperty(exports, "SemanticRecall", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SemanticRecall; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SemanticRecall; } | ||
| }); | ||
| Object.defineProperty(exports, "SkillSearchProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SkillSearchProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SkillSearchProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "SkillsProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SkillsProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SkillsProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "SourcePartSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SourcePartSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SourcePartSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "StepStartPartSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.StepStartPartSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.StepStartPartSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "StreamErrorRetryProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.StreamErrorRetryProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.StreamErrorRetryProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "StructuredOutputProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.StructuredOutputProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.StructuredOutputProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "SystemPromptScrubber", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SystemPromptScrubber; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SystemPromptScrubber; } | ||
| }); | ||
| Object.defineProperty(exports, "TextPartSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.TextPartSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.TextPartSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "TokenLimiter", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.TokenLimiterProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.TokenLimiterProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "TokenLimiterProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.TokenLimiterProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.TokenLimiterProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "ToolCallFilter", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ToolCallFilter; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ToolCallFilter; } | ||
| }); | ||
| Object.defineProperty(exports, "ToolInvocationPartSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ToolInvocationPartSchema; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ToolInvocationPartSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "ToolSearchProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ToolSearchProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ToolSearchProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "UnicodeNormalizer", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.UnicodeNormalizer; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.UnicodeNormalizer; } | ||
| }); | ||
| Object.defineProperty(exports, "WorkingMemory", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.WorkingMemory; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.WorkingMemory; } | ||
| }); | ||
| Object.defineProperty(exports, "WorkspaceInstructionsProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.WorkspaceInstructionsProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.WorkspaceInstructionsProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "anthropicToolIdFormat", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.anthropicToolIdFormat; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.anthropicToolIdFormat; } | ||
| }); | ||
| Object.defineProperty(exports, "buildResponseCacheKey", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.buildResponseCacheKey; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.buildResponseCacheKey; } | ||
| }); | ||
| Object.defineProperty(exports, "cerebrasStripReasoningContent", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.cerebrasStripReasoningContent; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.cerebrasStripReasoningContent; } | ||
| }); | ||
| Object.defineProperty(exports, "globalEmbeddingCache", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.globalEmbeddingCache; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.globalEmbeddingCache; } | ||
| }); | ||
| Object.defineProperty(exports, "isBadRequestError", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.isBadRequestError; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.isBadRequestError; } | ||
| }); | ||
| Object.defineProperty(exports, "isRetryableOpenAIResponsesStreamError", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.isRetryableOpenAIResponsesStreamError; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.isRetryableOpenAIResponsesStreamError; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorRunner", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.ProcessorRunner; } | ||
| get: function () { return chunkH3Y3YAMF_cjs.ProcessorRunner; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorState", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.ProcessorState; } | ||
| get: function () { return chunkH3Y3YAMF_cjs.ProcessorState; } | ||
| }); | ||
| Object.defineProperty(exports, "createProcessorSendSignal", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.createProcessorSendSignal; } | ||
| get: function () { return chunkH3Y3YAMF_cjs.createProcessorSendSignal; } | ||
| }); | ||
| Object.defineProperty(exports, "isProcessorWorkflow", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.isProcessorWorkflow; } | ||
| get: function () { return chunkH3Y3YAMF_cjs.isProcessorWorkflow; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,4 +0,4 @@ | ||
| export { AgentsMDInjector, BaseProcessor, BatchPartsProcessor, CostGuardProcessor, DEFAULT_RESPONSE_CACHE_TTL_SECONDS, FilePartSchema, ImagePartSchema, LanguageDetector, MessageContentSchema, MessageHistory, MessagePartSchema, ModerationProcessor, PIIDetector, PrefillErrorHandler, ProcessorInputPhaseSchema, ProcessorInputStepPhaseSchema, ProcessorMessageContentSchema, ProcessorMessageSchema, ProcessorOutputResultPhaseSchema, ProcessorOutputStepPhaseSchema, ProcessorOutputStreamPhaseSchema, ProcessorStepInputSchema, ProcessorStepOutputSchema, ProcessorStepSchema, PromptInjectionDetector, ProviderHistoryCompat, RESPONSE_CACHE_CONTEXT_KEY, ReasoningPartSchema, RegexFilterProcessor, ResponseCache, SemanticRecall, SkillSearchProcessor, SkillsProcessor, SourcePartSchema, StepStartPartSchema, StreamErrorRetryProcessor, StructuredOutputProcessor, SystemPromptScrubber, TextPartSchema, TokenLimiterProcessor as TokenLimiter, TokenLimiterProcessor, ToolCallFilter, ToolInvocationPartSchema, ToolSearchProcessor, UnicodeNormalizer, WorkingMemory, WorkspaceInstructionsProcessor, anthropicToolIdFormat, buildResponseCacheKey, cerebrasStripReasoningContent, globalEmbeddingCache, isBadRequestError, isRetryableOpenAIResponsesStreamError } from '../chunk-MVA25X63.js'; | ||
| export { ProcessorRunner, ProcessorState, createProcessorSendSignal, isProcessorWorkflow } from '../chunk-HCSJNNEN.js'; | ||
| export { AgentsMDInjector, BaseProcessor, BatchPartsProcessor, CostGuardProcessor, DEFAULT_RESPONSE_CACHE_TTL_SECONDS, FilePartSchema, ImagePartSchema, LanguageDetector, MessageContentSchema, MessageHistory, MessagePartSchema, ModerationProcessor, PIIDetector, PrefillErrorHandler, ProcessorInputPhaseSchema, ProcessorInputStepPhaseSchema, ProcessorMessageContentSchema, ProcessorMessageSchema, ProcessorOutputResultPhaseSchema, ProcessorOutputStepPhaseSchema, ProcessorOutputStreamPhaseSchema, ProcessorStepInputSchema, ProcessorStepOutputSchema, ProcessorStepSchema, PromptInjectionDetector, ProviderHistoryCompat, RESPONSE_CACHE_CONTEXT_KEY, ReasoningPartSchema, RegexFilterProcessor, ResponseCache, SemanticRecall, SkillSearchProcessor, SkillsProcessor, SourcePartSchema, StepStartPartSchema, StreamErrorRetryProcessor, StructuredOutputProcessor, SystemPromptScrubber, TextPartSchema, TokenLimiterProcessor as TokenLimiter, TokenLimiterProcessor, ToolCallFilter, ToolInvocationPartSchema, ToolSearchProcessor, UnicodeNormalizer, WorkingMemory, WorkspaceInstructionsProcessor, anthropicToolIdFormat, buildResponseCacheKey, cerebrasStripReasoningContent, globalEmbeddingCache, isBadRequestError, isRetryableOpenAIResponsesStreamError } from '../chunk-PQ5PN4TW.js'; | ||
| export { ProcessorRunner, ProcessorState, createProcessorSendSignal, isProcessorWorkflow } from '../chunk-YNS26J6E.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkLZIIAAGJ_cjs = require('../chunk-LZIIAAGJ.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
| var chunkH3Y3YAMF_cjs = require('../chunk-H3Y3YAMF.cjs'); | ||
@@ -21,3 +21,3 @@ // src/relevance/relevance-score-provider.ts | ||
| constructor(name, model) { | ||
| this.agent = new chunkGSWZYCY4_cjs.Agent({ | ||
| this.agent = new chunkQJ3FDYCK_cjs.Agent({ | ||
| id: `relevance-scorer-${name}`, | ||
@@ -42,3 +42,3 @@ name: `Relevance Scorer ${name}`, | ||
| let response; | ||
| if (chunkLZIIAAGJ_cjs.isSupportedLanguageModel(model)) { | ||
| if (chunkH3Y3YAMF_cjs.isSupportedLanguageModel(model)) { | ||
| const responseText = await this.agent.generate(prompt); | ||
@@ -45,0 +45,0 @@ response = responseText.text; |
@@ -1,3 +0,3 @@ | ||
| import { Agent } from '../chunk-MVA25X63.js'; | ||
| import { isSupportedLanguageModel } from '../chunk-HCSJNNEN.js'; | ||
| import { Agent } from '../chunk-PQ5PN4TW.js'; | ||
| import { isSupportedLanguageModel } from '../chunk-YNS26J6E.js'; | ||
@@ -4,0 +4,0 @@ // src/relevance/relevance-score-provider.ts |
| 'use strict'; | ||
| var chunkORIBHWNH_cjs = require('../chunk-ORIBHWNH.cjs'); | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunk7QFVYQT7_cjs = require('../chunk-7QFVYQT7.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
@@ -10,25 +10,25 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkORIBHWNH_cjs.TaskSignalProvider; } | ||
| get: function () { return chunk7QFVYQT7_cjs.TaskSignalProvider; } | ||
| }); | ||
| Object.defineProperty(exports, "GoalSignalProvider", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.GoalSignalProvider; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.GoalSignalProvider; } | ||
| }); | ||
| Object.defineProperty(exports, "SignalProvider", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SignalProvider; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SignalProvider; } | ||
| }); | ||
| Object.defineProperty(exports, "WebhookSignalProvider", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.WebhookSignalProvider; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.WebhookSignalProvider; } | ||
| }); | ||
| Object.defineProperty(exports, "assignTaskIds", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.assignTaskIds; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.assignTaskIds; } | ||
| }); | ||
| Object.defineProperty(exports, "isSignalProvider", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.isSignalProvider; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.isSignalProvider; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,4 +0,4 @@ | ||
| export { TaskSignalProvider } from '../chunk-T27PG4IC.js'; | ||
| export { GoalSignalProvider, SignalProvider, WebhookSignalProvider, assignTaskIds, isSignalProvider } from '../chunk-MVA25X63.js'; | ||
| export { TaskSignalProvider } from '../chunk-SBQZFH46.js'; | ||
| export { GoalSignalProvider, SignalProvider, WebhookSignalProvider, assignTaskIds, isSignalProvider } from '../chunk-PQ5PN4TW.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkW62XF4LN_cjs = require('../../../chunk-W62XF4LN.cjs'); | ||
| var chunkHLSFGO57_cjs = require('../../../chunk-HLSFGO57.cjs'); | ||
@@ -9,17 +9,17 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkW62XF4LN_cjs.AgentsStorage; } | ||
| get: function () { return chunkHLSFGO57_cjs.AgentsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "FilesystemAgentsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkW62XF4LN_cjs.FilesystemAgentsStorage; } | ||
| get: function () { return chunkHLSFGO57_cjs.FilesystemAgentsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryAgentsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkW62XF4LN_cjs.InMemoryAgentsStorage; } | ||
| get: function () { return chunkHLSFGO57_cjs.InMemoryAgentsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "SourceAgentsSourceControl", { | ||
| enumerable: true, | ||
| get: function () { return chunkW62XF4LN_cjs.SourceAgentsSourceControl; } | ||
| get: function () { return chunkHLSFGO57_cjs.SourceAgentsSourceControl; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,3 +0,3 @@ | ||
| export { AgentsStorage, FilesystemAgentsStorage, InMemoryAgentsStorage, SourceAgentsSourceControl } from '../../../chunk-GUEWXCCO.js'; | ||
| export { AgentsStorage, FilesystemAgentsStorage, InMemoryAgentsStorage, SourceAgentsSourceControl } from '../../../chunk-4BSRNVSZ.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunk7EDD27SS_cjs = require('../../../chunk-7EDD27SS.cjs'); | ||
| var chunk4M6XWZDY_cjs = require('../../../chunk-4M6XWZDY.cjs'); | ||
@@ -9,13 +9,13 @@ | ||
| enumerable: true, | ||
| get: function () { return chunk7EDD27SS_cjs.FilesystemMCPClientsStorage; } | ||
| get: function () { return chunk4M6XWZDY_cjs.FilesystemMCPClientsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryMCPClientsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunk7EDD27SS_cjs.InMemoryMCPClientsStorage; } | ||
| get: function () { return chunk4M6XWZDY_cjs.InMemoryMCPClientsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "MCPClientsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunk7EDD27SS_cjs.MCPClientsStorage; } | ||
| get: function () { return chunk4M6XWZDY_cjs.MCPClientsStorage; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,3 +0,3 @@ | ||
| export { FilesystemMCPClientsStorage, InMemoryMCPClientsStorage, MCPClientsStorage } from '../../../chunk-XMHU3JJ7.js'; | ||
| export { FilesystemMCPClientsStorage, InMemoryMCPClientsStorage, MCPClientsStorage } from '../../../chunk-Q4AIRH5U.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkWMV636D2_cjs = require('../../../chunk-WMV636D2.cjs'); | ||
| var chunkKWXEVPXK_cjs = require('../../../chunk-KWXEVPXK.cjs'); | ||
@@ -9,13 +9,13 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkWMV636D2_cjs.FilesystemMCPServersStorage; } | ||
| get: function () { return chunkKWXEVPXK_cjs.FilesystemMCPServersStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryMCPServersStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkWMV636D2_cjs.InMemoryMCPServersStorage; } | ||
| get: function () { return chunkKWXEVPXK_cjs.InMemoryMCPServersStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "MCPServersStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkWMV636D2_cjs.MCPServersStorage; } | ||
| get: function () { return chunkKWXEVPXK_cjs.MCPServersStorage; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,3 +0,3 @@ | ||
| export { FilesystemMCPServersStorage, InMemoryMCPServersStorage, MCPServersStorage } from '../../../chunk-B7OS7GGE.js'; | ||
| export { FilesystemMCPServersStorage, InMemoryMCPServersStorage, MCPServersStorage } from '../../../chunk-2IBWJI4I.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkMGRR5QZ2_cjs = require('../../../chunk-MGRR5QZ2.cjs'); | ||
| var chunkGGJVCX4I_cjs = require('../../../chunk-GGJVCX4I.cjs'); | ||
@@ -9,13 +9,13 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkMGRR5QZ2_cjs.FilesystemPromptBlocksStorage; } | ||
| get: function () { return chunkGGJVCX4I_cjs.FilesystemPromptBlocksStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryPromptBlocksStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkMGRR5QZ2_cjs.InMemoryPromptBlocksStorage; } | ||
| get: function () { return chunkGGJVCX4I_cjs.InMemoryPromptBlocksStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "PromptBlocksStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkMGRR5QZ2_cjs.PromptBlocksStorage; } | ||
| get: function () { return chunkGGJVCX4I_cjs.PromptBlocksStorage; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,3 +0,3 @@ | ||
| export { FilesystemPromptBlocksStorage, InMemoryPromptBlocksStorage, PromptBlocksStorage } from '../../../chunk-Z23TV6IV.js'; | ||
| export { FilesystemPromptBlocksStorage, InMemoryPromptBlocksStorage, PromptBlocksStorage } from '../../../chunk-BXKJRFIE.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkSK5EI32N_cjs = require('../../../chunk-SK5EI32N.cjs'); | ||
| var chunkEXFCDNO4_cjs = require('../../../chunk-EXFCDNO4.cjs'); | ||
@@ -9,13 +9,13 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkSK5EI32N_cjs.FilesystemScorerDefinitionsStorage; } | ||
| get: function () { return chunkEXFCDNO4_cjs.FilesystemScorerDefinitionsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryScorerDefinitionsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkSK5EI32N_cjs.InMemoryScorerDefinitionsStorage; } | ||
| get: function () { return chunkEXFCDNO4_cjs.InMemoryScorerDefinitionsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "ScorerDefinitionsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkSK5EI32N_cjs.ScorerDefinitionsStorage; } | ||
| get: function () { return chunkEXFCDNO4_cjs.ScorerDefinitionsStorage; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,3 +0,3 @@ | ||
| export { FilesystemScorerDefinitionsStorage, InMemoryScorerDefinitionsStorage, ScorerDefinitionsStorage } from '../../../chunk-MCAHK3LA.js'; | ||
| export { FilesystemScorerDefinitionsStorage, InMemoryScorerDefinitionsStorage, ScorerDefinitionsStorage } from '../../../chunk-5HRFZGRZ.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunk64LOMCAH_cjs = require('../../../chunk-64LOMCAH.cjs'); | ||
| var chunkLGSQSQFN_cjs = require('../../../chunk-LGSQSQFN.cjs'); | ||
@@ -9,13 +9,13 @@ | ||
| enumerable: true, | ||
| get: function () { return chunk64LOMCAH_cjs.FilesystemWorkspacesStorage; } | ||
| get: function () { return chunkLGSQSQFN_cjs.FilesystemWorkspacesStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryWorkspacesStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunk64LOMCAH_cjs.InMemoryWorkspacesStorage; } | ||
| get: function () { return chunkLGSQSQFN_cjs.InMemoryWorkspacesStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "WorkspacesStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunk64LOMCAH_cjs.WorkspacesStorage; } | ||
| get: function () { return chunkLGSQSQFN_cjs.WorkspacesStorage; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,3 +0,3 @@ | ||
| export { FilesystemWorkspacesStorage, InMemoryWorkspacesStorage, WorkspacesStorage } from '../../../chunk-4JHST2EN.js'; | ||
| export { FilesystemWorkspacesStorage, InMemoryWorkspacesStorage, WorkspacesStorage } from '../../../chunk-IZ3TT3AZ.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
+87
-87
| 'use strict'; | ||
| var chunkPVH4I7QG_cjs = require('../chunk-PVH4I7QG.cjs'); | ||
| var chunkWMV636D2_cjs = require('../chunk-WMV636D2.cjs'); | ||
| var chunkMGRR5QZ2_cjs = require('../chunk-MGRR5QZ2.cjs'); | ||
| var chunkSK5EI32N_cjs = require('../chunk-SK5EI32N.cjs'); | ||
| var chunkYLFDILPM_cjs = require('../chunk-YLFDILPM.cjs'); | ||
| var chunkKWXEVPXK_cjs = require('../chunk-KWXEVPXK.cjs'); | ||
| var chunkGGJVCX4I_cjs = require('../chunk-GGJVCX4I.cjs'); | ||
| var chunkEXFCDNO4_cjs = require('../chunk-EXFCDNO4.cjs'); | ||
| var chunkZVZXKOMS_cjs = require('../chunk-ZVZXKOMS.cjs'); | ||
| var chunk64LOMCAH_cjs = require('../chunk-64LOMCAH.cjs'); | ||
| var chunkW62XF4LN_cjs = require('../chunk-W62XF4LN.cjs'); | ||
| var chunkLGSQSQFN_cjs = require('../chunk-LGSQSQFN.cjs'); | ||
| var chunkHLSFGO57_cjs = require('../chunk-HLSFGO57.cjs'); | ||
| var chunkGJE2FI3V_cjs = require('../chunk-GJE2FI3V.cjs'); | ||
| var chunk7EDD27SS_cjs = require('../chunk-7EDD27SS.cjs'); | ||
| var chunk4M6XWZDY_cjs = require('../chunk-4M6XWZDY.cjs'); | ||
| var chunk2UAP4LDC_cjs = require('../chunk-2UAP4LDC.cjs'); | ||
@@ -20,275 +20,275 @@ var chunk3I6MKYQG_cjs = require('../chunk-3I6MKYQG.cjs'); | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.BackgroundTasksInMemory; } | ||
| get: function () { return chunkYLFDILPM_cjs.BackgroundTasksInMemory; } | ||
| }); | ||
| Object.defineProperty(exports, "BackgroundTasksStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.BackgroundTasksStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.BackgroundTasksStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "BlobStore", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.BlobStore; } | ||
| get: function () { return chunkYLFDILPM_cjs.BlobStore; } | ||
| }); | ||
| Object.defineProperty(exports, "ChannelsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.ChannelsStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.ChannelsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "DatasetsInMemory", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.DatasetsInMemory; } | ||
| get: function () { return chunkYLFDILPM_cjs.DatasetsInMemory; } | ||
| }); | ||
| Object.defineProperty(exports, "DatasetsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.DatasetsStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.DatasetsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "ExperimentsInMemory", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.ExperimentsInMemory; } | ||
| get: function () { return chunkYLFDILPM_cjs.ExperimentsInMemory; } | ||
| }); | ||
| Object.defineProperty(exports, "ExperimentsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.ExperimentsStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.ExperimentsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "FilesystemDB", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.FilesystemDB; } | ||
| get: function () { return chunkYLFDILPM_cjs.FilesystemDB; } | ||
| }); | ||
| Object.defineProperty(exports, "FilesystemStore", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.FilesystemStore; } | ||
| get: function () { return chunkYLFDILPM_cjs.FilesystemStore; } | ||
| }); | ||
| Object.defineProperty(exports, "GitHubSourceControlProvider", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.GitHubSourceControlProvider; } | ||
| get: function () { return chunkYLFDILPM_cjs.GitHubSourceControlProvider; } | ||
| }); | ||
| Object.defineProperty(exports, "HarnessStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.HarnessStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.HarnessStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryBlobStore", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.InMemoryBlobStore; } | ||
| get: function () { return chunkYLFDILPM_cjs.InMemoryBlobStore; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryChannelsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.InMemoryChannelsStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.InMemoryChannelsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryHarness", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.InMemoryHarness; } | ||
| get: function () { return chunkYLFDILPM_cjs.InMemoryHarness; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryMemory", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.InMemoryMemory; } | ||
| get: function () { return chunkYLFDILPM_cjs.InMemoryMemory; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryNotificationsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.InMemoryNotificationsStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.InMemoryNotificationsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemorySchedulesStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.InMemorySchedulesStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.InMemorySchedulesStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryStore", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.InMemoryStore; } | ||
| get: function () { return chunkYLFDILPM_cjs.InMemoryStore; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryToolProviderConnectionsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.InMemoryToolProviderConnectionsStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.InMemoryToolProviderConnectionsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "MemoryStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.MemoryStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.MemoryStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "MockStore", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.MockStore; } | ||
| get: function () { return chunkYLFDILPM_cjs.MockStore; } | ||
| }); | ||
| Object.defineProperty(exports, "NotificationsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.NotificationsStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.NotificationsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "ObservabilityInMemory", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.ObservabilityInMemory; } | ||
| get: function () { return chunkYLFDILPM_cjs.ObservabilityInMemory; } | ||
| }); | ||
| Object.defineProperty(exports, "ObservabilityStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.ObservabilityStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.ObservabilityStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "SchedulesStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.SchedulesStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.SchedulesStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "ScoresInMemory", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.ScoresInMemory; } | ||
| get: function () { return chunkYLFDILPM_cjs.ScoresInMemory; } | ||
| }); | ||
| Object.defineProperty(exports, "ScoresStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.ScoresStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.ScoresStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "StoreOperations", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.StoreOperations; } | ||
| get: function () { return chunkYLFDILPM_cjs.StoreOperations; } | ||
| }); | ||
| Object.defineProperty(exports, "StoreOperationsInMemory", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.StoreOperationsInMemory; } | ||
| get: function () { return chunkYLFDILPM_cjs.StoreOperationsInMemory; } | ||
| }); | ||
| Object.defineProperty(exports, "ToolProviderConnectionsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.ToolProviderConnectionsStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.ToolProviderConnectionsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "WorkflowsInMemory", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.WorkflowsInMemory; } | ||
| get: function () { return chunkYLFDILPM_cjs.WorkflowsInMemory; } | ||
| }); | ||
| Object.defineProperty(exports, "WorkflowsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.WorkflowsStorage; } | ||
| get: function () { return chunkYLFDILPM_cjs.WorkflowsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "buildCreateSpanRecord", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.buildCreateSpanRecord; } | ||
| get: function () { return chunkYLFDILPM_cjs.buildCreateSpanRecord; } | ||
| }); | ||
| Object.defineProperty(exports, "buildFeedbackRecord", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.buildFeedbackRecord; } | ||
| get: function () { return chunkYLFDILPM_cjs.buildFeedbackRecord; } | ||
| }); | ||
| Object.defineProperty(exports, "buildLogRecord", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.buildLogRecord; } | ||
| get: function () { return chunkYLFDILPM_cjs.buildLogRecord; } | ||
| }); | ||
| Object.defineProperty(exports, "buildMetricRecord", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.buildMetricRecord; } | ||
| get: function () { return chunkYLFDILPM_cjs.buildMetricRecord; } | ||
| }); | ||
| Object.defineProperty(exports, "buildScoreRecord", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.buildScoreRecord; } | ||
| get: function () { return chunkYLFDILPM_cjs.buildScoreRecord; } | ||
| }); | ||
| Object.defineProperty(exports, "buildUpdateSpanRecord", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.buildUpdateSpanRecord; } | ||
| get: function () { return chunkYLFDILPM_cjs.buildUpdateSpanRecord; } | ||
| }); | ||
| Object.defineProperty(exports, "cloneRunData", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.cloneRunData; } | ||
| get: function () { return chunkYLFDILPM_cjs.cloneRunData; } | ||
| }); | ||
| Object.defineProperty(exports, "createEmptyWorkflowSnapshot", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.createEmptyWorkflowSnapshot; } | ||
| get: function () { return chunkYLFDILPM_cjs.createEmptyWorkflowSnapshot; } | ||
| }); | ||
| Object.defineProperty(exports, "createGitHubSourceControlProviderFromEnv", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.createGitHubSourceControlProviderFromEnv; } | ||
| get: function () { return chunkYLFDILPM_cjs.createGitHubSourceControlProviderFromEnv; } | ||
| }); | ||
| Object.defineProperty(exports, "createStorageErrorId", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.createStorageErrorId; } | ||
| get: function () { return chunkYLFDILPM_cjs.createStorageErrorId; } | ||
| }); | ||
| Object.defineProperty(exports, "createStoreErrorId", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.createStoreErrorId; } | ||
| get: function () { return chunkYLFDILPM_cjs.createStoreErrorId; } | ||
| }); | ||
| Object.defineProperty(exports, "createVectorErrorId", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.createVectorErrorId; } | ||
| get: function () { return chunkYLFDILPM_cjs.createVectorErrorId; } | ||
| }); | ||
| Object.defineProperty(exports, "dispatchDueNotifications", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.dispatchDueNotifications; } | ||
| get: function () { return chunkYLFDILPM_cjs.dispatchDueNotifications; } | ||
| }); | ||
| Object.defineProperty(exports, "ensureDate", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.ensureDate; } | ||
| get: function () { return chunkYLFDILPM_cjs.ensureDate; } | ||
| }); | ||
| Object.defineProperty(exports, "filterByDateRange", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.filterByDateRange; } | ||
| get: function () { return chunkYLFDILPM_cjs.filterByDateRange; } | ||
| }); | ||
| Object.defineProperty(exports, "getDefaultValue", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.getDefaultValue; } | ||
| get: function () { return chunkYLFDILPM_cjs.getDefaultValue; } | ||
| }); | ||
| Object.defineProperty(exports, "getObjectOrNull", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.getObjectOrNull; } | ||
| get: function () { return chunkYLFDILPM_cjs.getObjectOrNull; } | ||
| }); | ||
| Object.defineProperty(exports, "getSqlType", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.getSqlType; } | ||
| get: function () { return chunkYLFDILPM_cjs.getSqlType; } | ||
| }); | ||
| Object.defineProperty(exports, "getStringOrNull", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.getStringOrNull; } | ||
| get: function () { return chunkYLFDILPM_cjs.getStringOrNull; } | ||
| }); | ||
| Object.defineProperty(exports, "jsonValueEquals", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.jsonValueEquals; } | ||
| get: function () { return chunkYLFDILPM_cjs.jsonValueEquals; } | ||
| }); | ||
| Object.defineProperty(exports, "mergeWorkflowStepResult", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.mergeWorkflowStepResult; } | ||
| get: function () { return chunkYLFDILPM_cjs.mergeWorkflowStepResult; } | ||
| }); | ||
| Object.defineProperty(exports, "safelyParseJSON", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.safelyParseJSON; } | ||
| get: function () { return chunkYLFDILPM_cjs.safelyParseJSON; } | ||
| }); | ||
| Object.defineProperty(exports, "serializeDate", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.serializeDate; } | ||
| get: function () { return chunkYLFDILPM_cjs.serializeDate; } | ||
| }); | ||
| Object.defineProperty(exports, "serializeSpanAttributes", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.serializeSpanAttributes; } | ||
| get: function () { return chunkYLFDILPM_cjs.serializeSpanAttributes; } | ||
| }); | ||
| Object.defineProperty(exports, "toEntityType", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.toEntityType; } | ||
| get: function () { return chunkYLFDILPM_cjs.toEntityType; } | ||
| }); | ||
| Object.defineProperty(exports, "transformRow", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.transformRow; } | ||
| get: function () { return chunkYLFDILPM_cjs.transformRow; } | ||
| }); | ||
| Object.defineProperty(exports, "transformScoreRow", { | ||
| enumerable: true, | ||
| get: function () { return chunkPVH4I7QG_cjs.transformScoreRow; } | ||
| get: function () { return chunkYLFDILPM_cjs.transformScoreRow; } | ||
| }); | ||
| Object.defineProperty(exports, "FilesystemMCPServersStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkWMV636D2_cjs.FilesystemMCPServersStorage; } | ||
| get: function () { return chunkKWXEVPXK_cjs.FilesystemMCPServersStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryMCPServersStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkWMV636D2_cjs.InMemoryMCPServersStorage; } | ||
| get: function () { return chunkKWXEVPXK_cjs.InMemoryMCPServersStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "MCPServersStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkWMV636D2_cjs.MCPServersStorage; } | ||
| get: function () { return chunkKWXEVPXK_cjs.MCPServersStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "FilesystemPromptBlocksStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkMGRR5QZ2_cjs.FilesystemPromptBlocksStorage; } | ||
| get: function () { return chunkGGJVCX4I_cjs.FilesystemPromptBlocksStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryPromptBlocksStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkMGRR5QZ2_cjs.InMemoryPromptBlocksStorage; } | ||
| get: function () { return chunkGGJVCX4I_cjs.InMemoryPromptBlocksStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "PromptBlocksStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkMGRR5QZ2_cjs.PromptBlocksStorage; } | ||
| get: function () { return chunkGGJVCX4I_cjs.PromptBlocksStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "FilesystemScorerDefinitionsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkSK5EI32N_cjs.FilesystemScorerDefinitionsStorage; } | ||
| get: function () { return chunkEXFCDNO4_cjs.FilesystemScorerDefinitionsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryScorerDefinitionsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkSK5EI32N_cjs.InMemoryScorerDefinitionsStorage; } | ||
| get: function () { return chunkEXFCDNO4_cjs.InMemoryScorerDefinitionsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "ScorerDefinitionsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkSK5EI32N_cjs.ScorerDefinitionsStorage; } | ||
| get: function () { return chunkEXFCDNO4_cjs.ScorerDefinitionsStorage; } | ||
| }); | ||
@@ -313,31 +313,31 @@ Object.defineProperty(exports, "FilesystemSkillsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunk64LOMCAH_cjs.FilesystemWorkspacesStorage; } | ||
| get: function () { return chunkLGSQSQFN_cjs.FilesystemWorkspacesStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryWorkspacesStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunk64LOMCAH_cjs.InMemoryWorkspacesStorage; } | ||
| get: function () { return chunkLGSQSQFN_cjs.InMemoryWorkspacesStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "WorkspacesStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunk64LOMCAH_cjs.WorkspacesStorage; } | ||
| get: function () { return chunkLGSQSQFN_cjs.WorkspacesStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "AgentsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkW62XF4LN_cjs.AgentsStorage; } | ||
| get: function () { return chunkHLSFGO57_cjs.AgentsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "FilesystemAgentsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkW62XF4LN_cjs.FilesystemAgentsStorage; } | ||
| get: function () { return chunkHLSFGO57_cjs.FilesystemAgentsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryAgentsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunkW62XF4LN_cjs.InMemoryAgentsStorage; } | ||
| get: function () { return chunkHLSFGO57_cjs.InMemoryAgentsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryDB", { | ||
| enumerable: true, | ||
| get: function () { return chunkW62XF4LN_cjs.InMemoryDB; } | ||
| get: function () { return chunkHLSFGO57_cjs.InMemoryDB; } | ||
| }); | ||
| Object.defineProperty(exports, "SourceAgentsSourceControl", { | ||
| enumerable: true, | ||
| get: function () { return chunkW62XF4LN_cjs.SourceAgentsSourceControl; } | ||
| get: function () { return chunkHLSFGO57_cjs.SourceAgentsSourceControl; } | ||
| }); | ||
@@ -354,11 +354,11 @@ Object.defineProperty(exports, "FavoritesStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunk7EDD27SS_cjs.FilesystemMCPClientsStorage; } | ||
| get: function () { return chunk4M6XWZDY_cjs.FilesystemMCPClientsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "InMemoryMCPClientsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunk7EDD27SS_cjs.InMemoryMCPClientsStorage; } | ||
| get: function () { return chunk4M6XWZDY_cjs.InMemoryMCPClientsStorage; } | ||
| }); | ||
| Object.defineProperty(exports, "MCPClientsStorage", { | ||
| enumerable: true, | ||
| get: function () { return chunk7EDD27SS_cjs.MCPClientsStorage; } | ||
| get: function () { return chunk4M6XWZDY_cjs.MCPClientsStorage; } | ||
| }); | ||
@@ -365,0 +365,0 @@ Object.defineProperty(exports, "EDITOR_DOMAINS", { |
@@ -1,10 +0,10 @@ | ||
| export { BackgroundTasksInMemory, BackgroundTasksStorage, BlobStore, ChannelsStorage, DatasetsInMemory, DatasetsStorage, ExperimentsInMemory, ExperimentsStorage, FilesystemDB, FilesystemStore, GitHubSourceControlProvider, HarnessStorage, InMemoryBlobStore, InMemoryChannelsStorage, InMemoryHarness, InMemoryMemory, InMemoryNotificationsStorage, InMemorySchedulesStorage, InMemoryStore, InMemoryToolProviderConnectionsStorage, MemoryStorage, MockStore, NotificationsStorage, ObservabilityInMemory, ObservabilityStorage, SchedulesStorage, ScoresInMemory, ScoresStorage, StoreOperations, StoreOperationsInMemory, ToolProviderConnectionsStorage, WorkflowsInMemory, WorkflowsStorage, buildCreateSpanRecord, buildFeedbackRecord, buildLogRecord, buildMetricRecord, buildScoreRecord, buildUpdateSpanRecord, cloneRunData, createEmptyWorkflowSnapshot, createGitHubSourceControlProviderFromEnv, createStorageErrorId, createStoreErrorId, createVectorErrorId, dispatchDueNotifications, ensureDate, filterByDateRange, getDefaultValue, getObjectOrNull, getSqlType, getStringOrNull, jsonValueEquals, mergeWorkflowStepResult, safelyParseJSON, serializeDate, serializeSpanAttributes, toEntityType, transformRow, transformScoreRow } from '../chunk-BXKPCDLM.js'; | ||
| export { FilesystemMCPServersStorage, InMemoryMCPServersStorage, MCPServersStorage } from '../chunk-B7OS7GGE.js'; | ||
| export { FilesystemPromptBlocksStorage, InMemoryPromptBlocksStorage, PromptBlocksStorage } from '../chunk-Z23TV6IV.js'; | ||
| export { FilesystemScorerDefinitionsStorage, InMemoryScorerDefinitionsStorage, ScorerDefinitionsStorage } from '../chunk-MCAHK3LA.js'; | ||
| export { BackgroundTasksInMemory, BackgroundTasksStorage, BlobStore, ChannelsStorage, DatasetsInMemory, DatasetsStorage, ExperimentsInMemory, ExperimentsStorage, FilesystemDB, FilesystemStore, GitHubSourceControlProvider, HarnessStorage, InMemoryBlobStore, InMemoryChannelsStorage, InMemoryHarness, InMemoryMemory, InMemoryNotificationsStorage, InMemorySchedulesStorage, InMemoryStore, InMemoryToolProviderConnectionsStorage, MemoryStorage, MockStore, NotificationsStorage, ObservabilityInMemory, ObservabilityStorage, SchedulesStorage, ScoresInMemory, ScoresStorage, StoreOperations, StoreOperationsInMemory, ToolProviderConnectionsStorage, WorkflowsInMemory, WorkflowsStorage, buildCreateSpanRecord, buildFeedbackRecord, buildLogRecord, buildMetricRecord, buildScoreRecord, buildUpdateSpanRecord, cloneRunData, createEmptyWorkflowSnapshot, createGitHubSourceControlProviderFromEnv, createStorageErrorId, createStoreErrorId, createVectorErrorId, dispatchDueNotifications, ensureDate, filterByDateRange, getDefaultValue, getObjectOrNull, getSqlType, getStringOrNull, jsonValueEquals, mergeWorkflowStepResult, safelyParseJSON, serializeDate, serializeSpanAttributes, toEntityType, transformRow, transformScoreRow } from '../chunk-RIIPXHAY.js'; | ||
| export { FilesystemMCPServersStorage, InMemoryMCPServersStorage, MCPServersStorage } from '../chunk-2IBWJI4I.js'; | ||
| export { FilesystemPromptBlocksStorage, InMemoryPromptBlocksStorage, PromptBlocksStorage } from '../chunk-BXKJRFIE.js'; | ||
| export { FilesystemScorerDefinitionsStorage, InMemoryScorerDefinitionsStorage, ScorerDefinitionsStorage } from '../chunk-5HRFZGRZ.js'; | ||
| export { FilesystemSkillsStorage, InMemorySkillsStorage, SkillsStorage, skillSnapshotFieldValuesEqual } from '../chunk-UZRM2G6L.js'; | ||
| export { FilesystemWorkspacesStorage, InMemoryWorkspacesStorage, WorkspacesStorage } from '../chunk-4JHST2EN.js'; | ||
| export { AgentsStorage, FilesystemAgentsStorage, InMemoryAgentsStorage, InMemoryDB, SourceAgentsSourceControl } from '../chunk-GUEWXCCO.js'; | ||
| export { FilesystemWorkspacesStorage, InMemoryWorkspacesStorage, WorkspacesStorage } from '../chunk-IZ3TT3AZ.js'; | ||
| export { AgentsStorage, FilesystemAgentsStorage, InMemoryAgentsStorage, InMemoryDB, SourceAgentsSourceControl } from '../chunk-4BSRNVSZ.js'; | ||
| export { FavoritesStorage, InMemoryFavoritesStorage } from '../chunk-7QYTAPIQ.js'; | ||
| export { FilesystemMCPClientsStorage, InMemoryMCPClientsStorage, MCPClientsStorage } from '../chunk-XMHU3JJ7.js'; | ||
| export { FilesystemMCPClientsStorage, InMemoryMCPClientsStorage, MCPClientsStorage } from '../chunk-Q4AIRH5U.js'; | ||
| export { EDITOR_DOMAINS, FilesystemVersionedHelpers, GitHistory, InMemoryThreadStateStorage, MastraCompositeStore, MastraStorage, SOURCE_CONTROL_AGENTS_DIR, StorageDomain, ThreadStateStorage, VersionedStorageDomain, calculatePagination, getSourceAgentFilePath, getSourceControlEntityFilePath, normalizePerPage } from '../chunk-SKZRHFF3.js'; | ||
@@ -11,0 +11,0 @@ export { AGENTS_SCHEMA, AGENT_VERSIONS_SCHEMA, BRANCH_SPAN_TYPES, BRANCH_SPAN_TYPE_SET, DATASETS_SCHEMA, DATASET_ITEMS_SCHEMA, DATASET_VERSIONS_SCHEMA, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, FAVORITES_SCHEMA, HARNESS_SESSIONS_SCHEMA, MCP_CLIENTS_SCHEMA, MCP_CLIENT_VERSIONS_SCHEMA, MCP_SERVERS_SCHEMA, MCP_SERVER_VERSIONS_SCHEMA, NOTIFICATIONS_SCHEMA, OBSERVATIONAL_MEMORY_SCHEMA, OBSERVATIONAL_MEMORY_TABLE_SCHEMA, OLD_SPAN_SCHEMA, PROMPT_BLOCKS_SCHEMA, PROMPT_BLOCK_VERSIONS_SCHEMA, SCORERS_SCHEMA, SCORER_DEFINITIONS_SCHEMA, SCORER_DEFINITION_VERSIONS_SCHEMA, SKILLS_SCHEMA, SKILL_BLOBS_SCHEMA, SKILL_VERSIONS_SCHEMA, SPAN_SCHEMA, STORAGE_FAVORITE_ENTITY_TYPES, STORAGE_VISIBILITY_VALUES, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_BACKGROUND_TASKS, TABLE_CHANNEL_CONFIG, TABLE_CHANNEL_INSTALLATIONS, TABLE_CONFIGS, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, TABLE_FAVORITES, TABLE_HARNESS_SESSIONS, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, TABLE_MESSAGES, TABLE_NOTIFICATIONS, TABLE_OBSERVATIONAL_MEMORY, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCHEMAS, TABLE_SCORERS, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SKILLS, TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SPANS, TABLE_THREADS, TABLE_THREAD_STATE, TABLE_TOOL_PROVIDER_CONNECTIONS, TABLE_TRACES, TABLE_WORKFLOW_SNAPSHOT, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, THREAD_STATE_SCHEMA, TOOL_PROVIDER_CONNECTIONS_SCHEMA, TraceStatus, WORKSPACES_SCHEMA, WORKSPACE_VERSIONS_SCHEMA, batchCreateSpansArgsSchema, batchDeleteTracesArgsSchema, batchUpdateSpansArgsSchema, branchesFilterSchema, branchesOrderByFieldSchema, branchesOrderBySchema, buildStorageSchema, computeTraceStatus, createSpanArgsSchema, createSpanRecordSchema, extractBranchSpans, getBranchArgsSchema, getBranchResponseSchema, getRootSpanArgsSchema, getRootSpanResponseSchema, getSpanArgsSchema, getSpanResponseSchema, getSpansArgsSchema, getSpansResponseSchema, getStructureResponseSchema, getTraceArgsSchema, getTraceLightResponseSchema, getTraceResponseSchema, lightSpanRecordSchema, listBranchesArgsSchema, listBranchesResponseSchema, listScoresBySpanResponseSchema, listTracesArgsSchema, listTracesLightResponseSchema, listTracesResponseSchema, scoreTracesRequestSchema, scoreTracesResponseSchema, spanIds, spanIdsSchema, spanRecordSchema, toTraceSpan, toTraceSpans, traceSpanSchema, tracesFilterSchema, tracesOrderByFieldSchema, tracesOrderBySchema, updateSpanArgsSchema, updateSpanRecordSchema } from '../chunk-PUHREAKR.js'; |
+13
-13
| 'use strict'; | ||
| var chunkNYZSFMD6_cjs = require('../chunk-NYZSFMD6.cjs'); | ||
| var chunkLZIIAAGJ_cjs = require('../chunk-LZIIAAGJ.cjs'); | ||
| var chunk4THHYWDP_cjs = require('../chunk-4THHYWDP.cjs'); | ||
| var chunkLH3OTIIL_cjs = require('../chunk-LH3OTIIL.cjs'); | ||
| var chunkH3Y3YAMF_cjs = require('../chunk-H3Y3YAMF.cjs'); | ||
| var chunk2PXTHATK_cjs = require('../chunk-2PXTHATK.cjs'); | ||
| var chunkPUEQNTX6_cjs = require('../chunk-PUEQNTX6.cjs'); | ||
@@ -12,39 +12,39 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkNYZSFMD6_cjs.MastraAgentNetworkStream; } | ||
| get: function () { return chunkLH3OTIIL_cjs.MastraAgentNetworkStream; } | ||
| }); | ||
| Object.defineProperty(exports, "WorkflowRunOutput", { | ||
| enumerable: true, | ||
| get: function () { return chunkNYZSFMD6_cjs.WorkflowRunOutput; } | ||
| get: function () { return chunkLH3OTIIL_cjs.WorkflowRunOutput; } | ||
| }); | ||
| Object.defineProperty(exports, "convertFullStreamChunkToMastra", { | ||
| enumerable: true, | ||
| get: function () { return chunkNYZSFMD6_cjs.convertFullStreamChunkToMastra; } | ||
| get: function () { return chunkLH3OTIIL_cjs.convertFullStreamChunkToMastra; } | ||
| }); | ||
| Object.defineProperty(exports, "convertFullStreamChunkToUIMessageStream", { | ||
| enumerable: true, | ||
| get: function () { return chunkNYZSFMD6_cjs.convertFullStreamChunkToUIMessageStream; } | ||
| get: function () { return chunkLH3OTIIL_cjs.convertFullStreamChunkToUIMessageStream; } | ||
| }); | ||
| Object.defineProperty(exports, "convertMastraChunkToAISDKv5", { | ||
| enumerable: true, | ||
| get: function () { return chunkNYZSFMD6_cjs.convertMastraChunkToAISDKv5; } | ||
| get: function () { return chunkLH3OTIIL_cjs.convertMastraChunkToAISDKv5; } | ||
| }); | ||
| Object.defineProperty(exports, "createCachingTransformStream", { | ||
| enumerable: true, | ||
| get: function () { return chunkNYZSFMD6_cjs.createCachingTransformStream; } | ||
| get: function () { return chunkLH3OTIIL_cjs.createCachingTransformStream; } | ||
| }); | ||
| Object.defineProperty(exports, "createReplayStream", { | ||
| enumerable: true, | ||
| get: function () { return chunkNYZSFMD6_cjs.createReplayStream; } | ||
| get: function () { return chunkLH3OTIIL_cjs.createReplayStream; } | ||
| }); | ||
| Object.defineProperty(exports, "withStreamCaching", { | ||
| enumerable: true, | ||
| get: function () { return chunkNYZSFMD6_cjs.withStreamCaching; } | ||
| get: function () { return chunkLH3OTIIL_cjs.withStreamCaching; } | ||
| }); | ||
| Object.defineProperty(exports, "MastraModelOutput", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.MastraModelOutput; } | ||
| get: function () { return chunkH3Y3YAMF_cjs.MastraModelOutput; } | ||
| }); | ||
| Object.defineProperty(exports, "ChunkFrom", { | ||
| enumerable: true, | ||
| get: function () { return chunk4THHYWDP_cjs.ChunkFrom; } | ||
| get: function () { return chunk2PXTHATK_cjs.ChunkFrom; } | ||
| }); | ||
@@ -51,0 +51,0 @@ Object.defineProperty(exports, "DefaultGeneratedFile", { |
@@ -1,6 +0,6 @@ | ||
| export { MastraAgentNetworkStream, WorkflowRunOutput, convertFullStreamChunkToMastra, convertFullStreamChunkToUIMessageStream, convertMastraChunkToAISDKv5, createCachingTransformStream, createReplayStream, withStreamCaching } from '../chunk-OP6KXMTE.js'; | ||
| export { MastraModelOutput } from '../chunk-HCSJNNEN.js'; | ||
| export { ChunkFrom } from '../chunk-4VYRSIOP.js'; | ||
| export { MastraAgentNetworkStream, WorkflowRunOutput, convertFullStreamChunkToMastra, convertFullStreamChunkToUIMessageStream, convertMastraChunkToAISDKv5, createCachingTransformStream, createReplayStream, withStreamCaching } from '../chunk-HIJT3Z73.js'; | ||
| export { MastraModelOutput } from '../chunk-YNS26J6E.js'; | ||
| export { ChunkFrom } from '../chunk-ORABIARW.js'; | ||
| export { DefaultGeneratedFile, DefaultGeneratedFileWithType } from '../chunk-HHYICF3X.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
@@ -9,13 +9,13 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.getSettings; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.getSettings; } | ||
| }); | ||
| Object.defineProperty(exports, "isToolLoopAgentLike", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.isToolLoopAgentLike; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.isToolLoopAgentLike; } | ||
| }); | ||
| Object.defineProperty(exports, "toolLoopAgentToMastraAgent", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.toolLoopAgentToMastraAgent; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.toolLoopAgentToMastraAgent; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,3 +0,3 @@ | ||
| export { getSettings, isToolLoopAgentLike, toolLoopAgentToMastraAgent } from '../chunk-MVA25X63.js'; | ||
| export { getSettings, isToolLoopAgentLike, toolLoopAgentToMastraAgent } from '../chunk-PQ5PN4TW.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
+41
-41
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkB3SPPQQ3_cjs = require('../chunk-B3SPPQQ3.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
| var chunkBP67LMWW_cjs = require('../chunk-BP67LMWW.cjs'); | ||
| var chunkDZ44ZU2T_cjs = require('../chunk-DZ44ZU2T.cjs'); | ||
@@ -12,155 +12,155 @@ var chunkDC5C6QMM_cjs = require('../chunk-DC5C6QMM.cjs'); | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.DEFAULT_GOAL_JUDGE_PROMPT; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.DEFAULT_GOAL_JUDGE_PROMPT; } | ||
| }); | ||
| Object.defineProperty(exports, "DEFAULT_GOAL_MAX_RUNS", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.DEFAULT_GOAL_MAX_RUNS; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.DEFAULT_GOAL_MAX_RUNS; } | ||
| }); | ||
| Object.defineProperty(exports, "FRAME_PREFIX", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.FRAME_PREFIX; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.FRAME_PREFIX; } | ||
| }); | ||
| Object.defineProperty(exports, "GOAL_STATE_ID", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.GOAL_STATE_ID; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.GOAL_STATE_ID; } | ||
| }); | ||
| Object.defineProperty(exports, "GOAL_STATE_TYPE", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.GOAL_STATE_TYPE; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.GOAL_STATE_TYPE; } | ||
| }); | ||
| Object.defineProperty(exports, "GoalStateProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.GoalStateProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.GoalStateProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "StdioCodeModeTransport", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.StdioCodeModeTransport; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.StdioCodeModeTransport; } | ||
| }); | ||
| Object.defineProperty(exports, "TASKS_REQUEST_CONTEXT_KEY", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.TASKS_REQUEST_CONTEXT_KEY; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.TASKS_REQUEST_CONTEXT_KEY; } | ||
| }); | ||
| Object.defineProperty(exports, "TASKS_STATE_ID", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.TASKS_STATE_ID; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.TASKS_STATE_ID; } | ||
| }); | ||
| Object.defineProperty(exports, "TASK_STATE_TYPE", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.TASK_STATE_TYPE; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.TASK_STATE_TYPE; } | ||
| }); | ||
| Object.defineProperty(exports, "TaskStateProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.TaskStateProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.TaskStateProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "askUserTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.askUserTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.askUserTool; } | ||
| }); | ||
| Object.defineProperty(exports, "assignTaskIds", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.assignTaskIds; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.assignTaskIds; } | ||
| }); | ||
| Object.defineProperty(exports, "buildProgramModule", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.buildProgramModule; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.buildProgramModule; } | ||
| }); | ||
| Object.defineProperty(exports, "buildRunner", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.buildRunner; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.buildRunner; } | ||
| }); | ||
| Object.defineProperty(exports, "clearObjective", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.clearObjective; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.clearObjective; } | ||
| }); | ||
| Object.defineProperty(exports, "createCodeMode", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createCodeMode; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createCodeMode; } | ||
| }); | ||
| Object.defineProperty(exports, "createCodeModeInstructions", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createCodeModeInstructions; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createCodeModeInstructions; } | ||
| }); | ||
| Object.defineProperty(exports, "createCodeModeTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createCodeModeTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createCodeModeTool; } | ||
| }); | ||
| Object.defineProperty(exports, "demoteExtraInProgress", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.demoteExtraInProgress; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.demoteExtraInProgress; } | ||
| }); | ||
| Object.defineProperty(exports, "formatQuestionAnswer", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.formatQuestionAnswer; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.formatQuestionAnswer; } | ||
| }); | ||
| Object.defineProperty(exports, "formatTaskListResult", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.formatTaskListResult; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.formatTaskListResult; } | ||
| }); | ||
| Object.defineProperty(exports, "generateStubs", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.generateStubs; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.generateStubs; } | ||
| }); | ||
| Object.defineProperty(exports, "getObjectiveFromRequestContext", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.getObjectiveFromRequestContext; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.getObjectiveFromRequestContext; } | ||
| }); | ||
| Object.defineProperty(exports, "getTasksFromRequestContext", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.getTasksFromRequestContext; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.getTasksFromRequestContext; } | ||
| }); | ||
| Object.defineProperty(exports, "hasMultipleInProgress", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.hasMultipleInProgress; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.hasMultipleInProgress; } | ||
| }); | ||
| Object.defineProperty(exports, "jsonSchemaToTsString", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.jsonSchemaToTsString; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.jsonSchemaToTsString; } | ||
| }); | ||
| Object.defineProperty(exports, "readObjective", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.readObjective; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.readObjective; } | ||
| }); | ||
| Object.defineProperty(exports, "resolveEffectiveGoalSettings", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.resolveEffectiveGoalSettings; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.resolveEffectiveGoalSettings; } | ||
| }); | ||
| Object.defineProperty(exports, "resolveGoalStore", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.resolveGoalStore; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.resolveGoalStore; } | ||
| }); | ||
| Object.defineProperty(exports, "submitPlanTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.submitPlanTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.submitPlanTool; } | ||
| }); | ||
| Object.defineProperty(exports, "summarizeTaskCheck", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.summarizeTaskCheck; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.summarizeTaskCheck; } | ||
| }); | ||
| Object.defineProperty(exports, "taskCheckTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.taskCheckTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.taskCheckTool; } | ||
| }); | ||
| Object.defineProperty(exports, "taskCompleteTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.taskCompleteTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.taskCompleteTool; } | ||
| }); | ||
| Object.defineProperty(exports, "taskUpdateTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.taskUpdateTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.taskUpdateTool; } | ||
| }); | ||
| Object.defineProperty(exports, "taskWriteTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.taskWriteTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.taskWriteTool; } | ||
| }); | ||
| Object.defineProperty(exports, "writeObjective", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.writeObjective; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.writeObjective; } | ||
| }); | ||
| Object.defineProperty(exports, "ToolStream", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.ToolStream; } | ||
| get: function () { return chunkBP67LMWW_cjs.ToolStream; } | ||
| }); | ||
| Object.defineProperty(exports, "noopObserve", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.noopObserve; } | ||
| get: function () { return chunkBP67LMWW_cjs.noopObserve; } | ||
| }); | ||
@@ -167,0 +167,0 @@ Object.defineProperty(exports, "MASTRA_TOOL_MARKER", { |
@@ -1,3 +0,3 @@ | ||
| export { DEFAULT_GOAL_JUDGE_PROMPT, DEFAULT_GOAL_MAX_RUNS, FRAME_PREFIX, GOAL_STATE_ID, GOAL_STATE_TYPE, GoalStateProcessor, StdioCodeModeTransport, TASKS_REQUEST_CONTEXT_KEY, TASKS_STATE_ID, TASK_STATE_TYPE, TaskStateProcessor, askUserTool, assignTaskIds, buildProgramModule, buildRunner, clearObjective, createCodeMode, createCodeModeInstructions, createCodeModeTool, demoteExtraInProgress, formatQuestionAnswer, formatTaskListResult, generateStubs, getObjectiveFromRequestContext, getTasksFromRequestContext, hasMultipleInProgress, jsonSchemaToTsString, readObjective, resolveEffectiveGoalSettings, resolveGoalStore, submitPlanTool, summarizeTaskCheck, taskCheckTool, taskCompleteTool, taskUpdateTool, taskWriteTool, writeObjective } from '../chunk-MVA25X63.js'; | ||
| export { ToolStream, noopObserve } from '../chunk-MVLICRVY.js'; | ||
| export { DEFAULT_GOAL_JUDGE_PROMPT, DEFAULT_GOAL_MAX_RUNS, FRAME_PREFIX, GOAL_STATE_ID, GOAL_STATE_TYPE, GoalStateProcessor, StdioCodeModeTransport, TASKS_REQUEST_CONTEXT_KEY, TASKS_STATE_ID, TASK_STATE_TYPE, TaskStateProcessor, askUserTool, assignTaskIds, buildProgramModule, buildRunner, clearObjective, createCodeMode, createCodeModeInstructions, createCodeModeTool, demoteExtraInProgress, formatQuestionAnswer, formatTaskListResult, generateStubs, getObjectiveFromRequestContext, getTasksFromRequestContext, hasMultipleInProgress, jsonSchemaToTsString, readObjective, resolveEffectiveGoalSettings, resolveGoalStore, submitPlanTool, summarizeTaskCheck, taskCheckTool, taskCompleteTool, taskUpdateTool, taskWriteTool, writeObjective } from '../chunk-PQ5PN4TW.js'; | ||
| export { ToolStream, noopObserve } from '../chunk-M2TW4P2L.js'; | ||
| export { MASTRA_TOOL_MARKER, Tool, createTool, isProviderDefinedTool, isProviderTool, isValidationError, isVercelTool } from '../chunk-VLJMDX6T.js'; | ||
@@ -4,0 +4,0 @@ export { getTransformedToolPayload, hasTransformedToolPayload } from '../chunk-FDU3KNKR.js'; |
+24
-24
| 'use strict'; | ||
| var chunkB3SPPQQ3_cjs = require('./chunk-B3SPPQQ3.cjs'); | ||
| var chunkBP67LMWW_cjs = require('./chunk-BP67LMWW.cjs'); | ||
| var chunkCMKSC37Z_cjs = require('./chunk-CMKSC37Z.cjs'); | ||
@@ -11,91 +11,91 @@ var chunkPAMAGEYY_cjs = require('./chunk-PAMAGEYY.cjs'); | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.checkEvalStorageFields; } | ||
| get: function () { return chunkBP67LMWW_cjs.checkEvalStorageFields; } | ||
| }); | ||
| Object.defineProperty(exports, "createMastraProxy", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.createMastraProxy; } | ||
| get: function () { return chunkBP67LMWW_cjs.createMastraProxy; } | ||
| }); | ||
| Object.defineProperty(exports, "deepEqual", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.deepEqual; } | ||
| get: function () { return chunkBP67LMWW_cjs.deepEqual; } | ||
| }); | ||
| Object.defineProperty(exports, "deepMerge", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.deepMerge; } | ||
| get: function () { return chunkBP67LMWW_cjs.deepMerge; } | ||
| }); | ||
| Object.defineProperty(exports, "delay", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.delay; } | ||
| get: function () { return chunkBP67LMWW_cjs.delay; } | ||
| }); | ||
| Object.defineProperty(exports, "ensureSerializable", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.ensureSerializable; } | ||
| get: function () { return chunkBP67LMWW_cjs.ensureSerializable; } | ||
| }); | ||
| Object.defineProperty(exports, "ensureToolProperties", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.ensureToolProperties; } | ||
| get: function () { return chunkBP67LMWW_cjs.ensureToolProperties; } | ||
| }); | ||
| Object.defineProperty(exports, "generateEmptyFromSchema", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.generateEmptyFromSchema; } | ||
| get: function () { return chunkBP67LMWW_cjs.generateEmptyFromSchema; } | ||
| }); | ||
| Object.defineProperty(exports, "getNestedValue", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.getNestedValue; } | ||
| get: function () { return chunkBP67LMWW_cjs.getNestedValue; } | ||
| }); | ||
| Object.defineProperty(exports, "isCoreMessage", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.isCoreMessage; } | ||
| get: function () { return chunkBP67LMWW_cjs.isCoreMessage; } | ||
| }); | ||
| Object.defineProperty(exports, "isUiMessage", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.isUiMessage; } | ||
| get: function () { return chunkBP67LMWW_cjs.isUiMessage; } | ||
| }); | ||
| Object.defineProperty(exports, "isZodType", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.isZodType; } | ||
| get: function () { return chunkBP67LMWW_cjs.isZodType; } | ||
| }); | ||
| Object.defineProperty(exports, "makeCoreTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.makeCoreTool; } | ||
| get: function () { return chunkBP67LMWW_cjs.makeCoreTool; } | ||
| }); | ||
| Object.defineProperty(exports, "makeCoreToolV5", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.makeCoreToolV5; } | ||
| get: function () { return chunkBP67LMWW_cjs.makeCoreToolV5; } | ||
| }); | ||
| Object.defineProperty(exports, "maskStreamTags", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.maskStreamTags; } | ||
| get: function () { return chunkBP67LMWW_cjs.maskStreamTags; } | ||
| }); | ||
| Object.defineProperty(exports, "omitKeys", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.omitKeys; } | ||
| get: function () { return chunkBP67LMWW_cjs.omitKeys; } | ||
| }); | ||
| Object.defineProperty(exports, "parseFieldKey", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.parseFieldKey; } | ||
| get: function () { return chunkBP67LMWW_cjs.parseFieldKey; } | ||
| }); | ||
| Object.defineProperty(exports, "parseSqlIdentifier", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.parseSqlIdentifier; } | ||
| get: function () { return chunkBP67LMWW_cjs.parseSqlIdentifier; } | ||
| }); | ||
| Object.defineProperty(exports, "removeUndefinedValues", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.removeUndefinedValues; } | ||
| get: function () { return chunkBP67LMWW_cjs.removeUndefinedValues; } | ||
| }); | ||
| Object.defineProperty(exports, "resolveSerializedZodOutput", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.resolveSerializedZodOutput; } | ||
| get: function () { return chunkBP67LMWW_cjs.resolveSerializedZodOutput; } | ||
| }); | ||
| Object.defineProperty(exports, "safeStringify", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.safeStringify; } | ||
| get: function () { return chunkBP67LMWW_cjs.safeStringify; } | ||
| }); | ||
| Object.defineProperty(exports, "selectFields", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.selectFields; } | ||
| get: function () { return chunkBP67LMWW_cjs.selectFields; } | ||
| }); | ||
| Object.defineProperty(exports, "setNestedValue", { | ||
| enumerable: true, | ||
| get: function () { return chunkB3SPPQQ3_cjs.setNestedValue; } | ||
| get: function () { return chunkBP67LMWW_cjs.setNestedValue; } | ||
| }); | ||
@@ -102,0 +102,0 @@ Object.defineProperty(exports, "getZodDef", { |
+1
-1
@@ -1,2 +0,2 @@ | ||
| export { checkEvalStorageFields, createMastraProxy, deepEqual, deepMerge, delay, ensureSerializable, ensureToolProperties, generateEmptyFromSchema, getNestedValue, isCoreMessage, isUiMessage, isZodType, makeCoreTool, makeCoreToolV5, maskStreamTags, omitKeys, parseFieldKey, parseSqlIdentifier, removeUndefinedValues, resolveSerializedZodOutput, safeStringify, selectFields, setNestedValue } from './chunk-MVLICRVY.js'; | ||
| export { checkEvalStorageFields, createMastraProxy, deepEqual, deepMerge, delay, ensureSerializable, ensureToolProperties, generateEmptyFromSchema, getNestedValue, isCoreMessage, isUiMessage, isZodType, makeCoreTool, makeCoreToolV5, maskStreamTags, omitKeys, parseFieldKey, parseSqlIdentifier, removeUndefinedValues, resolveSerializedZodOutput, safeStringify, selectFields, setNestedValue } from './chunk-M2TW4P2L.js'; | ||
| export { getZodDef, getZodTypeName, isZodArray, isZodObject } from './chunk-TBHKQLPL.js'; | ||
@@ -3,0 +3,0 @@ export { fetchWithRetry } from './chunk-RBJJ4Y4N.js'; |
| 'use strict'; | ||
| var chunk6XCINXZ7_cjs = require('../chunk-6XCINXZ7.cjs'); | ||
| var chunkPVH4I7QG_cjs = require('../chunk-PVH4I7QG.cjs'); | ||
| var chunkYLFDILPM_cjs = require('../chunk-YLFDILPM.cjs'); | ||
| var chunkWSD4JNMB_cjs = require('../chunk-WSD4JNMB.cjs'); | ||
@@ -94,3 +94,3 @@ var chunkVRIGWPHF_cjs = require('../chunk-VRIGWPHF.cjs'); | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: chunkPVH4I7QG_cjs.createVectorErrorId(storeName, "UPSERT", "EMPTY_VECTORS"), | ||
| id: chunkYLFDILPM_cjs.createVectorErrorId(storeName, "UPSERT", "EMPTY_VECTORS"), | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.MASTRA_VECTOR, | ||
@@ -105,3 +105,3 @@ category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: chunkPVH4I7QG_cjs.createVectorErrorId(storeName, "UPSERT", "METADATA_LENGTH_MISMATCH"), | ||
| id: chunkYLFDILPM_cjs.createVectorErrorId(storeName, "UPSERT", "METADATA_LENGTH_MISMATCH"), | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.MASTRA_VECTOR, | ||
@@ -118,3 +118,3 @@ category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: chunkPVH4I7QG_cjs.createVectorErrorId(storeName, "UPSERT", "IDS_LENGTH_MISMATCH"), | ||
| id: chunkYLFDILPM_cjs.createVectorErrorId(storeName, "UPSERT", "IDS_LENGTH_MISMATCH"), | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.MASTRA_VECTOR, | ||
@@ -133,3 +133,3 @@ category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: chunkPVH4I7QG_cjs.createVectorErrorId(storeName, "QUERY", "INVALID_TOP_K"), | ||
| id: chunkYLFDILPM_cjs.createVectorErrorId(storeName, "QUERY", "INVALID_TOP_K"), | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.MASTRA_VECTOR, | ||
@@ -149,3 +149,3 @@ category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: chunkPVH4I7QG_cjs.createVectorErrorId(storeName, "UPSERT", "INVALID_VECTOR"), | ||
| id: chunkYLFDILPM_cjs.createVectorErrorId(storeName, "UPSERT", "INVALID_VECTOR"), | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.MASTRA_VECTOR, | ||
@@ -163,3 +163,3 @@ category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: chunkPVH4I7QG_cjs.createVectorErrorId(storeName, "UPSERT", "INVALID_VECTOR_VALUE"), | ||
| id: chunkYLFDILPM_cjs.createVectorErrorId(storeName, "UPSERT", "INVALID_VECTOR_VALUE"), | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.MASTRA_VECTOR, | ||
@@ -166,0 +166,0 @@ category: chunkXSOONORA_cjs.ErrorCategory.USER, |
| export { BaseFilterTranslator } from '../chunk-BWYU7D33.js'; | ||
| import { createVectorErrorId } from '../chunk-BXKPCDLM.js'; | ||
| import { createVectorErrorId } from '../chunk-RIIPXHAY.js'; | ||
| import { MastraBase } from '../chunk-77VL4DNS.js'; | ||
@@ -4,0 +4,0 @@ export { embed as embedV2 } from '../chunk-JPZJEO6I.js'; |
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
| var chunkCWKMGK5K_cjs = require('../chunk-CWKMGK5K.cjs'); | ||
@@ -10,23 +10,23 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.BackgroundTaskWorker; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.BackgroundTaskWorker; } | ||
| }); | ||
| Object.defineProperty(exports, "HttpRemoteStrategy", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.HttpRemoteStrategy; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.HttpRemoteStrategy; } | ||
| }); | ||
| Object.defineProperty(exports, "InProcessStrategy", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.InProcessStrategy; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.InProcessStrategy; } | ||
| }); | ||
| Object.defineProperty(exports, "OrchestrationWorker", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.OrchestrationWorker; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.OrchestrationWorker; } | ||
| }); | ||
| Object.defineProperty(exports, "SchedulerWorker", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SchedulerWorker; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SchedulerWorker; } | ||
| }); | ||
| Object.defineProperty(exports, "StepExecutionError", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.StepExecutionError; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.StepExecutionError; } | ||
| }); | ||
@@ -33,0 +33,0 @@ Object.defineProperty(exports, "MastraWorker", { |
@@ -1,4 +0,4 @@ | ||
| export { BackgroundTaskWorker, HttpRemoteStrategy, InProcessStrategy, OrchestrationWorker, SchedulerWorker, StepExecutionError } from '../chunk-MVA25X63.js'; | ||
| export { BackgroundTaskWorker, HttpRemoteStrategy, InProcessStrategy, OrchestrationWorker, SchedulerWorker, StepExecutionError } from '../chunk-PQ5PN4TW.js'; | ||
| export { MastraWorker, PullTransport } from '../chunk-2JTOKKYG.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../../chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../../chunk-QJ3FDYCK.cjs'); | ||
@@ -9,37 +9,37 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.EventedExecutionEngine; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.EventedExecutionEngine; } | ||
| }); | ||
| Object.defineProperty(exports, "EventedRun", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.EventedRun; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.EventedRun; } | ||
| }); | ||
| Object.defineProperty(exports, "EventedWorkflow", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.EventedWorkflow; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.EventedWorkflow; } | ||
| }); | ||
| Object.defineProperty(exports, "StepExecutor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.StepExecutor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.StepExecutor; } | ||
| }); | ||
| Object.defineProperty(exports, "WorkflowEventProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.WorkflowEventProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.WorkflowEventProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "cloneStep", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.cloneStep2; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.cloneStep2; } | ||
| }); | ||
| Object.defineProperty(exports, "cloneWorkflow", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.cloneWorkflow2; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.cloneWorkflow2; } | ||
| }); | ||
| Object.defineProperty(exports, "createStep", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createStep2; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createStep2; } | ||
| }); | ||
| Object.defineProperty(exports, "createWorkflow", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createWorkflow2; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createWorkflow2; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,3 +0,3 @@ | ||
| export { EventedExecutionEngine, EventedRun, EventedWorkflow, StepExecutor, WorkflowEventProcessor, cloneStep2 as cloneStep, cloneWorkflow2 as cloneWorkflow, createStep2 as createStep, createWorkflow2 as createWorkflow } from '../../chunk-MVA25X63.js'; | ||
| export { EventedExecutionEngine, EventedRun, EventedWorkflow, StepExecutor, WorkflowEventProcessor, cloneStep2 as cloneStep, cloneWorkflow2 as cloneWorkflow, createStep2 as createStep, createWorkflow2 as createWorkflow } from '../../chunk-PQ5PN4TW.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
+31
-31
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
@@ -81,119 +81,119 @@ // src/workflows/state-reader.ts | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.DefaultExecutionEngine; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.DefaultExecutionEngine; } | ||
| }); | ||
| Object.defineProperty(exports, "ExecutionEngine", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ExecutionEngine; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ExecutionEngine; } | ||
| }); | ||
| Object.defineProperty(exports, "Run", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.Run; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.Run; } | ||
| }); | ||
| Object.defineProperty(exports, "Scheduler", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.Scheduler; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.Scheduler; } | ||
| }); | ||
| Object.defineProperty(exports, "Workflow", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.Workflow; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.Workflow; } | ||
| }); | ||
| Object.defineProperty(exports, "WorkflowScheduler", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.WorkflowScheduler; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.WorkflowScheduler; } | ||
| }); | ||
| Object.defineProperty(exports, "cleanStepResult", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.cleanStepResult; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.cleanStepResult; } | ||
| }); | ||
| Object.defineProperty(exports, "cloneStep", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.cloneStep; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.cloneStep; } | ||
| }); | ||
| Object.defineProperty(exports, "cloneWorkflow", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.cloneWorkflow; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.cloneWorkflow; } | ||
| }); | ||
| Object.defineProperty(exports, "computeNextFireAt", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.computeNextFireAt; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.computeNextFireAt; } | ||
| }); | ||
| Object.defineProperty(exports, "createDeprecationProxy", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createDeprecationProxy; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createDeprecationProxy; } | ||
| }); | ||
| Object.defineProperty(exports, "createEventedWorkflow", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createEventedWorkflow; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createEventedWorkflow; } | ||
| }); | ||
| Object.defineProperty(exports, "createRestartExecutionParams", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createRestartExecutionParams; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createRestartExecutionParams; } | ||
| }); | ||
| Object.defineProperty(exports, "createStep", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createStep; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createStep; } | ||
| }); | ||
| Object.defineProperty(exports, "createTimeTravelExecutionParams", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createTimeTravelExecutionParams; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createTimeTravelExecutionParams; } | ||
| }); | ||
| Object.defineProperty(exports, "createWorkflow", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createWorkflow; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createWorkflow; } | ||
| }); | ||
| Object.defineProperty(exports, "getResumeLabelsByStepId", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.getResumeLabelsByStepId; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.getResumeLabelsByStepId; } | ||
| }); | ||
| Object.defineProperty(exports, "getStepIds", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.getStepIds; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.getStepIds; } | ||
| }); | ||
| Object.defineProperty(exports, "getStepResult", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.getStepResult; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.getStepResult; } | ||
| }); | ||
| Object.defineProperty(exports, "hydrateSerializedStepErrors", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.hydrateSerializedStepErrors; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.hydrateSerializedStepErrors; } | ||
| }); | ||
| Object.defineProperty(exports, "isProcessor", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.isProcessor; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.isProcessor; } | ||
| }); | ||
| Object.defineProperty(exports, "mapVariable", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.mapVariable; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.mapVariable; } | ||
| }); | ||
| Object.defineProperty(exports, "runCountDeprecationMessage", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.runCountDeprecationMessage; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.runCountDeprecationMessage; } | ||
| }); | ||
| Object.defineProperty(exports, "validateCron", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.validateCron; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.validateCron; } | ||
| }); | ||
| Object.defineProperty(exports, "validateStepInput", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.validateStepInput; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.validateStepInput; } | ||
| }); | ||
| Object.defineProperty(exports, "validateStepRequestContext", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.validateStepRequestContext; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.validateStepRequestContext; } | ||
| }); | ||
| Object.defineProperty(exports, "validateStepResumeData", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.validateStepResumeData; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.validateStepResumeData; } | ||
| }); | ||
| Object.defineProperty(exports, "validateStepStateData", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.validateStepStateData; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.validateStepStateData; } | ||
| }); | ||
| Object.defineProperty(exports, "validateStepSuspendData", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.validateStepSuspendData; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.validateStepSuspendData; } | ||
| }); | ||
| Object.defineProperty(exports, "waitForSuspendedSnapshot", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.waitForSuspendedSnapshot; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.waitForSuspendedSnapshot; } | ||
| }); | ||
@@ -200,0 +200,0 @@ exports.createWorkflowStateReader = createWorkflowStateReader; |
@@ -1,2 +0,2 @@ | ||
| export { DefaultExecutionEngine, ExecutionEngine, Run, Scheduler, Workflow, WorkflowScheduler, cleanStepResult, cloneStep, cloneWorkflow, computeNextFireAt, createDeprecationProxy, createEventedWorkflow, createRestartExecutionParams, createStep, createTimeTravelExecutionParams, createWorkflow, getResumeLabelsByStepId, getStepIds, getStepResult, hydrateSerializedStepErrors, isProcessor, mapVariable, runCountDeprecationMessage, validateCron, validateStepInput, validateStepRequestContext, validateStepResumeData, validateStepStateData, validateStepSuspendData, waitForSuspendedSnapshot } from '../chunk-MVA25X63.js'; | ||
| export { DefaultExecutionEngine, ExecutionEngine, Run, Scheduler, Workflow, WorkflowScheduler, cleanStepResult, cloneStep, cloneWorkflow, computeNextFireAt, createDeprecationProxy, createEventedWorkflow, createRestartExecutionParams, createStep, createTimeTravelExecutionParams, createWorkflow, getResumeLabelsByStepId, getStepIds, getStepResult, hydrateSerializedStepErrors, isProcessor, mapVariable, runCountDeprecationMessage, validateCron, validateStepInput, validateStepRequestContext, validateStepResumeData, validateStepStateData, validateStepSuspendData, waitForSuspendedSnapshot } from '../chunk-PQ5PN4TW.js'; | ||
@@ -3,0 +3,0 @@ // src/workflows/state-reader.ts |
+45
-45
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('../chunk-GSWZYCY4.cjs'); | ||
| var chunkQJ3FDYCK_cjs = require('../chunk-QJ3FDYCK.cjs'); | ||
| var chunkZNDOO55R_cjs = require('../chunk-ZNDOO55R.cjs'); | ||
@@ -10,175 +10,175 @@ | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.CompositeFilesystem; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.CompositeFilesystem; } | ||
| }); | ||
| Object.defineProperty(exports, "CompositeVersionedSkillSource", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.CompositeVersionedSkillSource; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.CompositeVersionedSkillSource; } | ||
| }); | ||
| Object.defineProperty(exports, "FilesystemNotMountableError", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.FilesystemNotMountableError; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.FilesystemNotMountableError; } | ||
| }); | ||
| Object.defineProperty(exports, "IsolationUnavailableError", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.IsolationUnavailableError; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.IsolationUnavailableError; } | ||
| }); | ||
| Object.defineProperty(exports, "LocalFilesystem", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.LocalFilesystem; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.LocalFilesystem; } | ||
| }); | ||
| Object.defineProperty(exports, "LocalSandbox", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.LocalSandbox; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.LocalSandbox; } | ||
| }); | ||
| Object.defineProperty(exports, "MastraFilesystem", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MastraFilesystem; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MastraFilesystem; } | ||
| }); | ||
| Object.defineProperty(exports, "MastraSandbox", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MastraSandbox; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MastraSandbox; } | ||
| }); | ||
| Object.defineProperty(exports, "MountError", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MountError; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MountError; } | ||
| }); | ||
| Object.defineProperty(exports, "MountManager", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MountManager; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MountManager; } | ||
| }); | ||
| Object.defineProperty(exports, "MountNotSupportedError", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.MountNotSupportedError; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.MountNotSupportedError; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessHandle", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.ProcessHandle; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.ProcessHandle; } | ||
| }); | ||
| Object.defineProperty(exports, "SandboxError", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SandboxError; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SandboxError; } | ||
| }); | ||
| Object.defineProperty(exports, "SandboxExecutionError", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SandboxExecutionError; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SandboxExecutionError; } | ||
| }); | ||
| Object.defineProperty(exports, "SandboxNotReadyError", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SandboxNotReadyError; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SandboxNotReadyError; } | ||
| }); | ||
| Object.defineProperty(exports, "SandboxProcessManager", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SandboxProcessManager; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SandboxProcessManager; } | ||
| }); | ||
| Object.defineProperty(exports, "SandboxTimeoutError", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.SandboxTimeoutError; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.SandboxTimeoutError; } | ||
| }); | ||
| Object.defineProperty(exports, "VersionedSkillSource", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.VersionedSkillSource; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.VersionedSkillSource; } | ||
| }); | ||
| Object.defineProperty(exports, "WORKSPACE_TOOLS", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.WORKSPACE_TOOLS; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.WORKSPACE_TOOLS; } | ||
| }); | ||
| Object.defineProperty(exports, "WORKSPACE_TOOLS_PREFIX", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.WORKSPACE_TOOLS_PREFIX; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.WORKSPACE_TOOLS_PREFIX; } | ||
| }); | ||
| Object.defineProperty(exports, "Workspace", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.Workspace; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.Workspace; } | ||
| }); | ||
| Object.defineProperty(exports, "callLifecycle", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.callLifecycle; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.callLifecycle; } | ||
| }); | ||
| Object.defineProperty(exports, "collectSkillForPublish", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.collectSkillForPublish; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.collectSkillForPublish; } | ||
| }); | ||
| Object.defineProperty(exports, "createSkillTools", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createSkillTools; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createSkillTools; } | ||
| }); | ||
| Object.defineProperty(exports, "createWorkspaceTools", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.createWorkspaceTools; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.createWorkspaceTools; } | ||
| }); | ||
| Object.defineProperty(exports, "deleteFileTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.deleteFileTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.deleteFileTool; } | ||
| }); | ||
| Object.defineProperty(exports, "detectIsolation", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.detectIsolation; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.detectIsolation; } | ||
| }); | ||
| Object.defineProperty(exports, "editFileTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.editFileTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.editFileTool; } | ||
| }); | ||
| Object.defineProperty(exports, "executeCommandTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.executeCommandTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.executeCommandTool; } | ||
| }); | ||
| Object.defineProperty(exports, "fileStatTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.fileStatTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.fileStatTool; } | ||
| }); | ||
| Object.defineProperty(exports, "formatSkillActivation", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.formatSkillActivation; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.formatSkillActivation; } | ||
| }); | ||
| Object.defineProperty(exports, "getRecommendedIsolation", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.getRecommendedIsolation; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.getRecommendedIsolation; } | ||
| }); | ||
| Object.defineProperty(exports, "indexContentTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.indexContentTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.indexContentTool; } | ||
| }); | ||
| Object.defineProperty(exports, "isIsolationAvailable", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.isIsolationAvailable; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.isIsolationAvailable; } | ||
| }); | ||
| Object.defineProperty(exports, "listFilesTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.listFilesTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.listFilesTool; } | ||
| }); | ||
| Object.defineProperty(exports, "mkdirTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.mkdirTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.mkdirTool; } | ||
| }); | ||
| Object.defineProperty(exports, "publishSkillFromSource", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.publishSkillFromSource; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.publishSkillFromSource; } | ||
| }); | ||
| Object.defineProperty(exports, "readFileTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.readFileTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.readFileTool; } | ||
| }); | ||
| Object.defineProperty(exports, "requireFilesystem", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.requireFilesystem; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.requireFilesystem; } | ||
| }); | ||
| Object.defineProperty(exports, "requireSandbox", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.requireSandbox; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.requireSandbox; } | ||
| }); | ||
| Object.defineProperty(exports, "requireWorkspace", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.requireWorkspace; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.requireWorkspace; } | ||
| }); | ||
| Object.defineProperty(exports, "resolveToolConfig", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.resolveToolConfig; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.resolveToolConfig; } | ||
| }); | ||
| Object.defineProperty(exports, "searchTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.searchTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.searchTool; } | ||
| }); | ||
| Object.defineProperty(exports, "writeFileTool", { | ||
| enumerable: true, | ||
| get: function () { return chunkGSWZYCY4_cjs.writeFileTool; } | ||
| get: function () { return chunkQJ3FDYCK_cjs.writeFileTool; } | ||
| }); | ||
@@ -185,0 +185,0 @@ Object.defineProperty(exports, "DirectoryNotEmptyError", { |
@@ -1,4 +0,4 @@ | ||
| export { CompositeFilesystem, CompositeVersionedSkillSource, FilesystemNotMountableError, IsolationUnavailableError, LocalFilesystem, LocalSandbox, MastraFilesystem, MastraSandbox, MountError, MountManager, MountNotSupportedError, ProcessHandle, SandboxError, SandboxExecutionError, SandboxNotReadyError, SandboxProcessManager, SandboxTimeoutError, VersionedSkillSource, WORKSPACE_TOOLS, WORKSPACE_TOOLS_PREFIX, Workspace, callLifecycle, collectSkillForPublish, createSkillTools, createWorkspaceTools, deleteFileTool, detectIsolation, editFileTool, executeCommandTool, fileStatTool, formatSkillActivation, getRecommendedIsolation, indexContentTool, isIsolationAvailable, listFilesTool, mkdirTool, publishSkillFromSource, readFileTool, requireFilesystem, requireSandbox, requireWorkspace, resolveToolConfig, searchTool, writeFileTool } from '../chunk-MVA25X63.js'; | ||
| export { CompositeFilesystem, CompositeVersionedSkillSource, FilesystemNotMountableError, IsolationUnavailableError, LocalFilesystem, LocalSandbox, MastraFilesystem, MastraSandbox, MountError, MountManager, MountNotSupportedError, ProcessHandle, SandboxError, SandboxExecutionError, SandboxNotReadyError, SandboxProcessManager, SandboxTimeoutError, VersionedSkillSource, WORKSPACE_TOOLS, WORKSPACE_TOOLS_PREFIX, Workspace, callLifecycle, collectSkillForPublish, createSkillTools, createWorkspaceTools, deleteFileTool, detectIsolation, editFileTool, executeCommandTool, fileStatTool, formatSkillActivation, getRecommendedIsolation, indexContentTool, isIsolationAvailable, listFilesTool, mkdirTool, publishSkillFromSource, readFileTool, requireFilesystem, requireSandbox, requireWorkspace, resolveToolConfig, searchTool, writeFileTool } from '../chunk-PQ5PN4TW.js'; | ||
| export { DirectoryNotEmptyError, DirectoryNotFoundError, FileExistsError, FileNotFoundError, FileReadRequiredError, FilesystemError, FilesystemNotAvailableError, FilesystemNotReadyError, IsDirectoryError, LocalSkillSource, NotDirectoryError, PermissionError, SandboxFeatureNotSupportedError, SandboxNotAvailableError, SearchNotAvailableError, StaleFileError, WorkspaceError, WorkspaceNotAvailableError, WorkspaceNotReadyError, WorkspaceReadOnlyError, createGlobMatcher, extractGlobBase, isGlobPattern, matchGlob } from '../chunk-TY5V5RIZ.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
+13
-13
| { | ||
| "name": "@mastra/core", | ||
| "version": "1.48.0-alpha.10", | ||
| "version": "1.48.0", | ||
| "license": "Apache-2.0", | ||
@@ -849,3 +849,3 @@ "type": "module", | ||
| "xxhash-wasm": "^1.1.0", | ||
| "@mastra/schema-compat": "1.3.2-alpha.1" | ||
| "@mastra/schema-compat": "1.3.2" | ||
| }, | ||
@@ -908,14 +908,14 @@ "peerDependencies": { | ||
| "zod": "^4.4.3", | ||
| "@internal/ai-sdk-v4": "0.0.56", | ||
| "@internal/ai-v6": "0.0.56", | ||
| "@internal/ai-sdk-v5": "0.0.56", | ||
| "@internal/ai-v7": "0.0.56", | ||
| "@internal/auth": "0.0.1", | ||
| "@internal/ai-sdk-v4": "0.0.57", | ||
| "@internal/ai-v6": "0.0.57", | ||
| "@internal/ai-sdk-v5": "0.0.57", | ||
| "@internal/ai-v7": "0.0.57", | ||
| "@internal/auth": "0.0.2", | ||
| "@internal/core": "0.1.0", | ||
| "@internal/external-types": "0.0.59", | ||
| "@internal/lint": "0.0.109", | ||
| "@internal/test-utils": "0.0.45", | ||
| "@internal/llm-recorder": "0.0.45", | ||
| "@internal/types-builder": "0.0.84", | ||
| "@internal/voice": "0.0.9" | ||
| "@internal/lint": "0.0.110", | ||
| "@internal/test-utils": "0.0.46", | ||
| "@internal/external-types": "0.0.60", | ||
| "@internal/llm-recorder": "0.0.46", | ||
| "@internal/types-builder": "0.0.85", | ||
| "@internal/voice": "0.0.10" | ||
| }, | ||
@@ -922,0 +922,0 @@ "engines": { |
| import { VersionedStorageDomain, normalizePerPage, calculatePagination, FilesystemVersionedHelpers } from './chunk-SKZRHFF3.js'; | ||
| import { deepEqual } from './chunk-MVLICRVY.js'; | ||
| // src/storage/domains/workspaces/base.ts | ||
| var WorkspacesStorage = class extends VersionedStorageDomain { | ||
| listKey = "workspaces"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "workspaceId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "WORKSPACES" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/workspaces/inmemory.ts | ||
| var InMemoryWorkspacesStorage = class extends WorkspacesStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.workspaces.clear(); | ||
| this.db.workspaceVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Workspace CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const config = this.db.workspaces.get(id); | ||
| return config ? this.deepCopyConfig(config) : null; | ||
| } | ||
| async create(input) { | ||
| const { workspace } = input; | ||
| if (this.db.workspaces.has(workspace.id)) { | ||
| throw new Error(`Workspace with id ${workspace.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newConfig = { | ||
| id: workspace.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: workspace.authorId, | ||
| metadata: workspace.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.workspaces.set(workspace.id, newConfig); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| workspaceId: workspace.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyConfig(newConfig); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingConfig = this.db.workspaces.get(id); | ||
| if (!existingConfig) { | ||
| throw new Error(`Workspace with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status, ...rawConfigFields } = updates; | ||
| const configFields = {}; | ||
| for (const [key, value] of Object.entries(rawConfigFields)) { | ||
| if (value !== void 0) configFields[key] = value; | ||
| } | ||
| const configFieldNames = [ | ||
| "name", | ||
| "description", | ||
| "filesystem", | ||
| "sandbox", | ||
| "mounts", | ||
| "search", | ||
| "skills", | ||
| "tools", | ||
| "autoSync", | ||
| "operationTimeout" | ||
| ]; | ||
| const hasConfigUpdate = configFieldNames.some((field) => field in configFields); | ||
| const updatedConfig = { | ||
| ...existingConfig, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingConfig.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| if (activeVersionId !== void 0 && status === void 0) { | ||
| updatedConfig.status = "published"; | ||
| } | ||
| if (hasConfigUpdate) { | ||
| const latestVersion = await this.getLatestVersion(id); | ||
| if (!latestVersion) { | ||
| throw new Error(`No versions found for workspace ${id}`); | ||
| } | ||
| const { | ||
| id: _versionId, | ||
| workspaceId: _workspaceId, | ||
| versionNumber: _versionNumber, | ||
| changedFields: _changedFields, | ||
| changeMessage: _changeMessage, | ||
| createdAt: _createdAt, | ||
| ...latestConfig | ||
| } = latestVersion; | ||
| const newConfig = { | ||
| ...latestConfig, | ||
| ...configFields | ||
| }; | ||
| const changedFields = configFieldNames.filter( | ||
| (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field]) | ||
| ); | ||
| if (changedFields.length > 0) { | ||
| const newVersionId = crypto.randomUUID(); | ||
| const newVersionNumber = latestVersion.versionNumber + 1; | ||
| await this.createVersion({ | ||
| id: newVersionId, | ||
| workspaceId: id, | ||
| versionNumber: newVersionNumber, | ||
| ...newConfig, | ||
| changedFields, | ||
| changeMessage: `Updated ${changedFields.join(", ")}` | ||
| }); | ||
| } | ||
| } | ||
| this.db.workspaces.set(id, updatedConfig); | ||
| return this.deepCopyConfig(updatedConfig); | ||
| } | ||
| async delete(id) { | ||
| this.db.workspaces.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let configs = Array.from(this.db.workspaces.values()); | ||
| if (authorId !== void 0) { | ||
| configs = configs.filter((config) => config.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| configs = configs.filter((config) => { | ||
| if (!config.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedConfigs = this.sortConfigs(configs, field, direction); | ||
| const clonedConfigs = sortedConfigs.map((config) => this.deepCopyConfig(config)); | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| workspaces: clonedConfigs.slice(offset, offset + perPage), | ||
| total: clonedConfigs.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedConfigs.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Workspace Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.workspaceVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.workspaceVersions.values()) { | ||
| if (version2.workspaceId === input.workspaceId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for workspace ${input.workspaceId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.workspaceVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.workspaceVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(workspaceId, versionNumber) { | ||
| for (const version of this.db.workspaceVersions.values()) { | ||
| if (version.workspaceId === workspaceId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(workspaceId) { | ||
| let latest = null; | ||
| for (const version of this.db.workspaceVersions.values()) { | ||
| if (version.workspaceId === workspaceId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { workspaceId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.workspaceVersions.values()).filter((v) => v.workspaceId === workspaceId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.workspaceVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.workspaceVersions.entries()) { | ||
| if (version.workspaceId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.workspaceVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(workspaceId) { | ||
| let count = 0; | ||
| for (const version of this.db.workspaceVersions.values()) { | ||
| if (version.workspaceId === workspaceId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyConfig(config) { | ||
| return { | ||
| ...config, | ||
| metadata: config.metadata ? { ...config.metadata } : config.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return structuredClone(version); | ||
| } | ||
| sortConfigs(configs, field, direction) { | ||
| return configs.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/workspaces/filesystem.ts | ||
| var FilesystemWorkspacesStorage = class extends WorkspacesStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "workspaces.json", | ||
| parentIdField: "workspaceId", | ||
| name: "FilesystemWorkspacesStorage", | ||
| versionMetadataFields: ["id", "workspaceId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { workspace } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: workspace.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: workspace.authorId, | ||
| metadata: workspace.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(workspace.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| workspaceId: workspace.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "workspaces", | ||
| filters: { authorId, metadata } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(workspaceId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(workspaceId, versionNumber); | ||
| } | ||
| async getLatestVersion(workspaceId) { | ||
| return this.helpers.getLatestVersion(workspaceId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "workspaceId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(workspaceId) { | ||
| return this.helpers.countVersions(workspaceId); | ||
| } | ||
| }; | ||
| export { FilesystemWorkspacesStorage, InMemoryWorkspacesStorage, WorkspacesStorage }; | ||
| //# sourceMappingURL=chunk-4JHST2EN.js.map | ||
| //# sourceMappingURL=chunk-4JHST2EN.js.map |
| {"version":3,"sources":["../src/storage/domains/workspaces/base.ts","../src/storage/domains/workspaces/inmemory.ts","../src/storage/domains/workspaces/filesystem.ts"],"names":["version"],"mappings":"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","file":"chunk-4JHST2EN.js","sourcesContent":["import type {\n StorageWorkspaceType,\n StorageWorkspaceSnapshotType,\n StorageResolvedWorkspaceType,\n StorageCreateWorkspaceInput,\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput,\n StorageListWorkspacesOutput,\n StorageListWorkspacesResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// Workspace Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of a workspace's configuration.\n * Config fields are top-level on the version row (no nested snapshot object).\n */\nexport interface WorkspaceVersion extends StorageWorkspaceSnapshotType, VersionBase {\n /** ID of the workspace this version belongs to */\n workspaceId: string;\n}\n\n/**\n * Input for creating a new workspace version.\n * Config fields are top-level (no nested snapshot object).\n */\nexport interface CreateWorkspaceVersionInput extends StorageWorkspaceSnapshotType, CreateVersionInputBase {\n /** ID of the workspace this version belongs to */\n workspaceId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type WorkspaceVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type WorkspaceVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing workspace versions with pagination and sorting.\n */\nexport interface ListWorkspaceVersionsInput extends ListVersionsInputBase {\n /** ID of the workspace to list versions for */\n workspaceId: string;\n}\n\n/**\n * Output for listing workspace versions with pagination info.\n */\nexport interface ListWorkspaceVersionsOutput extends ListVersionsOutputBase<WorkspaceVersion> {}\n\n// ============================================================================\n// WorkspacesStorage Base Class\n// ============================================================================\n\nexport abstract class WorkspacesStorage extends VersionedStorageDomain<\n StorageWorkspaceType,\n StorageWorkspaceSnapshotType,\n StorageResolvedWorkspaceType,\n WorkspaceVersion,\n CreateWorkspaceVersionInput,\n ListWorkspaceVersionsInput,\n ListWorkspaceVersionsOutput,\n { workspace: StorageCreateWorkspaceInput },\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput | undefined,\n StorageListWorkspacesOutput,\n StorageListWorkspacesResolvedOutput\n> {\n protected readonly listKey = 'workspaces';\n protected readonly versionMetadataFields = [\n 'id',\n 'workspaceId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof WorkspaceVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'WORKSPACES',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageWorkspaceType,\n StorageCreateWorkspaceInput,\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput,\n StorageListWorkspacesOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n WorkspaceVersion,\n CreateWorkspaceVersionInput,\n ListWorkspaceVersionsInput,\n ListWorkspaceVersionsOutput,\n WorkspaceVersionOrderBy,\n WorkspaceVersionSortDirection,\n} from './base';\nimport { WorkspacesStorage } from './base';\n\nexport class InMemoryWorkspacesStorage extends WorkspacesStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.workspaces.clear();\n this.db.workspaceVersions.clear();\n }\n\n // ==========================================================================\n // Workspace CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageWorkspaceType | null> {\n const config = this.db.workspaces.get(id);\n return config ? this.deepCopyConfig(config) : null;\n }\n\n async create(input: { workspace: StorageCreateWorkspaceInput }): Promise<StorageWorkspaceType> {\n const { workspace } = input;\n\n if (this.db.workspaces.has(workspace.id)) {\n throw new Error(`Workspace with id ${workspace.id} already exists`);\n }\n\n const now = new Date();\n const newConfig: StorageWorkspaceType = {\n id: workspace.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: workspace.authorId,\n metadata: workspace.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.workspaces.set(workspace.id, newConfig);\n\n // Extract config fields from the flat input (everything except record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n workspaceId: workspace.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin record\n return this.deepCopyConfig(newConfig);\n }\n\n async update(input: StorageUpdateWorkspaceInput): Promise<StorageWorkspaceType> {\n const { id, ...updates } = input;\n\n const existingConfig = this.db.workspaces.get(id);\n if (!existingConfig) {\n throw new Error(`Workspace with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status, ...rawConfigFields } = updates;\n\n // Strip undefined keys so omitted PATCH fields don't overwrite persisted values\n const configFields: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(rawConfigFields)) {\n if (value !== undefined) configFields[key] = value;\n }\n\n // Config field names from StorageWorkspaceSnapshotType\n const configFieldNames = [\n 'name',\n 'description',\n 'filesystem',\n 'sandbox',\n 'mounts',\n 'search',\n 'skills',\n 'tools',\n 'autoSync',\n 'operationTimeout',\n ];\n\n // Check if any config fields are present in the update\n const hasConfigUpdate = configFieldNames.some(field => field in configFields);\n\n // Update metadata fields on the record\n const updatedConfig: StorageWorkspaceType = {\n ...existingConfig,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageWorkspaceType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingConfig.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Auto-set status to 'published' when activeVersionId is set, only if status is not explicitly provided\n if (activeVersionId !== undefined && status === undefined) {\n updatedConfig.status = 'published';\n }\n\n // If config fields are being updated, create a new version\n if (hasConfigUpdate) {\n // Get the latest version to use as base\n const latestVersion = await this.getLatestVersion(id);\n if (!latestVersion) {\n throw new Error(`No versions found for workspace ${id}`);\n }\n\n // Extract config from latest version\n const {\n id: _versionId,\n workspaceId: _workspaceId,\n versionNumber: _versionNumber,\n changedFields: _changedFields,\n changeMessage: _changeMessage,\n createdAt: _createdAt,\n ...latestConfig\n } = latestVersion;\n\n // Merge updates into latest config\n const newConfig = {\n ...latestConfig,\n ...configFields,\n };\n\n // Identify which fields changed\n const changedFields = configFieldNames.filter(\n field =>\n field in configFields &&\n JSON.stringify(configFields[field as keyof typeof configFields]) !==\n JSON.stringify(latestConfig[field as keyof typeof latestConfig]),\n );\n\n // Only create a new version if something actually changed\n if (changedFields.length > 0) {\n const newVersionId = crypto.randomUUID();\n const newVersionNumber = latestVersion.versionNumber + 1;\n\n await this.createVersion({\n id: newVersionId,\n workspaceId: id,\n versionNumber: newVersionNumber,\n ...newConfig,\n changedFields,\n changeMessage: `Updated ${changedFields.join(', ')}`,\n });\n }\n }\n\n // Save the updated record\n this.db.workspaces.set(id, updatedConfig);\n return this.deepCopyConfig(updatedConfig);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.workspaces.delete(id);\n // Also delete all versions for this workspace\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListWorkspacesInput): Promise<StorageListWorkspacesOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all workspaces and apply filters\n let configs = Array.from(this.db.workspaces.values());\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n configs = configs.filter(config => config.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n configs = configs.filter(config => {\n if (!config.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata![key], value));\n });\n }\n\n // Sort filtered configs\n const sortedConfigs = this.sortConfigs(configs, field, direction);\n\n // Deep clone to avoid mutation\n const clonedConfigs = sortedConfigs.map(config => this.deepCopyConfig(config));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n workspaces: clonedConfigs.slice(offset, offset + perPage),\n total: clonedConfigs.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedConfigs.length,\n };\n }\n\n // ==========================================================================\n // Workspace Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateWorkspaceVersionInput): Promise<WorkspaceVersion> {\n // Check if version with this ID already exists\n if (this.db.workspaceVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (workspaceId, versionNumber) pair\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === input.workspaceId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for workspace ${input.workspaceId}`);\n }\n }\n\n const version: WorkspaceVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.workspaceVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<WorkspaceVersion | null> {\n const version = this.db.workspaceVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(workspaceId: string, versionNumber: number): Promise<WorkspaceVersion | null> {\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === workspaceId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(workspaceId: string): Promise<WorkspaceVersion | null> {\n let latest: WorkspaceVersion | null = null;\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === workspaceId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListWorkspaceVersionsInput): Promise<ListWorkspaceVersionsOutput> {\n const { workspaceId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by workspaceId\n let versions = Array.from(this.db.workspaceVersions.values()).filter(v => v.workspaceId === workspaceId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.workspaceVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.workspaceVersions.entries()) {\n if (version.workspaceId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.workspaceVersions.delete(id);\n }\n }\n\n async countVersions(workspaceId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === workspaceId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyConfig(config: StorageWorkspaceType): StorageWorkspaceType {\n return {\n ...config,\n metadata: config.metadata ? { ...config.metadata } : config.metadata,\n };\n }\n\n private deepCopyVersion(version: WorkspaceVersion): WorkspaceVersion {\n return structuredClone(version);\n }\n\n private sortConfigs(\n configs: StorageWorkspaceType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageWorkspaceType[] {\n return configs.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: WorkspaceVersion[],\n field: WorkspaceVersionOrderBy,\n direction: WorkspaceVersionSortDirection,\n ): WorkspaceVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageWorkspaceType,\n StorageCreateWorkspaceInput,\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput,\n StorageListWorkspacesOutput,\n} from '../../types';\nimport type {\n WorkspaceVersion,\n CreateWorkspaceVersionInput,\n ListWorkspaceVersionsInput,\n ListWorkspaceVersionsOutput,\n} from './base';\nimport { WorkspacesStorage } from './base';\n\nexport class FilesystemWorkspacesStorage extends WorkspacesStorage {\n private helpers: FilesystemVersionedHelpers<StorageWorkspaceType, WorkspaceVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'workspaces.json',\n parentIdField: 'workspaceId',\n name: 'FilesystemWorkspacesStorage',\n versionMetadataFields: ['id', 'workspaceId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageWorkspaceType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { workspace: StorageCreateWorkspaceInput }): Promise<StorageWorkspaceType> {\n const { workspace } = input;\n const now = new Date();\n const entity: StorageWorkspaceType = {\n id: workspace.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: workspace.authorId,\n metadata: workspace.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(workspace.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n workspaceId: workspace.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateWorkspaceVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateWorkspaceInput): Promise<StorageWorkspaceType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListWorkspacesInput): Promise<StorageListWorkspacesOutput> {\n const { page, perPage, orderBy, authorId, metadata } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'workspaces',\n filters: { authorId, metadata },\n });\n return result as unknown as StorageListWorkspacesOutput;\n }\n\n async createVersion(input: CreateWorkspaceVersionInput): Promise<WorkspaceVersion> {\n return this.helpers.createVersion(input as WorkspaceVersion);\n }\n\n async getVersion(id: string): Promise<WorkspaceVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(workspaceId: string, versionNumber: number): Promise<WorkspaceVersion | null> {\n return this.helpers.getVersionByNumber(workspaceId, versionNumber);\n }\n\n async getLatestVersion(workspaceId: string): Promise<WorkspaceVersion | null> {\n return this.helpers.getLatestVersion(workspaceId);\n }\n\n async listVersions(input: ListWorkspaceVersionsInput): Promise<ListWorkspaceVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'workspaceId');\n return result as ListWorkspaceVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(workspaceId: string): Promise<number> {\n return this.helpers.countVersions(workspaceId);\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunk2UAP4LDC_cjs = require('./chunk-2UAP4LDC.cjs'); | ||
| var chunkB3SPPQQ3_cjs = require('./chunk-B3SPPQQ3.cjs'); | ||
| // src/storage/domains/workspaces/base.ts | ||
| var WorkspacesStorage = class extends chunk2UAP4LDC_cjs.VersionedStorageDomain { | ||
| listKey = "workspaces"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "workspaceId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "WORKSPACES" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/workspaces/inmemory.ts | ||
| var InMemoryWorkspacesStorage = class extends WorkspacesStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.workspaces.clear(); | ||
| this.db.workspaceVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Workspace CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const config = this.db.workspaces.get(id); | ||
| return config ? this.deepCopyConfig(config) : null; | ||
| } | ||
| async create(input) { | ||
| const { workspace } = input; | ||
| if (this.db.workspaces.has(workspace.id)) { | ||
| throw new Error(`Workspace with id ${workspace.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newConfig = { | ||
| id: workspace.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: workspace.authorId, | ||
| metadata: workspace.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.workspaces.set(workspace.id, newConfig); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| workspaceId: workspace.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyConfig(newConfig); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingConfig = this.db.workspaces.get(id); | ||
| if (!existingConfig) { | ||
| throw new Error(`Workspace with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status, ...rawConfigFields } = updates; | ||
| const configFields = {}; | ||
| for (const [key, value] of Object.entries(rawConfigFields)) { | ||
| if (value !== void 0) configFields[key] = value; | ||
| } | ||
| const configFieldNames = [ | ||
| "name", | ||
| "description", | ||
| "filesystem", | ||
| "sandbox", | ||
| "mounts", | ||
| "search", | ||
| "skills", | ||
| "tools", | ||
| "autoSync", | ||
| "operationTimeout" | ||
| ]; | ||
| const hasConfigUpdate = configFieldNames.some((field) => field in configFields); | ||
| const updatedConfig = { | ||
| ...existingConfig, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingConfig.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| if (activeVersionId !== void 0 && status === void 0) { | ||
| updatedConfig.status = "published"; | ||
| } | ||
| if (hasConfigUpdate) { | ||
| const latestVersion = await this.getLatestVersion(id); | ||
| if (!latestVersion) { | ||
| throw new Error(`No versions found for workspace ${id}`); | ||
| } | ||
| const { | ||
| id: _versionId, | ||
| workspaceId: _workspaceId, | ||
| versionNumber: _versionNumber, | ||
| changedFields: _changedFields, | ||
| changeMessage: _changeMessage, | ||
| createdAt: _createdAt, | ||
| ...latestConfig | ||
| } = latestVersion; | ||
| const newConfig = { | ||
| ...latestConfig, | ||
| ...configFields | ||
| }; | ||
| const changedFields = configFieldNames.filter( | ||
| (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field]) | ||
| ); | ||
| if (changedFields.length > 0) { | ||
| const newVersionId = crypto.randomUUID(); | ||
| const newVersionNumber = latestVersion.versionNumber + 1; | ||
| await this.createVersion({ | ||
| id: newVersionId, | ||
| workspaceId: id, | ||
| versionNumber: newVersionNumber, | ||
| ...newConfig, | ||
| changedFields, | ||
| changeMessage: `Updated ${changedFields.join(", ")}` | ||
| }); | ||
| } | ||
| } | ||
| this.db.workspaces.set(id, updatedConfig); | ||
| return this.deepCopyConfig(updatedConfig); | ||
| } | ||
| async delete(id) { | ||
| this.db.workspaces.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let configs = Array.from(this.db.workspaces.values()); | ||
| if (authorId !== void 0) { | ||
| configs = configs.filter((config) => config.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| configs = configs.filter((config) => { | ||
| if (!config.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => chunkB3SPPQQ3_cjs.deepEqual(config.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedConfigs = this.sortConfigs(configs, field, direction); | ||
| const clonedConfigs = sortedConfigs.map((config) => this.deepCopyConfig(config)); | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| workspaces: clonedConfigs.slice(offset, offset + perPage), | ||
| total: clonedConfigs.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedConfigs.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Workspace Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.workspaceVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.workspaceVersions.values()) { | ||
| if (version2.workspaceId === input.workspaceId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for workspace ${input.workspaceId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.workspaceVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.workspaceVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(workspaceId, versionNumber) { | ||
| for (const version of this.db.workspaceVersions.values()) { | ||
| if (version.workspaceId === workspaceId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(workspaceId) { | ||
| let latest = null; | ||
| for (const version of this.db.workspaceVersions.values()) { | ||
| if (version.workspaceId === workspaceId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { workspaceId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.workspaceVersions.values()).filter((v) => v.workspaceId === workspaceId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.workspaceVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.workspaceVersions.entries()) { | ||
| if (version.workspaceId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.workspaceVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(workspaceId) { | ||
| let count = 0; | ||
| for (const version of this.db.workspaceVersions.values()) { | ||
| if (version.workspaceId === workspaceId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyConfig(config) { | ||
| return { | ||
| ...config, | ||
| metadata: config.metadata ? { ...config.metadata } : config.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return structuredClone(version); | ||
| } | ||
| sortConfigs(configs, field, direction) { | ||
| return configs.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/workspaces/filesystem.ts | ||
| var FilesystemWorkspacesStorage = class extends WorkspacesStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new chunk2UAP4LDC_cjs.FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "workspaces.json", | ||
| parentIdField: "workspaceId", | ||
| name: "FilesystemWorkspacesStorage", | ||
| versionMetadataFields: ["id", "workspaceId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { workspace } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: workspace.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: workspace.authorId, | ||
| metadata: workspace.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(workspace.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| workspaceId: workspace.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "workspaces", | ||
| filters: { authorId, metadata } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(workspaceId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(workspaceId, versionNumber); | ||
| } | ||
| async getLatestVersion(workspaceId) { | ||
| return this.helpers.getLatestVersion(workspaceId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "workspaceId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(workspaceId) { | ||
| return this.helpers.countVersions(workspaceId); | ||
| } | ||
| }; | ||
| exports.FilesystemWorkspacesStorage = FilesystemWorkspacesStorage; | ||
| exports.InMemoryWorkspacesStorage = InMemoryWorkspacesStorage; | ||
| exports.WorkspacesStorage = WorkspacesStorage; | ||
| //# sourceMappingURL=chunk-64LOMCAH.cjs.map | ||
| //# sourceMappingURL=chunk-64LOMCAH.cjs.map |
| {"version":3,"sources":["../src/storage/domains/workspaces/base.ts","../src/storage/domains/workspaces/inmemory.ts","../src/storage/domains/workspaces/filesystem.ts"],"names":["VersionedStorageDomain","normalizePerPage","deepEqual","calculatePagination","version","FilesystemVersionedHelpers"],"mappings":"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","file":"chunk-64LOMCAH.cjs","sourcesContent":["import type {\n StorageWorkspaceType,\n StorageWorkspaceSnapshotType,\n StorageResolvedWorkspaceType,\n StorageCreateWorkspaceInput,\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput,\n StorageListWorkspacesOutput,\n StorageListWorkspacesResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// Workspace Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of a workspace's configuration.\n * Config fields are top-level on the version row (no nested snapshot object).\n */\nexport interface WorkspaceVersion extends StorageWorkspaceSnapshotType, VersionBase {\n /** ID of the workspace this version belongs to */\n workspaceId: string;\n}\n\n/**\n * Input for creating a new workspace version.\n * Config fields are top-level (no nested snapshot object).\n */\nexport interface CreateWorkspaceVersionInput extends StorageWorkspaceSnapshotType, CreateVersionInputBase {\n /** ID of the workspace this version belongs to */\n workspaceId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type WorkspaceVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type WorkspaceVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing workspace versions with pagination and sorting.\n */\nexport interface ListWorkspaceVersionsInput extends ListVersionsInputBase {\n /** ID of the workspace to list versions for */\n workspaceId: string;\n}\n\n/**\n * Output for listing workspace versions with pagination info.\n */\nexport interface ListWorkspaceVersionsOutput extends ListVersionsOutputBase<WorkspaceVersion> {}\n\n// ============================================================================\n// WorkspacesStorage Base Class\n// ============================================================================\n\nexport abstract class WorkspacesStorage extends VersionedStorageDomain<\n StorageWorkspaceType,\n StorageWorkspaceSnapshotType,\n StorageResolvedWorkspaceType,\n WorkspaceVersion,\n CreateWorkspaceVersionInput,\n ListWorkspaceVersionsInput,\n ListWorkspaceVersionsOutput,\n { workspace: StorageCreateWorkspaceInput },\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput | undefined,\n StorageListWorkspacesOutput,\n StorageListWorkspacesResolvedOutput\n> {\n protected readonly listKey = 'workspaces';\n protected readonly versionMetadataFields = [\n 'id',\n 'workspaceId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof WorkspaceVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'WORKSPACES',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageWorkspaceType,\n StorageCreateWorkspaceInput,\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput,\n StorageListWorkspacesOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n WorkspaceVersion,\n CreateWorkspaceVersionInput,\n ListWorkspaceVersionsInput,\n ListWorkspaceVersionsOutput,\n WorkspaceVersionOrderBy,\n WorkspaceVersionSortDirection,\n} from './base';\nimport { WorkspacesStorage } from './base';\n\nexport class InMemoryWorkspacesStorage extends WorkspacesStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.workspaces.clear();\n this.db.workspaceVersions.clear();\n }\n\n // ==========================================================================\n // Workspace CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageWorkspaceType | null> {\n const config = this.db.workspaces.get(id);\n return config ? this.deepCopyConfig(config) : null;\n }\n\n async create(input: { workspace: StorageCreateWorkspaceInput }): Promise<StorageWorkspaceType> {\n const { workspace } = input;\n\n if (this.db.workspaces.has(workspace.id)) {\n throw new Error(`Workspace with id ${workspace.id} already exists`);\n }\n\n const now = new Date();\n const newConfig: StorageWorkspaceType = {\n id: workspace.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: workspace.authorId,\n metadata: workspace.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.workspaces.set(workspace.id, newConfig);\n\n // Extract config fields from the flat input (everything except record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n workspaceId: workspace.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin record\n return this.deepCopyConfig(newConfig);\n }\n\n async update(input: StorageUpdateWorkspaceInput): Promise<StorageWorkspaceType> {\n const { id, ...updates } = input;\n\n const existingConfig = this.db.workspaces.get(id);\n if (!existingConfig) {\n throw new Error(`Workspace with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status, ...rawConfigFields } = updates;\n\n // Strip undefined keys so omitted PATCH fields don't overwrite persisted values\n const configFields: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(rawConfigFields)) {\n if (value !== undefined) configFields[key] = value;\n }\n\n // Config field names from StorageWorkspaceSnapshotType\n const configFieldNames = [\n 'name',\n 'description',\n 'filesystem',\n 'sandbox',\n 'mounts',\n 'search',\n 'skills',\n 'tools',\n 'autoSync',\n 'operationTimeout',\n ];\n\n // Check if any config fields are present in the update\n const hasConfigUpdate = configFieldNames.some(field => field in configFields);\n\n // Update metadata fields on the record\n const updatedConfig: StorageWorkspaceType = {\n ...existingConfig,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageWorkspaceType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingConfig.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Auto-set status to 'published' when activeVersionId is set, only if status is not explicitly provided\n if (activeVersionId !== undefined && status === undefined) {\n updatedConfig.status = 'published';\n }\n\n // If config fields are being updated, create a new version\n if (hasConfigUpdate) {\n // Get the latest version to use as base\n const latestVersion = await this.getLatestVersion(id);\n if (!latestVersion) {\n throw new Error(`No versions found for workspace ${id}`);\n }\n\n // Extract config from latest version\n const {\n id: _versionId,\n workspaceId: _workspaceId,\n versionNumber: _versionNumber,\n changedFields: _changedFields,\n changeMessage: _changeMessage,\n createdAt: _createdAt,\n ...latestConfig\n } = latestVersion;\n\n // Merge updates into latest config\n const newConfig = {\n ...latestConfig,\n ...configFields,\n };\n\n // Identify which fields changed\n const changedFields = configFieldNames.filter(\n field =>\n field in configFields &&\n JSON.stringify(configFields[field as keyof typeof configFields]) !==\n JSON.stringify(latestConfig[field as keyof typeof latestConfig]),\n );\n\n // Only create a new version if something actually changed\n if (changedFields.length > 0) {\n const newVersionId = crypto.randomUUID();\n const newVersionNumber = latestVersion.versionNumber + 1;\n\n await this.createVersion({\n id: newVersionId,\n workspaceId: id,\n versionNumber: newVersionNumber,\n ...newConfig,\n changedFields,\n changeMessage: `Updated ${changedFields.join(', ')}`,\n });\n }\n }\n\n // Save the updated record\n this.db.workspaces.set(id, updatedConfig);\n return this.deepCopyConfig(updatedConfig);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.workspaces.delete(id);\n // Also delete all versions for this workspace\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListWorkspacesInput): Promise<StorageListWorkspacesOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all workspaces and apply filters\n let configs = Array.from(this.db.workspaces.values());\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n configs = configs.filter(config => config.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n configs = configs.filter(config => {\n if (!config.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata![key], value));\n });\n }\n\n // Sort filtered configs\n const sortedConfigs = this.sortConfigs(configs, field, direction);\n\n // Deep clone to avoid mutation\n const clonedConfigs = sortedConfigs.map(config => this.deepCopyConfig(config));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n workspaces: clonedConfigs.slice(offset, offset + perPage),\n total: clonedConfigs.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedConfigs.length,\n };\n }\n\n // ==========================================================================\n // Workspace Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateWorkspaceVersionInput): Promise<WorkspaceVersion> {\n // Check if version with this ID already exists\n if (this.db.workspaceVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (workspaceId, versionNumber) pair\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === input.workspaceId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for workspace ${input.workspaceId}`);\n }\n }\n\n const version: WorkspaceVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.workspaceVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<WorkspaceVersion | null> {\n const version = this.db.workspaceVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(workspaceId: string, versionNumber: number): Promise<WorkspaceVersion | null> {\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === workspaceId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(workspaceId: string): Promise<WorkspaceVersion | null> {\n let latest: WorkspaceVersion | null = null;\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === workspaceId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListWorkspaceVersionsInput): Promise<ListWorkspaceVersionsOutput> {\n const { workspaceId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by workspaceId\n let versions = Array.from(this.db.workspaceVersions.values()).filter(v => v.workspaceId === workspaceId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.workspaceVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.workspaceVersions.entries()) {\n if (version.workspaceId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.workspaceVersions.delete(id);\n }\n }\n\n async countVersions(workspaceId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.workspaceVersions.values()) {\n if (version.workspaceId === workspaceId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyConfig(config: StorageWorkspaceType): StorageWorkspaceType {\n return {\n ...config,\n metadata: config.metadata ? { ...config.metadata } : config.metadata,\n };\n }\n\n private deepCopyVersion(version: WorkspaceVersion): WorkspaceVersion {\n return structuredClone(version);\n }\n\n private sortConfigs(\n configs: StorageWorkspaceType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageWorkspaceType[] {\n return configs.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: WorkspaceVersion[],\n field: WorkspaceVersionOrderBy,\n direction: WorkspaceVersionSortDirection,\n ): WorkspaceVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageWorkspaceType,\n StorageCreateWorkspaceInput,\n StorageUpdateWorkspaceInput,\n StorageListWorkspacesInput,\n StorageListWorkspacesOutput,\n} from '../../types';\nimport type {\n WorkspaceVersion,\n CreateWorkspaceVersionInput,\n ListWorkspaceVersionsInput,\n ListWorkspaceVersionsOutput,\n} from './base';\nimport { WorkspacesStorage } from './base';\n\nexport class FilesystemWorkspacesStorage extends WorkspacesStorage {\n private helpers: FilesystemVersionedHelpers<StorageWorkspaceType, WorkspaceVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'workspaces.json',\n parentIdField: 'workspaceId',\n name: 'FilesystemWorkspacesStorage',\n versionMetadataFields: ['id', 'workspaceId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageWorkspaceType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { workspace: StorageCreateWorkspaceInput }): Promise<StorageWorkspaceType> {\n const { workspace } = input;\n const now = new Date();\n const entity: StorageWorkspaceType = {\n id: workspace.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: workspace.authorId,\n metadata: workspace.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(workspace.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n workspaceId: workspace.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateWorkspaceVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateWorkspaceInput): Promise<StorageWorkspaceType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListWorkspacesInput): Promise<StorageListWorkspacesOutput> {\n const { page, perPage, orderBy, authorId, metadata } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'workspaces',\n filters: { authorId, metadata },\n });\n return result as unknown as StorageListWorkspacesOutput;\n }\n\n async createVersion(input: CreateWorkspaceVersionInput): Promise<WorkspaceVersion> {\n return this.helpers.createVersion(input as WorkspaceVersion);\n }\n\n async getVersion(id: string): Promise<WorkspaceVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(workspaceId: string, versionNumber: number): Promise<WorkspaceVersion | null> {\n return this.helpers.getVersionByNumber(workspaceId, versionNumber);\n }\n\n async getLatestVersion(workspaceId: string): Promise<WorkspaceVersion | null> {\n return this.helpers.getLatestVersion(workspaceId);\n }\n\n async listVersions(input: ListWorkspaceVersionsInput): Promise<ListWorkspaceVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'workspaceId');\n return result as ListWorkspaceVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(workspaceId: string): Promise<number> {\n return this.helpers.countVersions(workspaceId);\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunk2UAP4LDC_cjs = require('./chunk-2UAP4LDC.cjs'); | ||
| var chunkB3SPPQQ3_cjs = require('./chunk-B3SPPQQ3.cjs'); | ||
| // src/storage/domains/mcp-clients/base.ts | ||
| var MCPClientsStorage = class extends chunk2UAP4LDC_cjs.VersionedStorageDomain { | ||
| listKey = "mcpClients"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "mcpClientId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "MCP_CLIENTS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-clients/inmemory.ts | ||
| var InMemoryMCPClientsStorage = class extends MCPClientsStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.mcpClients.clear(); | ||
| this.db.mcpClientVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // MCP Client CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const config = this.db.mcpClients.get(id); | ||
| return config ? this.deepCopyConfig(config) : null; | ||
| } | ||
| async create(input) { | ||
| const { mcpClient } = input; | ||
| if (this.db.mcpClients.has(mcpClient.id)) { | ||
| throw new Error(`MCP client with id ${mcpClient.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newConfig = { | ||
| id: mcpClient.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpClient.authorId, | ||
| metadata: mcpClient.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.mcpClients.set(mcpClient.id, newConfig); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpClientId: mcpClient.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyConfig(newConfig); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingConfig = this.db.mcpClients.get(id); | ||
| if (!existingConfig) { | ||
| throw new Error(`MCP client with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedConfig = { | ||
| ...existingConfig, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingConfig.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpClients.set(id, updatedConfig); | ||
| return this.deepCopyConfig(updatedConfig); | ||
| } | ||
| async delete(id) { | ||
| this.db.mcpClients.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let configs = Array.from(this.db.mcpClients.values()); | ||
| if (status) { | ||
| configs = configs.filter((config) => config.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| configs = configs.filter((config) => config.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| configs = configs.filter((config) => { | ||
| if (!config.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => chunkB3SPPQQ3_cjs.deepEqual(config.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedConfigs = this.sortConfigs(configs, field, direction); | ||
| const clonedConfigs = sortedConfigs.map((config) => this.deepCopyConfig(config)); | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| mcpClients: clonedConfigs.slice(offset, offset + perPage), | ||
| total: clonedConfigs.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedConfigs.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // MCP Client Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.mcpClientVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.mcpClientVersions.values()) { | ||
| if (version2.mcpClientId === input.mcpClientId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for MCP client ${input.mcpClientId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpClientVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.mcpClientVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(mcpClientId, versionNumber) { | ||
| for (const version of this.db.mcpClientVersions.values()) { | ||
| if (version.mcpClientId === mcpClientId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(mcpClientId) { | ||
| let latest = null; | ||
| for (const version of this.db.mcpClientVersions.values()) { | ||
| if (version.mcpClientId === mcpClientId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { mcpClientId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.mcpClientVersions.values()).filter((v) => v.mcpClientId === mcpClientId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.mcpClientVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.mcpClientVersions.entries()) { | ||
| if (version.mcpClientId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.mcpClientVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(mcpClientId) { | ||
| let count = 0; | ||
| for (const version of this.db.mcpClientVersions.values()) { | ||
| if (version.mcpClientId === mcpClientId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyConfig(config) { | ||
| return { | ||
| ...config, | ||
| metadata: config.metadata ? { ...config.metadata } : config.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| servers: version.servers ? JSON.parse(JSON.stringify(version.servers)) : version.servers, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortConfigs(configs, field, direction) { | ||
| return configs.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-clients/filesystem.ts | ||
| var FilesystemMCPClientsStorage = class extends MCPClientsStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new chunk2UAP4LDC_cjs.FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "mcp-clients.json", | ||
| parentIdField: "mcpClientId", | ||
| name: "FilesystemMCPClientsStorage", | ||
| versionMetadataFields: ["id", "mcpClientId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { mcpClient } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: mcpClient.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpClient.authorId, | ||
| metadata: mcpClient.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(mcpClient.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpClientId: mcpClient.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "mcpClients", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(mcpClientId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(mcpClientId, versionNumber); | ||
| } | ||
| async getLatestVersion(mcpClientId) { | ||
| return this.helpers.getLatestVersion(mcpClientId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "mcpClientId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(mcpClientId) { | ||
| return this.helpers.countVersions(mcpClientId); | ||
| } | ||
| }; | ||
| exports.FilesystemMCPClientsStorage = FilesystemMCPClientsStorage; | ||
| exports.InMemoryMCPClientsStorage = InMemoryMCPClientsStorage; | ||
| exports.MCPClientsStorage = MCPClientsStorage; | ||
| //# sourceMappingURL=chunk-7EDD27SS.cjs.map | ||
| //# sourceMappingURL=chunk-7EDD27SS.cjs.map |
| {"version":3,"sources":["../src/storage/domains/mcp-clients/base.ts","../src/storage/domains/mcp-clients/inmemory.ts","../src/storage/domains/mcp-clients/filesystem.ts"],"names":["VersionedStorageDomain","normalizePerPage","deepEqual","calculatePagination","version","FilesystemVersionedHelpers"],"mappings":"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","file":"chunk-7EDD27SS.cjs","sourcesContent":["import type {\n StorageMCPClientType,\n StorageMCPClientSnapshotType,\n StorageResolvedMCPClientType,\n StorageCreateMCPClientInput,\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput,\n StorageListMCPClientsOutput,\n StorageListMCPClientsResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// MCP Client Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of an MCP client's content.\n * Client fields are top-level on the version row (no nested snapshot object).\n */\nexport interface MCPClientVersion extends StorageMCPClientSnapshotType, VersionBase {\n /** ID of the MCP client this version belongs to */\n mcpClientId: string;\n}\n\n/**\n * Input for creating a new MCP client version.\n * Client fields are top-level (no nested snapshot object).\n */\nexport interface CreateMCPClientVersionInput extends StorageMCPClientSnapshotType, CreateVersionInputBase {\n /** ID of the MCP client this version belongs to */\n mcpClientId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type MCPClientVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type MCPClientVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing MCP client versions with pagination and sorting.\n */\nexport interface ListMCPClientVersionsInput extends ListVersionsInputBase {\n /** ID of the MCP client to list versions for */\n mcpClientId: string;\n}\n\n/**\n * Output for listing MCP client versions with pagination info.\n */\nexport interface ListMCPClientVersionsOutput extends ListVersionsOutputBase<MCPClientVersion> {}\n\n// ============================================================================\n// MCPClientsStorage Base Class\n// ============================================================================\n\nexport abstract class MCPClientsStorage extends VersionedStorageDomain<\n StorageMCPClientType,\n StorageMCPClientSnapshotType,\n StorageResolvedMCPClientType,\n MCPClientVersion,\n CreateMCPClientVersionInput,\n ListMCPClientVersionsInput,\n ListMCPClientVersionsOutput,\n { mcpClient: StorageCreateMCPClientInput },\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput | undefined,\n StorageListMCPClientsOutput,\n StorageListMCPClientsResolvedOutput\n> {\n protected readonly listKey = 'mcpClients';\n protected readonly versionMetadataFields = [\n 'id',\n 'mcpClientId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof MCPClientVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'MCP_CLIENTS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageMCPClientType,\n StorageCreateMCPClientInput,\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput,\n StorageListMCPClientsOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n MCPClientVersion,\n CreateMCPClientVersionInput,\n ListMCPClientVersionsInput,\n ListMCPClientVersionsOutput,\n MCPClientVersionOrderBy,\n MCPClientVersionSortDirection,\n} from './base';\nimport { MCPClientsStorage } from './base';\n\nexport class InMemoryMCPClientsStorage extends MCPClientsStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.mcpClients.clear();\n this.db.mcpClientVersions.clear();\n }\n\n // ==========================================================================\n // MCP Client CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageMCPClientType | null> {\n const config = this.db.mcpClients.get(id);\n return config ? this.deepCopyConfig(config) : null;\n }\n\n async create(input: { mcpClient: StorageCreateMCPClientInput }): Promise<StorageMCPClientType> {\n const { mcpClient } = input;\n\n if (this.db.mcpClients.has(mcpClient.id)) {\n throw new Error(`MCP client with id ${mcpClient.id} already exists`);\n }\n\n const now = new Date();\n const newConfig: StorageMCPClientType = {\n id: mcpClient.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpClient.authorId,\n metadata: mcpClient.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.mcpClients.set(mcpClient.id, newConfig);\n\n // Extract config fields from the flat input (everything except record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpClientId: mcpClient.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin record\n return this.deepCopyConfig(newConfig);\n }\n\n async update(input: StorageUpdateMCPClientInput): Promise<StorageMCPClientType> {\n const { id, ...updates } = input;\n\n const existingConfig = this.db.mcpClients.get(id);\n if (!existingConfig) {\n throw new Error(`MCP client with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the record\n const updatedConfig: StorageMCPClientType = {\n ...existingConfig,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageMCPClientType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingConfig.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated record\n this.db.mcpClients.set(id, updatedConfig);\n return this.deepCopyConfig(updatedConfig);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.mcpClients.delete(id);\n // Also delete all versions for this client\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListMCPClientsInput): Promise<StorageListMCPClientsOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all MCP clients and apply filters\n let configs = Array.from(this.db.mcpClients.values());\n\n // Filter by status\n if (status) {\n configs = configs.filter(config => config.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n configs = configs.filter(config => config.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n configs = configs.filter(config => {\n if (!config.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata![key], value));\n });\n }\n\n // Sort filtered configs\n const sortedConfigs = this.sortConfigs(configs, field, direction);\n\n // Deep clone to avoid mutation\n const clonedConfigs = sortedConfigs.map(config => this.deepCopyConfig(config));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n mcpClients: clonedConfigs.slice(offset, offset + perPage),\n total: clonedConfigs.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedConfigs.length,\n };\n }\n\n // ==========================================================================\n // MCP Client Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateMCPClientVersionInput): Promise<MCPClientVersion> {\n // Check if version with this ID already exists\n if (this.db.mcpClientVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (mcpClientId, versionNumber) pair\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === input.mcpClientId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for MCP client ${input.mcpClientId}`);\n }\n }\n\n const version: MCPClientVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.mcpClientVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<MCPClientVersion | null> {\n const version = this.db.mcpClientVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(mcpClientId: string, versionNumber: number): Promise<MCPClientVersion | null> {\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === mcpClientId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(mcpClientId: string): Promise<MCPClientVersion | null> {\n let latest: MCPClientVersion | null = null;\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === mcpClientId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListMCPClientVersionsInput): Promise<ListMCPClientVersionsOutput> {\n const { mcpClientId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by mcpClientId\n let versions = Array.from(this.db.mcpClientVersions.values()).filter(v => v.mcpClientId === mcpClientId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.mcpClientVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.mcpClientVersions.entries()) {\n if (version.mcpClientId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.mcpClientVersions.delete(id);\n }\n }\n\n async countVersions(mcpClientId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === mcpClientId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyConfig(config: StorageMCPClientType): StorageMCPClientType {\n return {\n ...config,\n metadata: config.metadata ? { ...config.metadata } : config.metadata,\n };\n }\n\n private deepCopyVersion(version: MCPClientVersion): MCPClientVersion {\n return {\n ...version,\n servers: version.servers ? JSON.parse(JSON.stringify(version.servers)) : version.servers,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortConfigs(\n configs: StorageMCPClientType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageMCPClientType[] {\n return configs.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: MCPClientVersion[],\n field: MCPClientVersionOrderBy,\n direction: MCPClientVersionSortDirection,\n ): MCPClientVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageMCPClientType,\n StorageCreateMCPClientInput,\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput,\n StorageListMCPClientsOutput,\n} from '../../types';\nimport type {\n MCPClientVersion,\n CreateMCPClientVersionInput,\n ListMCPClientVersionsInput,\n ListMCPClientVersionsOutput,\n} from './base';\nimport { MCPClientsStorage } from './base';\n\nexport class FilesystemMCPClientsStorage extends MCPClientsStorage {\n private helpers: FilesystemVersionedHelpers<StorageMCPClientType, MCPClientVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'mcp-clients.json',\n parentIdField: 'mcpClientId',\n name: 'FilesystemMCPClientsStorage',\n versionMetadataFields: ['id', 'mcpClientId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageMCPClientType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { mcpClient: StorageCreateMCPClientInput }): Promise<StorageMCPClientType> {\n const { mcpClient } = input;\n const now = new Date();\n const entity: StorageMCPClientType = {\n id: mcpClient.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpClient.authorId,\n metadata: mcpClient.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(mcpClient.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpClientId: mcpClient.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateMCPClientVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateMCPClientInput): Promise<StorageMCPClientType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListMCPClientsInput): Promise<StorageListMCPClientsOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'mcpClients',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListMCPClientsOutput;\n }\n\n async createVersion(input: CreateMCPClientVersionInput): Promise<MCPClientVersion> {\n return this.helpers.createVersion(input as MCPClientVersion);\n }\n\n async getVersion(id: string): Promise<MCPClientVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(mcpClientId: string, versionNumber: number): Promise<MCPClientVersion | null> {\n return this.helpers.getVersionByNumber(mcpClientId, versionNumber);\n }\n\n async getLatestVersion(mcpClientId: string): Promise<MCPClientVersion | null> {\n return this.helpers.getLatestVersion(mcpClientId);\n }\n\n async listVersions(input: ListMCPClientVersionsInput): Promise<ListMCPClientVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'mcpClientId');\n return result as ListMCPClientVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(mcpClientId: string): Promise<number> {\n return this.helpers.countVersions(mcpClientId);\n }\n}\n"]} |
| 'use strict'; | ||
| var chunkDZ44ZU2T_cjs = require('./chunk-DZ44ZU2T.cjs'); | ||
| var chunkXB4FLS7A_cjs = require('./chunk-XB4FLS7A.cjs'); | ||
| var chunkCMKSC37Z_cjs = require('./chunk-CMKSC37Z.cjs'); | ||
| var chunkSZ2THGT4_cjs = require('./chunk-SZ2THGT4.cjs'); | ||
| var chunkLP4WZA6D_cjs = require('./chunk-LP4WZA6D.cjs'); | ||
| var chunkW7RLUWK5_cjs = require('./chunk-W7RLUWK5.cjs'); | ||
| var chunkBHNX447S_cjs = require('./chunk-BHNX447S.cjs'); | ||
| var chunkWSD4JNMB_cjs = require('./chunk-WSD4JNMB.cjs'); | ||
| var chunkPJIAL3WK_cjs = require('./chunk-PJIAL3WK.cjs'); | ||
| var chunkXSOONORA_cjs = require('./chunk-XSOONORA.cjs'); | ||
| var crypto = require('crypto'); | ||
| var jsonToZod = require('@mastra/schema-compat/json-to-zod'); | ||
| var v4 = require('zod/v4'); | ||
| var schemaCompat = require('@mastra/schema-compat'); | ||
| var web = require('stream/web'); | ||
| var ToolStream = class extends web.WritableStream { | ||
| prefix; | ||
| callId; | ||
| name; | ||
| runId; | ||
| writeFn; | ||
| constructor({ | ||
| prefix, | ||
| callId, | ||
| name, | ||
| runId | ||
| }, writeFn) { | ||
| super({ | ||
| async write(chunk) { | ||
| await getInstance()._write(chunk); | ||
| } | ||
| }); | ||
| const self = this; | ||
| function getInstance() { | ||
| return self; | ||
| } | ||
| this.prefix = prefix; | ||
| this.callId = callId; | ||
| this.name = name; | ||
| this.runId = runId; | ||
| this.writeFn = writeFn; | ||
| } | ||
| async _write(data) { | ||
| if (this.writeFn) { | ||
| await this.writeFn({ | ||
| type: `${this.prefix}-output`, | ||
| runId: this.runId, | ||
| from: "USER", | ||
| payload: { | ||
| output: data, | ||
| ...this.prefix === "workflow-step" ? { | ||
| runId: this.runId, | ||
| stepName: this.name | ||
| } : { | ||
| [`${this.prefix}CallId`]: this.callId, | ||
| [`${this.prefix}Name`]: this.name | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| async write(data) { | ||
| await this._write(data); | ||
| } | ||
| async custom(data) { | ||
| if (this.writeFn) { | ||
| await this.writeFn(data); | ||
| } | ||
| } | ||
| }; | ||
| // src/tools/types.ts | ||
| var noopObserve = { | ||
| async span(_name, fn) { | ||
| return fn(); | ||
| }, | ||
| log() { | ||
| } | ||
| }; | ||
| // src/tools/tool-builder/builder.ts | ||
| function mergeRequestContexts(closureRC, execRC) { | ||
| if (!closureRC && !execRC) return new chunkPJIAL3WK_cjs.RequestContext(); | ||
| if (!closureRC) return execRC instanceof chunkPJIAL3WK_cjs.RequestContext ? execRC : new chunkPJIAL3WK_cjs.RequestContext(); | ||
| if (!execRC || !(execRC instanceof chunkPJIAL3WK_cjs.RequestContext) || execRC.size() === 0) return closureRC; | ||
| const merged = new chunkPJIAL3WK_cjs.RequestContext(); | ||
| for (const [key, value] of execRC.entries()) { | ||
| merged.set(key, value); | ||
| } | ||
| for (const [key, value] of closureRC.entries()) { | ||
| merged.set(key, value); | ||
| } | ||
| return merged; | ||
| } | ||
| function isZodV4Schema(schema) { | ||
| const def = schema?._def; | ||
| return !!def && typeof def.type === "string" && !def.typeName; | ||
| } | ||
| function buildJsonOverrideSchema(originalSchema, splicedJsonSchema, injectedKeys) { | ||
| const fallback = chunkXB4FLS7A_cjs.toStandardSchema(splicedJsonSchema); | ||
| const original = originalSchema; | ||
| const originalValidate = original?.["~standard"]?.validate?.bind(original["~standard"]); | ||
| const splicedProperties = splicedJsonSchema && typeof splicedJsonSchema === "object" && "properties" in splicedJsonSchema ? splicedJsonSchema.properties ?? {} : {}; | ||
| const injectedProperties = {}; | ||
| for (const key of injectedKeys) { | ||
| if (splicedProperties[key] !== void 0) injectedProperties[key] = splicedProperties[key]; | ||
| } | ||
| const injectedValidator = chunkXB4FLS7A_cjs.toStandardSchema({ | ||
| type: "object", | ||
| properties: injectedProperties, | ||
| additionalProperties: false | ||
| }); | ||
| const stripInjected = (input) => { | ||
| if (!input || typeof input !== "object" || Array.isArray(input)) return { stripped: input, injected: {} }; | ||
| const injected = {}; | ||
| const stripped = {}; | ||
| for (const [k, v] of Object.entries(input)) { | ||
| if (injectedKeys.includes(k)) injected[k] = v; | ||
| else stripped[k] = v; | ||
| } | ||
| return { stripped, injected }; | ||
| }; | ||
| const validate = (input) => { | ||
| const { stripped, injected } = stripInjected(input); | ||
| const baseResult = originalValidate ? originalValidate(stripped) : fallback["~standard"].validate(stripped); | ||
| const injectedResult = injectedValidator["~standard"].validate(injected); | ||
| const combine = (base, inj) => { | ||
| const baseIssues = "issues" in base ? base.issues ?? [] : []; | ||
| const injIssues = "issues" in inj ? inj.issues ?? [] : []; | ||
| if (baseIssues.length || injIssues.length) { | ||
| return { issues: [...baseIssues, ...injIssues] }; | ||
| } | ||
| const baseValue = base.value; | ||
| const injValue = inj.value; | ||
| if (baseValue && typeof baseValue === "object" && !Array.isArray(baseValue)) { | ||
| const injMerged = injValue && typeof injValue === "object" && !Array.isArray(injValue) ? injValue : injected; | ||
| return { value: { ...baseValue, ...injMerged } }; | ||
| } | ||
| return base; | ||
| }; | ||
| const baseIsPromise = baseResult && typeof baseResult.then === "function"; | ||
| const injIsPromise = injectedResult && typeof injectedResult.then === "function"; | ||
| if (baseIsPromise || injIsPromise) { | ||
| return Promise.all([baseResult, injectedResult]).then( | ||
| ([b, i]) => combine( | ||
| b, | ||
| i | ||
| ) | ||
| ); | ||
| } | ||
| return combine( | ||
| baseResult, | ||
| injectedResult | ||
| ); | ||
| }; | ||
| return { | ||
| "~standard": { | ||
| version: 1, | ||
| vendor: "mastra-json-override", | ||
| validate, | ||
| jsonSchema: fallback["~standard"].jsonSchema | ||
| } | ||
| }; | ||
| } | ||
| var CoreToolBuilder = class extends chunkWSD4JNMB_cjs.MastraBase { | ||
| originalTool; | ||
| options; | ||
| logType; | ||
| constructor(input) { | ||
| super({ name: "CoreToolBuilder" }); | ||
| this.originalTool = input.originalTool; | ||
| this.options = input.options; | ||
| this.logType = input.logType; | ||
| const isBackgroundEligible = !!input.backgroundTaskEnabled; | ||
| const isResumableTool = input.autoResumeSuspendedTools || this.originalTool.id?.startsWith("agent-") || this.originalTool.id?.startsWith("workflow-"); | ||
| if (!chunkDZ44ZU2T_cjs.isVercelTool(this.originalTool) && !chunkDZ44ZU2T_cjs.isProviderDefinedTool(this.originalTool)) { | ||
| if (isBackgroundEligible || isResumableTool) { | ||
| let schema = this.originalTool.inputSchema; | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| if (!schema) { | ||
| schema = v4.z.object({}); | ||
| } | ||
| if (chunkCMKSC37Z_cjs.isZodObject(schema) && isZodV4Schema(schema)) { | ||
| let nextSchema = schema; | ||
| if (isBackgroundEligible) { | ||
| nextSchema = chunkCMKSC37Z_cjs.safeExtendZodObject(nextSchema, { | ||
| _background: chunkBHNX447S_cjs.backgroundOverrideZodSchema | ||
| }); | ||
| } | ||
| if (isResumableTool) { | ||
| nextSchema = chunkCMKSC37Z_cjs.safeExtendZodObject(nextSchema, { | ||
| suspendedToolRunId: v4.z.string().describe("The runId of the suspended tool").nullable().optional(), | ||
| resumeData: v4.z.any().describe("The resumeData object created from the resumeSchema of suspended tool").optional() | ||
| }); | ||
| } | ||
| this.originalTool.inputSchema = nextSchema; | ||
| } else { | ||
| const standardSchema = chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(schema) ? schema : chunkXB4FLS7A_cjs.toStandardSchema(schema); | ||
| const jsonSchema2 = chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(standardSchema, { io: "input" }); | ||
| if (jsonSchema2 && typeof jsonSchema2 === "object" && jsonSchema2.type === "object") { | ||
| const properties = { ...jsonSchema2.properties ?? {} }; | ||
| const injectedKeys = []; | ||
| if (isBackgroundEligible) { | ||
| properties._background = chunkBHNX447S_cjs.backgroundOverrideJsonSchema; | ||
| injectedKeys.push("_background"); | ||
| } | ||
| if (isResumableTool) { | ||
| properties.suspendedToolRunId = { | ||
| type: ["string", "null"], | ||
| description: "The runId of the suspended tool" | ||
| }; | ||
| properties.resumeData = { | ||
| description: "The resumeData object created from the resumeSchema of suspended tool" | ||
| }; | ||
| injectedKeys.push("suspendedToolRunId", "resumeData"); | ||
| } | ||
| this.originalTool.inputSchema = buildJsonOverrideSchema( | ||
| schema, | ||
| { ...jsonSchema2, properties }, | ||
| injectedKeys | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // Helper to get parameters based on tool type | ||
| getParameters = () => { | ||
| if (chunkDZ44ZU2T_cjs.isVercelTool(this.originalTool)) { | ||
| let schema2 = this.originalTool.parameters ?? ("inputSchema" in this.originalTool ? this.originalTool.inputSchema : void 0) ?? v4.z.object({}); | ||
| if (typeof schema2 === "function") { | ||
| schema2 = schema2(); | ||
| } | ||
| return schema2; | ||
| } | ||
| let schema = this.originalTool.inputSchema; | ||
| if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(schema)) { | ||
| return schema; | ||
| } | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| }; | ||
| getOutputSchema = () => { | ||
| if ("outputSchema" in this.originalTool) { | ||
| let schema = this.originalTool.outputSchema; | ||
| if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(schema)) { | ||
| return schema; | ||
| } | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| } | ||
| return null; | ||
| }; | ||
| getResumeSchema = () => { | ||
| if ("resumeSchema" in this.originalTool) { | ||
| let schema = this.originalTool.resumeSchema; | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| } | ||
| return null; | ||
| }; | ||
| getSuspendSchema = () => { | ||
| if ("suspendSchema" in this.originalTool) { | ||
| let schema = this.originalTool.suspendSchema; | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| } | ||
| return null; | ||
| }; | ||
| // For provider-defined tools, we need to include all required properties | ||
| // AI SDK v5 uses type: 'provider-defined', AI SDK v6 uses type: 'provider' | ||
| buildProviderTool(tool) { | ||
| if ("type" in tool && (tool.type === "provider-defined" || tool.type === "provider") && "id" in tool && typeof tool.id === "string" && tool.id.includes(".")) { | ||
| let parameters = "parameters" in tool ? tool.parameters : "inputSchema" in tool ? tool.inputSchema : void 0; | ||
| if (typeof parameters === "function") { | ||
| parameters = parameters(); | ||
| } | ||
| let outputSchema = "outputSchema" in tool ? tool.outputSchema : void 0; | ||
| if (typeof outputSchema === "function") { | ||
| outputSchema = outputSchema(); | ||
| } | ||
| let processedParameters; | ||
| if (parameters !== void 0 && parameters !== null) { | ||
| if (typeof parameters === "object" && "jsonSchema" in parameters) { | ||
| processedParameters = parameters; | ||
| } else if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(parameters)) { | ||
| const jsonSchema2 = chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(parameters, { io: "input" }); | ||
| processedParameters = { jsonSchema: jsonSchema2 }; | ||
| } else { | ||
| processedParameters = schemaCompat.convertZodSchemaToAISDKSchema(parameters); | ||
| } | ||
| } else { | ||
| processedParameters = { | ||
| jsonSchema: { | ||
| type: "object", | ||
| properties: {}, | ||
| additionalProperties: false | ||
| } | ||
| }; | ||
| } | ||
| let processedOutputSchema; | ||
| if (outputSchema !== void 0 && outputSchema !== null) { | ||
| if (typeof outputSchema === "object" && "jsonSchema" in outputSchema) { | ||
| processedOutputSchema = outputSchema; | ||
| } else if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(outputSchema)) { | ||
| const jsonSchema2 = chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(outputSchema); | ||
| processedOutputSchema = { jsonSchema: jsonSchema2 }; | ||
| } else { | ||
| processedOutputSchema = schemaCompat.convertZodSchemaToAISDKSchema(outputSchema); | ||
| } | ||
| } | ||
| return { | ||
| ...processedOutputSchema ? { outputSchema: processedOutputSchema } : {}, | ||
| type: "provider-defined", | ||
| id: tool.id, | ||
| // V5 SDK factories set a hardcoded `name` (e.g. "web_search" for | ||
| // anthropic.web_search_20250305). Preserve it so that when this tool | ||
| // is later used with a V6 provider, the bidirectional toolNameMapping | ||
| // resolves the correct model-facing name instead of the versioned ID. | ||
| ..."name" in tool && typeof tool.name === "string" ? { name: tool.name } : {}, | ||
| args: "args" in this.originalTool ? this.originalTool.args : {}, | ||
| description: tool.description, | ||
| parameters: processedParameters, | ||
| execute: this.originalTool.execute ? this.createExecute( | ||
| this.originalTool, | ||
| { ...this.options, description: this.originalTool.description }, | ||
| this.logType | ||
| ) : void 0, | ||
| toModelOutput: "toModelOutput" in this.originalTool ? this.originalTool.toModelOutput : void 0, | ||
| transform: "transform" in this.originalTool ? this.originalTool.transform : void 0, | ||
| inputExamples: "inputExamples" in this.originalTool ? this.originalTool.inputExamples : void 0 | ||
| }; | ||
| } | ||
| return void 0; | ||
| } | ||
| createLogMessageOptions({ agentName, toolName, type }) { | ||
| const toolType = type === "toolset" ? "toolset" : "tool"; | ||
| return { | ||
| start: `Executing ${toolType}`, | ||
| error: `Failed ${toolType} execution`, | ||
| logData: { agent: agentName, tool: toolName } | ||
| }; | ||
| } | ||
| createExecute(tool, options, logType) { | ||
| const { | ||
| logger, | ||
| mastra: _mastra, | ||
| memory: _memory, | ||
| requestContext, | ||
| model, | ||
| tracingContext: _tracingContext, | ||
| tracingPolicy: _tracingPolicy, | ||
| ...rest | ||
| } = options; | ||
| const logModelObject = { | ||
| modelId: model?.modelId, | ||
| provider: model?.provider, | ||
| specificationVersion: model?.specificationVersion | ||
| }; | ||
| const { start, logData } = this.createLogMessageOptions({ | ||
| agentName: options.agentName, | ||
| toolName: options.name, | ||
| type: logType | ||
| }); | ||
| const mcpMeta = !chunkDZ44ZU2T_cjs.isVercelTool(tool) && "mcpMetadata" in tool ? tool.mcpMetadata : void 0; | ||
| const execFunction = async (args, execOptions, toolSpan) => { | ||
| try { | ||
| let result; | ||
| let suspendData = null; | ||
| if (chunkDZ44ZU2T_cjs.isVercelTool(tool)) { | ||
| result = await chunkLP4WZA6D_cjs.executeWithContext({ | ||
| span: toolSpan, | ||
| fn: async () => tool?.execute?.(args, execOptions) | ||
| }); | ||
| } else { | ||
| const wrappedMastra = options.mastra ? chunkSZ2THGT4_cjs.wrapMastra(options.mastra, { currentSpan: toolSpan }) : options.mastra; | ||
| const resumeSchema = this.getResumeSchema(); | ||
| const baseContext = { | ||
| threadId: options.threadId, | ||
| resourceId: options.resourceId, | ||
| mastra: wrappedMastra, | ||
| memory: options.memory, | ||
| runId: options.runId, | ||
| requestContext: mergeRequestContexts(options.requestContext, execOptions.requestContext), | ||
| actor: execOptions.actor, | ||
| // Workspace for file operations and command execution | ||
| // Execution-time workspace (from prepareStep/processInputStep) takes precedence over build-time workspace | ||
| workspace: execOptions.workspace ?? options.workspace, | ||
| // Browser for web automation (lazily initialized on first use) | ||
| browser: options.browser, | ||
| observe: execOptions.observe ?? noopObserve, | ||
| writer: new ToolStream( | ||
| { | ||
| prefix: "tool", | ||
| callId: execOptions.toolCallId, | ||
| name: options.name, | ||
| runId: options.runId | ||
| }, | ||
| options.outputWriter || execOptions.outputWriter | ||
| ), | ||
| ...chunkSZ2THGT4_cjs.createObservabilityContext({ currentSpan: toolSpan }), | ||
| abortSignal: execOptions.abortSignal, | ||
| suspend: (args2, suspendOptions) => { | ||
| suspendData = args2; | ||
| const newSuspendOptions = { | ||
| ...suspendOptions ?? {}, | ||
| resumeSchema: suspendOptions?.resumeSchema ?? (resumeSchema ? JSON.stringify(chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(chunkXB4FLS7A_cjs.toStandardSchema(resumeSchema), { io: "input" })) : void 0) | ||
| }; | ||
| return execOptions.suspend?.(args2, newSuspendOptions); | ||
| }, | ||
| resumeData: execOptions.resumeData | ||
| }; | ||
| const isAgentExecution = execOptions.toolCallId && execOptions.messages || options.agentName && options.threadId && !options.workflowId; | ||
| const isWorkflowExecution = !isAgentExecution && (options.workflow || options.workflowId); | ||
| let toolContext; | ||
| if (isAgentExecution) { | ||
| const { suspend, resumeData: resumeData2, threadId, resourceId, ...restBaseContext } = baseContext; | ||
| toolContext = { | ||
| ...restBaseContext, | ||
| agent: { | ||
| agentId: options.agentId || "", | ||
| toolCallId: execOptions.toolCallId || "", | ||
| messages: execOptions.messages || [], | ||
| suspend, | ||
| resumeData: resumeData2, | ||
| threadId, | ||
| resourceId, | ||
| outputWriter: options.outputWriter || execOptions.outputWriter, | ||
| flushMessages: execOptions.flushMessages | ||
| } | ||
| }; | ||
| } else if (isWorkflowExecution) { | ||
| const { suspend, resumeData: resumeData2, ...restBaseContext } = baseContext; | ||
| toolContext = { | ||
| ...restBaseContext, | ||
| workflow: options.workflow || { | ||
| runId: options.runId, | ||
| workflowId: options.workflowId, | ||
| state: options.state, | ||
| setState: options.setState, | ||
| suspend, | ||
| resumeData: resumeData2 | ||
| } | ||
| }; | ||
| } else if (execOptions.mcp) { | ||
| toolContext = { | ||
| ...baseContext, | ||
| mcp: execOptions.mcp | ||
| }; | ||
| } else { | ||
| toolContext = baseContext; | ||
| } | ||
| const resumeData = execOptions.resumeData; | ||
| if (resumeData) { | ||
| const resumeValidation = chunkDZ44ZU2T_cjs.validateToolInput(resumeSchema, resumeData, options.name); | ||
| if (resumeValidation.error) { | ||
| logger?.warn(resumeValidation.error.message); | ||
| toolSpan?.end({ output: resumeValidation.error, attributes: { success: false } }); | ||
| return resumeValidation.error; | ||
| } | ||
| } | ||
| result = await chunkLP4WZA6D_cjs.executeWithContext({ span: toolSpan, fn: async () => tool?.execute?.(args, toolContext) }); | ||
| } | ||
| if (suspendData) { | ||
| const suspendSchema = this.getSuspendSchema(); | ||
| const suspendValidation = chunkDZ44ZU2T_cjs.validateToolSuspendData(suspendSchema, suspendData, options.name); | ||
| if (suspendValidation.error) { | ||
| logger?.warn(suspendValidation.error.message); | ||
| toolSpan?.end({ output: suspendValidation.error, attributes: { success: false } }); | ||
| return suspendValidation.error; | ||
| } | ||
| } | ||
| const shouldSkipValidation = typeof result === "undefined" && !!suspendData; | ||
| if (shouldSkipValidation) { | ||
| toolSpan?.end({ output: result, attributes: { success: true } }); | ||
| return result; | ||
| } | ||
| if (chunkDZ44ZU2T_cjs.isVercelTool(tool)) { | ||
| const outputSchema = this.getOutputSchema(); | ||
| const outputValidation = chunkDZ44ZU2T_cjs.validateToolOutput(outputSchema, result, options.name, false); | ||
| if (outputValidation.error) { | ||
| logger?.warn(outputValidation.error.message); | ||
| toolSpan?.end({ output: outputValidation.error, attributes: { success: false } }); | ||
| return outputValidation.error; | ||
| } | ||
| result = outputValidation.data; | ||
| } | ||
| toolSpan?.end({ output: result, attributes: { success: true } }); | ||
| return result; | ||
| } catch (error) { | ||
| toolSpan?.error({ error, attributes: { success: false } }); | ||
| throw error; | ||
| } | ||
| }; | ||
| return async (args, execOptions) => { | ||
| let logger2 = options.logger || this.logger; | ||
| const tracingContext = execOptions?.tracingContext || options.tracingContext; | ||
| const toolRequestContext = execOptions?.requestContext ?? options.requestContext; | ||
| const toolSpan = chunkLP4WZA6D_cjs.getOrCreateSpan({ | ||
| type: mcpMeta ? "mcp_tool_call" /* MCP_TOOL_CALL */ : "tool_call" /* TOOL_CALL */, | ||
| name: mcpMeta ? `mcp_tool: '${options.name}' on '${mcpMeta.serverName}'` : `tool: '${options.name}'`, | ||
| input: args, | ||
| entityType: chunkLP4WZA6D_cjs.EntityType.TOOL, | ||
| entityId: options.name, | ||
| entityName: options.name, | ||
| attributes: mcpMeta ? { | ||
| mcpServer: mcpMeta.serverName, | ||
| serverVersion: mcpMeta.serverVersion, | ||
| toolDescription: options.description | ||
| } : { | ||
| toolDescription: options.description, | ||
| toolType: logType || "tool" | ||
| }, | ||
| tracingPolicy: options.tracingPolicy, | ||
| tracingContext, | ||
| requestContext: toolRequestContext, | ||
| mastra: options.mastra && "observability" in options.mastra ? options.mastra : void 0 | ||
| }); | ||
| const fgaProvider = options.mastra?.getServer?.()?.fga; | ||
| const user = toolRequestContext?.get("user"); | ||
| if (fgaProvider) { | ||
| const { getAgentToolFGAResourceId, getMCPToolFGAResourceId, getStandaloneToolFGAResourceId, requireFGA } = await import('./fga-check-BIMTM2YF.cjs'); | ||
| const toolResourceId = mcpMeta?.serverName ? getMCPToolFGAResourceId(mcpMeta.serverName, options.name) : options.agentId ? getAgentToolFGAResourceId(options.agentId, options.name) : getStandaloneToolFGAResourceId(options.name); | ||
| await requireFGA({ | ||
| fgaProvider, | ||
| user, | ||
| resource: { type: "tool", id: toolResourceId }, | ||
| permission: chunkW7RLUWK5_cjs.MastraFGAPermissions.TOOLS_EXECUTE, | ||
| requestContext: toolRequestContext, | ||
| actor: execOptions?.actor, | ||
| context: { | ||
| resourceId: options.resourceId | ||
| }, | ||
| metadata: { | ||
| toolName: options.name, | ||
| agentId: options.agentId, | ||
| agentName: options.agentName, | ||
| runId: options.runId, | ||
| threadId: options.threadId, | ||
| executionResourceId: options.resourceId, | ||
| mcpMetadata: mcpMeta | ||
| } | ||
| }); | ||
| } | ||
| try { | ||
| logger2.debug(start, { ...logData, ...rest, model: logModelObject, args }); | ||
| const isResuming = !!execOptions?.resumeData; | ||
| const parameters = this.getParameters(); | ||
| if (!isResuming) { | ||
| const { data, error } = chunkDZ44ZU2T_cjs.validateToolInput(parameters, args, options.name); | ||
| const suspendedToolRunIdErrToIgnore = error?.message?.includes("suspendedToolRunId: Required") && !args?.resumeData; | ||
| if (error && !suspendedToolRunIdErrToIgnore) { | ||
| logger2.warn("Tool input validation failed", { ...logData, validationError: error.message }); | ||
| toolSpan?.end({ output: error, attributes: { success: false } }); | ||
| return error; | ||
| } | ||
| args = data; | ||
| } | ||
| return await new Promise((resolve, reject) => { | ||
| setImmediate(async () => { | ||
| try { | ||
| const result = await execFunction(args, execOptions, toolSpan); | ||
| resolve(result); | ||
| } catch (err) { | ||
| reject(err); | ||
| } | ||
| }); | ||
| }); | ||
| } catch (err) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "TOOL_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.TOOL, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| errorMessage: String(err), | ||
| argsJson: safeStringify(args), | ||
| model: model?.modelId ?? "" | ||
| } | ||
| }, | ||
| err | ||
| ); | ||
| toolSpan?.error({ error: mastraError, attributes: { success: false } }); | ||
| logger2.trackException(mastraError, { ...logData, ...rest, model: logModelObject, args }); | ||
| throw mastraError; | ||
| } | ||
| }; | ||
| } | ||
| buildV5() { | ||
| const builtTool = this.build(); | ||
| if (!builtTool.parameters) { | ||
| throw new Error("Tool parameters are required"); | ||
| } | ||
| const base = { | ||
| ...builtTool, | ||
| inputSchema: builtTool.parameters, | ||
| onInputStart: "onInputStart" in this.originalTool ? this.originalTool.onInputStart : void 0, | ||
| onInputDelta: "onInputDelta" in this.originalTool ? this.originalTool.onInputDelta : void 0, | ||
| onInputAvailable: "onInputAvailable" in this.originalTool ? this.originalTool.onInputAvailable : void 0, | ||
| onOutput: "onOutput" in this.originalTool ? this.originalTool.onOutput : void 0 | ||
| }; | ||
| if (builtTool.type === "provider-defined") { | ||
| const { execute, parameters, ...rest } = base; | ||
| const name = ("name" in builtTool && typeof builtTool.name === "string" ? builtTool.name : null) || builtTool.id.split(".")[1] || builtTool.id; | ||
| return { | ||
| ...rest, | ||
| type: builtTool.type, | ||
| id: builtTool.id, | ||
| name, | ||
| args: builtTool.args | ||
| }; | ||
| } | ||
| return base; | ||
| } | ||
| build() { | ||
| const providerTool = this.buildProviderTool(this.originalTool); | ||
| if (providerTool) { | ||
| return providerTool; | ||
| } | ||
| const model = this.options.model; | ||
| const schemaCompatLayers = []; | ||
| if (model) { | ||
| const supportsStructuredOutputs = "supportsStructuredOutputs" in model ? model.supportsStructuredOutputs ?? false : false; | ||
| const modelInfo = { | ||
| modelId: model.modelId, | ||
| supportsStructuredOutputs, | ||
| provider: model.provider | ||
| }; | ||
| schemaCompatLayers.push( | ||
| new schemaCompat.OpenAIReasoningSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.OpenAISchemaCompatLayer(modelInfo), | ||
| new schemaCompat.GoogleSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.AnthropicSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.DeepSeekSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.MetaSchemaCompatLayer(modelInfo) | ||
| ); | ||
| } | ||
| const originalSchema = this.getParameters(); | ||
| let processedInputSchema; | ||
| if (originalSchema) { | ||
| if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(originalSchema)) { | ||
| const applicableLayer = schemaCompatLayers.find((layer) => layer.shouldApply()); | ||
| let schemaToUse; | ||
| if (applicableLayer) { | ||
| schemaToUse = applicableLayer.processToCompatSchema(originalSchema); | ||
| } else { | ||
| schemaToUse = chunkXB4FLS7A_cjs.toStandardSchema(originalSchema); | ||
| } | ||
| processedInputSchema = schemaCompat.jsonSchema( | ||
| chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(schemaToUse, { | ||
| io: "input" | ||
| }), | ||
| { | ||
| validate: (value) => { | ||
| const result = schemaToUse["~standard"].validate(value); | ||
| if (result instanceof Promise) { | ||
| return result.then((r) => { | ||
| if ("issues" in r && r.issues) { | ||
| return { | ||
| success: false, | ||
| error: new Error(r.issues.map((i) => i.message).join(", ")) | ||
| }; | ||
| } | ||
| return { success: true, value: r.value }; | ||
| }); | ||
| } | ||
| if ("issues" in result && result.issues) { | ||
| return { | ||
| success: false, | ||
| error: new Error(result.issues.map((i) => i.message).join(", ")) | ||
| }; | ||
| } | ||
| return { success: true, value: result.value }; | ||
| } | ||
| } | ||
| ); | ||
| } else { | ||
| processedInputSchema = schemaCompat.applyCompatLayer({ | ||
| schema: originalSchema, | ||
| compatLayers: schemaCompatLayers, | ||
| mode: "aiSdkSchema" | ||
| }); | ||
| } | ||
| } | ||
| const outputSchema = this.getOutputSchema(); | ||
| let processedOutputSchema; | ||
| if (outputSchema) { | ||
| if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(outputSchema)) { | ||
| processedOutputSchema = chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(outputSchema, { io: "output" }); | ||
| } else { | ||
| processedOutputSchema = schemaCompat.applyCompatLayer({ | ||
| schema: outputSchema, | ||
| compatLayers: [], | ||
| mode: "aiSdkSchema" | ||
| }); | ||
| } | ||
| } | ||
| let requireApproval = false; | ||
| let needsApprovalFn; | ||
| if (typeof this.options.requireApproval === "function") { | ||
| requireApproval = true; | ||
| needsApprovalFn = this.options.requireApproval; | ||
| } else if (typeof this.options.requireApproval === "boolean") { | ||
| requireApproval = this.options.requireApproval; | ||
| needsApprovalFn = void 0; | ||
| } | ||
| if (chunkDZ44ZU2T_cjs.isVercelTool(this.originalTool) && "needsApproval" in this.originalTool) { | ||
| const needsApproval = this.originalTool.needsApproval; | ||
| if (typeof needsApproval === "boolean") { | ||
| requireApproval = needsApproval; | ||
| needsApprovalFn = void 0; | ||
| } else if (typeof needsApproval === "function") { | ||
| needsApprovalFn = needsApproval; | ||
| requireApproval = true; | ||
| } | ||
| } | ||
| const instanceNeedsApprovalFn = chunkDZ44ZU2T_cjs.getNeedsApprovalFn(this.originalTool); | ||
| if (!needsApprovalFn && instanceNeedsApprovalFn) { | ||
| needsApprovalFn = instanceNeedsApprovalFn; | ||
| requireApproval = true; | ||
| } | ||
| const definition = { | ||
| type: "function", | ||
| description: this.originalTool.description, | ||
| requireApproval, | ||
| needsApprovalFn, | ||
| hasSuspendSchema: !!this.getSuspendSchema(), | ||
| execute: this.originalTool.execute ? this.createExecute( | ||
| this.originalTool, | ||
| { ...this.options, description: this.originalTool.description }, | ||
| this.logType | ||
| ) : void 0 | ||
| }; | ||
| return { | ||
| ...definition, | ||
| id: "id" in this.originalTool ? this.originalTool.id : void 0, | ||
| parameters: processedInputSchema ?? v4.z.object({}), | ||
| outputSchema: processedOutputSchema, | ||
| strict: "strict" in this.originalTool ? this.originalTool.strict : void 0, | ||
| providerOptions: "providerOptions" in this.originalTool ? this.originalTool.providerOptions : void 0, | ||
| mcp: "mcp" in this.originalTool ? this.originalTool.mcp : void 0, | ||
| toModelOutput: "toModelOutput" in this.originalTool ? this.originalTool.toModelOutput : void 0, | ||
| transform: "transform" in this.originalTool ? this.originalTool.transform : void 0, | ||
| inputExamples: "inputExamples" in this.originalTool ? this.originalTool.inputExamples : void 0, | ||
| onInputStart: "onInputStart" in this.originalTool ? this.originalTool.onInputStart : void 0, | ||
| onInputDelta: "onInputDelta" in this.originalTool ? this.originalTool.onInputDelta : void 0, | ||
| onInputAvailable: "onInputAvailable" in this.originalTool ? this.originalTool.onInputAvailable : void 0, | ||
| onOutput: "onOutput" in this.originalTool ? this.originalTool.onOutput : void 0, | ||
| // Preserve tool-level background config so the agentic loop can pick it up | ||
| // from the converted CoreTool at dispatch time. | ||
| backgroundConfig: this.options.backgroundConfig | ||
| }; | ||
| } | ||
| }; | ||
| // src/utils.ts | ||
| var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); | ||
| function safeStringify(value, space) { | ||
| const stack = []; | ||
| return JSON.stringify( | ||
| value, | ||
| function(_key, val) { | ||
| if (typeof val === "bigint") return val.toString(); | ||
| if (val !== null && typeof val === "object") { | ||
| while (stack.length > 0 && stack[stack.length - 1] !== this) { | ||
| stack.pop(); | ||
| } | ||
| if (stack.includes(val)) return "[Circular]"; | ||
| stack.push(val); | ||
| } | ||
| return val; | ||
| }, | ||
| space | ||
| ); | ||
| } | ||
| function ensureSerializable(value) { | ||
| if (value === null || typeof value !== "object") return value; | ||
| try { | ||
| JSON.stringify(value); | ||
| return value; | ||
| } catch { | ||
| return JSON.parse(safeStringify(value)); | ||
| } | ||
| } | ||
| function isPlainObject(value) { | ||
| if (value === null || typeof value !== "object") return false; | ||
| const proto = Object.getPrototypeOf(value); | ||
| return proto === Object.prototype || proto === null; | ||
| } | ||
| function deepMerge(target, source) { | ||
| const output = { ...target }; | ||
| if (!source) return output; | ||
| Object.keys(source).forEach((key) => { | ||
| const targetValue = output[key]; | ||
| const sourceValue = source[key]; | ||
| if (isPlainObject(targetValue) && isPlainObject(sourceValue)) { | ||
| output[key] = deepMerge(targetValue, sourceValue); | ||
| } else if (sourceValue !== void 0) { | ||
| output[key] = sourceValue; | ||
| } | ||
| }); | ||
| return output; | ||
| } | ||
| function deepEqual(a, b) { | ||
| if (a === b) return true; | ||
| if (a == null || b == null) return a === b; | ||
| if (typeof a !== typeof b) return false; | ||
| if (Array.isArray(a) && Array.isArray(b)) { | ||
| if (a.length !== b.length) return false; | ||
| return a.every((item, index) => deepEqual(item, b[index])); | ||
| } | ||
| if (a instanceof Date && b instanceof Date) { | ||
| return a.getTime() === b.getTime(); | ||
| } | ||
| if (typeof a === "object" && typeof b === "object") { | ||
| const aObj = a; | ||
| const bObj = b; | ||
| const aKeys = Object.keys(aObj); | ||
| const bKeys = Object.keys(bObj); | ||
| if (aKeys.length !== bKeys.length) return false; | ||
| return aKeys.every((key) => Object.prototype.hasOwnProperty.call(bObj, key) && deepEqual(aObj[key], bObj[key])); | ||
| } | ||
| return false; | ||
| } | ||
| function generateEmptyFromSchema(schema) { | ||
| try { | ||
| const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema; | ||
| if (!parsedSchema || parsedSchema.type !== "object" || !parsedSchema.properties) return {}; | ||
| const obj = {}; | ||
| for (const [key, prop] of Object.entries( | ||
| parsedSchema.properties | ||
| )) { | ||
| if (prop.default !== void 0) { | ||
| obj[key] = typeof prop.default === "object" && prop.default !== null ? JSON.parse(JSON.stringify(prop.default)) : prop.default; | ||
| } else if (prop.type === "object" && prop.properties) { | ||
| obj[key] = generateEmptyFromSchema(prop); | ||
| } else if (prop.type === "object") { | ||
| obj[key] = {}; | ||
| } else if (prop.type === "string") { | ||
| obj[key] = ""; | ||
| } else if (prop.type === "array") { | ||
| obj[key] = []; | ||
| } else if (prop.type === "number" || prop.type === "integer") { | ||
| obj[key] = 0; | ||
| } else if (prop.type === "boolean") { | ||
| obj[key] = false; | ||
| } else { | ||
| obj[key] = null; | ||
| } | ||
| } | ||
| return obj; | ||
| } catch { | ||
| return {}; | ||
| } | ||
| } | ||
| async function* maskStreamTags(stream, tag, options = {}) { | ||
| const { onStart, onEnd, onMask } = options; | ||
| const openTag = `<${tag}>`; | ||
| const closeTag = `</${tag}>`; | ||
| let buffer = ""; | ||
| let fullContent = ""; | ||
| let isMasking = false; | ||
| let isBuffering = false; | ||
| const trimOutsideDelimiter = (text, delimiter, trim) => { | ||
| if (!text.includes(delimiter)) { | ||
| return text; | ||
| } | ||
| const parts = text.split(delimiter); | ||
| if (trim === `before-start`) { | ||
| return `${delimiter}${parts[1]}`; | ||
| } | ||
| return `${parts[0]}${delimiter}`; | ||
| }; | ||
| const startsWith = (text, pattern) => { | ||
| if (pattern.includes(openTag.substring(0, 3))) { | ||
| pattern = trimOutsideDelimiter(pattern, `<`, `before-start`); | ||
| } | ||
| return text.trim().startsWith(pattern.trim()); | ||
| }; | ||
| for await (const chunk of stream) { | ||
| fullContent += chunk; | ||
| if (isBuffering) buffer += chunk; | ||
| const chunkHasTag = startsWith(chunk, openTag); | ||
| const bufferHasTag = !chunkHasTag && isBuffering && startsWith(openTag, buffer); | ||
| let toYieldBeforeMaskedStartTag = ``; | ||
| if (!isMasking && (chunkHasTag || bufferHasTag)) { | ||
| isMasking = true; | ||
| isBuffering = false; | ||
| const taggedTextToMask = trimOutsideDelimiter(buffer, `<`, `before-start`); | ||
| if (taggedTextToMask !== buffer.trim()) { | ||
| toYieldBeforeMaskedStartTag = buffer.replace(taggedTextToMask, ``); | ||
| } | ||
| buffer = ""; | ||
| onStart?.(); | ||
| } | ||
| if (!isMasking && !isBuffering && startsWith(openTag, chunk) && chunk.trim() !== "") { | ||
| isBuffering = true; | ||
| buffer += chunk; | ||
| continue; | ||
| } | ||
| if (isBuffering && buffer && !startsWith(openTag, buffer)) { | ||
| yield buffer; | ||
| buffer = ""; | ||
| isBuffering = false; | ||
| continue; | ||
| } | ||
| if (isMasking && fullContent.includes(closeTag)) { | ||
| onMask?.(chunk); | ||
| onEnd?.(); | ||
| isMasking = false; | ||
| const lastFullContent = fullContent; | ||
| fullContent = ``; | ||
| const textUntilEndTag = trimOutsideDelimiter(lastFullContent, closeTag, "after-end"); | ||
| if (textUntilEndTag !== lastFullContent) { | ||
| yield lastFullContent.replace(textUntilEndTag, ``); | ||
| } | ||
| continue; | ||
| } | ||
| if (isMasking) { | ||
| onMask?.(chunk); | ||
| if (toYieldBeforeMaskedStartTag) { | ||
| yield toYieldBeforeMaskedStartTag; | ||
| } | ||
| continue; | ||
| } | ||
| yield chunk; | ||
| } | ||
| } | ||
| function resolveSerializedZodOutput(schema) { | ||
| return Function("z", `"use strict";return (${schema});`)(v4.z); | ||
| } | ||
| function isZodType(value) { | ||
| return typeof value === "object" && value !== null && "_def" in value && "parse" in value && typeof value.parse === "function" && "safeParse" in value && typeof value.safeParse === "function"; | ||
| } | ||
| function createDeterministicId(input) { | ||
| return crypto.createHash("sha256").update(input).digest("hex").slice(0, 8); | ||
| } | ||
| function setVercelToolProperties(tool) { | ||
| const inputSchema = "inputSchema" in tool ? tool.inputSchema : convertVercelToolParameters(tool); | ||
| const toolId = !("id" in tool) ? tool.description ? `tool-${createDeterministicId(tool.description)}` : `tool-${Math.random().toString(36).substring(2, 9)}` : tool.id; | ||
| return { | ||
| ...tool, | ||
| id: toolId, | ||
| inputSchema | ||
| }; | ||
| } | ||
| function ensureToolProperties(tools) { | ||
| const toolsWithProperties = Object.keys(tools).reduce((acc, key) => { | ||
| const tool = tools?.[key]; | ||
| if (tool) { | ||
| if (typeof tool === "function" && !(tool instanceof chunkDZ44ZU2T_cjs.Tool) && !chunkDZ44ZU2T_cjs.isVercelTool(tool)) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "TOOL_INVALID_FORMAT", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.TOOL, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| text: `Tool "${key}" is not a valid tool format. Tools must be created using createTool() or be a valid Vercel AI SDK tool. Received a function.` | ||
| }); | ||
| } | ||
| if (chunkDZ44ZU2T_cjs.isVercelTool(tool)) { | ||
| acc[key] = setVercelToolProperties(tool); | ||
| } else { | ||
| acc[key] = tool; | ||
| } | ||
| } | ||
| return acc; | ||
| }, {}); | ||
| return toolsWithProperties; | ||
| } | ||
| function convertVercelToolParameters(tool) { | ||
| let schema = tool.parameters ?? v4.z.object({}); | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return isZodType(schema) ? schema : resolveSerializedZodOutput(jsonToZod.jsonSchemaToZod(schema)); | ||
| } | ||
| function makeCoreTool(originalTool, options, logType, autoResumeSuspendedTools, backgroundTaskEnabled) { | ||
| return new CoreToolBuilder({ | ||
| originalTool, | ||
| options, | ||
| logType, | ||
| autoResumeSuspendedTools, | ||
| backgroundTaskEnabled | ||
| }).build(); | ||
| } | ||
| function makeCoreToolV5(originalTool, options, logType, autoResumeSuspendedTools, backgroundTaskEnabled) { | ||
| return new CoreToolBuilder({ | ||
| originalTool, | ||
| options, | ||
| logType, | ||
| autoResumeSuspendedTools, | ||
| backgroundTaskEnabled | ||
| }).buildV5(); | ||
| } | ||
| function createMastraProxy({ mastra, logger }) { | ||
| return new Proxy(mastra, { | ||
| get(target, prop) { | ||
| const hasProp = Reflect.has(target, prop); | ||
| if (hasProp) { | ||
| const value = Reflect.get(target, prop); | ||
| const isFunction = typeof value === "function"; | ||
| if (isFunction) { | ||
| return value.bind(target); | ||
| } | ||
| return value; | ||
| } | ||
| if (prop === "logger") { | ||
| logger.warn("Please use 'getLogger' instead, logger is deprecated"); | ||
| return Reflect.apply(target.getLogger, target, []); | ||
| } | ||
| if (prop === "storage") { | ||
| logger.warn("Please use 'getStorage' instead, storage is deprecated"); | ||
| return Reflect.get(target, "storage"); | ||
| } | ||
| if (prop === "agents") { | ||
| logger.warn("Please use 'listAgents' instead, agents is deprecated"); | ||
| return Reflect.apply(target.listAgents, target, []); | ||
| } | ||
| if (prop === "tts") { | ||
| logger.warn("Please use 'getTTS' instead, tts is deprecated"); | ||
| return Reflect.apply(target.getTTS, target, []); | ||
| } | ||
| if (prop === "vectors") { | ||
| logger.warn("Please use 'getVectors' instead, vectors is deprecated"); | ||
| return Reflect.apply(target.getVectors, target, []); | ||
| } | ||
| if (prop === "memory") { | ||
| logger.warn("Please use 'getMemory' instead, memory is deprecated"); | ||
| return Reflect.get(target, "memory"); | ||
| } | ||
| return Reflect.get(target, prop); | ||
| } | ||
| }); | ||
| } | ||
| function checkEvalStorageFields(traceObject, logger) { | ||
| const missingFields = []; | ||
| if (!traceObject.input) missingFields.push("input"); | ||
| if (!traceObject.output) missingFields.push("output"); | ||
| if (!traceObject.agentName) missingFields.push("agent_name"); | ||
| if (!traceObject.metricName) missingFields.push("metric_name"); | ||
| if (!traceObject.instructions) missingFields.push("instructions"); | ||
| if (!traceObject.globalRunId) missingFields.push("global_run_id"); | ||
| if (!traceObject.runId) missingFields.push("run_id"); | ||
| if (missingFields.length > 0) { | ||
| if (logger) { | ||
| logger.warn("Skipping evaluation storage due to missing required fields", { | ||
| missingFields, | ||
| runId: traceObject.runId, | ||
| agentName: traceObject.agentName | ||
| }); | ||
| } else { | ||
| console.warn("Skipping evaluation storage due to missing required fields", { | ||
| missingFields, | ||
| runId: traceObject.runId, | ||
| agentName: traceObject.agentName | ||
| }); | ||
| } | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| function detectSingleMessageCharacteristics(message) { | ||
| if (typeof message === "object" && message !== null && (message.role === "function" || // UI-only role | ||
| message.role === "data" || // UI-only role | ||
| "toolInvocations" in message || // UI-specific field | ||
| "parts" in message || // UI-specific field | ||
| "experimental_attachments" in message)) { | ||
| return "has-ui-specific-parts"; | ||
| } else if (typeof message === "object" && message !== null && "content" in message && (Array.isArray(message.content) || // Core messages can have array content | ||
| "experimental_providerMetadata" in message || "providerOptions" in message)) { | ||
| return "has-core-specific-parts"; | ||
| } else if (typeof message === "object" && message !== null && "role" in message && "content" in message && typeof message.content === "string" && ["system", "user", "assistant", "tool"].includes(message.role)) { | ||
| return "message"; | ||
| } else { | ||
| return "other"; | ||
| } | ||
| } | ||
| function isUiMessage(message) { | ||
| return detectSingleMessageCharacteristics(message) === `has-ui-specific-parts`; | ||
| } | ||
| function isCoreMessage(message) { | ||
| return [`has-core-specific-parts`, `message`].includes(detectSingleMessageCharacteristics(message)); | ||
| } | ||
| var SQL_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/; | ||
| function parseSqlIdentifier(name, kind = "identifier") { | ||
| if (!SQL_IDENTIFIER_PATTERN.test(name) || name.length > 63) { | ||
| throw new Error( | ||
| `Invalid ${kind}: ${name}. Must start with a letter or underscore, contain only letters, numbers, or underscores, and be at most 63 characters long.` | ||
| ); | ||
| } | ||
| return name; | ||
| } | ||
| function parseFieldKey(key) { | ||
| if (!key) throw new Error("Field key cannot be empty"); | ||
| const segments = key.split("."); | ||
| for (const segment of segments) { | ||
| if (!SQL_IDENTIFIER_PATTERN.test(segment) || segment.length > 63) { | ||
| throw new Error(`Invalid field key segment: ${segment} in ${key}`); | ||
| } | ||
| } | ||
| return key; | ||
| } | ||
| function omitKeys(obj, keysToOmit) { | ||
| return Object.fromEntries(Object.entries(obj).filter(([key]) => !keysToOmit.includes(key))); | ||
| } | ||
| function selectFields(obj, fields) { | ||
| if (!obj || typeof obj !== "object") { | ||
| return obj; | ||
| } | ||
| const result = {}; | ||
| for (const field of fields) { | ||
| const value = getNestedValue(obj, field); | ||
| if (value !== void 0) { | ||
| setNestedValue(result, field, value); | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function getNestedValue(obj, path) { | ||
| return path.split(".").reduce((current, key) => { | ||
| return current && typeof current === "object" ? current[key] : void 0; | ||
| }, obj); | ||
| } | ||
| function setNestedValue(obj, path, value) { | ||
| const keys = path.split("."); | ||
| const lastKey = keys.pop(); | ||
| if (!lastKey) return; | ||
| for (const key of keys) { | ||
| if (key === "__proto__" || key === "constructor" || key === "prototype") { | ||
| return; | ||
| } | ||
| } | ||
| if (lastKey === "__proto__" || lastKey === "constructor" || lastKey === "prototype") { | ||
| return; | ||
| } | ||
| let current = obj; | ||
| for (const key of keys) { | ||
| const existing = Object.prototype.hasOwnProperty.call(current, key) ? current[key] : void 0; | ||
| if (existing === null || typeof existing !== "object") { | ||
| const container = /* @__PURE__ */ Object.create(null); | ||
| Object.defineProperty(current, key, { value: container, writable: true, enumerable: true, configurable: true }); | ||
| } | ||
| current = current[key]; | ||
| } | ||
| Object.defineProperty(current, lastKey, { value, writable: true, enumerable: true, configurable: true }); | ||
| } | ||
| var removeUndefinedValues = (obj) => { | ||
| return Object.fromEntries(Object.entries(obj).filter(([_, value]) => value !== void 0)); | ||
| }; | ||
| exports.ToolStream = ToolStream; | ||
| exports.checkEvalStorageFields = checkEvalStorageFields; | ||
| exports.createMastraProxy = createMastraProxy; | ||
| exports.deepEqual = deepEqual; | ||
| exports.deepMerge = deepMerge; | ||
| exports.delay = delay; | ||
| exports.ensureSerializable = ensureSerializable; | ||
| exports.ensureToolProperties = ensureToolProperties; | ||
| exports.generateEmptyFromSchema = generateEmptyFromSchema; | ||
| exports.getNestedValue = getNestedValue; | ||
| exports.isCoreMessage = isCoreMessage; | ||
| exports.isUiMessage = isUiMessage; | ||
| exports.isZodType = isZodType; | ||
| exports.makeCoreTool = makeCoreTool; | ||
| exports.makeCoreToolV5 = makeCoreToolV5; | ||
| exports.maskStreamTags = maskStreamTags; | ||
| exports.noopObserve = noopObserve; | ||
| exports.omitKeys = omitKeys; | ||
| exports.parseFieldKey = parseFieldKey; | ||
| exports.parseSqlIdentifier = parseSqlIdentifier; | ||
| exports.removeUndefinedValues = removeUndefinedValues; | ||
| exports.resolveSerializedZodOutput = resolveSerializedZodOutput; | ||
| exports.safeStringify = safeStringify; | ||
| exports.selectFields = selectFields; | ||
| exports.setNestedValue = setNestedValue; | ||
| //# sourceMappingURL=chunk-B3SPPQQ3.cjs.map | ||
| //# sourceMappingURL=chunk-B3SPPQQ3.cjs.map |
Sorry, the diff of this file is too big to display
| import { VersionedStorageDomain, normalizePerPage, calculatePagination, FilesystemVersionedHelpers } from './chunk-SKZRHFF3.js'; | ||
| import { deepEqual } from './chunk-MVLICRVY.js'; | ||
| // src/storage/domains/mcp-servers/base.ts | ||
| var MCPServersStorage = class extends VersionedStorageDomain { | ||
| listKey = "mcpServers"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "mcpServerId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "MCP_SERVERS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-servers/inmemory.ts | ||
| var InMemoryMCPServersStorage = class extends MCPServersStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.mcpServers.clear(); | ||
| this.db.mcpServerVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // MCP Server CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const config = this.db.mcpServers.get(id); | ||
| return config ? this.deepCopyConfig(config) : null; | ||
| } | ||
| async create(input) { | ||
| const { mcpServer } = input; | ||
| if (this.db.mcpServers.has(mcpServer.id)) { | ||
| throw new Error(`MCP server with id ${mcpServer.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newConfig = { | ||
| id: mcpServer.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpServer.authorId, | ||
| metadata: mcpServer.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.mcpServers.set(mcpServer.id, newConfig); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpServerId: mcpServer.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyConfig(newConfig); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingConfig = this.db.mcpServers.get(id); | ||
| if (!existingConfig) { | ||
| throw new Error(`MCP server with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedConfig = { | ||
| ...existingConfig, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingConfig.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpServers.set(id, updatedConfig); | ||
| return this.deepCopyConfig(updatedConfig); | ||
| } | ||
| async delete(id) { | ||
| this.db.mcpServers.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status = "published" } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let configs = Array.from(this.db.mcpServers.values()); | ||
| if (status) { | ||
| configs = configs.filter((config) => config.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| configs = configs.filter((config) => config.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| configs = configs.filter((config) => { | ||
| if (!config.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedConfigs = this.sortConfigs(configs, field, direction); | ||
| const clonedConfigs = sortedConfigs.map((config) => this.deepCopyConfig(config)); | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| mcpServers: clonedConfigs.slice(offset, offset + perPage), | ||
| total: clonedConfigs.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedConfigs.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // MCP Server Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.mcpServerVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.mcpServerVersions.values()) { | ||
| if (version2.mcpServerId === input.mcpServerId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for MCP server ${input.mcpServerId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpServerVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.mcpServerVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(mcpServerId, versionNumber) { | ||
| for (const version of this.db.mcpServerVersions.values()) { | ||
| if (version.mcpServerId === mcpServerId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(mcpServerId) { | ||
| let latest = null; | ||
| for (const version of this.db.mcpServerVersions.values()) { | ||
| if (version.mcpServerId === mcpServerId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { mcpServerId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.mcpServerVersions.values()).filter((v) => v.mcpServerId === mcpServerId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.mcpServerVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.mcpServerVersions.entries()) { | ||
| if (version.mcpServerId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.mcpServerVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(mcpServerId) { | ||
| let count = 0; | ||
| for (const version of this.db.mcpServerVersions.values()) { | ||
| if (version.mcpServerId === mcpServerId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyConfig(config) { | ||
| return { | ||
| ...config, | ||
| metadata: config.metadata ? { ...config.metadata } : config.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| tools: version.tools ? JSON.parse(JSON.stringify(version.tools)) : version.tools, | ||
| agents: version.agents ? JSON.parse(JSON.stringify(version.agents)) : version.agents, | ||
| workflows: version.workflows ? JSON.parse(JSON.stringify(version.workflows)) : version.workflows, | ||
| repository: version.repository ? { ...version.repository } : version.repository, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortConfigs(configs, field, direction) { | ||
| return configs.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-servers/filesystem.ts | ||
| var FilesystemMCPServersStorage = class extends MCPServersStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "mcp-servers.json", | ||
| parentIdField: "mcpServerId", | ||
| name: "FilesystemMCPServersStorage", | ||
| versionMetadataFields: ["id", "mcpServerId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { mcpServer } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: mcpServer.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpServer.authorId, | ||
| metadata: mcpServer.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(mcpServer.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpServerId: mcpServer.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "mcpServers", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(mcpServerId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(mcpServerId, versionNumber); | ||
| } | ||
| async getLatestVersion(mcpServerId) { | ||
| return this.helpers.getLatestVersion(mcpServerId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "mcpServerId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(mcpServerId) { | ||
| return this.helpers.countVersions(mcpServerId); | ||
| } | ||
| }; | ||
| export { FilesystemMCPServersStorage, InMemoryMCPServersStorage, MCPServersStorage }; | ||
| //# sourceMappingURL=chunk-B7OS7GGE.js.map | ||
| //# sourceMappingURL=chunk-B7OS7GGE.js.map |
| {"version":3,"sources":["../src/storage/domains/mcp-servers/base.ts","../src/storage/domains/mcp-servers/inmemory.ts","../src/storage/domains/mcp-servers/filesystem.ts"],"names":["version"],"mappings":"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","file":"chunk-B7OS7GGE.js","sourcesContent":["import type {\n StorageMCPServerType,\n StorageMCPServerSnapshotType,\n StorageResolvedMCPServerType,\n StorageCreateMCPServerInput,\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput,\n StorageListMCPServersOutput,\n StorageListMCPServersResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// MCP Server Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of an MCP server's content.\n * Server fields are top-level on the version row (no nested snapshot object).\n */\nexport interface MCPServerVersion extends StorageMCPServerSnapshotType, VersionBase {\n /** ID of the MCP server this version belongs to */\n mcpServerId: string;\n}\n\n/**\n * Input for creating a new MCP server version.\n * Server fields are top-level (no nested snapshot object).\n */\nexport interface CreateMCPServerVersionInput extends StorageMCPServerSnapshotType, CreateVersionInputBase {\n /** ID of the MCP server this version belongs to */\n mcpServerId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type MCPServerVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type MCPServerVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing MCP server versions with pagination and sorting.\n */\nexport interface ListMCPServerVersionsInput extends ListVersionsInputBase {\n /** ID of the MCP server to list versions for */\n mcpServerId: string;\n}\n\n/**\n * Output for listing MCP server versions with pagination info.\n */\nexport interface ListMCPServerVersionsOutput extends ListVersionsOutputBase<MCPServerVersion> {}\n\n// ============================================================================\n// MCPServersStorage Base Class\n// ============================================================================\n\nexport abstract class MCPServersStorage extends VersionedStorageDomain<\n StorageMCPServerType,\n StorageMCPServerSnapshotType,\n StorageResolvedMCPServerType,\n MCPServerVersion,\n CreateMCPServerVersionInput,\n ListMCPServerVersionsInput,\n ListMCPServerVersionsOutput,\n { mcpServer: StorageCreateMCPServerInput },\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput | undefined,\n StorageListMCPServersOutput,\n StorageListMCPServersResolvedOutput\n> {\n protected readonly listKey = 'mcpServers';\n protected readonly versionMetadataFields = [\n 'id',\n 'mcpServerId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof MCPServerVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'MCP_SERVERS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageMCPServerType,\n StorageCreateMCPServerInput,\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput,\n StorageListMCPServersOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n MCPServerVersion,\n CreateMCPServerVersionInput,\n ListMCPServerVersionsInput,\n ListMCPServerVersionsOutput,\n MCPServerVersionOrderBy,\n MCPServerVersionSortDirection,\n} from './base';\nimport { MCPServersStorage } from './base';\n\nexport class InMemoryMCPServersStorage extends MCPServersStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.mcpServers.clear();\n this.db.mcpServerVersions.clear();\n }\n\n // ==========================================================================\n // MCP Server CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageMCPServerType | null> {\n const config = this.db.mcpServers.get(id);\n return config ? this.deepCopyConfig(config) : null;\n }\n\n async create(input: { mcpServer: StorageCreateMCPServerInput }): Promise<StorageMCPServerType> {\n const { mcpServer } = input;\n\n if (this.db.mcpServers.has(mcpServer.id)) {\n throw new Error(`MCP server with id ${mcpServer.id} already exists`);\n }\n\n const now = new Date();\n const newConfig: StorageMCPServerType = {\n id: mcpServer.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpServer.authorId,\n metadata: mcpServer.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.mcpServers.set(mcpServer.id, newConfig);\n\n // Extract config fields from the flat input (everything except record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpServerId: mcpServer.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin record\n return this.deepCopyConfig(newConfig);\n }\n\n async update(input: StorageUpdateMCPServerInput): Promise<StorageMCPServerType> {\n const { id, ...updates } = input;\n\n const existingConfig = this.db.mcpServers.get(id);\n if (!existingConfig) {\n throw new Error(`MCP server with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the record\n const updatedConfig: StorageMCPServerType = {\n ...existingConfig,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageMCPServerType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingConfig.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated record\n this.db.mcpServers.set(id, updatedConfig);\n return this.deepCopyConfig(updatedConfig);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.mcpServers.delete(id);\n // Also delete all versions for this server\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListMCPServersInput): Promise<StorageListMCPServersOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status = 'published' } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all MCP servers and apply filters\n let configs = Array.from(this.db.mcpServers.values());\n\n // Filter by status\n if (status) {\n configs = configs.filter(config => config.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n configs = configs.filter(config => config.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n configs = configs.filter(config => {\n if (!config.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata![key], value));\n });\n }\n\n // Sort filtered configs\n const sortedConfigs = this.sortConfigs(configs, field, direction);\n\n // Deep clone to avoid mutation\n const clonedConfigs = sortedConfigs.map(config => this.deepCopyConfig(config));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n mcpServers: clonedConfigs.slice(offset, offset + perPage),\n total: clonedConfigs.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedConfigs.length,\n };\n }\n\n // ==========================================================================\n // MCP Server Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateMCPServerVersionInput): Promise<MCPServerVersion> {\n // Check if version with this ID already exists\n if (this.db.mcpServerVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (mcpServerId, versionNumber) pair\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === input.mcpServerId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for MCP server ${input.mcpServerId}`);\n }\n }\n\n const version: MCPServerVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.mcpServerVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<MCPServerVersion | null> {\n const version = this.db.mcpServerVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(mcpServerId: string, versionNumber: number): Promise<MCPServerVersion | null> {\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === mcpServerId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(mcpServerId: string): Promise<MCPServerVersion | null> {\n let latest: MCPServerVersion | null = null;\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === mcpServerId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListMCPServerVersionsInput): Promise<ListMCPServerVersionsOutput> {\n const { mcpServerId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by mcpServerId\n let versions = Array.from(this.db.mcpServerVersions.values()).filter(v => v.mcpServerId === mcpServerId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.mcpServerVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.mcpServerVersions.entries()) {\n if (version.mcpServerId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.mcpServerVersions.delete(id);\n }\n }\n\n async countVersions(mcpServerId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === mcpServerId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyConfig(config: StorageMCPServerType): StorageMCPServerType {\n return {\n ...config,\n metadata: config.metadata ? { ...config.metadata } : config.metadata,\n };\n }\n\n private deepCopyVersion(version: MCPServerVersion): MCPServerVersion {\n return {\n ...version,\n tools: version.tools ? JSON.parse(JSON.stringify(version.tools)) : version.tools,\n agents: version.agents ? JSON.parse(JSON.stringify(version.agents)) : version.agents,\n workflows: version.workflows ? JSON.parse(JSON.stringify(version.workflows)) : version.workflows,\n repository: version.repository ? { ...version.repository } : version.repository,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortConfigs(\n configs: StorageMCPServerType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageMCPServerType[] {\n return configs.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: MCPServerVersion[],\n field: MCPServerVersionOrderBy,\n direction: MCPServerVersionSortDirection,\n ): MCPServerVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageMCPServerType,\n StorageCreateMCPServerInput,\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput,\n StorageListMCPServersOutput,\n} from '../../types';\nimport type {\n MCPServerVersion,\n CreateMCPServerVersionInput,\n ListMCPServerVersionsInput,\n ListMCPServerVersionsOutput,\n} from './base';\nimport { MCPServersStorage } from './base';\n\nexport class FilesystemMCPServersStorage extends MCPServersStorage {\n private helpers: FilesystemVersionedHelpers<StorageMCPServerType, MCPServerVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'mcp-servers.json',\n parentIdField: 'mcpServerId',\n name: 'FilesystemMCPServersStorage',\n versionMetadataFields: ['id', 'mcpServerId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageMCPServerType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { mcpServer: StorageCreateMCPServerInput }): Promise<StorageMCPServerType> {\n const { mcpServer } = input;\n const now = new Date();\n const entity: StorageMCPServerType = {\n id: mcpServer.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpServer.authorId,\n metadata: mcpServer.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(mcpServer.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpServerId: mcpServer.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateMCPServerVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateMCPServerInput): Promise<StorageMCPServerType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListMCPServersInput): Promise<StorageListMCPServersOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'mcpServers',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListMCPServersOutput;\n }\n\n async createVersion(input: CreateMCPServerVersionInput): Promise<MCPServerVersion> {\n return this.helpers.createVersion(input as MCPServerVersion);\n }\n\n async getVersion(id: string): Promise<MCPServerVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(mcpServerId: string, versionNumber: number): Promise<MCPServerVersion | null> {\n return this.helpers.getVersionByNumber(mcpServerId, versionNumber);\n }\n\n async getLatestVersion(mcpServerId: string): Promise<MCPServerVersion | null> {\n return this.helpers.getLatestVersion(mcpServerId);\n }\n\n async listVersions(input: ListMCPServerVersionsInput): Promise<ListMCPServerVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'mcpServerId');\n return result as ListMCPServerVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(mcpServerId: string): Promise<number> {\n return this.helpers.countVersions(mcpServerId);\n }\n}\n"]} |
| 'use strict'; | ||
| var crypto = require('crypto'); | ||
| var v4 = require('zod/v4'); | ||
| // src/background-tasks/manager.ts | ||
| // src/background-tasks/workflow-id.ts | ||
| var BACKGROUND_TASK_WORKFLOW_ID = "__background-task"; | ||
| // src/background-tasks/manager.ts | ||
| var TOPIC_DISPATCH = "background-tasks"; | ||
| var TOPIC_RESULT = "background-tasks-result"; | ||
| var WORKER_GROUP = "background-task-workers"; | ||
| var BackgroundTaskManager = class { | ||
| pubsub; | ||
| config; | ||
| #mastra; | ||
| // Per-task contexts — keyed by task ID, holds closures from the caller's stream. | ||
| /** @internal — read by the workflow-engine step bodies in workflow.ts */ | ||
| taskContexts = /* @__PURE__ */ new Map(); | ||
| // Static executors keyed by tool name. Populated by `Mastra` for every | ||
| // registered tool, and by `BackgroundTaskWorker.#wireStaticTools` on | ||
| // standalone worker processes. Used as the fallback for cross-process | ||
| // dispatch where the producer's per-task closure (taskContexts) is not | ||
| // visible — a remote worker resolves the tool by name instead. | ||
| staticExecutors = /* @__PURE__ */ new Map(); | ||
| // Track active AbortControllers for running tasks (for cancellation + timeout) | ||
| /** @internal — read by the workflow-engine step bodies in workflow.ts */ | ||
| activeAbortControllers = /* @__PURE__ */ new Map(); | ||
| // Pubsub callbacks (kept for unsubscribe) | ||
| workerCallback; | ||
| resultCallback; | ||
| shuttingDown = false; | ||
| // Cleanup interval handle | ||
| cleanupInterval; | ||
| // Tracks the in-flight `init(pubsub)` so consumers can await readiness. | ||
| // Mastra fires init as fire-and-forget in `#ensureBackgroundTaskManager`, | ||
| // so without this any caller that hits `enqueue`/`resume`/`cancel` | ||
| // before init completes races against worker subscription + workflow | ||
| // registration. Public methods that depend on init await this promise | ||
| // before doing work. | ||
| initPromise; | ||
| constructor(config = { enabled: false }) { | ||
| this.config = { | ||
| globalConcurrency: config.globalConcurrency ?? 10, | ||
| perAgentConcurrency: config.perAgentConcurrency ?? 5, | ||
| backpressure: config.backpressure ?? "queue", | ||
| defaultTimeoutMs: config.defaultTimeoutMs ?? 3e5, | ||
| ...config | ||
| }; | ||
| } | ||
| __registerMastra(mastra) { | ||
| this.#mastra = mastra; | ||
| } | ||
| async getStorage() { | ||
| const storage = this.#mastra?.getStorage(); | ||
| if (!storage) { | ||
| throw new Error("Storage is not initialized"); | ||
| } | ||
| const bgStore = await storage.getStore("backgroundTasks"); | ||
| if (!bgStore) { | ||
| throw new Error("Background tasks storage is not available"); | ||
| } | ||
| return bgStore; | ||
| } | ||
| async init(pubsub) { | ||
| if (this.initPromise) return this.initPromise; | ||
| this.initPromise = this.#doInit(pubsub); | ||
| return this.initPromise; | ||
| } | ||
| async #doInit(pubsub) { | ||
| this.pubsub = pubsub; | ||
| this.workerCallback = async (event, ack) => { | ||
| if (event.type === "task.dispatch") { | ||
| await this.handleDispatch(event); | ||
| } else if (event.type === "task.resume") { | ||
| await this.handleResume(event); | ||
| } else if (event.type === "task.cancel") { | ||
| this.handleCancel(event); | ||
| } | ||
| await ack?.(); | ||
| }; | ||
| this.resultCallback = async (event, ack) => { | ||
| if (event.type === "task.completed" || event.type === "task.failed") { | ||
| await this.handleResult(event); | ||
| } | ||
| await ack?.(); | ||
| }; | ||
| if (this.#mastra) { | ||
| const { buildBackgroundTaskWorkflow } = await import('./workflow-ZBZQHIFN.cjs'); | ||
| const workflow = buildBackgroundTaskWorkflow(this); | ||
| if (!this.#mastra.__hasInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID)) { | ||
| this.#mastra.__registerInternalWorkflow( | ||
| workflow | ||
| ); | ||
| } | ||
| } | ||
| await this.pubsub.subscribe(TOPIC_DISPATCH, this.workerCallback, { group: WORKER_GROUP }); | ||
| await this.pubsub.subscribe(TOPIC_RESULT, this.resultCallback); | ||
| await this.recoverStaleTasks(); | ||
| const cleanupConfig = this.config.cleanup; | ||
| if (cleanupConfig) { | ||
| const intervalMs = cleanupConfig.cleanupIntervalMs ?? 6e4; | ||
| this.cleanupInterval = setInterval(() => { | ||
| void this.cleanup(); | ||
| }, intervalMs); | ||
| } | ||
| } | ||
| // --- Per-task context registration --- | ||
| /** | ||
| * Register per-task hooks (executor, stream emitter, result injector). | ||
| * Called internally by createBackgroundTask or directly for advanced usage. | ||
| */ | ||
| registerTaskContext(taskId, context) { | ||
| this.taskContexts.set(taskId, context); | ||
| } | ||
| /** | ||
| * Remove per-task hooks. Called after task reaches terminal state. | ||
| */ | ||
| deregisterTaskContext(taskId) { | ||
| this.taskContexts.delete(taskId); | ||
| } | ||
| /** | ||
| * Register a tool executor by tool name. Used for cross-process dispatch: | ||
| * when a worker in a different process picks up a `task.dispatch` event, | ||
| * it has no per-task closure (`taskContexts`) for that taskId, but it can | ||
| * resolve the executor by tool name via this registry. | ||
| */ | ||
| registerStaticExecutor(toolName, executor) { | ||
| if (this.staticExecutors.has(toolName)) { | ||
| this.#mastra?.getLogger?.()?.debug?.(`Overwriting existing static executor for tool "${toolName}"`); | ||
| } | ||
| this.staticExecutors.set(toolName, executor); | ||
| } | ||
| /** | ||
| * Symmetric to `registerStaticExecutor`. Called when a tool is removed | ||
| * from `Mastra`. | ||
| */ | ||
| unregisterStaticExecutor(toolName) { | ||
| this.staticExecutors.delete(toolName); | ||
| } | ||
| /** | ||
| * Look up an executor by tool name. Read by the workflow-step body in | ||
| * `workflow.ts:runAttemptStep` as a fallback when no per-task `TaskContext` | ||
| * is registered (cross-process path). | ||
| */ | ||
| getStaticExecutor(toolName) { | ||
| return this.staticExecutors.get(toolName); | ||
| } | ||
| // --- Core operations --- | ||
| /** | ||
| * Enqueue a task for background execution. | ||
| * Prefer `createBackgroundTask()` which returns a self-contained handle. | ||
| */ | ||
| async enqueue(payload, context) { | ||
| if (this.shuttingDown) { | ||
| throw new Error("BackgroundTaskManager is shutting down, cannot enqueue new tasks"); | ||
| } | ||
| if (this.initPromise) await this.initPromise; | ||
| const task = { | ||
| id: this.#mastra?.generateId() ?? crypto.randomUUID(), | ||
| status: "pending", | ||
| toolName: payload.toolName, | ||
| toolCallId: payload.toolCallId, | ||
| args: payload.args, | ||
| agentId: payload.agentId, | ||
| threadId: payload.threadId, | ||
| resourceId: payload.resourceId, | ||
| runId: payload.runId, | ||
| retryCount: 0, | ||
| maxRetries: payload.maxRetries ?? this.config.defaultRetries?.maxRetries ?? 0, | ||
| timeoutMs: payload.timeoutMs ?? this.config.defaultTimeoutMs, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| if (context) { | ||
| this.registerTaskContext(task.id, context); | ||
| } | ||
| const storage = await this.getStorage(); | ||
| await storage.createTask(task); | ||
| const canRun = await this.checkConcurrency(task.agentId); | ||
| if (canRun) { | ||
| await this.dispatch(task); | ||
| return { task }; | ||
| } | ||
| switch (this.config.backpressure) { | ||
| case "reject": | ||
| this.deregisterTaskContext(task.id); | ||
| await storage.deleteTask(task.id); | ||
| throw new Error(`Concurrency limit reached, cannot enqueue task for tool "${task.toolName}"`); | ||
| case "fallback-sync": | ||
| this.deregisterTaskContext(task.id); | ||
| await storage.deleteTask(task.id); | ||
| return { task, fallbackToSync: true }; | ||
| case "queue": | ||
| default: | ||
| return { task }; | ||
| } | ||
| } | ||
| async cancel(taskId) { | ||
| if (this.initPromise) await this.initPromise; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task) { | ||
| throw new Error(`Task not found: ${taskId}`); | ||
| } | ||
| if (task.status === "completed" || task.status === "failed" || task.status === "cancelled" || task.status === "timed_out") { | ||
| return; | ||
| } | ||
| if (task.status === "pending") { | ||
| await storage.updateTask(taskId, { status: "cancelled", completedAt: /* @__PURE__ */ new Date() }); | ||
| const cancelledTask = await storage.getTask(taskId); | ||
| if (cancelledTask) await this.publishLifecycleEvent("task.cancelled", cancelledTask); | ||
| this.deregisterTaskContext(taskId); | ||
| return; | ||
| } | ||
| if (task.status === "suspended") { | ||
| await storage.updateTask(taskId, { status: "cancelled", completedAt: /* @__PURE__ */ new Date() }); | ||
| if (this.#mastra) { | ||
| try { | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const wrapper = await workflow.createRun({ runId: taskId }); | ||
| await wrapper.cancel(); | ||
| } catch (err) { | ||
| this.#mastra?.getLogger?.()?.warn(`background-task workflow cancel failed for ${taskId}:`, err); | ||
| } | ||
| } | ||
| const cancelledTask = await storage.getTask(taskId); | ||
| if (cancelledTask) await this.publishLifecycleEvent("task.cancelled", cancelledTask); | ||
| this.deregisterTaskContext(taskId); | ||
| return; | ||
| } | ||
| if (task.status === "running") { | ||
| await storage.updateTask(taskId, { status: "cancelled", completedAt: /* @__PURE__ */ new Date() }); | ||
| const controller = this.activeAbortControllers.get(taskId); | ||
| if (controller) { | ||
| controller.abort(new Error("Task cancelled")); | ||
| this.activeAbortControllers.delete(taskId); | ||
| } | ||
| if (this.#mastra) { | ||
| try { | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const wrapper = await workflow.createRun({ runId: taskId }); | ||
| await wrapper.cancel(); | ||
| } catch (err) { | ||
| this.#mastra?.getLogger?.()?.warn(`background-task workflow cancel failed for ${taskId}:`, err); | ||
| } | ||
| } | ||
| const cancelledTask = await storage.getTask(taskId); | ||
| if (cancelledTask) await this.publishLifecycleEvent("task.cancelled", cancelledTask); | ||
| this.deregisterTaskContext(taskId); | ||
| await this.pubsub.publish(TOPIC_DISPATCH, { | ||
| type: "task.cancel", | ||
| data: { taskId }, | ||
| runId: taskId | ||
| }); | ||
| } | ||
| } | ||
| /** | ||
| * Resume a suspended task. The tool executor must be re-registered via | ||
| * `registerTaskContext(taskId, ...)` before calling this if the original | ||
| * registration is gone (e.g. process restart) — the manager doesn't | ||
| * rehydrate executor closures from storage. | ||
| * | ||
| * `resumeData` is forwarded to the tool's `execute` options on the | ||
| * resumed run. | ||
| */ | ||
| async resume(taskId, resumeData) { | ||
| if (!this.#mastra) { | ||
| throw new Error("Mastra is not registered with this manager"); | ||
| } | ||
| if (this.initPromise) await this.initPromise; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task) { | ||
| throw new Error(`Task not found: ${taskId}`); | ||
| } | ||
| if (task.status !== "suspended") { | ||
| throw new Error(`Cannot resume task in status '${task.status}' (expected 'suspended')`); | ||
| } | ||
| const canRun = await this.checkConcurrency(task.agentId); | ||
| if (!canRun) { | ||
| throw new Error(`Concurrency limit reached, cannot resume task "${taskId}" \u2014 retry once a slot is available`); | ||
| } | ||
| await this.pubsub.publish(TOPIC_DISPATCH, { | ||
| type: "task.resume", | ||
| data: { taskId, resumeData }, | ||
| runId: taskId | ||
| }); | ||
| return task; | ||
| } | ||
| async getTask(taskId) { | ||
| const storage = await this.getStorage(); | ||
| return storage.getTask(taskId); | ||
| } | ||
| async listTasks(filter = {}) { | ||
| const storage = await this.getStorage(); | ||
| return storage.listTasks(filter); | ||
| } | ||
| /** | ||
| * Deletes old completed/failed/cancelled/timed_out task records from storage. | ||
| */ | ||
| async cleanup() { | ||
| const completedTtlMs = this.config.cleanup?.completedTtlMs ?? 36e5; | ||
| const failedTtlMs = this.config.cleanup?.failedTtlMs ?? 864e5; | ||
| const now = Date.now(); | ||
| const storage = await this.getStorage(); | ||
| await storage.deleteTasks({ | ||
| status: ["completed"], | ||
| toDate: new Date(now - completedTtlMs), | ||
| dateFilterBy: "completedAt" | ||
| }); | ||
| await storage.deleteTasks({ | ||
| status: ["failed", "cancelled", "timed_out"], | ||
| toDate: new Date(now - failedTtlMs), | ||
| dateFilterBy: "completedAt" | ||
| }); | ||
| } | ||
| /** | ||
| * Returns a promise that resolves when the next task from the given set | ||
| * reaches a terminal state. | ||
| */ | ||
| async waitForNextTask(taskIds, options) { | ||
| const storage = await this.getStorage(); | ||
| const isTerminal = (status) => status === "completed" || status === "failed" || status === "cancelled" || status === "timed_out"; | ||
| for (const id of taskIds) { | ||
| const task = await storage.getTask(id); | ||
| if (task && isTerminal(task.status)) { | ||
| return task; | ||
| } | ||
| } | ||
| return new Promise((resolve, reject) => { | ||
| const startTime = Date.now(); | ||
| const timeout = options?.timeoutMs ? setTimeout(() => { | ||
| clearInterval(pollInterval); | ||
| if (progressInterval) clearInterval(progressInterval); | ||
| reject(new Error("Timed out waiting for background task")); | ||
| }, options.timeoutMs) : void 0; | ||
| const progressInterval = options?.onProgress ? setInterval(() => { | ||
| options.onProgress(Date.now() - startTime); | ||
| }, options.progressIntervalMs ?? 3e3) : void 0; | ||
| const pollInterval = setInterval(async () => { | ||
| for (const id of taskIds) { | ||
| const task = await storage.getTask(id); | ||
| if (task && isTerminal(task.status)) { | ||
| clearInterval(pollInterval); | ||
| if (timeout) clearTimeout(timeout); | ||
| if (progressInterval) clearInterval(progressInterval); | ||
| resolve(task); | ||
| return; | ||
| } | ||
| } | ||
| }, 50); | ||
| }); | ||
| } | ||
| /** | ||
| * Returns a ReadableStream of all background task lifecycle events, | ||
| * filtered by optional criteria. Intended to be piped directly to an SSE response. | ||
| * | ||
| * On connection, emits the current state of all non-terminal tasks as a snapshot, | ||
| * then subscribes to live pubsub events for subsequent updates. | ||
| * | ||
| * Events include: | ||
| * - `task.running` (status: 'running') — task picked up by a worker | ||
| * - `task.completed` (status: 'completed') — task finished successfully | ||
| * - `task.failed` (status: 'failed' or 'timed_out') — task errored or timed out | ||
| * - `task.cancelled` (status: 'cancelled') — task was cancelled | ||
| * - `task.suspended` (status: 'suspended') — task paused via `suspend()` from | ||
| * inside its tool executor; resume with `manager.resume(taskId, data)` | ||
| * - `task.resumed` (status: 'running') — suspended task resumed | ||
| * | ||
| * The stream stays open until the caller's AbortSignal fires (client disconnect). | ||
| */ | ||
| stream(options) { | ||
| const manager = this; | ||
| const pubsub = this.pubsub; | ||
| const { agentId, runId, threadId, resourceId, abortSignal, taskId } = options ?? {}; | ||
| const EVENT_STATUS_MAP = { | ||
| "task.running": "running", | ||
| "task.output": "running", | ||
| "task.completed": "completed", | ||
| "task.failed": "failed", | ||
| "task.cancelled": "cancelled", | ||
| "task.suspended": "suspended", | ||
| "task.resumed": "running" | ||
| }; | ||
| const CHUNK_EVENT_MAP = { | ||
| "task.running": "background-task-running", | ||
| "task.output": "background-task-output", | ||
| "task.completed": "background-task-completed", | ||
| "task.failed": "background-task-failed", | ||
| "task.cancelled": "background-task-cancelled", | ||
| "task.suspended": "background-task-suspended", | ||
| "task.resumed": "background-task-resumed" | ||
| }; | ||
| return new ReadableStream({ | ||
| async start(controller) { | ||
| const handler = async (event) => { | ||
| const status = EVENT_STATUS_MAP[event.type]; | ||
| if (!status) return; | ||
| const data = event.data; | ||
| if (agentId && data.agentId !== agentId) return; | ||
| if (runId && data.runId !== runId) return; | ||
| if (threadId && data.threadId !== threadId) return; | ||
| if (resourceId && data.resourceId !== resourceId) return; | ||
| if (taskId && data.taskId !== taskId) return; | ||
| const payload = { | ||
| taskId: data.taskId, | ||
| toolName: data.toolName, | ||
| toolCallId: data.toolCallId, | ||
| agentId: data.agentId, | ||
| runId: data.runId | ||
| }; | ||
| switch (event.type) { | ||
| case "task.running": | ||
| payload.startedAt = data.startedAt; | ||
| payload.args = data.args; | ||
| break; | ||
| case "task.completed": | ||
| payload.completedAt = data.completedAt; | ||
| payload.result = data.result; | ||
| break; | ||
| case "task.failed": | ||
| payload.completedAt = data.completedAt; | ||
| payload.error = data.error; | ||
| break; | ||
| case "task.cancelled": | ||
| payload.completedAt = data.completedAt; | ||
| break; | ||
| case "task.output": | ||
| payload.payload = data.chunk; | ||
| break; | ||
| case "task.suspended": | ||
| payload.suspendPayload = data.suspendPayload; | ||
| payload.suspendedAt = data.suspendedAt; | ||
| payload.args = data.args; | ||
| break; | ||
| case "task.resumed": | ||
| payload.startedAt = data.startedAt; | ||
| payload.args = data.args; | ||
| break; | ||
| } | ||
| try { | ||
| controller.enqueue({ | ||
| type: CHUNK_EVENT_MAP[event.type], | ||
| payload | ||
| }); | ||
| } catch { | ||
| } | ||
| }; | ||
| void pubsub.subscribe(TOPIC_RESULT, handler); | ||
| abortSignal?.addEventListener("abort", () => { | ||
| void pubsub.unsubscribe(TOPIC_RESULT, handler); | ||
| try { | ||
| controller.close(); | ||
| } catch { | ||
| } | ||
| }); | ||
| try { | ||
| const storage = await manager.getStorage(); | ||
| if (taskId) { | ||
| const task = await storage.getTask(taskId); | ||
| if (task && task.status === "running") { | ||
| controller.enqueue({ | ||
| type: "background-task-running", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| agentId: task.agentId, | ||
| runId: task.runId, | ||
| startedAt: task.startedAt, | ||
| args: task.args | ||
| } | ||
| }); | ||
| } | ||
| } else { | ||
| const { tasks: existing } = await storage.listTasks({ | ||
| agentId, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| status: ["running"] | ||
| }); | ||
| for (const task of existing) { | ||
| if (abortSignal?.aborted) break; | ||
| try { | ||
| controller.enqueue({ | ||
| type: "background-task-running", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| agentId: task.agentId, | ||
| runId: task.runId, | ||
| startedAt: task.startedAt, | ||
| args: task.args | ||
| } | ||
| }); | ||
| } catch { | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| } catch { | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| async shutdown() { | ||
| this.shuttingDown = true; | ||
| if (this.cleanupInterval) { | ||
| clearInterval(this.cleanupInterval); | ||
| this.cleanupInterval = void 0; | ||
| } | ||
| if (this.workerCallback) { | ||
| await this.pubsub.unsubscribe(TOPIC_DISPATCH, this.workerCallback); | ||
| } | ||
| if (this.resultCallback) { | ||
| await this.pubsub.unsubscribe(TOPIC_RESULT, this.resultCallback); | ||
| } | ||
| this.taskContexts.clear(); | ||
| await this.pubsub.flush(); | ||
| } | ||
| // --- Internal --- | ||
| async dispatch(task) { | ||
| await this.pubsub.publish(TOPIC_DISPATCH, { | ||
| type: "task.dispatch", | ||
| data: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| args: task.args, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| timeoutMs: task.timeoutMs, | ||
| maxRetries: task.maxRetries, | ||
| runId: task.runId | ||
| }, | ||
| runId: task.id | ||
| }); | ||
| } | ||
| /** | ||
| * Handles a task.dispatch event. Returns true if the message was nacked (for retry). | ||
| */ | ||
| async handleDispatch(event) { | ||
| const { taskId } = event.data; | ||
| const deliveryAttempt = event.deliveryAttempt ?? 1; | ||
| let nacked = false; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task || task.status === "cancelled") { | ||
| this.deregisterTaskContext(taskId); | ||
| return false; | ||
| } | ||
| await storage.updateTask(taskId, { status: "running", startedAt: /* @__PURE__ */ new Date(), retryCount: deliveryAttempt - 1 }); | ||
| const runningTask = await storage.getTask(taskId); | ||
| if (runningTask) await this.publishLifecycleEvent("task.running", runningTask); | ||
| if (this.#mastra) { | ||
| if (runningTask) void this.runLocalExecutionHook(runningTask); | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const run = await workflow.createRun({ runId: taskId }); | ||
| void run.start({ inputData: { taskId } }).then((result) => { | ||
| if (result.status !== "suspended") { | ||
| void workflow.deleteWorkflowRunById(taskId); | ||
| } | ||
| }).catch((err) => { | ||
| this.#mastra?.getLogger?.()?.error(`background-task workflow start failed for ${taskId}:`, err); | ||
| }).finally(() => { | ||
| void this.drainPending(); | ||
| }); | ||
| } | ||
| return nacked; | ||
| } | ||
| /** | ||
| * Handles a task.resume event. Mirrors the workflow branch of handleDispatch | ||
| * but resumes an existing run from its suspended snapshot instead of starting | ||
| * a fresh one. Concurrency gating, suspended-status validation, and the | ||
| * `task.resumed` lifecycle publish all happen here so a different process | ||
| * than the one that suspended the task can drive the resume. | ||
| */ | ||
| async handleResume(event) { | ||
| const { taskId, resumeData } = event.data; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task || task.status !== "suspended") { | ||
| return; | ||
| } | ||
| await storage.updateTask(taskId, { | ||
| status: "running", | ||
| startedAt: /* @__PURE__ */ new Date(), | ||
| suspendPayload: void 0, | ||
| suspendedAt: void 0 | ||
| }); | ||
| const resumedTask = await storage.getTask(taskId); | ||
| if (resumedTask) { | ||
| await this.publishLifecycleEvent("task.resumed", resumedTask); | ||
| } | ||
| if (!this.#mastra) return; | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const run = await workflow.createRun({ runId: taskId }); | ||
| void run.resume({ resumeData }).then((result) => { | ||
| if (result.status !== "suspended") { | ||
| void workflow.deleteWorkflowRunById(taskId); | ||
| } | ||
| }).catch((err) => { | ||
| this.#mastra?.getLogger?.()?.error(`background-task workflow resume failed for ${taskId}:`, err); | ||
| }).finally(() => { | ||
| void this.drainPending(); | ||
| }); | ||
| } | ||
| /** | ||
| * Run per-task hooks (onChunk, onResult, onComplete/onFailed) locally in the | ||
| * worker path, before publishing the terminal lifecycle event. Ensures | ||
| * memory / stream state is consistent by the time any pubsub subscriber is | ||
| * notified. After running, the task context is deregistered so | ||
| * `handleResult` (which also fires from pubsub) becomes a no-op for this | ||
| * task in the same process. | ||
| * | ||
| * In distributed deployments where the worker runs in a different process | ||
| * from the dispatcher, `this.taskContexts` won't contain an entry for | ||
| * `task.id` — this method is a no-op there, and `handleResult` in the | ||
| * dispatching process runs the hooks instead. | ||
| */ | ||
| /** | ||
| * Terminal-state hooks only. Called when a task reaches `'completed'` or | ||
| * `'failed'`. Suspend is non-terminal — see `runLocalSuspendHooks` for that | ||
| * path. | ||
| * | ||
| * @internal — also called by the workflow-engine step bodies in workflow.ts | ||
| */ | ||
| async runLocalCompletionHooks(task, status, extras) { | ||
| const ctx = this.taskContexts.get(task.id); | ||
| if (!ctx) return; | ||
| try { | ||
| if (status === "completed") { | ||
| ctx.onChunk?.({ | ||
| type: "background-task-completed", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| runId: task.runId, | ||
| result: extras.result, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx.onResult?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| result: extras.result, | ||
| status: "completed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| await ctx.onComplete?.(task); | ||
| } else { | ||
| ctx.onChunk?.({ | ||
| type: "background-task-failed", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| runId: task.runId, | ||
| error: extras.error ?? { message: "Unknown error" }, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx.onResult?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| error: extras.error, | ||
| status: "failed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| await ctx.onFailed?.(task); | ||
| } | ||
| } finally { | ||
| this.deregisterTaskContext(task.id); | ||
| } | ||
| } | ||
| /** | ||
| * Per-task suspend hooks. Fires `ctx.onResult({ status: 'suspended', ... })` | ||
| * so the message list / memory pick up the suspension as the tool's | ||
| * current invocation state. Does NOT deregister the task context — resume | ||
| * needs the executor closure intact. | ||
| * | ||
| * @internal — called by the workflow-engine step bodies in workflow.ts | ||
| */ | ||
| async runLocalSuspendHooks(task) { | ||
| const ctx = this.taskContexts.get(task.id); | ||
| if (!ctx) return; | ||
| await ctx.onExecution?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| startedAt: task.startedAt, | ||
| suspendedAt: task.suspendedAt | ||
| }); | ||
| } | ||
| /** @internal — also called by the workflow-engine step bodies in workflow.ts */ | ||
| async runLocalExecutionHook(task) { | ||
| const ctx = this.taskContexts.get(task.id); | ||
| if (!ctx) return; | ||
| try { | ||
| await ctx.onExecution?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| startedAt: task.startedAt | ||
| }); | ||
| } catch { | ||
| } | ||
| } | ||
| async handleResult(event) { | ||
| const { taskId, toolName, toolCallId, threadId, resourceId, runId } = event.data; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (task?.completedAt) { | ||
| const ctx = this.taskContexts.get(taskId); | ||
| if (event.type === "task.completed") { | ||
| ctx?.onChunk?.({ | ||
| type: "background-task-completed", | ||
| payload: { | ||
| taskId, | ||
| toolName, | ||
| toolCallId, | ||
| runId, | ||
| result: event.data.result, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx?.onResult?.({ | ||
| runId, | ||
| taskId, | ||
| toolCallId, | ||
| toolName, | ||
| agentId: event.data.agentId, | ||
| threadId, | ||
| resourceId, | ||
| result: event.data.result, | ||
| status: "completed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| if (task) { | ||
| await Promise.all([ctx?.onComplete?.(task), this.config.onTaskComplete?.(task)]); | ||
| } | ||
| } | ||
| if (event.type === "task.failed") { | ||
| ctx?.onChunk?.({ | ||
| type: "background-task-failed", | ||
| payload: { | ||
| taskId, | ||
| toolName, | ||
| toolCallId, | ||
| runId, | ||
| error: event.data.error, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx?.onResult?.({ | ||
| runId, | ||
| taskId, | ||
| toolCallId, | ||
| toolName, | ||
| agentId: event.data.agentId, | ||
| threadId, | ||
| resourceId, | ||
| error: event.data.error, | ||
| status: "failed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| if (task) { | ||
| await Promise.all([ctx?.onFailed?.(task), this.config.onTaskFailed?.(task)]); | ||
| } | ||
| } | ||
| this.deregisterTaskContext(taskId); | ||
| } | ||
| } | ||
| handleCancel(event) { | ||
| const { taskId } = event.data; | ||
| const controller = this.activeAbortControllers.get(taskId); | ||
| if (controller) { | ||
| controller.abort(new Error("Task cancelled")); | ||
| this.activeAbortControllers.delete(taskId); | ||
| } | ||
| this.deregisterTaskContext(taskId); | ||
| } | ||
| /** @internal — also called by the workflow-engine step bodies in workflow.ts */ | ||
| async publishLifecycleEvent(type, task) { | ||
| await this.pubsub.publish(TOPIC_RESULT, { | ||
| type, | ||
| data: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| runId: task.runId, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| args: task.args, | ||
| result: task.result, | ||
| error: task.error, | ||
| chunk: task.chunk, | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt, | ||
| suspendPayload: task.suspendPayload, | ||
| suspendedAt: task.suspendedAt | ||
| }, | ||
| runId: task.id | ||
| }); | ||
| } | ||
| async checkConcurrency(agentId) { | ||
| const storage = await this.getStorage(); | ||
| const globalRunning = await storage.getRunningCount(); | ||
| if (globalRunning >= this.config.globalConcurrency) { | ||
| return false; | ||
| } | ||
| const agentRunning = await storage.getRunningCountByAgent(agentId); | ||
| if (agentRunning >= this.config.perAgentConcurrency) { | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| async drainPending() { | ||
| const storage = await this.getStorage(); | ||
| const { tasks: pending } = await storage.listTasks({ | ||
| status: "pending", | ||
| orderBy: "createdAt", | ||
| orderDirection: "asc" | ||
| }); | ||
| for (const task of pending) { | ||
| if (await this.checkConcurrency(task.agentId)) { | ||
| await this.dispatch(task); | ||
| } | ||
| } | ||
| } | ||
| /** | ||
| * Recovers tasks left in 'running' or 'pending' state from a previous process. | ||
| */ | ||
| async recoverStaleTasks() { | ||
| try { | ||
| const storage = await this.getStorage(); | ||
| const { tasks: staleTasks } = await storage.listTasks({ status: "running" }); | ||
| for (const task of staleTasks) { | ||
| if (task.maxRetries > 0) { | ||
| await storage.updateTask(task.id, { | ||
| status: "pending", | ||
| startedAt: void 0 | ||
| }); | ||
| } else { | ||
| await storage.updateTask(task.id, { | ||
| status: "failed", | ||
| error: { message: "Worker process terminated before task completed" }, | ||
| completedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| } | ||
| } | ||
| const { tasks: pendingTasks } = await storage.listTasks({ | ||
| status: "pending", | ||
| orderBy: "createdAt", | ||
| orderDirection: "asc" | ||
| }); | ||
| for (const task of pendingTasks) { | ||
| if (await this.checkConcurrency(task.agentId)) { | ||
| await this.dispatch(task); | ||
| } | ||
| } | ||
| } catch (error) { | ||
| const logger = this.#mastra?.getLogger(); | ||
| if (logger) { | ||
| logger.error("Failed to recover stale background tasks", error); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| // src/background-tasks/create.ts | ||
| function createBackgroundTask(manager, options) { | ||
| const { context, ...payload } = options; | ||
| let taskId; | ||
| return { | ||
| get task() { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return { id: taskId }; | ||
| }, | ||
| async dispatch() { | ||
| const result = await manager.enqueue(payload, context); | ||
| taskId = result.task.id; | ||
| return result; | ||
| }, | ||
| async checkIfSuspended(args) { | ||
| const result = await manager.listTasks({ | ||
| toolCallId: args.toolCallId, | ||
| runId: args.runId, | ||
| agentId: args.agentId, | ||
| threadId: args.threadId, | ||
| resourceId: args.resourceId, | ||
| toolName: args.toolName, | ||
| status: "suspended" | ||
| }); | ||
| if (result.total > 0) { | ||
| const task = result.tasks[0]; | ||
| if (task) { | ||
| taskId = task.id; | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| }, | ||
| async resume(resumeData) { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return manager.resume(taskId, resumeData); | ||
| }, | ||
| async cancel() { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return manager.cancel(taskId); | ||
| }, | ||
| async waitForCompletion(waitOptions) { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return manager.waitForNextTask([taskId], waitOptions); | ||
| } | ||
| }; | ||
| } | ||
| // src/background-tasks/resolve-config.ts | ||
| function resolveBackgroundConfig({ | ||
| llmBgOverrides, | ||
| toolName, | ||
| toolConfig, | ||
| agentConfig, | ||
| managerConfig | ||
| }) { | ||
| const llmOverride = llmBgOverrides; | ||
| if (agentConfig?.disabled) { | ||
| return { | ||
| runInBackground: false, | ||
| timeoutMs: managerConfig?.defaultTimeoutMs ?? 3e5, | ||
| maxRetries: managerConfig?.defaultRetries?.maxRetries ?? 0 | ||
| }; | ||
| } | ||
| const agentToolConfig = resolveAgentToolConfig(toolName, agentConfig); | ||
| const baseEnabled = agentToolConfig?.enabled ?? toolConfig?.enabled ?? false; | ||
| const enabled = baseEnabled ? llmOverride?.enabled ?? true : false; | ||
| const timeoutMs = llmOverride?.timeoutMs ?? agentToolConfig?.timeoutMs ?? toolConfig?.timeoutMs ?? managerConfig?.defaultTimeoutMs ?? 3e5; | ||
| const maxRetries = llmOverride?.maxRetries ?? toolConfig?.maxRetries ?? managerConfig?.defaultRetries?.maxRetries ?? 0; | ||
| return { runInBackground: enabled, timeoutMs, maxRetries }; | ||
| } | ||
| function resolveAgentToolConfig(toolName, agentConfig) { | ||
| if (!agentConfig?.tools) return void 0; | ||
| if (agentConfig.tools === "all") { | ||
| return { enabled: true }; | ||
| } | ||
| if (toolName.startsWith("agent-")) { | ||
| toolName = toolName.substring("agent-".length); | ||
| } else if (toolName.startsWith("workflow-")) { | ||
| toolName = toolName.substring("workflow-".length); | ||
| } | ||
| const entry = agentConfig.tools[toolName]; | ||
| if (entry === void 0) return void 0; | ||
| if (typeof entry === "boolean") return { enabled: entry }; | ||
| return entry; | ||
| } | ||
| var backgroundOverrideJsonSchema = { | ||
| type: "object", | ||
| description: "Optional: override background execution behavior for this specific call. Set enabled=false to force foreground, enabled=true to force background. Omit entirely to use the default configuration.", | ||
| properties: { | ||
| enabled: { | ||
| type: "boolean", | ||
| description: "Force background (true) or foreground (false) execution for this call." | ||
| }, | ||
| timeoutMs: { | ||
| type: "number", | ||
| description: "Override timeout in milliseconds for this call." | ||
| }, | ||
| maxRetries: { | ||
| type: "number", | ||
| description: "Override maximum retry attempts for this call." | ||
| } | ||
| }, | ||
| additionalProperties: false | ||
| }; | ||
| var backgroundOverrideZodSchema = v4.z.object({ | ||
| enabled: v4.z.boolean().optional().describe("Force background (true) or foreground (false) execution for this call."), | ||
| timeoutMs: v4.z.number().optional().describe("Override timeout in milliseconds for this call."), | ||
| maxRetries: v4.z.number().optional().describe("Override maximum retry attempts for this call.") | ||
| }).optional().describe( | ||
| "Optional: override background execution behavior for this specific call. Set enabled=false to force foreground, enabled=true to force background. Omit entirely to use the default configuration." | ||
| ); | ||
| // src/background-tasks/system-prompt.ts | ||
| function generateBackgroundTaskSystemPrompt(tools, agentConfig) { | ||
| const eligibleTools = []; | ||
| const enableAll = agentConfig?.tools === "all"; | ||
| for (const [toolName, tool] of Object.entries(tools)) { | ||
| const bgEnabledFromAgentConfig = agentConfig?.tools === "all" ? false : typeof agentConfig?.tools?.[toolName] === "boolean" ? agentConfig.tools[toolName] : agentConfig?.tools?.[toolName]?.enabled ?? false; | ||
| eligibleTools.push({ | ||
| toolName, | ||
| toolConfig: tool.background, | ||
| defaultBackground: enableAll ? true : bgEnabledFromAgentConfig ?? tool.background?.enabled ?? false | ||
| }); | ||
| } | ||
| if (eligibleTools.length === 0) { | ||
| return void 0; | ||
| } | ||
| const toolLines = eligibleTools.map((t) => `- ${t.toolName} (default: ${t.defaultBackground ? "background" : "foreground"})`).join("\n"); | ||
| return `You have the ability to run certain tools in the background while continuing the conversation. The following tools support background execution: | ||
| ${toolLines} | ||
| For any of these tools, you can include a "_background" field in the tool arguments to override the default: | ||
| "_background": { "enabled": true/false, "timeoutMs": number, "maxRetries": number } | ||
| All fields in "_background" are optional. Only include what you want to override. | ||
| Guidelines: | ||
| - Use background execution when the user doesn't need the result immediately, or when you're launching multiple independent tasks. | ||
| - Use foreground execution when the user is directly waiting for the result and the conversation can't continue without it. | ||
| - If you don't include "_background", the tool's default configuration is used. | ||
| - When a tool runs in the background, you'll receive a placeholder result with a task ID. You can reference this in your response to the user. | ||
| IMPORTANT: "_background" field is always an object. The fields in the _background field should be inside the _background object, not outside of it.`; | ||
| } | ||
| exports.BACKGROUND_TASK_WORKFLOW_ID = BACKGROUND_TASK_WORKFLOW_ID; | ||
| exports.BackgroundTaskManager = BackgroundTaskManager; | ||
| exports.backgroundOverrideJsonSchema = backgroundOverrideJsonSchema; | ||
| exports.backgroundOverrideZodSchema = backgroundOverrideZodSchema; | ||
| exports.createBackgroundTask = createBackgroundTask; | ||
| exports.generateBackgroundTaskSystemPrompt = generateBackgroundTaskSystemPrompt; | ||
| exports.resolveBackgroundConfig = resolveBackgroundConfig; | ||
| //# sourceMappingURL=chunk-BHNX447S.cjs.map | ||
| //# sourceMappingURL=chunk-BHNX447S.cjs.map |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { VersionedStorageDomain, normalizePerPage, calculatePagination, FilesystemVersionedHelpers, SOURCE_CONTROL_AGENTS_DIR, getSourceAgentFilePath } from './chunk-SKZRHFF3.js'; | ||
| import { deepEqual } from './chunk-MVLICRVY.js'; | ||
| // src/storage/domains/agents/base.ts | ||
| var AgentsStorage = class extends VersionedStorageDomain { | ||
| listKey = "agents"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "agentId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "AGENTS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/agents/inmemory.ts | ||
| var InMemoryAgentsStorage = class extends AgentsStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.agents.clear(); | ||
| this.db.agentVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Agent CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const agent = this.db.agents.get(id); | ||
| return agent ? this.deepCopyAgent(agent) : null; | ||
| } | ||
| async create(input) { | ||
| const { agent } = input; | ||
| if (this.db.agents.has(agent.id)) { | ||
| throw new Error(`Agent with id ${agent.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const visibility = agent.visibility ?? (agent.authorId ? "private" : void 0); | ||
| const newAgent = { | ||
| id: agent.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: agent.authorId, | ||
| visibility, | ||
| metadata: agent.metadata, | ||
| favoriteCount: 0, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.agents.set(agent.id, newAgent); | ||
| const { id: _id, authorId: _authorId, visibility: _visibility, metadata: _metadata, ...snapshotConfig } = agent; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| agentId: agent.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyAgent(newAgent); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingAgent = this.db.agents.get(id); | ||
| if (!existingAgent) { | ||
| throw new Error(`Agent with id ${id} not found`); | ||
| } | ||
| const { authorId, visibility, activeVersionId, metadata, status } = updates; | ||
| const updatedAgent = { | ||
| ...existingAgent, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...visibility !== void 0 && { visibility }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingAgent.metadata, ...metadata } | ||
| }, | ||
| ...status !== void 0 && { status }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.agents.set(id, updatedAgent); | ||
| return this.deepCopyAgent(updatedAgent); | ||
| } | ||
| async delete(id) { | ||
| this.db.agents.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { | ||
| page = 0, | ||
| perPage: perPageInput, | ||
| orderBy, | ||
| authorId, | ||
| visibility, | ||
| metadata, | ||
| status, | ||
| entityIds, | ||
| pinFavoritedFor, | ||
| favoritedOnly | ||
| } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let agents = Array.from(this.db.agents.values()); | ||
| if (entityIds !== void 0) { | ||
| if (entityIds.length === 0) { | ||
| return { | ||
| agents: [], | ||
| total: 0, | ||
| page, | ||
| perPage: perPageInput === false ? false : perPage, | ||
| hasMore: false | ||
| }; | ||
| } | ||
| const idSet = new Set(entityIds); | ||
| agents = agents.filter((agent) => idSet.has(agent.id)); | ||
| } | ||
| if (status) { | ||
| agents = agents.filter((agent) => agent.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| agents = agents.filter((agent) => agent.authorId === authorId); | ||
| } | ||
| if (visibility !== void 0) { | ||
| agents = agents.filter((agent) => agent.visibility === visibility); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| agents = agents.filter((agent) => { | ||
| if (!agent.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => deepEqual(agent.metadata[key], value)); | ||
| }); | ||
| } | ||
| const favoritedIds = pinFavoritedFor ? this.collectFavoritedIdsFor(pinFavoritedFor) : void 0; | ||
| if (favoritedOnly) { | ||
| if (favoritedIds) { | ||
| agents = agents.filter((agent) => favoritedIds.has(agent.id)); | ||
| } else { | ||
| agents = []; | ||
| } | ||
| } | ||
| const sortedAgents = this.sortAgents(agents, field, direction, favoritedIds); | ||
| const clonedAgents = sortedAgents.map((agent) => this.deepCopyAgent(agent)); | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| agents: clonedAgents.slice(offset, offset + perPage), | ||
| total: clonedAgents.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedAgents.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Agent Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.agentVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.agentVersions.values()) { | ||
| if (version2.agentId === input.agentId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for agent ${input.agentId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.agentVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.agentVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(agentId, versionNumber) { | ||
| for (const version of this.db.agentVersions.values()) { | ||
| if (version.agentId === agentId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(agentId) { | ||
| let latest = null; | ||
| for (const version of this.db.agentVersions.values()) { | ||
| if (version.agentId === agentId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { agentId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.agentVersions.values()).filter((v) => v.agentId === agentId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.agentVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.agentVersions.entries()) { | ||
| if (version.agentId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.agentVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(agentId) { | ||
| let count = 0; | ||
| for (const version of this.db.agentVersions.values()) { | ||
| if (version.agentId === agentId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| /** | ||
| * Deep copy a thin agent record to prevent external mutation of stored data | ||
| */ | ||
| deepCopyAgent(agent) { | ||
| return { | ||
| ...agent, | ||
| metadata: agent.metadata ? { ...agent.metadata } : agent.metadata | ||
| }; | ||
| } | ||
| /** | ||
| * Deep copy a version to prevent external mutation of stored data | ||
| */ | ||
| deepCopyVersion(version) { | ||
| return structuredClone(version); | ||
| } | ||
| sortAgents(agents, field, direction, favoritedIds) { | ||
| return agents.sort((a, b) => { | ||
| if (favoritedIds) { | ||
| const aFav = favoritedIds.has(a.id) ? 1 : 0; | ||
| const bFav = favoritedIds.has(b.id) ? 1 : 0; | ||
| if (aFav !== bFav) return bFav - aFav; | ||
| } | ||
| const aValue = new Date(a[field]).getTime(); | ||
| const bValue = new Date(b[field]).getTime(); | ||
| if (aValue !== bValue) { | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| } | ||
| return a.id < b.id ? -1 : a.id > b.id ? 1 : 0; | ||
| }); | ||
| } | ||
| /** | ||
| * Collect the set of agent IDs favorited by the given user. Returns an empty | ||
| * Set when the favorites domain is not wired or the user has no favorites. | ||
| */ | ||
| collectFavoritedIdsFor(userId) { | ||
| const favorited = /* @__PURE__ */ new Set(); | ||
| for (const row of this.db.favorites.values()) { | ||
| if (row.userId === userId && row.entityType === "agent") { | ||
| favorited.add(row.entityId); | ||
| } | ||
| } | ||
| return favorited; | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/inmemory-db.ts | ||
| var InMemoryDB = class { | ||
| threads = /* @__PURE__ */ new Map(); | ||
| messages = /* @__PURE__ */ new Map(); | ||
| resources = /* @__PURE__ */ new Map(); | ||
| workflows = /* @__PURE__ */ new Map(); | ||
| scores = /* @__PURE__ */ new Map(); | ||
| traces = /* @__PURE__ */ new Map(); | ||
| metricRecords = []; | ||
| logRecords = []; | ||
| scoreRecords = []; | ||
| feedbackRecords = []; | ||
| observabilityNextCursorId = 1; | ||
| traceCursorIds = /* @__PURE__ */ new Map(); | ||
| branchCursorIds = /* @__PURE__ */ new Map(); | ||
| metricCursorIds = /* @__PURE__ */ new Map(); | ||
| logCursorIds = /* @__PURE__ */ new Map(); | ||
| scoreCursorIds = /* @__PURE__ */ new Map(); | ||
| feedbackCursorIds = /* @__PURE__ */ new Map(); | ||
| agents = /* @__PURE__ */ new Map(); | ||
| agentVersions = /* @__PURE__ */ new Map(); | ||
| promptBlocks = /* @__PURE__ */ new Map(); | ||
| promptBlockVersions = /* @__PURE__ */ new Map(); | ||
| scorerDefinitions = /* @__PURE__ */ new Map(); | ||
| scorerDefinitionVersions = /* @__PURE__ */ new Map(); | ||
| mcpClients = /* @__PURE__ */ new Map(); | ||
| mcpClientVersions = /* @__PURE__ */ new Map(); | ||
| mcpServers = /* @__PURE__ */ new Map(); | ||
| mcpServerVersions = /* @__PURE__ */ new Map(); | ||
| workspaces = /* @__PURE__ */ new Map(); | ||
| workspaceVersions = /* @__PURE__ */ new Map(); | ||
| skills = /* @__PURE__ */ new Map(); | ||
| skillVersions = /* @__PURE__ */ new Map(); | ||
| /** | ||
| * Favorites keyed by `${userId}\u0000${entityType}\u0000${entityId}`. The | ||
| * favorites domain owns reads/writes; this Map lives on InMemoryDB so the | ||
| * favorites domain can also mutate `agents` / `skills` `favoriteCount` atomically | ||
| * within the same synchronous block. | ||
| */ | ||
| favorites = /* @__PURE__ */ new Map(); | ||
| /** Observational memory records, keyed by resourceId, each holding array of records (generations) */ | ||
| observationalMemory = /* @__PURE__ */ new Map(); | ||
| // Dataset domain maps | ||
| datasets = /* @__PURE__ */ new Map(); | ||
| datasetItems = /* @__PURE__ */ new Map(); | ||
| datasetVersions = /* @__PURE__ */ new Map(); | ||
| // Experiment domain maps | ||
| experiments = /* @__PURE__ */ new Map(); | ||
| experimentResults = /* @__PURE__ */ new Map(); | ||
| // Background tasks domain | ||
| backgroundTasks = /* @__PURE__ */ new Map(); | ||
| // Schedules domain | ||
| schedules = /* @__PURE__ */ new Map(); | ||
| scheduleTriggers = []; | ||
| /** | ||
| * Tool provider connections keyed by `${authorId}\u0000${providerId}\u0000${connectionId}`. | ||
| */ | ||
| toolProviderConnections = /* @__PURE__ */ new Map(); | ||
| /** | ||
| * Clears all data from all collections. | ||
| * Useful for testing. | ||
| */ | ||
| clear() { | ||
| this.threads.clear(); | ||
| this.messages.clear(); | ||
| this.resources.clear(); | ||
| this.workflows.clear(); | ||
| this.scores.clear(); | ||
| this.traces.clear(); | ||
| this.metricRecords.length = 0; | ||
| this.logRecords.length = 0; | ||
| this.scoreRecords.length = 0; | ||
| this.feedbackRecords.length = 0; | ||
| this.observabilityNextCursorId = 1; | ||
| this.traceCursorIds.clear(); | ||
| this.branchCursorIds.clear(); | ||
| this.metricCursorIds.clear(); | ||
| this.logCursorIds.clear(); | ||
| this.scoreCursorIds.clear(); | ||
| this.feedbackCursorIds.clear(); | ||
| this.agents.clear(); | ||
| this.agentVersions.clear(); | ||
| this.promptBlocks.clear(); | ||
| this.promptBlockVersions.clear(); | ||
| this.scorerDefinitions.clear(); | ||
| this.scorerDefinitionVersions.clear(); | ||
| this.mcpClients.clear(); | ||
| this.mcpClientVersions.clear(); | ||
| this.mcpServers.clear(); | ||
| this.mcpServerVersions.clear(); | ||
| this.workspaces.clear(); | ||
| this.workspaceVersions.clear(); | ||
| this.skills.clear(); | ||
| this.skillVersions.clear(); | ||
| this.favorites.clear(); | ||
| this.observationalMemory.clear(); | ||
| this.datasets.clear(); | ||
| this.datasetItems.clear(); | ||
| this.datasetVersions.clear(); | ||
| this.experiments.clear(); | ||
| this.experimentResults.clear(); | ||
| this.backgroundTasks.clear(); | ||
| this.schedules.clear(); | ||
| this.scheduleTriggers.length = 0; | ||
| this.toolProviderConnections.clear(); | ||
| } | ||
| }; | ||
| // src/storage/domains/agents/filesystem.ts | ||
| var PERSISTED_SNAPSHOT_FIELDS = /* @__PURE__ */ new Set([ | ||
| "name", | ||
| "instructions", | ||
| "model", | ||
| "tools", | ||
| "integrationTools", | ||
| "toolProviders", | ||
| "mcpClients", | ||
| "requestContextSchema" | ||
| ]); | ||
| var CODE_MODE_EXCLUDED_FIELDS = /* @__PURE__ */ new Set(["model", "name"]); | ||
| var OWNED_FIELDS_BY_GROUP = { | ||
| instructions: ["instructions"], | ||
| tools: ["tools", "integrationTools", "mcpClients"] | ||
| }; | ||
| function ownershipFromEditorConfig(editorConfig) { | ||
| if (editorConfig === false) { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| if (editorConfig === void 0 || editorConfig === null) { | ||
| return { ownsInstructions: true, ownsTools: true }; | ||
| } | ||
| if (typeof editorConfig !== "object") { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| const cfg = editorConfig; | ||
| const ownsInstructions = cfg.instructions === true; | ||
| const toolsCfg = cfg.tools; | ||
| const ownsTools = toolsCfg === true || typeof toolsCfg === "object" && toolsCfg !== null && toolsCfg.description === true; | ||
| return { ownsInstructions, ownsTools }; | ||
| } | ||
| function stripUnusedFields(obj) { | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| if (PERSISTED_SNAPSHOT_FIELDS.has(key)) { | ||
| result[key] = value; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function isAgentNotFoundError(error, entityId) { | ||
| if (!error || typeof error !== "object") return false; | ||
| const maybeError = error; | ||
| return maybeError.id === "MASTRA_GET_AGENT_BY_AGENT_ID_NOT_FOUND" || maybeError.details?.status === 404 && maybeError.details?.agentId === entityId || maybeError.message === `Agent with id ${entityId} not found`; | ||
| } | ||
| var FilesystemAgentsStorage = class extends AgentsStorage { | ||
| helpers; | ||
| storageMastra; | ||
| constructor({ db }) { | ||
| super(); | ||
| const getCodeAgent = (entityId) => { | ||
| try { | ||
| const agent = this.storageMastra?.getAgentById?.(entityId); | ||
| return agent?.source === "code" ? agent : void 0; | ||
| } catch (error) { | ||
| if (isAgentNotFoundError(error, entityId)) { | ||
| return void 0; | ||
| } | ||
| throw error; | ||
| } | ||
| }; | ||
| const isCodeAgent = (entityId) => Boolean(getCodeAgent(entityId)); | ||
| const editorConfigFor = (entityId) => getCodeAgent(entityId)?.__getEditorConfig?.(); | ||
| this.helpers = new FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "agents.json", | ||
| parentIdField: "agentId", | ||
| name: "FilesystemAgentsStorage", | ||
| versionMetadataFields: ["id", "agentId", "versionNumber", "changedFields", "changeMessage", "createdAt"], | ||
| perEntityFilesDir: "agents", | ||
| // Per-entity layout is used only for code-mode agents — i.e. agents | ||
| // that are declared in code (`source === 'code'`). For db-mode and | ||
| // user-created stored agents we keep the shared `agents.json` layout. | ||
| shouldPersistToPerEntityFile: (entity) => isCodeAgent(entity.id), | ||
| perEntitySnapshotFilter: (snapshot, entity) => { | ||
| const { ownsInstructions, ownsTools } = ownershipFromEditorConfig(editorConfigFor(entity.id)); | ||
| const excludedByOwnership = /* @__PURE__ */ new Set(); | ||
| if (!ownsInstructions) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP.instructions) excludedByOwnership.add(field); | ||
| } | ||
| if (!ownsTools) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP.tools) excludedByOwnership.add(field); | ||
| } | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(snapshot)) { | ||
| if (CODE_MODE_EXCLUDED_FIELDS.has(key)) continue; | ||
| if (excludedByOwnership.has(key)) continue; | ||
| result[key] = value; | ||
| } | ||
| return result; | ||
| } | ||
| }); | ||
| } | ||
| __registerMastra(mastra) { | ||
| this.storageMastra = mastra; | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { agent } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const visibility = agent.visibility ?? (agent.authorId ? "private" : void 0); | ||
| const entity = { | ||
| id: agent.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: agent.authorId, | ||
| visibility, | ||
| metadata: agent.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(agent.id, entity); | ||
| const { id: _id, authorId: _authorId, visibility: _visibility, metadata: _metadata, ...snapshotConfig } = agent; | ||
| const filtered = stripUnusedFields(snapshotConfig); | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| agentId: agent.id, | ||
| versionNumber: 1, | ||
| ...filtered, | ||
| changedFields: Object.keys(filtered), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const entityUpdates = {}; | ||
| const entityFields = /* @__PURE__ */ new Set(["authorId", "visibility", "metadata", "activeVersionId", "status"]); | ||
| for (const [key, value] of Object.entries(updates)) { | ||
| if (entityFields.has(key)) { | ||
| entityUpdates[key] = value; | ||
| } | ||
| } | ||
| return this.helpers.updateEntity(id, entityUpdates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, visibility, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "agents", | ||
| filters: { authorId, visibility, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| const { id, agentId, versionNumber, changedFields, changeMessage, ...snapshotFields } = input; | ||
| const filtered = stripUnusedFields(snapshotFields); | ||
| return this.helpers.createVersion({ | ||
| id, | ||
| agentId, | ||
| versionNumber, | ||
| changedFields, | ||
| changeMessage, | ||
| ...filtered | ||
| }); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(agentId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(agentId, versionNumber); | ||
| } | ||
| async getLatestVersion(agentId) { | ||
| return this.helpers.getLatestVersion(agentId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "agentId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(agentId) { | ||
| return this.helpers.countVersions(agentId); | ||
| } | ||
| }; | ||
| // src/storage/domains/agents/source.ts | ||
| var SOURCE_VERSION_PREFIX = "source:"; | ||
| var COMMON_EXCLUDED_FIELDS = /* @__PURE__ */ new Set([ | ||
| "id", | ||
| "model", | ||
| "scorers", | ||
| "skills", | ||
| "workflows", | ||
| "agents", | ||
| "integrationTools", | ||
| "toolProviders", | ||
| "inputProcessors", | ||
| "outputProcessors", | ||
| "memory", | ||
| "mcpClients", | ||
| "workspace", | ||
| "browser", | ||
| "defaultOptions" | ||
| ]); | ||
| var CODE_SOURCE_EXCLUDED_FIELDS = /* @__PURE__ */ new Set(["name"]); | ||
| var OWNED_FIELDS_BY_GROUP2 = { | ||
| instructions: ["instructions"], | ||
| tools: ["tools"] | ||
| }; | ||
| function ownershipFromEditorConfig2(editorConfig) { | ||
| if (editorConfig === false) { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| if (editorConfig === void 0 || editorConfig === null) { | ||
| return { ownsInstructions: true, ownsTools: true }; | ||
| } | ||
| if (typeof editorConfig !== "object") { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| const cfg = editorConfig; | ||
| const ownsInstructions = cfg.instructions === true; | ||
| const toolsCfg = cfg.tools; | ||
| const ownsTools = toolsCfg === true || typeof toolsCfg === "object" && toolsCfg !== null && toolsCfg.description === true; | ||
| return { ownsInstructions, ownsTools }; | ||
| } | ||
| function snapshotFromVersion(version) { | ||
| const { id, agentId, versionNumber, changedFields, changeMessage, createdAt, ...snapshot } = version; | ||
| return snapshot; | ||
| } | ||
| function filterSourceSnapshot(snapshot, editorConfig, isCodeDefinedAgent) { | ||
| const excludedByOwnership = /* @__PURE__ */ new Set(); | ||
| if (isCodeDefinedAgent) { | ||
| const { ownsInstructions, ownsTools } = ownershipFromEditorConfig2(editorConfig); | ||
| if (!ownsInstructions) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP2.instructions) excludedByOwnership.add(field); | ||
| } | ||
| if (!ownsTools) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP2.tools) excludedByOwnership.add(field); | ||
| } | ||
| } | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(snapshot)) { | ||
| if (COMMON_EXCLUDED_FIELDS.has(key)) continue; | ||
| if (isCodeDefinedAgent && CODE_SOURCE_EXCLUDED_FIELDS.has(key)) continue; | ||
| if (excludedByOwnership.has(key)) continue; | ||
| if (value === void 0) continue; | ||
| result[key] = value; | ||
| } | ||
| return result; | ||
| } | ||
| function parseJsonObject(content) { | ||
| try { | ||
| const parsed = JSON.parse(content); | ||
| return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null; | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
| function stableStringify(value) { | ||
| if (Array.isArray(value)) { | ||
| return `[${value.map(stableStringify).join(",")}]`; | ||
| } | ||
| if (value && typeof value === "object") { | ||
| const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([a], [b]) => a.localeCompare(b)); | ||
| return `{${entries.map(([key, entryValue]) => `${JSON.stringify(key)}:${stableStringify(entryValue)}`).join(",")}}`; | ||
| } | ||
| return JSON.stringify(value); | ||
| } | ||
| function agentIdFromSourcePath(path) { | ||
| const prefix = `${SOURCE_CONTROL_AGENTS_DIR}/`; | ||
| if (!path.startsWith(prefix) || !path.endsWith(".json")) return void 0; | ||
| const filename = path.slice(prefix.length, -".json".length); | ||
| if (!filename || filename.includes("/")) return void 0; | ||
| try { | ||
| return decodeURIComponent(filename); | ||
| } catch { | ||
| return filename; | ||
| } | ||
| } | ||
| var SourceAgentsSourceControl = class extends AgentsStorage { | ||
| provider; | ||
| knownAgentIds; | ||
| db = new InMemoryDB(); | ||
| memory = new InMemoryAgentsStorage({ db: this.db }); | ||
| storageMastra; | ||
| providerVersions = /* @__PURE__ */ new Map(); | ||
| loadedHistory = /* @__PURE__ */ new Set(); | ||
| hydratedAgents = /* @__PURE__ */ new Set(); | ||
| activeRefs = /* @__PURE__ */ new Map(); | ||
| providerAgentIdsDiscovered = false; | ||
| constructor({ provider, agentIds = [] }) { | ||
| super(); | ||
| this.provider = provider; | ||
| this.knownAgentIds = new Set(agentIds); | ||
| } | ||
| __registerMastra(mastra) { | ||
| this.storageMastra = mastra; | ||
| } | ||
| async init() { | ||
| const capabilities = await this.provider.getCapabilities(); | ||
| if (!capabilities.canRead) { | ||
| throw new Error(capabilities.reason ?? `Source provider ${this.provider.displayName} cannot read files`); | ||
| } | ||
| this.refreshKnownAgentIds(); | ||
| await this.discoverProviderAgentIds(); | ||
| await Promise.all([...this.knownAgentIds].map((agentId) => this.hydrateAgent(agentId))); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.hydratedAgents.clear(); | ||
| this.loadedHistory.clear(); | ||
| this.providerVersions.clear(); | ||
| this.activeRefs.clear(); | ||
| this.providerAgentIdsDiscovered = false; | ||
| await this.memory.dangerouslyClearAll(); | ||
| } | ||
| async useProviderRef(agentId, ref) { | ||
| this.activeRefs.set(agentId, ref); | ||
| this.hydratedAgents.delete(agentId); | ||
| this.loadedHistory.delete(agentId); | ||
| for (const [versionId, version] of this.providerVersions.entries()) { | ||
| if (version.agentId === agentId) { | ||
| this.providerVersions.delete(versionId); | ||
| } | ||
| } | ||
| await this.memory.delete(agentId); | ||
| await this.hydrateAgent(agentId); | ||
| } | ||
| async getById(id) { | ||
| await this.hydrateAgent(id); | ||
| return this.memory.getById(id); | ||
| } | ||
| async create(input) { | ||
| await this.hydrateAgent(input.agent.id); | ||
| const existing = await this.memory.getById(input.agent.id); | ||
| if (existing) { | ||
| throw new Error(`Agent with id ${input.agent.id} already exists`); | ||
| } | ||
| await this.persistSnapshot(input.agent.id, { ...input.agent }, "Initial version"); | ||
| const created = await this.memory.create(input); | ||
| this.knownAgentIds.add(input.agent.id); | ||
| return created; | ||
| } | ||
| async update(input) { | ||
| await this.hydrateAgent(input.id); | ||
| return this.memory.update(input); | ||
| } | ||
| async delete(id) { | ||
| this.knownAgentIds.delete(id); | ||
| this.hydratedAgents.delete(id); | ||
| this.loadedHistory.delete(id); | ||
| for (const versionId of this.providerVersions.keys()) { | ||
| if (this.providerVersions.get(versionId)?.agentId === id) { | ||
| this.providerVersions.delete(versionId); | ||
| } | ||
| } | ||
| await this.memory.delete(id); | ||
| } | ||
| async list(args) { | ||
| this.refreshKnownAgentIds(); | ||
| await this.discoverProviderAgentIds(); | ||
| await Promise.all([...this.knownAgentIds].map((agentId) => this.hydrateAgent(agentId))); | ||
| return this.memory.list(args); | ||
| } | ||
| async createVersion(input) { | ||
| await this.hydrateAgent(input.agentId); | ||
| const existingVersion = await this.memory.getVersion(input.id); | ||
| if (existingVersion) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| const existingVersionNumber = await this.memory.getVersionByNumber(input.agentId, input.versionNumber); | ||
| if (existingVersionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for agent ${input.agentId}`); | ||
| } | ||
| const snapshot = snapshotFromVersion({ ...input, createdAt: /* @__PURE__ */ new Date() }); | ||
| const result = await this.persistSnapshot(input.agentId, snapshot, input.changeMessage); | ||
| const version = await this.memory.createVersion(input); | ||
| this.rememberProviderVersion(input.agentId, version, result); | ||
| return version; | ||
| } | ||
| async getVersion(id) { | ||
| const providerVersion = this.providerVersions.get(id); | ||
| if (providerVersion) { | ||
| return structuredClone(providerVersion); | ||
| } | ||
| return this.memory.getVersion(id); | ||
| } | ||
| async getVersionByNumber(agentId, versionNumber) { | ||
| await this.loadHistory(agentId); | ||
| const providerVersion = [...this.providerVersions.values()].find( | ||
| (version) => version.agentId === agentId && version.versionNumber === versionNumber | ||
| ); | ||
| if (providerVersion) { | ||
| return structuredClone(providerVersion); | ||
| } | ||
| return this.memory.getVersionByNumber(agentId, versionNumber); | ||
| } | ||
| async getLatestVersion(agentId) { | ||
| await this.loadHistory(agentId); | ||
| const providerLatest = [...this.providerVersions.values()].filter((version) => version.agentId === agentId).sort((a, b) => b.versionNumber - a.versionNumber)[0]; | ||
| if (providerLatest) { | ||
| return structuredClone(providerLatest); | ||
| } | ||
| return this.memory.getLatestVersion(agentId); | ||
| } | ||
| async listVersions(input) { | ||
| await this.loadHistory(input.agentId); | ||
| const providerVersions = [...this.providerVersions.values()].filter((version) => version.agentId === input.agentId); | ||
| if (providerVersions.length === 0) { | ||
| return this.memory.listVersions(input); | ||
| } | ||
| const { page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| const sortedVersions = this.sortVersions(providerVersions, field, direction).map( | ||
| (version) => structuredClone(version) | ||
| ); | ||
| const total = sortedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| versions: sortedVersions.slice(offset, offset + perPage), | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.providerVersions.delete(id); | ||
| await this.memory.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| for (const [versionId, version] of this.providerVersions.entries()) { | ||
| if (version.agentId === entityId) { | ||
| this.providerVersions.delete(versionId); | ||
| } | ||
| } | ||
| await this.memory.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(entityId) { | ||
| await this.loadHistory(entityId); | ||
| const providerCount = [...this.providerVersions.values()].filter((version) => version.agentId === entityId).length; | ||
| return providerCount || this.memory.countVersions(entityId); | ||
| } | ||
| refreshKnownAgentIds() { | ||
| const agents = this.storageMastra?.listAgents?.(); | ||
| if (!agents) return; | ||
| for (const agent of Object.values(agents)) { | ||
| if (agent.source === "code") { | ||
| this.knownAgentIds.add(agent.id); | ||
| } | ||
| } | ||
| } | ||
| async discoverProviderAgentIds() { | ||
| if (this.providerAgentIdsDiscovered || !this.provider.listFiles) return; | ||
| const files = await this.provider.listFiles({ path: SOURCE_CONTROL_AGENTS_DIR }); | ||
| for (const file of files) { | ||
| const agentId = agentIdFromSourcePath(file.path); | ||
| if (agentId) { | ||
| this.knownAgentIds.add(agentId); | ||
| } | ||
| } | ||
| this.providerAgentIdsDiscovered = true; | ||
| } | ||
| async hydrateAgent(agentId) { | ||
| if (this.hydratedAgents.has(agentId)) return; | ||
| const ref = this.activeRefs.get(agentId); | ||
| const file = await this.provider.readFile({ path: getSourceAgentFilePath(agentId), ref }); | ||
| if (!file) { | ||
| this.hydratedAgents.add(agentId); | ||
| return; | ||
| } | ||
| const snapshot = parseJsonObject(file.content); | ||
| if (!snapshot) { | ||
| this.hydratedAgents.add(agentId); | ||
| return; | ||
| } | ||
| this.knownAgentIds.add(agentId); | ||
| this.hydratedAgents.add(agentId); | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const versionId = `hydrated-${agentId}-v1`; | ||
| this.db.agents.set(agentId, { | ||
| id: agentId, | ||
| status: "published", | ||
| activeVersionId: versionId, | ||
| favoriteCount: 0, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }); | ||
| this.db.agentVersions.set(versionId, { | ||
| id: versionId, | ||
| agentId, | ||
| versionNumber: 1, | ||
| ...snapshot, | ||
| createdAt: now | ||
| }); | ||
| } | ||
| getCodeDefinedAgent(agentId) { | ||
| try { | ||
| const agent = this.storageMastra?.getAgentById?.(agentId); | ||
| return agent?.source === "code" ? agent : void 0; | ||
| } catch { | ||
| return void 0; | ||
| } | ||
| } | ||
| async persistSnapshot(agentId, snapshot, message) { | ||
| const capabilities = await this.provider.getCapabilities(); | ||
| if (!capabilities.canWrite) { | ||
| throw new Error(capabilities.reason ?? `Source provider ${this.provider.displayName} cannot write files`); | ||
| } | ||
| const agent = this.getCodeDefinedAgent(agentId); | ||
| const filtered = filterSourceSnapshot(snapshot, agent?.__getEditorConfig?.(), Boolean(agent)); | ||
| return this.provider.writeFile({ | ||
| path: getSourceAgentFilePath(agentId), | ||
| ref: this.activeRefs.get(agentId), | ||
| content: `${stableStringify(filtered)} | ||
| `, | ||
| message | ||
| }); | ||
| } | ||
| async loadHistory(agentId) { | ||
| if (this.loadedHistory.has(agentId)) return; | ||
| const capabilities = await this.provider.getCapabilities(); | ||
| if (!capabilities.canListHistory) { | ||
| this.loadedHistory.add(agentId); | ||
| return; | ||
| } | ||
| const activeRef = this.activeRefs.get(agentId); | ||
| const entries = await this.provider.listFileHistory({ path: getSourceAgentFilePath(agentId), ref: activeRef }); | ||
| const orderedEntries = [...entries].reverse(); | ||
| const versions = /* @__PURE__ */ new Map(); | ||
| let versionNumber = 0; | ||
| for (const entry of orderedEntries) { | ||
| const file = await this.provider.readFile({ path: getSourceAgentFilePath(agentId), ref: entry.ref ?? entry.id }); | ||
| if (!file) continue; | ||
| const snapshot = parseJsonObject(file.content); | ||
| if (!snapshot) continue; | ||
| versionNumber += 1; | ||
| const version = this.versionFromHistoryEntry(agentId, entry, versionNumber, snapshot); | ||
| versions.set(version.id, version); | ||
| } | ||
| for (const [versionId, version] of versions) { | ||
| this.providerVersions.set(versionId, version); | ||
| } | ||
| this.loadedHistory.add(agentId); | ||
| } | ||
| rememberProviderVersion(agentId, version, result) { | ||
| const versionId = result.commitSha ? `${SOURCE_VERSION_PREFIX}${result.commitSha}:${agentId}` : version.id; | ||
| this.providerVersions.set(versionId, { | ||
| ...structuredClone(version), | ||
| id: versionId, | ||
| agentId, | ||
| versionNumber: this.nextProviderVersionNumber(agentId) | ||
| }); | ||
| } | ||
| versionFromHistoryEntry(agentId, entry, versionNumber, snapshot) { | ||
| return { | ||
| id: `${SOURCE_VERSION_PREFIX}${entry.id}:${agentId}`, | ||
| agentId, | ||
| versionNumber, | ||
| changeMessage: entry.message, | ||
| ...snapshot, | ||
| createdAt: new Date(entry.createdAt) | ||
| }; | ||
| } | ||
| nextProviderVersionNumber(agentId) { | ||
| const latest = [...this.providerVersions.values()].filter((version) => version.agentId === agentId).sort((a, b) => b.versionNumber - a.versionNumber)[0]; | ||
| return (latest?.versionNumber ?? 0) + 1; | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| const aVal = field === "createdAt" ? a.createdAt.getTime() : a.versionNumber; | ||
| const bVal = field === "createdAt" ? b.createdAt.getTime() : b.versionNumber; | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| export { AgentsStorage, FilesystemAgentsStorage, InMemoryAgentsStorage, InMemoryDB, SourceAgentsSourceControl }; | ||
| //# sourceMappingURL=chunk-GUEWXCCO.js.map | ||
| //# sourceMappingURL=chunk-GUEWXCCO.js.map |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { VersionedStorageDomain, normalizePerPage, calculatePagination, FilesystemVersionedHelpers } from './chunk-SKZRHFF3.js'; | ||
| import { deepEqual } from './chunk-MVLICRVY.js'; | ||
| // src/storage/domains/scorer-definitions/base.ts | ||
| var ScorerDefinitionsStorage = class extends VersionedStorageDomain { | ||
| listKey = "scorerDefinitions"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "scorerDefinitionId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "SCORER_DEFINITIONS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/scorer-definitions/inmemory.ts | ||
| var InMemoryScorerDefinitionsStorage = class extends ScorerDefinitionsStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.scorerDefinitions.clear(); | ||
| this.db.scorerDefinitionVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Scorer Definition CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const scorer = this.db.scorerDefinitions.get(id); | ||
| return scorer ? this.deepCopyScorer(scorer) : null; | ||
| } | ||
| async create(input) { | ||
| const { scorerDefinition } = input; | ||
| if (this.db.scorerDefinitions.has(scorerDefinition.id)) { | ||
| throw new Error(`Scorer definition with id ${scorerDefinition.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newScorer = { | ||
| id: scorerDefinition.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: scorerDefinition.authorId, | ||
| metadata: scorerDefinition.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.scorerDefinitions.set(scorerDefinition.id, newScorer); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| scorerDefinitionId: scorerDefinition.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyScorer(newScorer); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingScorer = this.db.scorerDefinitions.get(id); | ||
| if (!existingScorer) { | ||
| throw new Error(`Scorer definition with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedScorer = { | ||
| ...existingScorer, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingScorer.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.scorerDefinitions.set(id, updatedScorer); | ||
| return this.deepCopyScorer(updatedScorer); | ||
| } | ||
| async delete(id) { | ||
| this.db.scorerDefinitions.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let scorers = Array.from(this.db.scorerDefinitions.values()); | ||
| if (status) { | ||
| scorers = scorers.filter((scorer) => scorer.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| scorers = scorers.filter((scorer) => scorer.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| scorers = scorers.filter((scorer) => { | ||
| if (!scorer.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => deepEqual(scorer.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedScorers = this.sortScorers(scorers, field, direction); | ||
| const clonedScorers = sortedScorers.map((scorer) => this.deepCopyScorer(scorer)); | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| scorerDefinitions: clonedScorers.slice(offset, offset + perPage), | ||
| total: clonedScorers.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedScorers.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Scorer Definition Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.scorerDefinitionVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.scorerDefinitionVersions.values()) { | ||
| if (version2.scorerDefinitionId === input.scorerDefinitionId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error( | ||
| `Version number ${input.versionNumber} already exists for scorer definition ${input.scorerDefinitionId}` | ||
| ); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.scorerDefinitionVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.scorerDefinitionVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(scorerDefinitionId, versionNumber) { | ||
| for (const version of this.db.scorerDefinitionVersions.values()) { | ||
| if (version.scorerDefinitionId === scorerDefinitionId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(scorerDefinitionId) { | ||
| let latest = null; | ||
| for (const version of this.db.scorerDefinitionVersions.values()) { | ||
| if (version.scorerDefinitionId === scorerDefinitionId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { scorerDefinitionId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.scorerDefinitionVersions.values()).filter( | ||
| (v) => v.scorerDefinitionId === scorerDefinitionId | ||
| ); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.scorerDefinitionVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.scorerDefinitionVersions.entries()) { | ||
| if (version.scorerDefinitionId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.scorerDefinitionVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(scorerDefinitionId) { | ||
| let count = 0; | ||
| for (const version of this.db.scorerDefinitionVersions.values()) { | ||
| if (version.scorerDefinitionId === scorerDefinitionId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyScorer(scorer) { | ||
| return { | ||
| ...scorer, | ||
| metadata: scorer.metadata ? { ...scorer.metadata } : scorer.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| model: version.model ? JSON.parse(JSON.stringify(version.model)) : version.model, | ||
| scoreRange: version.scoreRange ? JSON.parse(JSON.stringify(version.scoreRange)) : version.scoreRange, | ||
| presetConfig: version.presetConfig ? JSON.parse(JSON.stringify(version.presetConfig)) : version.presetConfig, | ||
| defaultSampling: version.defaultSampling ? JSON.parse(JSON.stringify(version.defaultSampling)) : version.defaultSampling, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortScorers(scorers, field, direction) { | ||
| return scorers.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/scorer-definitions/filesystem.ts | ||
| var FilesystemScorerDefinitionsStorage = class extends ScorerDefinitionsStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "scorer-definitions.json", | ||
| parentIdField: "scorerDefinitionId", | ||
| name: "FilesystemScorerDefinitionsStorage", | ||
| versionMetadataFields: [ | ||
| "id", | ||
| "scorerDefinitionId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { scorerDefinition } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: scorerDefinition.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: scorerDefinition.authorId, | ||
| metadata: scorerDefinition.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(scorerDefinition.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| scorerDefinitionId: scorerDefinition.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "scorerDefinitions", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(scorerDefinitionId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(scorerDefinitionId, versionNumber); | ||
| } | ||
| async getLatestVersion(scorerDefinitionId) { | ||
| return this.helpers.getLatestVersion(scorerDefinitionId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "scorerDefinitionId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(scorerDefinitionId) { | ||
| return this.helpers.countVersions(scorerDefinitionId); | ||
| } | ||
| }; | ||
| export { FilesystemScorerDefinitionsStorage, InMemoryScorerDefinitionsStorage, ScorerDefinitionsStorage }; | ||
| //# sourceMappingURL=chunk-MCAHK3LA.js.map | ||
| //# sourceMappingURL=chunk-MCAHK3LA.js.map |
| {"version":3,"sources":["../src/storage/domains/scorer-definitions/base.ts","../src/storage/domains/scorer-definitions/inmemory.ts","../src/storage/domains/scorer-definitions/filesystem.ts"],"names":["version"],"mappings":"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","file":"chunk-MCAHK3LA.js","sourcesContent":["import type {\n StorageScorerDefinitionType,\n StorageScorerDefinitionSnapshotType,\n StorageResolvedScorerDefinitionType,\n StorageCreateScorerDefinitionInput,\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput,\n StorageListScorerDefinitionsOutput,\n StorageListScorerDefinitionsResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// Scorer Definition Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of a scorer definition's content.\n * Config fields are top-level on the version row (no nested snapshot object).\n */\nexport interface ScorerDefinitionVersion extends StorageScorerDefinitionSnapshotType, VersionBase {\n /** ID of the scorer definition this version belongs to */\n scorerDefinitionId: string;\n}\n\n/**\n * Input for creating a new scorer definition version.\n * Config fields are top-level (no nested snapshot object).\n */\nexport interface CreateScorerDefinitionVersionInput\n extends StorageScorerDefinitionSnapshotType, CreateVersionInputBase {\n /** ID of the scorer definition this version belongs to */\n scorerDefinitionId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type ScorerDefinitionVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type ScorerDefinitionVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing scorer definition versions with pagination and sorting.\n */\nexport interface ListScorerDefinitionVersionsInput extends ListVersionsInputBase {\n /** ID of the scorer definition to list versions for */\n scorerDefinitionId: string;\n}\n\n/**\n * Output for listing scorer definition versions with pagination info.\n */\nexport interface ListScorerDefinitionVersionsOutput extends ListVersionsOutputBase<ScorerDefinitionVersion> {}\n\n// ============================================================================\n// ScorerDefinitionsStorage Base Class\n// ============================================================================\n\nexport abstract class ScorerDefinitionsStorage extends VersionedStorageDomain<\n StorageScorerDefinitionType,\n StorageScorerDefinitionSnapshotType,\n StorageResolvedScorerDefinitionType,\n ScorerDefinitionVersion,\n CreateScorerDefinitionVersionInput,\n ListScorerDefinitionVersionsInput,\n ListScorerDefinitionVersionsOutput,\n { scorerDefinition: StorageCreateScorerDefinitionInput },\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput | undefined,\n StorageListScorerDefinitionsOutput,\n StorageListScorerDefinitionsResolvedOutput\n> {\n protected readonly listKey = 'scorerDefinitions';\n protected readonly versionMetadataFields = [\n 'id',\n 'scorerDefinitionId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof ScorerDefinitionVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'SCORER_DEFINITIONS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageScorerDefinitionType,\n StorageCreateScorerDefinitionInput,\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput,\n StorageListScorerDefinitionsOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n ScorerDefinitionVersion,\n CreateScorerDefinitionVersionInput,\n ListScorerDefinitionVersionsInput,\n ListScorerDefinitionVersionsOutput,\n ScorerDefinitionVersionOrderBy,\n ScorerDefinitionVersionSortDirection,\n} from './base';\nimport { ScorerDefinitionsStorage } from './base';\n\nexport class InMemoryScorerDefinitionsStorage extends ScorerDefinitionsStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.scorerDefinitions.clear();\n this.db.scorerDefinitionVersions.clear();\n }\n\n // ==========================================================================\n // Scorer Definition CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageScorerDefinitionType | null> {\n const scorer = this.db.scorerDefinitions.get(id);\n return scorer ? this.deepCopyScorer(scorer) : null;\n }\n\n async create(input: { scorerDefinition: StorageCreateScorerDefinitionInput }): Promise<StorageScorerDefinitionType> {\n const { scorerDefinition } = input;\n\n if (this.db.scorerDefinitions.has(scorerDefinition.id)) {\n throw new Error(`Scorer definition with id ${scorerDefinition.id} already exists`);\n }\n\n const now = new Date();\n const newScorer: StorageScorerDefinitionType = {\n id: scorerDefinition.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: scorerDefinition.authorId,\n metadata: scorerDefinition.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.scorerDefinitions.set(scorerDefinition.id, newScorer);\n\n // Extract config fields from the flat input (everything except scorer-record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n scorerDefinitionId: scorerDefinition.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin scorer record\n return this.deepCopyScorer(newScorer);\n }\n\n async update(input: StorageUpdateScorerDefinitionInput): Promise<StorageScorerDefinitionType> {\n const { id, ...updates } = input;\n\n const existingScorer = this.db.scorerDefinitions.get(id);\n if (!existingScorer) {\n throw new Error(`Scorer definition with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the scorer record\n const updatedScorer: StorageScorerDefinitionType = {\n ...existingScorer,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageScorerDefinitionType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingScorer.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated scorer record\n this.db.scorerDefinitions.set(id, updatedScorer);\n return this.deepCopyScorer(updatedScorer);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.scorerDefinitions.delete(id);\n // Also delete all versions for this scorer definition\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListScorerDefinitionsInput): Promise<StorageListScorerDefinitionsOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all scorer definitions and apply filters\n let scorers = Array.from(this.db.scorerDefinitions.values());\n\n // Filter by status\n if (status) {\n scorers = scorers.filter(scorer => scorer.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n scorers = scorers.filter(scorer => scorer.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n scorers = scorers.filter(scorer => {\n if (!scorer.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(scorer.metadata![key], value));\n });\n }\n\n // Sort filtered scorer definitions\n const sortedScorers = this.sortScorers(scorers, field, direction);\n\n // Deep clone scorers to avoid mutation\n const clonedScorers = sortedScorers.map(scorer => this.deepCopyScorer(scorer));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n scorerDefinitions: clonedScorers.slice(offset, offset + perPage),\n total: clonedScorers.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedScorers.length,\n };\n }\n\n // ==========================================================================\n // Scorer Definition Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateScorerDefinitionVersionInput): Promise<ScorerDefinitionVersion> {\n // Check if version with this ID already exists\n if (this.db.scorerDefinitionVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (scorerDefinitionId, versionNumber) pair\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === input.scorerDefinitionId && version.versionNumber === input.versionNumber) {\n throw new Error(\n `Version number ${input.versionNumber} already exists for scorer definition ${input.scorerDefinitionId}`,\n );\n }\n }\n\n const version: ScorerDefinitionVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.scorerDefinitionVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<ScorerDefinitionVersion | null> {\n const version = this.db.scorerDefinitionVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(scorerDefinitionId: string, versionNumber: number): Promise<ScorerDefinitionVersion | null> {\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === scorerDefinitionId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(scorerDefinitionId: string): Promise<ScorerDefinitionVersion | null> {\n let latest: ScorerDefinitionVersion | null = null;\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === scorerDefinitionId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListScorerDefinitionVersionsInput): Promise<ListScorerDefinitionVersionsOutput> {\n const { scorerDefinitionId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by scorerDefinitionId\n let versions = Array.from(this.db.scorerDefinitionVersions.values()).filter(\n v => v.scorerDefinitionId === scorerDefinitionId,\n );\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.scorerDefinitionVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.scorerDefinitionVersions.entries()) {\n if (version.scorerDefinitionId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.scorerDefinitionVersions.delete(id);\n }\n }\n\n async countVersions(scorerDefinitionId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === scorerDefinitionId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyScorer(scorer: StorageScorerDefinitionType): StorageScorerDefinitionType {\n return {\n ...scorer,\n metadata: scorer.metadata ? { ...scorer.metadata } : scorer.metadata,\n };\n }\n\n private deepCopyVersion(version: ScorerDefinitionVersion): ScorerDefinitionVersion {\n return {\n ...version,\n model: version.model ? JSON.parse(JSON.stringify(version.model)) : version.model,\n scoreRange: version.scoreRange ? JSON.parse(JSON.stringify(version.scoreRange)) : version.scoreRange,\n presetConfig: version.presetConfig ? JSON.parse(JSON.stringify(version.presetConfig)) : version.presetConfig,\n defaultSampling: version.defaultSampling\n ? JSON.parse(JSON.stringify(version.defaultSampling))\n : version.defaultSampling,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortScorers(\n scorers: StorageScorerDefinitionType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageScorerDefinitionType[] {\n return scorers.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: ScorerDefinitionVersion[],\n field: ScorerDefinitionVersionOrderBy,\n direction: ScorerDefinitionVersionSortDirection,\n ): ScorerDefinitionVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageScorerDefinitionType,\n StorageCreateScorerDefinitionInput,\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput,\n StorageListScorerDefinitionsOutput,\n} from '../../types';\nimport type {\n ScorerDefinitionVersion,\n CreateScorerDefinitionVersionInput,\n ListScorerDefinitionVersionsInput,\n ListScorerDefinitionVersionsOutput,\n} from './base';\nimport { ScorerDefinitionsStorage } from './base';\n\nexport class FilesystemScorerDefinitionsStorage extends ScorerDefinitionsStorage {\n private helpers: FilesystemVersionedHelpers<StorageScorerDefinitionType, ScorerDefinitionVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'scorer-definitions.json',\n parentIdField: 'scorerDefinitionId',\n name: 'FilesystemScorerDefinitionsStorage',\n versionMetadataFields: [\n 'id',\n 'scorerDefinitionId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageScorerDefinitionType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { scorerDefinition: StorageCreateScorerDefinitionInput }): Promise<StorageScorerDefinitionType> {\n const { scorerDefinition } = input;\n const now = new Date();\n const entity: StorageScorerDefinitionType = {\n id: scorerDefinition.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: scorerDefinition.authorId,\n metadata: scorerDefinition.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(scorerDefinition.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n scorerDefinitionId: scorerDefinition.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateScorerDefinitionVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateScorerDefinitionInput): Promise<StorageScorerDefinitionType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListScorerDefinitionsInput): Promise<StorageListScorerDefinitionsOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'scorerDefinitions',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListScorerDefinitionsOutput;\n }\n\n async createVersion(input: CreateScorerDefinitionVersionInput): Promise<ScorerDefinitionVersion> {\n return this.helpers.createVersion(input as ScorerDefinitionVersion);\n }\n\n async getVersion(id: string): Promise<ScorerDefinitionVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(scorerDefinitionId: string, versionNumber: number): Promise<ScorerDefinitionVersion | null> {\n return this.helpers.getVersionByNumber(scorerDefinitionId, versionNumber);\n }\n\n async getLatestVersion(scorerDefinitionId: string): Promise<ScorerDefinitionVersion | null> {\n return this.helpers.getLatestVersion(scorerDefinitionId);\n }\n\n async listVersions(input: ListScorerDefinitionVersionsInput): Promise<ListScorerDefinitionVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'scorerDefinitionId');\n return result as ListScorerDefinitionVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(scorerDefinitionId: string): Promise<number> {\n return this.helpers.countVersions(scorerDefinitionId);\n }\n}\n"]} |
| 'use strict'; | ||
| var chunk2UAP4LDC_cjs = require('./chunk-2UAP4LDC.cjs'); | ||
| var chunkB3SPPQQ3_cjs = require('./chunk-B3SPPQQ3.cjs'); | ||
| // src/storage/domains/prompt-blocks/base.ts | ||
| var PromptBlocksStorage = class extends chunk2UAP4LDC_cjs.VersionedStorageDomain { | ||
| listKey = "promptBlocks"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "blockId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "PROMPT_BLOCKS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/prompt-blocks/inmemory.ts | ||
| var InMemoryPromptBlocksStorage = class extends PromptBlocksStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.promptBlocks.clear(); | ||
| this.db.promptBlockVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Prompt Block CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const block = this.db.promptBlocks.get(id); | ||
| return block ? this.deepCopyBlock(block) : null; | ||
| } | ||
| async create(input) { | ||
| const { promptBlock } = input; | ||
| if (this.db.promptBlocks.has(promptBlock.id)) { | ||
| throw new Error(`Prompt block with id ${promptBlock.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newBlock = { | ||
| id: promptBlock.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: promptBlock.authorId, | ||
| metadata: promptBlock.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.promptBlocks.set(promptBlock.id, newBlock); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| blockId: promptBlock.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyBlock(newBlock); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingBlock = this.db.promptBlocks.get(id); | ||
| if (!existingBlock) { | ||
| throw new Error(`Prompt block with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedBlock = { | ||
| ...existingBlock, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingBlock.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.promptBlocks.set(id, updatedBlock); | ||
| return this.deepCopyBlock(updatedBlock); | ||
| } | ||
| async delete(id) { | ||
| this.db.promptBlocks.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let blocks = Array.from(this.db.promptBlocks.values()); | ||
| if (status) { | ||
| blocks = blocks.filter((block) => block.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| blocks = blocks.filter((block) => block.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| blocks = blocks.filter((block) => { | ||
| if (!block.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => chunkB3SPPQQ3_cjs.deepEqual(block.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedBlocks = this.sortBlocks(blocks, field, direction); | ||
| const clonedBlocks = sortedBlocks.map((block) => this.deepCopyBlock(block)); | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| promptBlocks: clonedBlocks.slice(offset, offset + perPage), | ||
| total: clonedBlocks.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedBlocks.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Prompt Block Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.promptBlockVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.promptBlockVersions.values()) { | ||
| if (version2.blockId === input.blockId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for prompt block ${input.blockId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.promptBlockVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.promptBlockVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(blockId, versionNumber) { | ||
| for (const version of this.db.promptBlockVersions.values()) { | ||
| if (version.blockId === blockId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(blockId) { | ||
| let latest = null; | ||
| for (const version of this.db.promptBlockVersions.values()) { | ||
| if (version.blockId === blockId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { blockId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.promptBlockVersions.values()).filter((v) => v.blockId === blockId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.promptBlockVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.promptBlockVersions.entries()) { | ||
| if (version.blockId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.promptBlockVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(blockId) { | ||
| let count = 0; | ||
| for (const version of this.db.promptBlockVersions.values()) { | ||
| if (version.blockId === blockId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyBlock(block) { | ||
| return { | ||
| ...block, | ||
| metadata: block.metadata ? { ...block.metadata } : block.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| rules: version.rules ? JSON.parse(JSON.stringify(version.rules)) : version.rules, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortBlocks(blocks, field, direction) { | ||
| return blocks.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/prompt-blocks/filesystem.ts | ||
| var FilesystemPromptBlocksStorage = class extends PromptBlocksStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new chunk2UAP4LDC_cjs.FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "prompt-blocks.json", | ||
| parentIdField: "blockId", | ||
| name: "FilesystemPromptBlocksStorage", | ||
| versionMetadataFields: ["id", "blockId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { promptBlock } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: promptBlock.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: promptBlock.authorId, | ||
| metadata: promptBlock.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(promptBlock.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| blockId: promptBlock.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "promptBlocks", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(blockId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(blockId, versionNumber); | ||
| } | ||
| async getLatestVersion(blockId) { | ||
| return this.helpers.getLatestVersion(blockId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "blockId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(blockId) { | ||
| return this.helpers.countVersions(blockId); | ||
| } | ||
| }; | ||
| exports.FilesystemPromptBlocksStorage = FilesystemPromptBlocksStorage; | ||
| exports.InMemoryPromptBlocksStorage = InMemoryPromptBlocksStorage; | ||
| exports.PromptBlocksStorage = PromptBlocksStorage; | ||
| //# sourceMappingURL=chunk-MGRR5QZ2.cjs.map | ||
| //# sourceMappingURL=chunk-MGRR5QZ2.cjs.map |
| {"version":3,"sources":["../src/storage/domains/prompt-blocks/base.ts","../src/storage/domains/prompt-blocks/inmemory.ts","../src/storage/domains/prompt-blocks/filesystem.ts"],"names":["VersionedStorageDomain","normalizePerPage","deepEqual","calculatePagination","version","FilesystemVersionedHelpers"],"mappings":"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","file":"chunk-MGRR5QZ2.cjs","sourcesContent":["import type {\n StoragePromptBlockType,\n StoragePromptBlockSnapshotType,\n StorageResolvedPromptBlockType,\n StorageCreatePromptBlockInput,\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput,\n StorageListPromptBlocksOutput,\n StorageListPromptBlocksResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// Prompt Block Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of a prompt block's content.\n * Config fields are top-level on the version row (no nested snapshot object).\n */\nexport interface PromptBlockVersion extends StoragePromptBlockSnapshotType, VersionBase {\n /** ID of the prompt block this version belongs to */\n blockId: string;\n}\n\n/**\n * Input for creating a new prompt block version.\n * Config fields are top-level (no nested snapshot object).\n */\nexport interface CreatePromptBlockVersionInput extends StoragePromptBlockSnapshotType, CreateVersionInputBase {\n /** ID of the prompt block this version belongs to */\n blockId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type PromptBlockVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type PromptBlockVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing prompt block versions with pagination and sorting.\n */\nexport interface ListPromptBlockVersionsInput extends ListVersionsInputBase {\n /** ID of the prompt block to list versions for */\n blockId: string;\n}\n\n/**\n * Output for listing prompt block versions with pagination info.\n */\nexport interface ListPromptBlockVersionsOutput extends ListVersionsOutputBase<PromptBlockVersion> {}\n\n// ============================================================================\n// PromptBlocksStorage Base Class\n// ============================================================================\n\nexport abstract class PromptBlocksStorage extends VersionedStorageDomain<\n StoragePromptBlockType,\n StoragePromptBlockSnapshotType,\n StorageResolvedPromptBlockType,\n PromptBlockVersion,\n CreatePromptBlockVersionInput,\n ListPromptBlockVersionsInput,\n ListPromptBlockVersionsOutput,\n { promptBlock: StorageCreatePromptBlockInput },\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput | undefined,\n StorageListPromptBlocksOutput,\n StorageListPromptBlocksResolvedOutput\n> {\n protected readonly listKey = 'promptBlocks';\n protected readonly versionMetadataFields = [\n 'id',\n 'blockId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof PromptBlockVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'PROMPT_BLOCKS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StoragePromptBlockType,\n StorageCreatePromptBlockInput,\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput,\n StorageListPromptBlocksOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n PromptBlockVersion,\n CreatePromptBlockVersionInput,\n ListPromptBlockVersionsInput,\n ListPromptBlockVersionsOutput,\n PromptBlockVersionOrderBy,\n PromptBlockVersionSortDirection,\n} from './base';\nimport { PromptBlocksStorage } from './base';\n\nexport class InMemoryPromptBlocksStorage extends PromptBlocksStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.promptBlocks.clear();\n this.db.promptBlockVersions.clear();\n }\n\n // ==========================================================================\n // Prompt Block CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StoragePromptBlockType | null> {\n const block = this.db.promptBlocks.get(id);\n return block ? this.deepCopyBlock(block) : null;\n }\n\n async create(input: { promptBlock: StorageCreatePromptBlockInput }): Promise<StoragePromptBlockType> {\n const { promptBlock } = input;\n\n if (this.db.promptBlocks.has(promptBlock.id)) {\n throw new Error(`Prompt block with id ${promptBlock.id} already exists`);\n }\n\n const now = new Date();\n const newBlock: StoragePromptBlockType = {\n id: promptBlock.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: promptBlock.authorId,\n metadata: promptBlock.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.promptBlocks.set(promptBlock.id, newBlock);\n\n // Extract config fields from the flat input (everything except block-record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n blockId: promptBlock.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin block record\n return this.deepCopyBlock(newBlock);\n }\n\n async update(input: StorageUpdatePromptBlockInput): Promise<StoragePromptBlockType> {\n const { id, ...updates } = input;\n\n const existingBlock = this.db.promptBlocks.get(id);\n if (!existingBlock) {\n throw new Error(`Prompt block with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the block record\n const updatedBlock: StoragePromptBlockType = {\n ...existingBlock,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StoragePromptBlockType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingBlock.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated block record\n this.db.promptBlocks.set(id, updatedBlock);\n return this.deepCopyBlock(updatedBlock);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.promptBlocks.delete(id);\n // Also delete all versions for this block\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListPromptBlocksInput): Promise<StorageListPromptBlocksOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all blocks and apply filters\n let blocks = Array.from(this.db.promptBlocks.values());\n\n // Filter by status\n if (status) {\n blocks = blocks.filter(block => block.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n blocks = blocks.filter(block => block.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n blocks = blocks.filter(block => {\n if (!block.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(block.metadata![key], value));\n });\n }\n\n // Sort filtered blocks\n const sortedBlocks = this.sortBlocks(blocks, field, direction);\n\n // Deep clone blocks to avoid mutation\n const clonedBlocks = sortedBlocks.map(block => this.deepCopyBlock(block));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n promptBlocks: clonedBlocks.slice(offset, offset + perPage),\n total: clonedBlocks.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedBlocks.length,\n };\n }\n\n // ==========================================================================\n // Prompt Block Version Methods\n // ==========================================================================\n\n async createVersion(input: CreatePromptBlockVersionInput): Promise<PromptBlockVersion> {\n // Check if version with this ID already exists\n if (this.db.promptBlockVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (blockId, versionNumber) pair\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === input.blockId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for prompt block ${input.blockId}`);\n }\n }\n\n const version: PromptBlockVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.promptBlockVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<PromptBlockVersion | null> {\n const version = this.db.promptBlockVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(blockId: string, versionNumber: number): Promise<PromptBlockVersion | null> {\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === blockId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(blockId: string): Promise<PromptBlockVersion | null> {\n let latest: PromptBlockVersion | null = null;\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === blockId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListPromptBlockVersionsInput): Promise<ListPromptBlockVersionsOutput> {\n const { blockId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by blockId\n let versions = Array.from(this.db.promptBlockVersions.values()).filter(v => v.blockId === blockId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.promptBlockVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.promptBlockVersions.entries()) {\n if (version.blockId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.promptBlockVersions.delete(id);\n }\n }\n\n async countVersions(blockId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === blockId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyBlock(block: StoragePromptBlockType): StoragePromptBlockType {\n return {\n ...block,\n metadata: block.metadata ? { ...block.metadata } : block.metadata,\n };\n }\n\n private deepCopyVersion(version: PromptBlockVersion): PromptBlockVersion {\n return {\n ...version,\n rules: version.rules ? JSON.parse(JSON.stringify(version.rules)) : version.rules,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortBlocks(\n blocks: StoragePromptBlockType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StoragePromptBlockType[] {\n return blocks.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: PromptBlockVersion[],\n field: PromptBlockVersionOrderBy,\n direction: PromptBlockVersionSortDirection,\n ): PromptBlockVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StoragePromptBlockType,\n StorageCreatePromptBlockInput,\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput,\n StorageListPromptBlocksOutput,\n} from '../../types';\nimport type {\n PromptBlockVersion,\n CreatePromptBlockVersionInput,\n ListPromptBlockVersionsInput,\n ListPromptBlockVersionsOutput,\n} from './base';\nimport { PromptBlocksStorage } from './base';\n\nexport class FilesystemPromptBlocksStorage extends PromptBlocksStorage {\n private helpers: FilesystemVersionedHelpers<StoragePromptBlockType, PromptBlockVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'prompt-blocks.json',\n parentIdField: 'blockId',\n name: 'FilesystemPromptBlocksStorage',\n versionMetadataFields: ['id', 'blockId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StoragePromptBlockType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { promptBlock: StorageCreatePromptBlockInput }): Promise<StoragePromptBlockType> {\n const { promptBlock } = input;\n const now = new Date();\n const entity: StoragePromptBlockType = {\n id: promptBlock.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: promptBlock.authorId,\n metadata: promptBlock.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(promptBlock.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n blockId: promptBlock.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreatePromptBlockVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdatePromptBlockInput): Promise<StoragePromptBlockType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListPromptBlocksInput): Promise<StorageListPromptBlocksOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'promptBlocks',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListPromptBlocksOutput;\n }\n\n async createVersion(input: CreatePromptBlockVersionInput): Promise<PromptBlockVersion> {\n return this.helpers.createVersion(input as PromptBlockVersion);\n }\n\n async getVersion(id: string): Promise<PromptBlockVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(blockId: string, versionNumber: number): Promise<PromptBlockVersion | null> {\n return this.helpers.getVersionByNumber(blockId, versionNumber);\n }\n\n async getLatestVersion(blockId: string): Promise<PromptBlockVersion | null> {\n return this.helpers.getLatestVersion(blockId);\n }\n\n async listVersions(input: ListPromptBlockVersionsInput): Promise<ListPromptBlockVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'blockId');\n return result as ListPromptBlockVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(blockId: string): Promise<number> {\n return this.helpers.countVersions(blockId);\n }\n}\n"]} |
| import { randomUUID } from 'crypto'; | ||
| import { z } from 'zod/v4'; | ||
| // src/background-tasks/manager.ts | ||
| // src/background-tasks/workflow-id.ts | ||
| var BACKGROUND_TASK_WORKFLOW_ID = "__background-task"; | ||
| // src/background-tasks/manager.ts | ||
| var TOPIC_DISPATCH = "background-tasks"; | ||
| var TOPIC_RESULT = "background-tasks-result"; | ||
| var WORKER_GROUP = "background-task-workers"; | ||
| var BackgroundTaskManager = class { | ||
| pubsub; | ||
| config; | ||
| #mastra; | ||
| // Per-task contexts — keyed by task ID, holds closures from the caller's stream. | ||
| /** @internal — read by the workflow-engine step bodies in workflow.ts */ | ||
| taskContexts = /* @__PURE__ */ new Map(); | ||
| // Static executors keyed by tool name. Populated by `Mastra` for every | ||
| // registered tool, and by `BackgroundTaskWorker.#wireStaticTools` on | ||
| // standalone worker processes. Used as the fallback for cross-process | ||
| // dispatch where the producer's per-task closure (taskContexts) is not | ||
| // visible — a remote worker resolves the tool by name instead. | ||
| staticExecutors = /* @__PURE__ */ new Map(); | ||
| // Track active AbortControllers for running tasks (for cancellation + timeout) | ||
| /** @internal — read by the workflow-engine step bodies in workflow.ts */ | ||
| activeAbortControllers = /* @__PURE__ */ new Map(); | ||
| // Pubsub callbacks (kept for unsubscribe) | ||
| workerCallback; | ||
| resultCallback; | ||
| shuttingDown = false; | ||
| // Cleanup interval handle | ||
| cleanupInterval; | ||
| // Tracks the in-flight `init(pubsub)` so consumers can await readiness. | ||
| // Mastra fires init as fire-and-forget in `#ensureBackgroundTaskManager`, | ||
| // so without this any caller that hits `enqueue`/`resume`/`cancel` | ||
| // before init completes races against worker subscription + workflow | ||
| // registration. Public methods that depend on init await this promise | ||
| // before doing work. | ||
| initPromise; | ||
| constructor(config = { enabled: false }) { | ||
| this.config = { | ||
| globalConcurrency: config.globalConcurrency ?? 10, | ||
| perAgentConcurrency: config.perAgentConcurrency ?? 5, | ||
| backpressure: config.backpressure ?? "queue", | ||
| defaultTimeoutMs: config.defaultTimeoutMs ?? 3e5, | ||
| ...config | ||
| }; | ||
| } | ||
| __registerMastra(mastra) { | ||
| this.#mastra = mastra; | ||
| } | ||
| async getStorage() { | ||
| const storage = this.#mastra?.getStorage(); | ||
| if (!storage) { | ||
| throw new Error("Storage is not initialized"); | ||
| } | ||
| const bgStore = await storage.getStore("backgroundTasks"); | ||
| if (!bgStore) { | ||
| throw new Error("Background tasks storage is not available"); | ||
| } | ||
| return bgStore; | ||
| } | ||
| async init(pubsub) { | ||
| if (this.initPromise) return this.initPromise; | ||
| this.initPromise = this.#doInit(pubsub); | ||
| return this.initPromise; | ||
| } | ||
| async #doInit(pubsub) { | ||
| this.pubsub = pubsub; | ||
| this.workerCallback = async (event, ack) => { | ||
| if (event.type === "task.dispatch") { | ||
| await this.handleDispatch(event); | ||
| } else if (event.type === "task.resume") { | ||
| await this.handleResume(event); | ||
| } else if (event.type === "task.cancel") { | ||
| this.handleCancel(event); | ||
| } | ||
| await ack?.(); | ||
| }; | ||
| this.resultCallback = async (event, ack) => { | ||
| if (event.type === "task.completed" || event.type === "task.failed") { | ||
| await this.handleResult(event); | ||
| } | ||
| await ack?.(); | ||
| }; | ||
| if (this.#mastra) { | ||
| const { buildBackgroundTaskWorkflow } = await import('./workflow-636ISDPH.js'); | ||
| const workflow = buildBackgroundTaskWorkflow(this); | ||
| if (!this.#mastra.__hasInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID)) { | ||
| this.#mastra.__registerInternalWorkflow( | ||
| workflow | ||
| ); | ||
| } | ||
| } | ||
| await this.pubsub.subscribe(TOPIC_DISPATCH, this.workerCallback, { group: WORKER_GROUP }); | ||
| await this.pubsub.subscribe(TOPIC_RESULT, this.resultCallback); | ||
| await this.recoverStaleTasks(); | ||
| const cleanupConfig = this.config.cleanup; | ||
| if (cleanupConfig) { | ||
| const intervalMs = cleanupConfig.cleanupIntervalMs ?? 6e4; | ||
| this.cleanupInterval = setInterval(() => { | ||
| void this.cleanup(); | ||
| }, intervalMs); | ||
| } | ||
| } | ||
| // --- Per-task context registration --- | ||
| /** | ||
| * Register per-task hooks (executor, stream emitter, result injector). | ||
| * Called internally by createBackgroundTask or directly for advanced usage. | ||
| */ | ||
| registerTaskContext(taskId, context) { | ||
| this.taskContexts.set(taskId, context); | ||
| } | ||
| /** | ||
| * Remove per-task hooks. Called after task reaches terminal state. | ||
| */ | ||
| deregisterTaskContext(taskId) { | ||
| this.taskContexts.delete(taskId); | ||
| } | ||
| /** | ||
| * Register a tool executor by tool name. Used for cross-process dispatch: | ||
| * when a worker in a different process picks up a `task.dispatch` event, | ||
| * it has no per-task closure (`taskContexts`) for that taskId, but it can | ||
| * resolve the executor by tool name via this registry. | ||
| */ | ||
| registerStaticExecutor(toolName, executor) { | ||
| if (this.staticExecutors.has(toolName)) { | ||
| this.#mastra?.getLogger?.()?.debug?.(`Overwriting existing static executor for tool "${toolName}"`); | ||
| } | ||
| this.staticExecutors.set(toolName, executor); | ||
| } | ||
| /** | ||
| * Symmetric to `registerStaticExecutor`. Called when a tool is removed | ||
| * from `Mastra`. | ||
| */ | ||
| unregisterStaticExecutor(toolName) { | ||
| this.staticExecutors.delete(toolName); | ||
| } | ||
| /** | ||
| * Look up an executor by tool name. Read by the workflow-step body in | ||
| * `workflow.ts:runAttemptStep` as a fallback when no per-task `TaskContext` | ||
| * is registered (cross-process path). | ||
| */ | ||
| getStaticExecutor(toolName) { | ||
| return this.staticExecutors.get(toolName); | ||
| } | ||
| // --- Core operations --- | ||
| /** | ||
| * Enqueue a task for background execution. | ||
| * Prefer `createBackgroundTask()` which returns a self-contained handle. | ||
| */ | ||
| async enqueue(payload, context) { | ||
| if (this.shuttingDown) { | ||
| throw new Error("BackgroundTaskManager is shutting down, cannot enqueue new tasks"); | ||
| } | ||
| if (this.initPromise) await this.initPromise; | ||
| const task = { | ||
| id: this.#mastra?.generateId() ?? randomUUID(), | ||
| status: "pending", | ||
| toolName: payload.toolName, | ||
| toolCallId: payload.toolCallId, | ||
| args: payload.args, | ||
| agentId: payload.agentId, | ||
| threadId: payload.threadId, | ||
| resourceId: payload.resourceId, | ||
| runId: payload.runId, | ||
| retryCount: 0, | ||
| maxRetries: payload.maxRetries ?? this.config.defaultRetries?.maxRetries ?? 0, | ||
| timeoutMs: payload.timeoutMs ?? this.config.defaultTimeoutMs, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| if (context) { | ||
| this.registerTaskContext(task.id, context); | ||
| } | ||
| const storage = await this.getStorage(); | ||
| await storage.createTask(task); | ||
| const canRun = await this.checkConcurrency(task.agentId); | ||
| if (canRun) { | ||
| await this.dispatch(task); | ||
| return { task }; | ||
| } | ||
| switch (this.config.backpressure) { | ||
| case "reject": | ||
| this.deregisterTaskContext(task.id); | ||
| await storage.deleteTask(task.id); | ||
| throw new Error(`Concurrency limit reached, cannot enqueue task for tool "${task.toolName}"`); | ||
| case "fallback-sync": | ||
| this.deregisterTaskContext(task.id); | ||
| await storage.deleteTask(task.id); | ||
| return { task, fallbackToSync: true }; | ||
| case "queue": | ||
| default: | ||
| return { task }; | ||
| } | ||
| } | ||
| async cancel(taskId) { | ||
| if (this.initPromise) await this.initPromise; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task) { | ||
| throw new Error(`Task not found: ${taskId}`); | ||
| } | ||
| if (task.status === "completed" || task.status === "failed" || task.status === "cancelled" || task.status === "timed_out") { | ||
| return; | ||
| } | ||
| if (task.status === "pending") { | ||
| await storage.updateTask(taskId, { status: "cancelled", completedAt: /* @__PURE__ */ new Date() }); | ||
| const cancelledTask = await storage.getTask(taskId); | ||
| if (cancelledTask) await this.publishLifecycleEvent("task.cancelled", cancelledTask); | ||
| this.deregisterTaskContext(taskId); | ||
| return; | ||
| } | ||
| if (task.status === "suspended") { | ||
| await storage.updateTask(taskId, { status: "cancelled", completedAt: /* @__PURE__ */ new Date() }); | ||
| if (this.#mastra) { | ||
| try { | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const wrapper = await workflow.createRun({ runId: taskId }); | ||
| await wrapper.cancel(); | ||
| } catch (err) { | ||
| this.#mastra?.getLogger?.()?.warn(`background-task workflow cancel failed for ${taskId}:`, err); | ||
| } | ||
| } | ||
| const cancelledTask = await storage.getTask(taskId); | ||
| if (cancelledTask) await this.publishLifecycleEvent("task.cancelled", cancelledTask); | ||
| this.deregisterTaskContext(taskId); | ||
| return; | ||
| } | ||
| if (task.status === "running") { | ||
| await storage.updateTask(taskId, { status: "cancelled", completedAt: /* @__PURE__ */ new Date() }); | ||
| const controller = this.activeAbortControllers.get(taskId); | ||
| if (controller) { | ||
| controller.abort(new Error("Task cancelled")); | ||
| this.activeAbortControllers.delete(taskId); | ||
| } | ||
| if (this.#mastra) { | ||
| try { | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const wrapper = await workflow.createRun({ runId: taskId }); | ||
| await wrapper.cancel(); | ||
| } catch (err) { | ||
| this.#mastra?.getLogger?.()?.warn(`background-task workflow cancel failed for ${taskId}:`, err); | ||
| } | ||
| } | ||
| const cancelledTask = await storage.getTask(taskId); | ||
| if (cancelledTask) await this.publishLifecycleEvent("task.cancelled", cancelledTask); | ||
| this.deregisterTaskContext(taskId); | ||
| await this.pubsub.publish(TOPIC_DISPATCH, { | ||
| type: "task.cancel", | ||
| data: { taskId }, | ||
| runId: taskId | ||
| }); | ||
| } | ||
| } | ||
| /** | ||
| * Resume a suspended task. The tool executor must be re-registered via | ||
| * `registerTaskContext(taskId, ...)` before calling this if the original | ||
| * registration is gone (e.g. process restart) — the manager doesn't | ||
| * rehydrate executor closures from storage. | ||
| * | ||
| * `resumeData` is forwarded to the tool's `execute` options on the | ||
| * resumed run. | ||
| */ | ||
| async resume(taskId, resumeData) { | ||
| if (!this.#mastra) { | ||
| throw new Error("Mastra is not registered with this manager"); | ||
| } | ||
| if (this.initPromise) await this.initPromise; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task) { | ||
| throw new Error(`Task not found: ${taskId}`); | ||
| } | ||
| if (task.status !== "suspended") { | ||
| throw new Error(`Cannot resume task in status '${task.status}' (expected 'suspended')`); | ||
| } | ||
| const canRun = await this.checkConcurrency(task.agentId); | ||
| if (!canRun) { | ||
| throw new Error(`Concurrency limit reached, cannot resume task "${taskId}" \u2014 retry once a slot is available`); | ||
| } | ||
| await this.pubsub.publish(TOPIC_DISPATCH, { | ||
| type: "task.resume", | ||
| data: { taskId, resumeData }, | ||
| runId: taskId | ||
| }); | ||
| return task; | ||
| } | ||
| async getTask(taskId) { | ||
| const storage = await this.getStorage(); | ||
| return storage.getTask(taskId); | ||
| } | ||
| async listTasks(filter = {}) { | ||
| const storage = await this.getStorage(); | ||
| return storage.listTasks(filter); | ||
| } | ||
| /** | ||
| * Deletes old completed/failed/cancelled/timed_out task records from storage. | ||
| */ | ||
| async cleanup() { | ||
| const completedTtlMs = this.config.cleanup?.completedTtlMs ?? 36e5; | ||
| const failedTtlMs = this.config.cleanup?.failedTtlMs ?? 864e5; | ||
| const now = Date.now(); | ||
| const storage = await this.getStorage(); | ||
| await storage.deleteTasks({ | ||
| status: ["completed"], | ||
| toDate: new Date(now - completedTtlMs), | ||
| dateFilterBy: "completedAt" | ||
| }); | ||
| await storage.deleteTasks({ | ||
| status: ["failed", "cancelled", "timed_out"], | ||
| toDate: new Date(now - failedTtlMs), | ||
| dateFilterBy: "completedAt" | ||
| }); | ||
| } | ||
| /** | ||
| * Returns a promise that resolves when the next task from the given set | ||
| * reaches a terminal state. | ||
| */ | ||
| async waitForNextTask(taskIds, options) { | ||
| const storage = await this.getStorage(); | ||
| const isTerminal = (status) => status === "completed" || status === "failed" || status === "cancelled" || status === "timed_out"; | ||
| for (const id of taskIds) { | ||
| const task = await storage.getTask(id); | ||
| if (task && isTerminal(task.status)) { | ||
| return task; | ||
| } | ||
| } | ||
| return new Promise((resolve, reject) => { | ||
| const startTime = Date.now(); | ||
| const timeout = options?.timeoutMs ? setTimeout(() => { | ||
| clearInterval(pollInterval); | ||
| if (progressInterval) clearInterval(progressInterval); | ||
| reject(new Error("Timed out waiting for background task")); | ||
| }, options.timeoutMs) : void 0; | ||
| const progressInterval = options?.onProgress ? setInterval(() => { | ||
| options.onProgress(Date.now() - startTime); | ||
| }, options.progressIntervalMs ?? 3e3) : void 0; | ||
| const pollInterval = setInterval(async () => { | ||
| for (const id of taskIds) { | ||
| const task = await storage.getTask(id); | ||
| if (task && isTerminal(task.status)) { | ||
| clearInterval(pollInterval); | ||
| if (timeout) clearTimeout(timeout); | ||
| if (progressInterval) clearInterval(progressInterval); | ||
| resolve(task); | ||
| return; | ||
| } | ||
| } | ||
| }, 50); | ||
| }); | ||
| } | ||
| /** | ||
| * Returns a ReadableStream of all background task lifecycle events, | ||
| * filtered by optional criteria. Intended to be piped directly to an SSE response. | ||
| * | ||
| * On connection, emits the current state of all non-terminal tasks as a snapshot, | ||
| * then subscribes to live pubsub events for subsequent updates. | ||
| * | ||
| * Events include: | ||
| * - `task.running` (status: 'running') — task picked up by a worker | ||
| * - `task.completed` (status: 'completed') — task finished successfully | ||
| * - `task.failed` (status: 'failed' or 'timed_out') — task errored or timed out | ||
| * - `task.cancelled` (status: 'cancelled') — task was cancelled | ||
| * - `task.suspended` (status: 'suspended') — task paused via `suspend()` from | ||
| * inside its tool executor; resume with `manager.resume(taskId, data)` | ||
| * - `task.resumed` (status: 'running') — suspended task resumed | ||
| * | ||
| * The stream stays open until the caller's AbortSignal fires (client disconnect). | ||
| */ | ||
| stream(options) { | ||
| const manager = this; | ||
| const pubsub = this.pubsub; | ||
| const { agentId, runId, threadId, resourceId, abortSignal, taskId } = options ?? {}; | ||
| const EVENT_STATUS_MAP = { | ||
| "task.running": "running", | ||
| "task.output": "running", | ||
| "task.completed": "completed", | ||
| "task.failed": "failed", | ||
| "task.cancelled": "cancelled", | ||
| "task.suspended": "suspended", | ||
| "task.resumed": "running" | ||
| }; | ||
| const CHUNK_EVENT_MAP = { | ||
| "task.running": "background-task-running", | ||
| "task.output": "background-task-output", | ||
| "task.completed": "background-task-completed", | ||
| "task.failed": "background-task-failed", | ||
| "task.cancelled": "background-task-cancelled", | ||
| "task.suspended": "background-task-suspended", | ||
| "task.resumed": "background-task-resumed" | ||
| }; | ||
| return new ReadableStream({ | ||
| async start(controller) { | ||
| const handler = async (event) => { | ||
| const status = EVENT_STATUS_MAP[event.type]; | ||
| if (!status) return; | ||
| const data = event.data; | ||
| if (agentId && data.agentId !== agentId) return; | ||
| if (runId && data.runId !== runId) return; | ||
| if (threadId && data.threadId !== threadId) return; | ||
| if (resourceId && data.resourceId !== resourceId) return; | ||
| if (taskId && data.taskId !== taskId) return; | ||
| const payload = { | ||
| taskId: data.taskId, | ||
| toolName: data.toolName, | ||
| toolCallId: data.toolCallId, | ||
| agentId: data.agentId, | ||
| runId: data.runId | ||
| }; | ||
| switch (event.type) { | ||
| case "task.running": | ||
| payload.startedAt = data.startedAt; | ||
| payload.args = data.args; | ||
| break; | ||
| case "task.completed": | ||
| payload.completedAt = data.completedAt; | ||
| payload.result = data.result; | ||
| break; | ||
| case "task.failed": | ||
| payload.completedAt = data.completedAt; | ||
| payload.error = data.error; | ||
| break; | ||
| case "task.cancelled": | ||
| payload.completedAt = data.completedAt; | ||
| break; | ||
| case "task.output": | ||
| payload.payload = data.chunk; | ||
| break; | ||
| case "task.suspended": | ||
| payload.suspendPayload = data.suspendPayload; | ||
| payload.suspendedAt = data.suspendedAt; | ||
| payload.args = data.args; | ||
| break; | ||
| case "task.resumed": | ||
| payload.startedAt = data.startedAt; | ||
| payload.args = data.args; | ||
| break; | ||
| } | ||
| try { | ||
| controller.enqueue({ | ||
| type: CHUNK_EVENT_MAP[event.type], | ||
| payload | ||
| }); | ||
| } catch { | ||
| } | ||
| }; | ||
| void pubsub.subscribe(TOPIC_RESULT, handler); | ||
| abortSignal?.addEventListener("abort", () => { | ||
| void pubsub.unsubscribe(TOPIC_RESULT, handler); | ||
| try { | ||
| controller.close(); | ||
| } catch { | ||
| } | ||
| }); | ||
| try { | ||
| const storage = await manager.getStorage(); | ||
| if (taskId) { | ||
| const task = await storage.getTask(taskId); | ||
| if (task && task.status === "running") { | ||
| controller.enqueue({ | ||
| type: "background-task-running", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| agentId: task.agentId, | ||
| runId: task.runId, | ||
| startedAt: task.startedAt, | ||
| args: task.args | ||
| } | ||
| }); | ||
| } | ||
| } else { | ||
| const { tasks: existing } = await storage.listTasks({ | ||
| agentId, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| status: ["running"] | ||
| }); | ||
| for (const task of existing) { | ||
| if (abortSignal?.aborted) break; | ||
| try { | ||
| controller.enqueue({ | ||
| type: "background-task-running", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| agentId: task.agentId, | ||
| runId: task.runId, | ||
| startedAt: task.startedAt, | ||
| args: task.args | ||
| } | ||
| }); | ||
| } catch { | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| } catch { | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| async shutdown() { | ||
| this.shuttingDown = true; | ||
| if (this.cleanupInterval) { | ||
| clearInterval(this.cleanupInterval); | ||
| this.cleanupInterval = void 0; | ||
| } | ||
| if (this.workerCallback) { | ||
| await this.pubsub.unsubscribe(TOPIC_DISPATCH, this.workerCallback); | ||
| } | ||
| if (this.resultCallback) { | ||
| await this.pubsub.unsubscribe(TOPIC_RESULT, this.resultCallback); | ||
| } | ||
| this.taskContexts.clear(); | ||
| await this.pubsub.flush(); | ||
| } | ||
| // --- Internal --- | ||
| async dispatch(task) { | ||
| await this.pubsub.publish(TOPIC_DISPATCH, { | ||
| type: "task.dispatch", | ||
| data: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| args: task.args, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| timeoutMs: task.timeoutMs, | ||
| maxRetries: task.maxRetries, | ||
| runId: task.runId | ||
| }, | ||
| runId: task.id | ||
| }); | ||
| } | ||
| /** | ||
| * Handles a task.dispatch event. Returns true if the message was nacked (for retry). | ||
| */ | ||
| async handleDispatch(event) { | ||
| const { taskId } = event.data; | ||
| const deliveryAttempt = event.deliveryAttempt ?? 1; | ||
| let nacked = false; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task || task.status === "cancelled") { | ||
| this.deregisterTaskContext(taskId); | ||
| return false; | ||
| } | ||
| await storage.updateTask(taskId, { status: "running", startedAt: /* @__PURE__ */ new Date(), retryCount: deliveryAttempt - 1 }); | ||
| const runningTask = await storage.getTask(taskId); | ||
| if (runningTask) await this.publishLifecycleEvent("task.running", runningTask); | ||
| if (this.#mastra) { | ||
| if (runningTask) void this.runLocalExecutionHook(runningTask); | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const run = await workflow.createRun({ runId: taskId }); | ||
| void run.start({ inputData: { taskId } }).then((result) => { | ||
| if (result.status !== "suspended") { | ||
| void workflow.deleteWorkflowRunById(taskId); | ||
| } | ||
| }).catch((err) => { | ||
| this.#mastra?.getLogger?.()?.error(`background-task workflow start failed for ${taskId}:`, err); | ||
| }).finally(() => { | ||
| void this.drainPending(); | ||
| }); | ||
| } | ||
| return nacked; | ||
| } | ||
| /** | ||
| * Handles a task.resume event. Mirrors the workflow branch of handleDispatch | ||
| * but resumes an existing run from its suspended snapshot instead of starting | ||
| * a fresh one. Concurrency gating, suspended-status validation, and the | ||
| * `task.resumed` lifecycle publish all happen here so a different process | ||
| * than the one that suspended the task can drive the resume. | ||
| */ | ||
| async handleResume(event) { | ||
| const { taskId, resumeData } = event.data; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task || task.status !== "suspended") { | ||
| return; | ||
| } | ||
| await storage.updateTask(taskId, { | ||
| status: "running", | ||
| startedAt: /* @__PURE__ */ new Date(), | ||
| suspendPayload: void 0, | ||
| suspendedAt: void 0 | ||
| }); | ||
| const resumedTask = await storage.getTask(taskId); | ||
| if (resumedTask) { | ||
| await this.publishLifecycleEvent("task.resumed", resumedTask); | ||
| } | ||
| if (!this.#mastra) return; | ||
| const workflow = this.#mastra.__getInternalWorkflow(BACKGROUND_TASK_WORKFLOW_ID); | ||
| const run = await workflow.createRun({ runId: taskId }); | ||
| void run.resume({ resumeData }).then((result) => { | ||
| if (result.status !== "suspended") { | ||
| void workflow.deleteWorkflowRunById(taskId); | ||
| } | ||
| }).catch((err) => { | ||
| this.#mastra?.getLogger?.()?.error(`background-task workflow resume failed for ${taskId}:`, err); | ||
| }).finally(() => { | ||
| void this.drainPending(); | ||
| }); | ||
| } | ||
| /** | ||
| * Run per-task hooks (onChunk, onResult, onComplete/onFailed) locally in the | ||
| * worker path, before publishing the terminal lifecycle event. Ensures | ||
| * memory / stream state is consistent by the time any pubsub subscriber is | ||
| * notified. After running, the task context is deregistered so | ||
| * `handleResult` (which also fires from pubsub) becomes a no-op for this | ||
| * task in the same process. | ||
| * | ||
| * In distributed deployments where the worker runs in a different process | ||
| * from the dispatcher, `this.taskContexts` won't contain an entry for | ||
| * `task.id` — this method is a no-op there, and `handleResult` in the | ||
| * dispatching process runs the hooks instead. | ||
| */ | ||
| /** | ||
| * Terminal-state hooks only. Called when a task reaches `'completed'` or | ||
| * `'failed'`. Suspend is non-terminal — see `runLocalSuspendHooks` for that | ||
| * path. | ||
| * | ||
| * @internal — also called by the workflow-engine step bodies in workflow.ts | ||
| */ | ||
| async runLocalCompletionHooks(task, status, extras) { | ||
| const ctx = this.taskContexts.get(task.id); | ||
| if (!ctx) return; | ||
| try { | ||
| if (status === "completed") { | ||
| ctx.onChunk?.({ | ||
| type: "background-task-completed", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| runId: task.runId, | ||
| result: extras.result, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx.onResult?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| result: extras.result, | ||
| status: "completed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| await ctx.onComplete?.(task); | ||
| } else { | ||
| ctx.onChunk?.({ | ||
| type: "background-task-failed", | ||
| payload: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| runId: task.runId, | ||
| error: extras.error ?? { message: "Unknown error" }, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx.onResult?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| error: extras.error, | ||
| status: "failed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| await ctx.onFailed?.(task); | ||
| } | ||
| } finally { | ||
| this.deregisterTaskContext(task.id); | ||
| } | ||
| } | ||
| /** | ||
| * Per-task suspend hooks. Fires `ctx.onResult({ status: 'suspended', ... })` | ||
| * so the message list / memory pick up the suspension as the tool's | ||
| * current invocation state. Does NOT deregister the task context — resume | ||
| * needs the executor closure intact. | ||
| * | ||
| * @internal — called by the workflow-engine step bodies in workflow.ts | ||
| */ | ||
| async runLocalSuspendHooks(task) { | ||
| const ctx = this.taskContexts.get(task.id); | ||
| if (!ctx) return; | ||
| await ctx.onExecution?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| startedAt: task.startedAt, | ||
| suspendedAt: task.suspendedAt | ||
| }); | ||
| } | ||
| /** @internal — also called by the workflow-engine step bodies in workflow.ts */ | ||
| async runLocalExecutionHook(task) { | ||
| const ctx = this.taskContexts.get(task.id); | ||
| if (!ctx) return; | ||
| try { | ||
| await ctx.onExecution?.({ | ||
| runId: task.runId, | ||
| taskId: task.id, | ||
| toolCallId: task.toolCallId, | ||
| toolName: task.toolName, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| startedAt: task.startedAt | ||
| }); | ||
| } catch { | ||
| } | ||
| } | ||
| async handleResult(event) { | ||
| const { taskId, toolName, toolCallId, threadId, resourceId, runId } = event.data; | ||
| const storage = await this.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (task?.completedAt) { | ||
| const ctx = this.taskContexts.get(taskId); | ||
| if (event.type === "task.completed") { | ||
| ctx?.onChunk?.({ | ||
| type: "background-task-completed", | ||
| payload: { | ||
| taskId, | ||
| toolName, | ||
| toolCallId, | ||
| runId, | ||
| result: event.data.result, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx?.onResult?.({ | ||
| runId, | ||
| taskId, | ||
| toolCallId, | ||
| toolName, | ||
| agentId: event.data.agentId, | ||
| threadId, | ||
| resourceId, | ||
| result: event.data.result, | ||
| status: "completed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| if (task) { | ||
| await Promise.all([ctx?.onComplete?.(task), this.config.onTaskComplete?.(task)]); | ||
| } | ||
| } | ||
| if (event.type === "task.failed") { | ||
| ctx?.onChunk?.({ | ||
| type: "background-task-failed", | ||
| payload: { | ||
| taskId, | ||
| toolName, | ||
| toolCallId, | ||
| runId, | ||
| error: event.data.error, | ||
| completedAt: task.completedAt, | ||
| agentId: task.agentId | ||
| } | ||
| }); | ||
| await ctx?.onResult?.({ | ||
| runId, | ||
| taskId, | ||
| toolCallId, | ||
| toolName, | ||
| agentId: event.data.agentId, | ||
| threadId, | ||
| resourceId, | ||
| error: event.data.error, | ||
| status: "failed", | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt | ||
| }); | ||
| if (task) { | ||
| await Promise.all([ctx?.onFailed?.(task), this.config.onTaskFailed?.(task)]); | ||
| } | ||
| } | ||
| this.deregisterTaskContext(taskId); | ||
| } | ||
| } | ||
| handleCancel(event) { | ||
| const { taskId } = event.data; | ||
| const controller = this.activeAbortControllers.get(taskId); | ||
| if (controller) { | ||
| controller.abort(new Error("Task cancelled")); | ||
| this.activeAbortControllers.delete(taskId); | ||
| } | ||
| this.deregisterTaskContext(taskId); | ||
| } | ||
| /** @internal — also called by the workflow-engine step bodies in workflow.ts */ | ||
| async publishLifecycleEvent(type, task) { | ||
| await this.pubsub.publish(TOPIC_RESULT, { | ||
| type, | ||
| data: { | ||
| taskId: task.id, | ||
| toolName: task.toolName, | ||
| toolCallId: task.toolCallId, | ||
| runId: task.runId, | ||
| agentId: task.agentId, | ||
| threadId: task.threadId, | ||
| resourceId: task.resourceId, | ||
| args: task.args, | ||
| result: task.result, | ||
| error: task.error, | ||
| chunk: task.chunk, | ||
| completedAt: task.completedAt, | ||
| startedAt: task.startedAt, | ||
| suspendPayload: task.suspendPayload, | ||
| suspendedAt: task.suspendedAt | ||
| }, | ||
| runId: task.id | ||
| }); | ||
| } | ||
| async checkConcurrency(agentId) { | ||
| const storage = await this.getStorage(); | ||
| const globalRunning = await storage.getRunningCount(); | ||
| if (globalRunning >= this.config.globalConcurrency) { | ||
| return false; | ||
| } | ||
| const agentRunning = await storage.getRunningCountByAgent(agentId); | ||
| if (agentRunning >= this.config.perAgentConcurrency) { | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| async drainPending() { | ||
| const storage = await this.getStorage(); | ||
| const { tasks: pending } = await storage.listTasks({ | ||
| status: "pending", | ||
| orderBy: "createdAt", | ||
| orderDirection: "asc" | ||
| }); | ||
| for (const task of pending) { | ||
| if (await this.checkConcurrency(task.agentId)) { | ||
| await this.dispatch(task); | ||
| } | ||
| } | ||
| } | ||
| /** | ||
| * Recovers tasks left in 'running' or 'pending' state from a previous process. | ||
| */ | ||
| async recoverStaleTasks() { | ||
| try { | ||
| const storage = await this.getStorage(); | ||
| const { tasks: staleTasks } = await storage.listTasks({ status: "running" }); | ||
| for (const task of staleTasks) { | ||
| if (task.maxRetries > 0) { | ||
| await storage.updateTask(task.id, { | ||
| status: "pending", | ||
| startedAt: void 0 | ||
| }); | ||
| } else { | ||
| await storage.updateTask(task.id, { | ||
| status: "failed", | ||
| error: { message: "Worker process terminated before task completed" }, | ||
| completedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| } | ||
| } | ||
| const { tasks: pendingTasks } = await storage.listTasks({ | ||
| status: "pending", | ||
| orderBy: "createdAt", | ||
| orderDirection: "asc" | ||
| }); | ||
| for (const task of pendingTasks) { | ||
| if (await this.checkConcurrency(task.agentId)) { | ||
| await this.dispatch(task); | ||
| } | ||
| } | ||
| } catch (error) { | ||
| const logger = this.#mastra?.getLogger(); | ||
| if (logger) { | ||
| logger.error("Failed to recover stale background tasks", error); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| // src/background-tasks/create.ts | ||
| function createBackgroundTask(manager, options) { | ||
| const { context, ...payload } = options; | ||
| let taskId; | ||
| return { | ||
| get task() { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return { id: taskId }; | ||
| }, | ||
| async dispatch() { | ||
| const result = await manager.enqueue(payload, context); | ||
| taskId = result.task.id; | ||
| return result; | ||
| }, | ||
| async checkIfSuspended(args) { | ||
| const result = await manager.listTasks({ | ||
| toolCallId: args.toolCallId, | ||
| runId: args.runId, | ||
| agentId: args.agentId, | ||
| threadId: args.threadId, | ||
| resourceId: args.resourceId, | ||
| toolName: args.toolName, | ||
| status: "suspended" | ||
| }); | ||
| if (result.total > 0) { | ||
| const task = result.tasks[0]; | ||
| if (task) { | ||
| taskId = task.id; | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| }, | ||
| async resume(resumeData) { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return manager.resume(taskId, resumeData); | ||
| }, | ||
| async cancel() { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return manager.cancel(taskId); | ||
| }, | ||
| async waitForCompletion(waitOptions) { | ||
| if (!taskId) throw new Error("Task has not been dispatched yet"); | ||
| return manager.waitForNextTask([taskId], waitOptions); | ||
| } | ||
| }; | ||
| } | ||
| // src/background-tasks/resolve-config.ts | ||
| function resolveBackgroundConfig({ | ||
| llmBgOverrides, | ||
| toolName, | ||
| toolConfig, | ||
| agentConfig, | ||
| managerConfig | ||
| }) { | ||
| const llmOverride = llmBgOverrides; | ||
| if (agentConfig?.disabled) { | ||
| return { | ||
| runInBackground: false, | ||
| timeoutMs: managerConfig?.defaultTimeoutMs ?? 3e5, | ||
| maxRetries: managerConfig?.defaultRetries?.maxRetries ?? 0 | ||
| }; | ||
| } | ||
| const agentToolConfig = resolveAgentToolConfig(toolName, agentConfig); | ||
| const baseEnabled = agentToolConfig?.enabled ?? toolConfig?.enabled ?? false; | ||
| const enabled = baseEnabled ? llmOverride?.enabled ?? true : false; | ||
| const timeoutMs = llmOverride?.timeoutMs ?? agentToolConfig?.timeoutMs ?? toolConfig?.timeoutMs ?? managerConfig?.defaultTimeoutMs ?? 3e5; | ||
| const maxRetries = llmOverride?.maxRetries ?? toolConfig?.maxRetries ?? managerConfig?.defaultRetries?.maxRetries ?? 0; | ||
| return { runInBackground: enabled, timeoutMs, maxRetries }; | ||
| } | ||
| function resolveAgentToolConfig(toolName, agentConfig) { | ||
| if (!agentConfig?.tools) return void 0; | ||
| if (agentConfig.tools === "all") { | ||
| return { enabled: true }; | ||
| } | ||
| if (toolName.startsWith("agent-")) { | ||
| toolName = toolName.substring("agent-".length); | ||
| } else if (toolName.startsWith("workflow-")) { | ||
| toolName = toolName.substring("workflow-".length); | ||
| } | ||
| const entry = agentConfig.tools[toolName]; | ||
| if (entry === void 0) return void 0; | ||
| if (typeof entry === "boolean") return { enabled: entry }; | ||
| return entry; | ||
| } | ||
| var backgroundOverrideJsonSchema = { | ||
| type: "object", | ||
| description: "Optional: override background execution behavior for this specific call. Set enabled=false to force foreground, enabled=true to force background. Omit entirely to use the default configuration.", | ||
| properties: { | ||
| enabled: { | ||
| type: "boolean", | ||
| description: "Force background (true) or foreground (false) execution for this call." | ||
| }, | ||
| timeoutMs: { | ||
| type: "number", | ||
| description: "Override timeout in milliseconds for this call." | ||
| }, | ||
| maxRetries: { | ||
| type: "number", | ||
| description: "Override maximum retry attempts for this call." | ||
| } | ||
| }, | ||
| additionalProperties: false | ||
| }; | ||
| var backgroundOverrideZodSchema = z.object({ | ||
| enabled: z.boolean().optional().describe("Force background (true) or foreground (false) execution for this call."), | ||
| timeoutMs: z.number().optional().describe("Override timeout in milliseconds for this call."), | ||
| maxRetries: z.number().optional().describe("Override maximum retry attempts for this call.") | ||
| }).optional().describe( | ||
| "Optional: override background execution behavior for this specific call. Set enabled=false to force foreground, enabled=true to force background. Omit entirely to use the default configuration." | ||
| ); | ||
| // src/background-tasks/system-prompt.ts | ||
| function generateBackgroundTaskSystemPrompt(tools, agentConfig) { | ||
| const eligibleTools = []; | ||
| const enableAll = agentConfig?.tools === "all"; | ||
| for (const [toolName, tool] of Object.entries(tools)) { | ||
| const bgEnabledFromAgentConfig = agentConfig?.tools === "all" ? false : typeof agentConfig?.tools?.[toolName] === "boolean" ? agentConfig.tools[toolName] : agentConfig?.tools?.[toolName]?.enabled ?? false; | ||
| eligibleTools.push({ | ||
| toolName, | ||
| toolConfig: tool.background, | ||
| defaultBackground: enableAll ? true : bgEnabledFromAgentConfig ?? tool.background?.enabled ?? false | ||
| }); | ||
| } | ||
| if (eligibleTools.length === 0) { | ||
| return void 0; | ||
| } | ||
| const toolLines = eligibleTools.map((t) => `- ${t.toolName} (default: ${t.defaultBackground ? "background" : "foreground"})`).join("\n"); | ||
| return `You have the ability to run certain tools in the background while continuing the conversation. The following tools support background execution: | ||
| ${toolLines} | ||
| For any of these tools, you can include a "_background" field in the tool arguments to override the default: | ||
| "_background": { "enabled": true/false, "timeoutMs": number, "maxRetries": number } | ||
| All fields in "_background" are optional. Only include what you want to override. | ||
| Guidelines: | ||
| - Use background execution when the user doesn't need the result immediately, or when you're launching multiple independent tasks. | ||
| - Use foreground execution when the user is directly waiting for the result and the conversation can't continue without it. | ||
| - If you don't include "_background", the tool's default configuration is used. | ||
| - When a tool runs in the background, you'll receive a placeholder result with a task ID. You can reference this in your response to the user. | ||
| IMPORTANT: "_background" field is always an object. The fields in the _background field should be inside the _background object, not outside of it.`; | ||
| } | ||
| export { BACKGROUND_TASK_WORKFLOW_ID, BackgroundTaskManager, backgroundOverrideJsonSchema, backgroundOverrideZodSchema, createBackgroundTask, generateBackgroundTaskSystemPrompt, resolveBackgroundConfig }; | ||
| //# sourceMappingURL=chunk-MLZSPNYB.js.map | ||
| //# sourceMappingURL=chunk-MLZSPNYB.js.map |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { Tool, isVercelTool, isProviderDefinedTool, validateToolInput, getNeedsApprovalFn, validateToolOutput, validateToolSuspendData } from './chunk-VLJMDX6T.js'; | ||
| import { isStandardSchemaWithJSON, toStandardSchema, standardSchemaToJSONSchema } from './chunk-6SRTDZ7S.js'; | ||
| import { isZodObject, safeExtendZodObject } from './chunk-TBHKQLPL.js'; | ||
| import { wrapMastra, createObservabilityContext } from './chunk-JPUBRZLW.js'; | ||
| import { getOrCreateSpan, EntityType, executeWithContext } from './chunk-DEQCJWZZ.js'; | ||
| import { MastraFGAPermissions } from './chunk-JAIH7QCD.js'; | ||
| import { backgroundOverrideZodSchema, backgroundOverrideJsonSchema } from './chunk-MLZSPNYB.js'; | ||
| import { MastraBase } from './chunk-77VL4DNS.js'; | ||
| import { RequestContext } from './chunk-RI37F2KY.js'; | ||
| import { MastraError, ErrorCategory, ErrorDomain } from './chunk-M7RBQNFP.js'; | ||
| import { createHash } from 'crypto'; | ||
| import { jsonSchemaToZod } from '@mastra/schema-compat/json-to-zod'; | ||
| import { z } from 'zod/v4'; | ||
| import { convertZodSchemaToAISDKSchema, OpenAIReasoningSchemaCompatLayer, OpenAISchemaCompatLayer, GoogleSchemaCompatLayer, AnthropicSchemaCompatLayer, DeepSeekSchemaCompatLayer, MetaSchemaCompatLayer, jsonSchema, applyCompatLayer } from '@mastra/schema-compat'; | ||
| import { WritableStream } from 'stream/web'; | ||
| var ToolStream = class extends WritableStream { | ||
| prefix; | ||
| callId; | ||
| name; | ||
| runId; | ||
| writeFn; | ||
| constructor({ | ||
| prefix, | ||
| callId, | ||
| name, | ||
| runId | ||
| }, writeFn) { | ||
| super({ | ||
| async write(chunk) { | ||
| await getInstance()._write(chunk); | ||
| } | ||
| }); | ||
| const self = this; | ||
| function getInstance() { | ||
| return self; | ||
| } | ||
| this.prefix = prefix; | ||
| this.callId = callId; | ||
| this.name = name; | ||
| this.runId = runId; | ||
| this.writeFn = writeFn; | ||
| } | ||
| async _write(data) { | ||
| if (this.writeFn) { | ||
| await this.writeFn({ | ||
| type: `${this.prefix}-output`, | ||
| runId: this.runId, | ||
| from: "USER", | ||
| payload: { | ||
| output: data, | ||
| ...this.prefix === "workflow-step" ? { | ||
| runId: this.runId, | ||
| stepName: this.name | ||
| } : { | ||
| [`${this.prefix}CallId`]: this.callId, | ||
| [`${this.prefix}Name`]: this.name | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| async write(data) { | ||
| await this._write(data); | ||
| } | ||
| async custom(data) { | ||
| if (this.writeFn) { | ||
| await this.writeFn(data); | ||
| } | ||
| } | ||
| }; | ||
| // src/tools/types.ts | ||
| var noopObserve = { | ||
| async span(_name, fn) { | ||
| return fn(); | ||
| }, | ||
| log() { | ||
| } | ||
| }; | ||
| // src/tools/tool-builder/builder.ts | ||
| function mergeRequestContexts(closureRC, execRC) { | ||
| if (!closureRC && !execRC) return new RequestContext(); | ||
| if (!closureRC) return execRC instanceof RequestContext ? execRC : new RequestContext(); | ||
| if (!execRC || !(execRC instanceof RequestContext) || execRC.size() === 0) return closureRC; | ||
| const merged = new RequestContext(); | ||
| for (const [key, value] of execRC.entries()) { | ||
| merged.set(key, value); | ||
| } | ||
| for (const [key, value] of closureRC.entries()) { | ||
| merged.set(key, value); | ||
| } | ||
| return merged; | ||
| } | ||
| function isZodV4Schema(schema) { | ||
| const def = schema?._def; | ||
| return !!def && typeof def.type === "string" && !def.typeName; | ||
| } | ||
| function buildJsonOverrideSchema(originalSchema, splicedJsonSchema, injectedKeys) { | ||
| const fallback = toStandardSchema(splicedJsonSchema); | ||
| const original = originalSchema; | ||
| const originalValidate = original?.["~standard"]?.validate?.bind(original["~standard"]); | ||
| const splicedProperties = splicedJsonSchema && typeof splicedJsonSchema === "object" && "properties" in splicedJsonSchema ? splicedJsonSchema.properties ?? {} : {}; | ||
| const injectedProperties = {}; | ||
| for (const key of injectedKeys) { | ||
| if (splicedProperties[key] !== void 0) injectedProperties[key] = splicedProperties[key]; | ||
| } | ||
| const injectedValidator = toStandardSchema({ | ||
| type: "object", | ||
| properties: injectedProperties, | ||
| additionalProperties: false | ||
| }); | ||
| const stripInjected = (input) => { | ||
| if (!input || typeof input !== "object" || Array.isArray(input)) return { stripped: input, injected: {} }; | ||
| const injected = {}; | ||
| const stripped = {}; | ||
| for (const [k, v] of Object.entries(input)) { | ||
| if (injectedKeys.includes(k)) injected[k] = v; | ||
| else stripped[k] = v; | ||
| } | ||
| return { stripped, injected }; | ||
| }; | ||
| const validate = (input) => { | ||
| const { stripped, injected } = stripInjected(input); | ||
| const baseResult = originalValidate ? originalValidate(stripped) : fallback["~standard"].validate(stripped); | ||
| const injectedResult = injectedValidator["~standard"].validate(injected); | ||
| const combine = (base, inj) => { | ||
| const baseIssues = "issues" in base ? base.issues ?? [] : []; | ||
| const injIssues = "issues" in inj ? inj.issues ?? [] : []; | ||
| if (baseIssues.length || injIssues.length) { | ||
| return { issues: [...baseIssues, ...injIssues] }; | ||
| } | ||
| const baseValue = base.value; | ||
| const injValue = inj.value; | ||
| if (baseValue && typeof baseValue === "object" && !Array.isArray(baseValue)) { | ||
| const injMerged = injValue && typeof injValue === "object" && !Array.isArray(injValue) ? injValue : injected; | ||
| return { value: { ...baseValue, ...injMerged } }; | ||
| } | ||
| return base; | ||
| }; | ||
| const baseIsPromise = baseResult && typeof baseResult.then === "function"; | ||
| const injIsPromise = injectedResult && typeof injectedResult.then === "function"; | ||
| if (baseIsPromise || injIsPromise) { | ||
| return Promise.all([baseResult, injectedResult]).then( | ||
| ([b, i]) => combine( | ||
| b, | ||
| i | ||
| ) | ||
| ); | ||
| } | ||
| return combine( | ||
| baseResult, | ||
| injectedResult | ||
| ); | ||
| }; | ||
| return { | ||
| "~standard": { | ||
| version: 1, | ||
| vendor: "mastra-json-override", | ||
| validate, | ||
| jsonSchema: fallback["~standard"].jsonSchema | ||
| } | ||
| }; | ||
| } | ||
| var CoreToolBuilder = class extends MastraBase { | ||
| originalTool; | ||
| options; | ||
| logType; | ||
| constructor(input) { | ||
| super({ name: "CoreToolBuilder" }); | ||
| this.originalTool = input.originalTool; | ||
| this.options = input.options; | ||
| this.logType = input.logType; | ||
| const isBackgroundEligible = !!input.backgroundTaskEnabled; | ||
| const isResumableTool = input.autoResumeSuspendedTools || this.originalTool.id?.startsWith("agent-") || this.originalTool.id?.startsWith("workflow-"); | ||
| if (!isVercelTool(this.originalTool) && !isProviderDefinedTool(this.originalTool)) { | ||
| if (isBackgroundEligible || isResumableTool) { | ||
| let schema = this.originalTool.inputSchema; | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| if (!schema) { | ||
| schema = z.object({}); | ||
| } | ||
| if (isZodObject(schema) && isZodV4Schema(schema)) { | ||
| let nextSchema = schema; | ||
| if (isBackgroundEligible) { | ||
| nextSchema = safeExtendZodObject(nextSchema, { | ||
| _background: backgroundOverrideZodSchema | ||
| }); | ||
| } | ||
| if (isResumableTool) { | ||
| nextSchema = safeExtendZodObject(nextSchema, { | ||
| suspendedToolRunId: z.string().describe("The runId of the suspended tool").nullable().optional(), | ||
| resumeData: z.any().describe("The resumeData object created from the resumeSchema of suspended tool").optional() | ||
| }); | ||
| } | ||
| this.originalTool.inputSchema = nextSchema; | ||
| } else { | ||
| const standardSchema = isStandardSchemaWithJSON(schema) ? schema : toStandardSchema(schema); | ||
| const jsonSchema2 = standardSchemaToJSONSchema(standardSchema, { io: "input" }); | ||
| if (jsonSchema2 && typeof jsonSchema2 === "object" && jsonSchema2.type === "object") { | ||
| const properties = { ...jsonSchema2.properties ?? {} }; | ||
| const injectedKeys = []; | ||
| if (isBackgroundEligible) { | ||
| properties._background = backgroundOverrideJsonSchema; | ||
| injectedKeys.push("_background"); | ||
| } | ||
| if (isResumableTool) { | ||
| properties.suspendedToolRunId = { | ||
| type: ["string", "null"], | ||
| description: "The runId of the suspended tool" | ||
| }; | ||
| properties.resumeData = { | ||
| description: "The resumeData object created from the resumeSchema of suspended tool" | ||
| }; | ||
| injectedKeys.push("suspendedToolRunId", "resumeData"); | ||
| } | ||
| this.originalTool.inputSchema = buildJsonOverrideSchema( | ||
| schema, | ||
| { ...jsonSchema2, properties }, | ||
| injectedKeys | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // Helper to get parameters based on tool type | ||
| getParameters = () => { | ||
| if (isVercelTool(this.originalTool)) { | ||
| let schema2 = this.originalTool.parameters ?? ("inputSchema" in this.originalTool ? this.originalTool.inputSchema : void 0) ?? z.object({}); | ||
| if (typeof schema2 === "function") { | ||
| schema2 = schema2(); | ||
| } | ||
| return schema2; | ||
| } | ||
| let schema = this.originalTool.inputSchema; | ||
| if (isStandardSchemaWithJSON(schema)) { | ||
| return schema; | ||
| } | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| }; | ||
| getOutputSchema = () => { | ||
| if ("outputSchema" in this.originalTool) { | ||
| let schema = this.originalTool.outputSchema; | ||
| if (isStandardSchemaWithJSON(schema)) { | ||
| return schema; | ||
| } | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| } | ||
| return null; | ||
| }; | ||
| getResumeSchema = () => { | ||
| if ("resumeSchema" in this.originalTool) { | ||
| let schema = this.originalTool.resumeSchema; | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| } | ||
| return null; | ||
| }; | ||
| getSuspendSchema = () => { | ||
| if ("suspendSchema" in this.originalTool) { | ||
| let schema = this.originalTool.suspendSchema; | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return schema; | ||
| } | ||
| return null; | ||
| }; | ||
| // For provider-defined tools, we need to include all required properties | ||
| // AI SDK v5 uses type: 'provider-defined', AI SDK v6 uses type: 'provider' | ||
| buildProviderTool(tool) { | ||
| if ("type" in tool && (tool.type === "provider-defined" || tool.type === "provider") && "id" in tool && typeof tool.id === "string" && tool.id.includes(".")) { | ||
| let parameters = "parameters" in tool ? tool.parameters : "inputSchema" in tool ? tool.inputSchema : void 0; | ||
| if (typeof parameters === "function") { | ||
| parameters = parameters(); | ||
| } | ||
| let outputSchema = "outputSchema" in tool ? tool.outputSchema : void 0; | ||
| if (typeof outputSchema === "function") { | ||
| outputSchema = outputSchema(); | ||
| } | ||
| let processedParameters; | ||
| if (parameters !== void 0 && parameters !== null) { | ||
| if (typeof parameters === "object" && "jsonSchema" in parameters) { | ||
| processedParameters = parameters; | ||
| } else if (isStandardSchemaWithJSON(parameters)) { | ||
| const jsonSchema2 = standardSchemaToJSONSchema(parameters, { io: "input" }); | ||
| processedParameters = { jsonSchema: jsonSchema2 }; | ||
| } else { | ||
| processedParameters = convertZodSchemaToAISDKSchema(parameters); | ||
| } | ||
| } else { | ||
| processedParameters = { | ||
| jsonSchema: { | ||
| type: "object", | ||
| properties: {}, | ||
| additionalProperties: false | ||
| } | ||
| }; | ||
| } | ||
| let processedOutputSchema; | ||
| if (outputSchema !== void 0 && outputSchema !== null) { | ||
| if (typeof outputSchema === "object" && "jsonSchema" in outputSchema) { | ||
| processedOutputSchema = outputSchema; | ||
| } else if (isStandardSchemaWithJSON(outputSchema)) { | ||
| const jsonSchema2 = standardSchemaToJSONSchema(outputSchema); | ||
| processedOutputSchema = { jsonSchema: jsonSchema2 }; | ||
| } else { | ||
| processedOutputSchema = convertZodSchemaToAISDKSchema(outputSchema); | ||
| } | ||
| } | ||
| return { | ||
| ...processedOutputSchema ? { outputSchema: processedOutputSchema } : {}, | ||
| type: "provider-defined", | ||
| id: tool.id, | ||
| // V5 SDK factories set a hardcoded `name` (e.g. "web_search" for | ||
| // anthropic.web_search_20250305). Preserve it so that when this tool | ||
| // is later used with a V6 provider, the bidirectional toolNameMapping | ||
| // resolves the correct model-facing name instead of the versioned ID. | ||
| ..."name" in tool && typeof tool.name === "string" ? { name: tool.name } : {}, | ||
| args: "args" in this.originalTool ? this.originalTool.args : {}, | ||
| description: tool.description, | ||
| parameters: processedParameters, | ||
| execute: this.originalTool.execute ? this.createExecute( | ||
| this.originalTool, | ||
| { ...this.options, description: this.originalTool.description }, | ||
| this.logType | ||
| ) : void 0, | ||
| toModelOutput: "toModelOutput" in this.originalTool ? this.originalTool.toModelOutput : void 0, | ||
| transform: "transform" in this.originalTool ? this.originalTool.transform : void 0, | ||
| inputExamples: "inputExamples" in this.originalTool ? this.originalTool.inputExamples : void 0 | ||
| }; | ||
| } | ||
| return void 0; | ||
| } | ||
| createLogMessageOptions({ agentName, toolName, type }) { | ||
| const toolType = type === "toolset" ? "toolset" : "tool"; | ||
| return { | ||
| start: `Executing ${toolType}`, | ||
| error: `Failed ${toolType} execution`, | ||
| logData: { agent: agentName, tool: toolName } | ||
| }; | ||
| } | ||
| createExecute(tool, options, logType) { | ||
| const { | ||
| logger, | ||
| mastra: _mastra, | ||
| memory: _memory, | ||
| requestContext, | ||
| model, | ||
| tracingContext: _tracingContext, | ||
| tracingPolicy: _tracingPolicy, | ||
| ...rest | ||
| } = options; | ||
| const logModelObject = { | ||
| modelId: model?.modelId, | ||
| provider: model?.provider, | ||
| specificationVersion: model?.specificationVersion | ||
| }; | ||
| const { start, logData } = this.createLogMessageOptions({ | ||
| agentName: options.agentName, | ||
| toolName: options.name, | ||
| type: logType | ||
| }); | ||
| const mcpMeta = !isVercelTool(tool) && "mcpMetadata" in tool ? tool.mcpMetadata : void 0; | ||
| const execFunction = async (args, execOptions, toolSpan) => { | ||
| try { | ||
| let result; | ||
| let suspendData = null; | ||
| if (isVercelTool(tool)) { | ||
| result = await executeWithContext({ | ||
| span: toolSpan, | ||
| fn: async () => tool?.execute?.(args, execOptions) | ||
| }); | ||
| } else { | ||
| const wrappedMastra = options.mastra ? wrapMastra(options.mastra, { currentSpan: toolSpan }) : options.mastra; | ||
| const resumeSchema = this.getResumeSchema(); | ||
| const baseContext = { | ||
| threadId: options.threadId, | ||
| resourceId: options.resourceId, | ||
| mastra: wrappedMastra, | ||
| memory: options.memory, | ||
| runId: options.runId, | ||
| requestContext: mergeRequestContexts(options.requestContext, execOptions.requestContext), | ||
| actor: execOptions.actor, | ||
| // Workspace for file operations and command execution | ||
| // Execution-time workspace (from prepareStep/processInputStep) takes precedence over build-time workspace | ||
| workspace: execOptions.workspace ?? options.workspace, | ||
| // Browser for web automation (lazily initialized on first use) | ||
| browser: options.browser, | ||
| observe: execOptions.observe ?? noopObserve, | ||
| writer: new ToolStream( | ||
| { | ||
| prefix: "tool", | ||
| callId: execOptions.toolCallId, | ||
| name: options.name, | ||
| runId: options.runId | ||
| }, | ||
| options.outputWriter || execOptions.outputWriter | ||
| ), | ||
| ...createObservabilityContext({ currentSpan: toolSpan }), | ||
| abortSignal: execOptions.abortSignal, | ||
| suspend: (args2, suspendOptions) => { | ||
| suspendData = args2; | ||
| const newSuspendOptions = { | ||
| ...suspendOptions ?? {}, | ||
| resumeSchema: suspendOptions?.resumeSchema ?? (resumeSchema ? JSON.stringify(standardSchemaToJSONSchema(toStandardSchema(resumeSchema), { io: "input" })) : void 0) | ||
| }; | ||
| return execOptions.suspend?.(args2, newSuspendOptions); | ||
| }, | ||
| resumeData: execOptions.resumeData | ||
| }; | ||
| const isAgentExecution = execOptions.toolCallId && execOptions.messages || options.agentName && options.threadId && !options.workflowId; | ||
| const isWorkflowExecution = !isAgentExecution && (options.workflow || options.workflowId); | ||
| let toolContext; | ||
| if (isAgentExecution) { | ||
| const { suspend, resumeData: resumeData2, threadId, resourceId, ...restBaseContext } = baseContext; | ||
| toolContext = { | ||
| ...restBaseContext, | ||
| agent: { | ||
| agentId: options.agentId || "", | ||
| toolCallId: execOptions.toolCallId || "", | ||
| messages: execOptions.messages || [], | ||
| suspend, | ||
| resumeData: resumeData2, | ||
| threadId, | ||
| resourceId, | ||
| outputWriter: options.outputWriter || execOptions.outputWriter, | ||
| flushMessages: execOptions.flushMessages | ||
| } | ||
| }; | ||
| } else if (isWorkflowExecution) { | ||
| const { suspend, resumeData: resumeData2, ...restBaseContext } = baseContext; | ||
| toolContext = { | ||
| ...restBaseContext, | ||
| workflow: options.workflow || { | ||
| runId: options.runId, | ||
| workflowId: options.workflowId, | ||
| state: options.state, | ||
| setState: options.setState, | ||
| suspend, | ||
| resumeData: resumeData2 | ||
| } | ||
| }; | ||
| } else if (execOptions.mcp) { | ||
| toolContext = { | ||
| ...baseContext, | ||
| mcp: execOptions.mcp | ||
| }; | ||
| } else { | ||
| toolContext = baseContext; | ||
| } | ||
| const resumeData = execOptions.resumeData; | ||
| if (resumeData) { | ||
| const resumeValidation = validateToolInput(resumeSchema, resumeData, options.name); | ||
| if (resumeValidation.error) { | ||
| logger?.warn(resumeValidation.error.message); | ||
| toolSpan?.end({ output: resumeValidation.error, attributes: { success: false } }); | ||
| return resumeValidation.error; | ||
| } | ||
| } | ||
| result = await executeWithContext({ span: toolSpan, fn: async () => tool?.execute?.(args, toolContext) }); | ||
| } | ||
| if (suspendData) { | ||
| const suspendSchema = this.getSuspendSchema(); | ||
| const suspendValidation = validateToolSuspendData(suspendSchema, suspendData, options.name); | ||
| if (suspendValidation.error) { | ||
| logger?.warn(suspendValidation.error.message); | ||
| toolSpan?.end({ output: suspendValidation.error, attributes: { success: false } }); | ||
| return suspendValidation.error; | ||
| } | ||
| } | ||
| const shouldSkipValidation = typeof result === "undefined" && !!suspendData; | ||
| if (shouldSkipValidation) { | ||
| toolSpan?.end({ output: result, attributes: { success: true } }); | ||
| return result; | ||
| } | ||
| if (isVercelTool(tool)) { | ||
| const outputSchema = this.getOutputSchema(); | ||
| const outputValidation = validateToolOutput(outputSchema, result, options.name, false); | ||
| if (outputValidation.error) { | ||
| logger?.warn(outputValidation.error.message); | ||
| toolSpan?.end({ output: outputValidation.error, attributes: { success: false } }); | ||
| return outputValidation.error; | ||
| } | ||
| result = outputValidation.data; | ||
| } | ||
| toolSpan?.end({ output: result, attributes: { success: true } }); | ||
| return result; | ||
| } catch (error) { | ||
| toolSpan?.error({ error, attributes: { success: false } }); | ||
| throw error; | ||
| } | ||
| }; | ||
| return async (args, execOptions) => { | ||
| let logger2 = options.logger || this.logger; | ||
| const tracingContext = execOptions?.tracingContext || options.tracingContext; | ||
| const toolRequestContext = execOptions?.requestContext ?? options.requestContext; | ||
| const toolSpan = getOrCreateSpan({ | ||
| type: mcpMeta ? "mcp_tool_call" /* MCP_TOOL_CALL */ : "tool_call" /* TOOL_CALL */, | ||
| name: mcpMeta ? `mcp_tool: '${options.name}' on '${mcpMeta.serverName}'` : `tool: '${options.name}'`, | ||
| input: args, | ||
| entityType: EntityType.TOOL, | ||
| entityId: options.name, | ||
| entityName: options.name, | ||
| attributes: mcpMeta ? { | ||
| mcpServer: mcpMeta.serverName, | ||
| serverVersion: mcpMeta.serverVersion, | ||
| toolDescription: options.description | ||
| } : { | ||
| toolDescription: options.description, | ||
| toolType: logType || "tool" | ||
| }, | ||
| tracingPolicy: options.tracingPolicy, | ||
| tracingContext, | ||
| requestContext: toolRequestContext, | ||
| mastra: options.mastra && "observability" in options.mastra ? options.mastra : void 0 | ||
| }); | ||
| const fgaProvider = options.mastra?.getServer?.()?.fga; | ||
| const user = toolRequestContext?.get("user"); | ||
| if (fgaProvider) { | ||
| const { getAgentToolFGAResourceId, getMCPToolFGAResourceId, getStandaloneToolFGAResourceId, requireFGA } = await import('./fga-check-7DWG6TWM.js'); | ||
| const toolResourceId = mcpMeta?.serverName ? getMCPToolFGAResourceId(mcpMeta.serverName, options.name) : options.agentId ? getAgentToolFGAResourceId(options.agentId, options.name) : getStandaloneToolFGAResourceId(options.name); | ||
| await requireFGA({ | ||
| fgaProvider, | ||
| user, | ||
| resource: { type: "tool", id: toolResourceId }, | ||
| permission: MastraFGAPermissions.TOOLS_EXECUTE, | ||
| requestContext: toolRequestContext, | ||
| actor: execOptions?.actor, | ||
| context: { | ||
| resourceId: options.resourceId | ||
| }, | ||
| metadata: { | ||
| toolName: options.name, | ||
| agentId: options.agentId, | ||
| agentName: options.agentName, | ||
| runId: options.runId, | ||
| threadId: options.threadId, | ||
| executionResourceId: options.resourceId, | ||
| mcpMetadata: mcpMeta | ||
| } | ||
| }); | ||
| } | ||
| try { | ||
| logger2.debug(start, { ...logData, ...rest, model: logModelObject, args }); | ||
| const isResuming = !!execOptions?.resumeData; | ||
| const parameters = this.getParameters(); | ||
| if (!isResuming) { | ||
| const { data, error } = validateToolInput(parameters, args, options.name); | ||
| const suspendedToolRunIdErrToIgnore = error?.message?.includes("suspendedToolRunId: Required") && !args?.resumeData; | ||
| if (error && !suspendedToolRunIdErrToIgnore) { | ||
| logger2.warn("Tool input validation failed", { ...logData, validationError: error.message }); | ||
| toolSpan?.end({ output: error, attributes: { success: false } }); | ||
| return error; | ||
| } | ||
| args = data; | ||
| } | ||
| return await new Promise((resolve, reject) => { | ||
| setImmediate(async () => { | ||
| try { | ||
| const result = await execFunction(args, execOptions, toolSpan); | ||
| resolve(result); | ||
| } catch (err) { | ||
| reject(err); | ||
| } | ||
| }); | ||
| }); | ||
| } catch (err) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "TOOL_EXECUTION_FAILED", | ||
| domain: ErrorDomain.TOOL, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| errorMessage: String(err), | ||
| argsJson: safeStringify(args), | ||
| model: model?.modelId ?? "" | ||
| } | ||
| }, | ||
| err | ||
| ); | ||
| toolSpan?.error({ error: mastraError, attributes: { success: false } }); | ||
| logger2.trackException(mastraError, { ...logData, ...rest, model: logModelObject, args }); | ||
| throw mastraError; | ||
| } | ||
| }; | ||
| } | ||
| buildV5() { | ||
| const builtTool = this.build(); | ||
| if (!builtTool.parameters) { | ||
| throw new Error("Tool parameters are required"); | ||
| } | ||
| const base = { | ||
| ...builtTool, | ||
| inputSchema: builtTool.parameters, | ||
| onInputStart: "onInputStart" in this.originalTool ? this.originalTool.onInputStart : void 0, | ||
| onInputDelta: "onInputDelta" in this.originalTool ? this.originalTool.onInputDelta : void 0, | ||
| onInputAvailable: "onInputAvailable" in this.originalTool ? this.originalTool.onInputAvailable : void 0, | ||
| onOutput: "onOutput" in this.originalTool ? this.originalTool.onOutput : void 0 | ||
| }; | ||
| if (builtTool.type === "provider-defined") { | ||
| const { execute, parameters, ...rest } = base; | ||
| const name = ("name" in builtTool && typeof builtTool.name === "string" ? builtTool.name : null) || builtTool.id.split(".")[1] || builtTool.id; | ||
| return { | ||
| ...rest, | ||
| type: builtTool.type, | ||
| id: builtTool.id, | ||
| name, | ||
| args: builtTool.args | ||
| }; | ||
| } | ||
| return base; | ||
| } | ||
| build() { | ||
| const providerTool = this.buildProviderTool(this.originalTool); | ||
| if (providerTool) { | ||
| return providerTool; | ||
| } | ||
| const model = this.options.model; | ||
| const schemaCompatLayers = []; | ||
| if (model) { | ||
| const supportsStructuredOutputs = "supportsStructuredOutputs" in model ? model.supportsStructuredOutputs ?? false : false; | ||
| const modelInfo = { | ||
| modelId: model.modelId, | ||
| supportsStructuredOutputs, | ||
| provider: model.provider | ||
| }; | ||
| schemaCompatLayers.push( | ||
| new OpenAIReasoningSchemaCompatLayer(modelInfo), | ||
| new OpenAISchemaCompatLayer(modelInfo), | ||
| new GoogleSchemaCompatLayer(modelInfo), | ||
| new AnthropicSchemaCompatLayer(modelInfo), | ||
| new DeepSeekSchemaCompatLayer(modelInfo), | ||
| new MetaSchemaCompatLayer(modelInfo) | ||
| ); | ||
| } | ||
| const originalSchema = this.getParameters(); | ||
| let processedInputSchema; | ||
| if (originalSchema) { | ||
| if (isStandardSchemaWithJSON(originalSchema)) { | ||
| const applicableLayer = schemaCompatLayers.find((layer) => layer.shouldApply()); | ||
| let schemaToUse; | ||
| if (applicableLayer) { | ||
| schemaToUse = applicableLayer.processToCompatSchema(originalSchema); | ||
| } else { | ||
| schemaToUse = toStandardSchema(originalSchema); | ||
| } | ||
| processedInputSchema = jsonSchema( | ||
| standardSchemaToJSONSchema(schemaToUse, { | ||
| io: "input" | ||
| }), | ||
| { | ||
| validate: (value) => { | ||
| const result = schemaToUse["~standard"].validate(value); | ||
| if (result instanceof Promise) { | ||
| return result.then((r) => { | ||
| if ("issues" in r && r.issues) { | ||
| return { | ||
| success: false, | ||
| error: new Error(r.issues.map((i) => i.message).join(", ")) | ||
| }; | ||
| } | ||
| return { success: true, value: r.value }; | ||
| }); | ||
| } | ||
| if ("issues" in result && result.issues) { | ||
| return { | ||
| success: false, | ||
| error: new Error(result.issues.map((i) => i.message).join(", ")) | ||
| }; | ||
| } | ||
| return { success: true, value: result.value }; | ||
| } | ||
| } | ||
| ); | ||
| } else { | ||
| processedInputSchema = applyCompatLayer({ | ||
| schema: originalSchema, | ||
| compatLayers: schemaCompatLayers, | ||
| mode: "aiSdkSchema" | ||
| }); | ||
| } | ||
| } | ||
| const outputSchema = this.getOutputSchema(); | ||
| let processedOutputSchema; | ||
| if (outputSchema) { | ||
| if (isStandardSchemaWithJSON(outputSchema)) { | ||
| processedOutputSchema = standardSchemaToJSONSchema(outputSchema, { io: "output" }); | ||
| } else { | ||
| processedOutputSchema = applyCompatLayer({ | ||
| schema: outputSchema, | ||
| compatLayers: [], | ||
| mode: "aiSdkSchema" | ||
| }); | ||
| } | ||
| } | ||
| let requireApproval = false; | ||
| let needsApprovalFn; | ||
| if (typeof this.options.requireApproval === "function") { | ||
| requireApproval = true; | ||
| needsApprovalFn = this.options.requireApproval; | ||
| } else if (typeof this.options.requireApproval === "boolean") { | ||
| requireApproval = this.options.requireApproval; | ||
| needsApprovalFn = void 0; | ||
| } | ||
| if (isVercelTool(this.originalTool) && "needsApproval" in this.originalTool) { | ||
| const needsApproval = this.originalTool.needsApproval; | ||
| if (typeof needsApproval === "boolean") { | ||
| requireApproval = needsApproval; | ||
| needsApprovalFn = void 0; | ||
| } else if (typeof needsApproval === "function") { | ||
| needsApprovalFn = needsApproval; | ||
| requireApproval = true; | ||
| } | ||
| } | ||
| const instanceNeedsApprovalFn = getNeedsApprovalFn(this.originalTool); | ||
| if (!needsApprovalFn && instanceNeedsApprovalFn) { | ||
| needsApprovalFn = instanceNeedsApprovalFn; | ||
| requireApproval = true; | ||
| } | ||
| const definition = { | ||
| type: "function", | ||
| description: this.originalTool.description, | ||
| requireApproval, | ||
| needsApprovalFn, | ||
| hasSuspendSchema: !!this.getSuspendSchema(), | ||
| execute: this.originalTool.execute ? this.createExecute( | ||
| this.originalTool, | ||
| { ...this.options, description: this.originalTool.description }, | ||
| this.logType | ||
| ) : void 0 | ||
| }; | ||
| return { | ||
| ...definition, | ||
| id: "id" in this.originalTool ? this.originalTool.id : void 0, | ||
| parameters: processedInputSchema ?? z.object({}), | ||
| outputSchema: processedOutputSchema, | ||
| strict: "strict" in this.originalTool ? this.originalTool.strict : void 0, | ||
| providerOptions: "providerOptions" in this.originalTool ? this.originalTool.providerOptions : void 0, | ||
| mcp: "mcp" in this.originalTool ? this.originalTool.mcp : void 0, | ||
| toModelOutput: "toModelOutput" in this.originalTool ? this.originalTool.toModelOutput : void 0, | ||
| transform: "transform" in this.originalTool ? this.originalTool.transform : void 0, | ||
| inputExamples: "inputExamples" in this.originalTool ? this.originalTool.inputExamples : void 0, | ||
| onInputStart: "onInputStart" in this.originalTool ? this.originalTool.onInputStart : void 0, | ||
| onInputDelta: "onInputDelta" in this.originalTool ? this.originalTool.onInputDelta : void 0, | ||
| onInputAvailable: "onInputAvailable" in this.originalTool ? this.originalTool.onInputAvailable : void 0, | ||
| onOutput: "onOutput" in this.originalTool ? this.originalTool.onOutput : void 0, | ||
| // Preserve tool-level background config so the agentic loop can pick it up | ||
| // from the converted CoreTool at dispatch time. | ||
| backgroundConfig: this.options.backgroundConfig | ||
| }; | ||
| } | ||
| }; | ||
| // src/utils.ts | ||
| var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); | ||
| function safeStringify(value, space) { | ||
| const stack = []; | ||
| return JSON.stringify( | ||
| value, | ||
| function(_key, val) { | ||
| if (typeof val === "bigint") return val.toString(); | ||
| if (val !== null && typeof val === "object") { | ||
| while (stack.length > 0 && stack[stack.length - 1] !== this) { | ||
| stack.pop(); | ||
| } | ||
| if (stack.includes(val)) return "[Circular]"; | ||
| stack.push(val); | ||
| } | ||
| return val; | ||
| }, | ||
| space | ||
| ); | ||
| } | ||
| function ensureSerializable(value) { | ||
| if (value === null || typeof value !== "object") return value; | ||
| try { | ||
| JSON.stringify(value); | ||
| return value; | ||
| } catch { | ||
| return JSON.parse(safeStringify(value)); | ||
| } | ||
| } | ||
| function isPlainObject(value) { | ||
| if (value === null || typeof value !== "object") return false; | ||
| const proto = Object.getPrototypeOf(value); | ||
| return proto === Object.prototype || proto === null; | ||
| } | ||
| function deepMerge(target, source) { | ||
| const output = { ...target }; | ||
| if (!source) return output; | ||
| Object.keys(source).forEach((key) => { | ||
| const targetValue = output[key]; | ||
| const sourceValue = source[key]; | ||
| if (isPlainObject(targetValue) && isPlainObject(sourceValue)) { | ||
| output[key] = deepMerge(targetValue, sourceValue); | ||
| } else if (sourceValue !== void 0) { | ||
| output[key] = sourceValue; | ||
| } | ||
| }); | ||
| return output; | ||
| } | ||
| function deepEqual(a, b) { | ||
| if (a === b) return true; | ||
| if (a == null || b == null) return a === b; | ||
| if (typeof a !== typeof b) return false; | ||
| if (Array.isArray(a) && Array.isArray(b)) { | ||
| if (a.length !== b.length) return false; | ||
| return a.every((item, index) => deepEqual(item, b[index])); | ||
| } | ||
| if (a instanceof Date && b instanceof Date) { | ||
| return a.getTime() === b.getTime(); | ||
| } | ||
| if (typeof a === "object" && typeof b === "object") { | ||
| const aObj = a; | ||
| const bObj = b; | ||
| const aKeys = Object.keys(aObj); | ||
| const bKeys = Object.keys(bObj); | ||
| if (aKeys.length !== bKeys.length) return false; | ||
| return aKeys.every((key) => Object.prototype.hasOwnProperty.call(bObj, key) && deepEqual(aObj[key], bObj[key])); | ||
| } | ||
| return false; | ||
| } | ||
| function generateEmptyFromSchema(schema) { | ||
| try { | ||
| const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema; | ||
| if (!parsedSchema || parsedSchema.type !== "object" || !parsedSchema.properties) return {}; | ||
| const obj = {}; | ||
| for (const [key, prop] of Object.entries( | ||
| parsedSchema.properties | ||
| )) { | ||
| if (prop.default !== void 0) { | ||
| obj[key] = typeof prop.default === "object" && prop.default !== null ? JSON.parse(JSON.stringify(prop.default)) : prop.default; | ||
| } else if (prop.type === "object" && prop.properties) { | ||
| obj[key] = generateEmptyFromSchema(prop); | ||
| } else if (prop.type === "object") { | ||
| obj[key] = {}; | ||
| } else if (prop.type === "string") { | ||
| obj[key] = ""; | ||
| } else if (prop.type === "array") { | ||
| obj[key] = []; | ||
| } else if (prop.type === "number" || prop.type === "integer") { | ||
| obj[key] = 0; | ||
| } else if (prop.type === "boolean") { | ||
| obj[key] = false; | ||
| } else { | ||
| obj[key] = null; | ||
| } | ||
| } | ||
| return obj; | ||
| } catch { | ||
| return {}; | ||
| } | ||
| } | ||
| async function* maskStreamTags(stream, tag, options = {}) { | ||
| const { onStart, onEnd, onMask } = options; | ||
| const openTag = `<${tag}>`; | ||
| const closeTag = `</${tag}>`; | ||
| let buffer = ""; | ||
| let fullContent = ""; | ||
| let isMasking = false; | ||
| let isBuffering = false; | ||
| const trimOutsideDelimiter = (text, delimiter, trim) => { | ||
| if (!text.includes(delimiter)) { | ||
| return text; | ||
| } | ||
| const parts = text.split(delimiter); | ||
| if (trim === `before-start`) { | ||
| return `${delimiter}${parts[1]}`; | ||
| } | ||
| return `${parts[0]}${delimiter}`; | ||
| }; | ||
| const startsWith = (text, pattern) => { | ||
| if (pattern.includes(openTag.substring(0, 3))) { | ||
| pattern = trimOutsideDelimiter(pattern, `<`, `before-start`); | ||
| } | ||
| return text.trim().startsWith(pattern.trim()); | ||
| }; | ||
| for await (const chunk of stream) { | ||
| fullContent += chunk; | ||
| if (isBuffering) buffer += chunk; | ||
| const chunkHasTag = startsWith(chunk, openTag); | ||
| const bufferHasTag = !chunkHasTag && isBuffering && startsWith(openTag, buffer); | ||
| let toYieldBeforeMaskedStartTag = ``; | ||
| if (!isMasking && (chunkHasTag || bufferHasTag)) { | ||
| isMasking = true; | ||
| isBuffering = false; | ||
| const taggedTextToMask = trimOutsideDelimiter(buffer, `<`, `before-start`); | ||
| if (taggedTextToMask !== buffer.trim()) { | ||
| toYieldBeforeMaskedStartTag = buffer.replace(taggedTextToMask, ``); | ||
| } | ||
| buffer = ""; | ||
| onStart?.(); | ||
| } | ||
| if (!isMasking && !isBuffering && startsWith(openTag, chunk) && chunk.trim() !== "") { | ||
| isBuffering = true; | ||
| buffer += chunk; | ||
| continue; | ||
| } | ||
| if (isBuffering && buffer && !startsWith(openTag, buffer)) { | ||
| yield buffer; | ||
| buffer = ""; | ||
| isBuffering = false; | ||
| continue; | ||
| } | ||
| if (isMasking && fullContent.includes(closeTag)) { | ||
| onMask?.(chunk); | ||
| onEnd?.(); | ||
| isMasking = false; | ||
| const lastFullContent = fullContent; | ||
| fullContent = ``; | ||
| const textUntilEndTag = trimOutsideDelimiter(lastFullContent, closeTag, "after-end"); | ||
| if (textUntilEndTag !== lastFullContent) { | ||
| yield lastFullContent.replace(textUntilEndTag, ``); | ||
| } | ||
| continue; | ||
| } | ||
| if (isMasking) { | ||
| onMask?.(chunk); | ||
| if (toYieldBeforeMaskedStartTag) { | ||
| yield toYieldBeforeMaskedStartTag; | ||
| } | ||
| continue; | ||
| } | ||
| yield chunk; | ||
| } | ||
| } | ||
| function resolveSerializedZodOutput(schema) { | ||
| return Function("z", `"use strict";return (${schema});`)(z); | ||
| } | ||
| function isZodType(value) { | ||
| return typeof value === "object" && value !== null && "_def" in value && "parse" in value && typeof value.parse === "function" && "safeParse" in value && typeof value.safeParse === "function"; | ||
| } | ||
| function createDeterministicId(input) { | ||
| return createHash("sha256").update(input).digest("hex").slice(0, 8); | ||
| } | ||
| function setVercelToolProperties(tool) { | ||
| const inputSchema = "inputSchema" in tool ? tool.inputSchema : convertVercelToolParameters(tool); | ||
| const toolId = !("id" in tool) ? tool.description ? `tool-${createDeterministicId(tool.description)}` : `tool-${Math.random().toString(36).substring(2, 9)}` : tool.id; | ||
| return { | ||
| ...tool, | ||
| id: toolId, | ||
| inputSchema | ||
| }; | ||
| } | ||
| function ensureToolProperties(tools) { | ||
| const toolsWithProperties = Object.keys(tools).reduce((acc, key) => { | ||
| const tool = tools?.[key]; | ||
| if (tool) { | ||
| if (typeof tool === "function" && !(tool instanceof Tool) && !isVercelTool(tool)) { | ||
| throw new MastraError({ | ||
| id: "TOOL_INVALID_FORMAT", | ||
| domain: ErrorDomain.TOOL, | ||
| category: ErrorCategory.USER, | ||
| text: `Tool "${key}" is not a valid tool format. Tools must be created using createTool() or be a valid Vercel AI SDK tool. Received a function.` | ||
| }); | ||
| } | ||
| if (isVercelTool(tool)) { | ||
| acc[key] = setVercelToolProperties(tool); | ||
| } else { | ||
| acc[key] = tool; | ||
| } | ||
| } | ||
| return acc; | ||
| }, {}); | ||
| return toolsWithProperties; | ||
| } | ||
| function convertVercelToolParameters(tool) { | ||
| let schema = tool.parameters ?? z.object({}); | ||
| if (typeof schema === "function") { | ||
| schema = schema(); | ||
| } | ||
| return isZodType(schema) ? schema : resolveSerializedZodOutput(jsonSchemaToZod(schema)); | ||
| } | ||
| function makeCoreTool(originalTool, options, logType, autoResumeSuspendedTools, backgroundTaskEnabled) { | ||
| return new CoreToolBuilder({ | ||
| originalTool, | ||
| options, | ||
| logType, | ||
| autoResumeSuspendedTools, | ||
| backgroundTaskEnabled | ||
| }).build(); | ||
| } | ||
| function makeCoreToolV5(originalTool, options, logType, autoResumeSuspendedTools, backgroundTaskEnabled) { | ||
| return new CoreToolBuilder({ | ||
| originalTool, | ||
| options, | ||
| logType, | ||
| autoResumeSuspendedTools, | ||
| backgroundTaskEnabled | ||
| }).buildV5(); | ||
| } | ||
| function createMastraProxy({ mastra, logger }) { | ||
| return new Proxy(mastra, { | ||
| get(target, prop) { | ||
| const hasProp = Reflect.has(target, prop); | ||
| if (hasProp) { | ||
| const value = Reflect.get(target, prop); | ||
| const isFunction = typeof value === "function"; | ||
| if (isFunction) { | ||
| return value.bind(target); | ||
| } | ||
| return value; | ||
| } | ||
| if (prop === "logger") { | ||
| logger.warn("Please use 'getLogger' instead, logger is deprecated"); | ||
| return Reflect.apply(target.getLogger, target, []); | ||
| } | ||
| if (prop === "storage") { | ||
| logger.warn("Please use 'getStorage' instead, storage is deprecated"); | ||
| return Reflect.get(target, "storage"); | ||
| } | ||
| if (prop === "agents") { | ||
| logger.warn("Please use 'listAgents' instead, agents is deprecated"); | ||
| return Reflect.apply(target.listAgents, target, []); | ||
| } | ||
| if (prop === "tts") { | ||
| logger.warn("Please use 'getTTS' instead, tts is deprecated"); | ||
| return Reflect.apply(target.getTTS, target, []); | ||
| } | ||
| if (prop === "vectors") { | ||
| logger.warn("Please use 'getVectors' instead, vectors is deprecated"); | ||
| return Reflect.apply(target.getVectors, target, []); | ||
| } | ||
| if (prop === "memory") { | ||
| logger.warn("Please use 'getMemory' instead, memory is deprecated"); | ||
| return Reflect.get(target, "memory"); | ||
| } | ||
| return Reflect.get(target, prop); | ||
| } | ||
| }); | ||
| } | ||
| function checkEvalStorageFields(traceObject, logger) { | ||
| const missingFields = []; | ||
| if (!traceObject.input) missingFields.push("input"); | ||
| if (!traceObject.output) missingFields.push("output"); | ||
| if (!traceObject.agentName) missingFields.push("agent_name"); | ||
| if (!traceObject.metricName) missingFields.push("metric_name"); | ||
| if (!traceObject.instructions) missingFields.push("instructions"); | ||
| if (!traceObject.globalRunId) missingFields.push("global_run_id"); | ||
| if (!traceObject.runId) missingFields.push("run_id"); | ||
| if (missingFields.length > 0) { | ||
| if (logger) { | ||
| logger.warn("Skipping evaluation storage due to missing required fields", { | ||
| missingFields, | ||
| runId: traceObject.runId, | ||
| agentName: traceObject.agentName | ||
| }); | ||
| } else { | ||
| console.warn("Skipping evaluation storage due to missing required fields", { | ||
| missingFields, | ||
| runId: traceObject.runId, | ||
| agentName: traceObject.agentName | ||
| }); | ||
| } | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| function detectSingleMessageCharacteristics(message) { | ||
| if (typeof message === "object" && message !== null && (message.role === "function" || // UI-only role | ||
| message.role === "data" || // UI-only role | ||
| "toolInvocations" in message || // UI-specific field | ||
| "parts" in message || // UI-specific field | ||
| "experimental_attachments" in message)) { | ||
| return "has-ui-specific-parts"; | ||
| } else if (typeof message === "object" && message !== null && "content" in message && (Array.isArray(message.content) || // Core messages can have array content | ||
| "experimental_providerMetadata" in message || "providerOptions" in message)) { | ||
| return "has-core-specific-parts"; | ||
| } else if (typeof message === "object" && message !== null && "role" in message && "content" in message && typeof message.content === "string" && ["system", "user", "assistant", "tool"].includes(message.role)) { | ||
| return "message"; | ||
| } else { | ||
| return "other"; | ||
| } | ||
| } | ||
| function isUiMessage(message) { | ||
| return detectSingleMessageCharacteristics(message) === `has-ui-specific-parts`; | ||
| } | ||
| function isCoreMessage(message) { | ||
| return [`has-core-specific-parts`, `message`].includes(detectSingleMessageCharacteristics(message)); | ||
| } | ||
| var SQL_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/; | ||
| function parseSqlIdentifier(name, kind = "identifier") { | ||
| if (!SQL_IDENTIFIER_PATTERN.test(name) || name.length > 63) { | ||
| throw new Error( | ||
| `Invalid ${kind}: ${name}. Must start with a letter or underscore, contain only letters, numbers, or underscores, and be at most 63 characters long.` | ||
| ); | ||
| } | ||
| return name; | ||
| } | ||
| function parseFieldKey(key) { | ||
| if (!key) throw new Error("Field key cannot be empty"); | ||
| const segments = key.split("."); | ||
| for (const segment of segments) { | ||
| if (!SQL_IDENTIFIER_PATTERN.test(segment) || segment.length > 63) { | ||
| throw new Error(`Invalid field key segment: ${segment} in ${key}`); | ||
| } | ||
| } | ||
| return key; | ||
| } | ||
| function omitKeys(obj, keysToOmit) { | ||
| return Object.fromEntries(Object.entries(obj).filter(([key]) => !keysToOmit.includes(key))); | ||
| } | ||
| function selectFields(obj, fields) { | ||
| if (!obj || typeof obj !== "object") { | ||
| return obj; | ||
| } | ||
| const result = {}; | ||
| for (const field of fields) { | ||
| const value = getNestedValue(obj, field); | ||
| if (value !== void 0) { | ||
| setNestedValue(result, field, value); | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function getNestedValue(obj, path) { | ||
| return path.split(".").reduce((current, key) => { | ||
| return current && typeof current === "object" ? current[key] : void 0; | ||
| }, obj); | ||
| } | ||
| function setNestedValue(obj, path, value) { | ||
| const keys = path.split("."); | ||
| const lastKey = keys.pop(); | ||
| if (!lastKey) return; | ||
| for (const key of keys) { | ||
| if (key === "__proto__" || key === "constructor" || key === "prototype") { | ||
| return; | ||
| } | ||
| } | ||
| if (lastKey === "__proto__" || lastKey === "constructor" || lastKey === "prototype") { | ||
| return; | ||
| } | ||
| let current = obj; | ||
| for (const key of keys) { | ||
| const existing = Object.prototype.hasOwnProperty.call(current, key) ? current[key] : void 0; | ||
| if (existing === null || typeof existing !== "object") { | ||
| const container = /* @__PURE__ */ Object.create(null); | ||
| Object.defineProperty(current, key, { value: container, writable: true, enumerable: true, configurable: true }); | ||
| } | ||
| current = current[key]; | ||
| } | ||
| Object.defineProperty(current, lastKey, { value, writable: true, enumerable: true, configurable: true }); | ||
| } | ||
| var removeUndefinedValues = (obj) => { | ||
| return Object.fromEntries(Object.entries(obj).filter(([_, value]) => value !== void 0)); | ||
| }; | ||
| export { ToolStream, checkEvalStorageFields, createMastraProxy, deepEqual, deepMerge, delay, ensureSerializable, ensureToolProperties, generateEmptyFromSchema, getNestedValue, isCoreMessage, isUiMessage, isZodType, makeCoreTool, makeCoreToolV5, maskStreamTags, noopObserve, omitKeys, parseFieldKey, parseSqlIdentifier, removeUndefinedValues, resolveSerializedZodOutput, safeStringify, selectFields, setNestedValue }; | ||
| //# sourceMappingURL=chunk-MVLICRVY.js.map | ||
| //# sourceMappingURL=chunk-MVLICRVY.js.map |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { isZodType, delay } from './chunk-MVLICRVY.js'; | ||
| import { toStandardSchema, standardSchemaToJSONSchema, isStandardSchemaWithJSON } from './chunk-6SRTDZ7S.js'; | ||
| import { isZodArray, getZodDef } from './chunk-TBHKQLPL.js'; | ||
| import { resolveObservabilityContext } from './chunk-JPUBRZLW.js'; | ||
| import { executeWithContext, executeWithContextSync } from './chunk-DEQCJWZZ.js'; | ||
| import { MastraBase } from './chunk-77VL4DNS.js'; | ||
| import { output_exports, generateText, generateObject, streamText, streamObject } from './chunk-D23QKBCZ.js'; | ||
| import { MastraError, ErrorCategory, ErrorDomain } from './chunk-M7RBQNFP.js'; | ||
| import { OpenAIReasoningSchemaCompatLayer, OpenAISchemaCompatLayer, GoogleSchemaCompatLayer, AnthropicSchemaCompatLayer, DeepSeekSchemaCompatLayer, MetaSchemaCompatLayer, applyCompatLayer, jsonSchema } from '@mastra/schema-compat'; | ||
| import { randomUUID } from 'crypto'; | ||
| // src/stream/aisdk/v4/usage.ts | ||
| function convertV4Usage(usage) { | ||
| if (!usage) { | ||
| return {}; | ||
| } | ||
| return { | ||
| inputTokens: usage.promptTokens, | ||
| outputTokens: usage.completionTokens | ||
| }; | ||
| } | ||
| // src/llm/model/model.ts | ||
| var MastraLLMV1 = class extends MastraBase { | ||
| #model; | ||
| #mastra; | ||
| #options; | ||
| constructor({ model, mastra, options }) { | ||
| super({ name: "aisdk" }); | ||
| this.#model = model; | ||
| this.#options = options; | ||
| if (mastra) { | ||
| this.#mastra = mastra; | ||
| if (mastra.getLogger()) { | ||
| this.__setLogger(this.#mastra.getLogger()); | ||
| } | ||
| } | ||
| } | ||
| __registerPrimitives(p) { | ||
| if (p.logger) { | ||
| this.__setLogger(p.logger); | ||
| } | ||
| } | ||
| __registerMastra(p) { | ||
| this.#mastra = p; | ||
| } | ||
| getProvider() { | ||
| return this.#model.provider; | ||
| } | ||
| getModelId() { | ||
| return this.#model.modelId; | ||
| } | ||
| getModel() { | ||
| return this.#model; | ||
| } | ||
| _applySchemaCompat(schema) { | ||
| const model = this.#model; | ||
| const schemaCompatLayers = []; | ||
| if (model) { | ||
| const modelInfo = { | ||
| modelId: model.modelId, | ||
| supportsStructuredOutputs: model.supportsStructuredOutputs ?? false, | ||
| provider: model.provider | ||
| }; | ||
| schemaCompatLayers.push( | ||
| new OpenAIReasoningSchemaCompatLayer(modelInfo), | ||
| new OpenAISchemaCompatLayer(modelInfo), | ||
| new GoogleSchemaCompatLayer(modelInfo), | ||
| new AnthropicSchemaCompatLayer(modelInfo), | ||
| new DeepSeekSchemaCompatLayer(modelInfo), | ||
| new MetaSchemaCompatLayer(modelInfo) | ||
| ); | ||
| } | ||
| return applyCompatLayer({ | ||
| schema, | ||
| compatLayers: schemaCompatLayers, | ||
| mode: "aiSdkSchema" | ||
| }); | ||
| } | ||
| async __text({ | ||
| runId, | ||
| messages, | ||
| maxSteps = 5, | ||
| tools = {}, | ||
| temperature, | ||
| toolChoice = "auto", | ||
| onStepFinish, | ||
| experimental_output, | ||
| threadId, | ||
| resourceId, | ||
| requestContext, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = resolveObservabilityContext(rest); | ||
| this.logger.debug("Generating text", { | ||
| runId, | ||
| messages, | ||
| maxSteps, | ||
| threadId, | ||
| resourceId, | ||
| tools: Object.keys(tools) | ||
| }); | ||
| let schema = void 0; | ||
| if (experimental_output) { | ||
| this.logger.debug("Using experimental output", { | ||
| runId | ||
| }); | ||
| if (isZodType(experimental_output)) { | ||
| schema = experimental_output; | ||
| if (isZodArray(schema)) { | ||
| schema = getZodDef(schema).type; | ||
| } | ||
| const standardSchema = toStandardSchema(schema); | ||
| const jsonSchemaToUse = standardSchemaToJSONSchema(standardSchema); | ||
| schema = jsonSchema(jsonSchemaToUse); | ||
| } else { | ||
| schema = jsonSchema(experimental_output); | ||
| } | ||
| } | ||
| if (tools && Object.keys(tools).length > 0) { | ||
| for (const tool of Object.values(tools)) { | ||
| if (tool.parameters) { | ||
| if ("validate" in tool.parameters) { | ||
| tool.parameters = tool.parameters; | ||
| } else if (isStandardSchemaWithJSON(tool.parameters)) { | ||
| tool.parameters = jsonSchema(standardSchemaToJSONSchema(tool.parameters)); | ||
| } else { | ||
| tool.parameters = jsonSchema(tool.parameters); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages, | ||
| schema | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: false | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| const argsForExecute = { | ||
| ...rest, | ||
| messages, | ||
| model, | ||
| temperature, | ||
| tools: { | ||
| ...tools | ||
| }, | ||
| toolChoice, | ||
| maxSteps, | ||
| onStepFinish: async (props) => { | ||
| try { | ||
| await onStepFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_TEXT_ON_STEP_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| finishReason: props?.finishReason, | ||
| toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "", | ||
| toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Text step change", { | ||
| text: props?.text, | ||
| toolCalls: props?.toolCalls, | ||
| toolResults: props?.toolResults, | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage, | ||
| runId | ||
| }); | ||
| const remainingTokens = parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"] ?? "", 10); | ||
| if (!isNaN(remainingTokens) && remainingTokens > 0 && remainingTokens < 2e3) { | ||
| this.logger.warn("Rate limit approaching, waiting 10 seconds", { runId, remainingTokens }); | ||
| const rateLimitSpan = llmSpan?.createChildSpan({ | ||
| name: "rate-limit-sleep", | ||
| type: "generic" /* GENERIC */, | ||
| metadata: { remainingTokens, delayMs: 1e4 } | ||
| }); | ||
| await delay(10 * 1e3); | ||
| rateLimitSpan?.end(); | ||
| } | ||
| }, | ||
| experimental_output: schema ? output_exports.object({ | ||
| schema | ||
| }) : void 0 | ||
| }; | ||
| try { | ||
| const result = await executeWithContext({ | ||
| span: llmSpan, | ||
| fn: () => generateText(argsForExecute) | ||
| }); | ||
| if (schema && result.finishReason === "stop") { | ||
| result.object = result.experimental_output; | ||
| } | ||
| llmSpan?.end({ | ||
| output: { | ||
| text: result.text, | ||
| object: result.object, | ||
| reasoning: result.reasoningDetails, | ||
| reasoningText: result.reasoning, | ||
| files: result.files, | ||
| sources: result.sources, | ||
| toolCalls: result.toolCalls, | ||
| warnings: result.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: result.finishReason, | ||
| responseId: result.response?.id, | ||
| responseModel: result.response?.modelId, | ||
| usage: convertV4Usage(result.usage) | ||
| } | ||
| }); | ||
| return result; | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_GENERATE_TEXT_AI_SDK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Generate text failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| async __textObject({ | ||
| messages, | ||
| structuredOutput, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| requestContext, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = resolveObservabilityContext(rest); | ||
| this.logger.debug("Generating text object", { runId }); | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature: rest.temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: false | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| try { | ||
| let output = "object"; | ||
| if (isZodArray(structuredOutput)) { | ||
| output = "array"; | ||
| const zodDef = getZodDef(structuredOutput); | ||
| if ("element" in zodDef) { | ||
| structuredOutput = zodDef.element; | ||
| } else { | ||
| structuredOutput = zodDef.type; | ||
| } | ||
| } | ||
| const processedSchema = this._applySchemaCompat(structuredOutput); | ||
| llmSpan?.update({ | ||
| input: { | ||
| messages, | ||
| schema: processedSchema | ||
| } | ||
| }); | ||
| const argsForExecute = { | ||
| ...rest, | ||
| messages, | ||
| model, | ||
| output, | ||
| schema: processedSchema | ||
| }; | ||
| try { | ||
| const result = await generateObject(argsForExecute); | ||
| llmSpan?.end({ | ||
| output: { | ||
| object: result.object, | ||
| warnings: result.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: result.finishReason, | ||
| responseId: result.response?.id, | ||
| responseModel: result.response?.modelId, | ||
| usage: convertV4Usage(result.usage) | ||
| } | ||
| }); | ||
| return result; | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_GENERATE_OBJECT_AI_SDK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Generate object failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } catch (e) { | ||
| if (e instanceof MastraError) { | ||
| throw e; | ||
| } | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_GENERATE_OBJECT_AI_SDK_SCHEMA_CONVERSION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Generate object schema conversion failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| __stream({ | ||
| messages, | ||
| onStepFinish, | ||
| onFinish, | ||
| maxSteps = 5, | ||
| tools = {}, | ||
| runId, | ||
| temperature, | ||
| toolChoice = "auto", | ||
| experimental_output, | ||
| threadId, | ||
| resourceId, | ||
| requestContext, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = resolveObservabilityContext(rest); | ||
| let schema; | ||
| if (experimental_output) { | ||
| if (typeof experimental_output.parse === "function") { | ||
| schema = experimental_output; | ||
| if (isZodArray(schema)) { | ||
| schema = getZodDef(schema).type; | ||
| } | ||
| } else { | ||
| schema = jsonSchema(experimental_output); | ||
| } | ||
| } | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: true | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| if (llmSpan) { | ||
| executeWithContextSync({ | ||
| span: llmSpan, | ||
| fn: () => this.logger.debug("Streaming text", { | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| messages, | ||
| maxSteps, | ||
| tools: Object.keys(tools || {}) | ||
| }) | ||
| }); | ||
| } | ||
| if (tools && Object.keys(tools).length > 0) { | ||
| for (const tool of Object.values(tools)) { | ||
| if (tool.parameters) { | ||
| if ("validate" in tool.parameters) { | ||
| tool.parameters = tool.parameters; | ||
| } else if (isStandardSchemaWithJSON(tool.parameters)) { | ||
| tool.parameters = jsonSchema(standardSchemaToJSONSchema(tool.parameters)); | ||
| } else { | ||
| tool.parameters = jsonSchema(tool.parameters); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| const argsForExecute = { | ||
| model, | ||
| temperature, | ||
| tools: { | ||
| ...tools | ||
| }, | ||
| maxSteps, | ||
| toolChoice, | ||
| onStepFinish: async (props) => { | ||
| try { | ||
| await onStepFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_ON_STEP_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| finishReason: props?.finishReason, | ||
| toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "", | ||
| toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.trackException(mastraError); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Stream step change", { | ||
| text: props?.text, | ||
| toolCalls: props?.toolCalls, | ||
| toolResults: props?.toolResults, | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage, | ||
| runId | ||
| }); | ||
| const remainingTokens = parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"] ?? "", 10); | ||
| if (!isNaN(remainingTokens) && remainingTokens > 0 && remainingTokens < 2e3) { | ||
| this.logger.warn("Rate limit approaching, waiting 10 seconds", { runId, remainingTokens }); | ||
| const rateLimitSpan = llmSpan?.createChildSpan({ | ||
| name: "rate-limit-sleep", | ||
| type: "generic" /* GENERIC */, | ||
| metadata: { remainingTokens, delayMs: 1e4 } | ||
| }); | ||
| await delay(10 * 1e3); | ||
| rateLimitSpan?.end(); | ||
| } | ||
| }, | ||
| onFinish: async (props) => { | ||
| llmSpan?.end({ | ||
| output: { | ||
| text: props?.text, | ||
| reasoning: props?.reasoningDetails, | ||
| reasoningText: props?.reasoning, | ||
| files: props?.files, | ||
| sources: props?.sources, | ||
| toolCalls: props?.toolCalls, | ||
| warnings: props?.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: props?.finishReason, | ||
| usage: convertV4Usage(props?.usage) | ||
| } | ||
| }); | ||
| try { | ||
| await onFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_ON_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| finishReason: props?.finishReason, | ||
| toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "", | ||
| toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| llmSpan?.error({ error: mastraError }); | ||
| this.logger.trackException(mastraError); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Stream finished", { | ||
| text: props?.text, | ||
| toolCalls: props?.toolCalls, | ||
| toolResults: props?.toolResults, | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage, | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }); | ||
| }, | ||
| onError: ({ error }) => { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_TEXT_AI_SDK_STREAMING_ERROR", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| error | ||
| ); | ||
| this.logger.error("Stream text error", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| }, | ||
| ...rest, | ||
| messages, | ||
| experimental_output: schema ? output_exports.object({ | ||
| schema | ||
| }) : void 0 | ||
| }; | ||
| try { | ||
| return executeWithContextSync({ span: llmSpan, fn: () => streamText(argsForExecute) }); | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_TEXT_AI_SDK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Stream text failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| __streamObject({ | ||
| messages, | ||
| runId, | ||
| requestContext, | ||
| threadId, | ||
| resourceId, | ||
| onFinish, | ||
| structuredOutput, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = resolveObservabilityContext(rest); | ||
| this.logger.debug("Streaming structured output", { | ||
| runId, | ||
| messages | ||
| }); | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature: rest.temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: true | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| try { | ||
| let output = "object"; | ||
| if (isZodArray(structuredOutput)) { | ||
| output = "array"; | ||
| structuredOutput = getZodDef(structuredOutput).type; | ||
| } | ||
| const processedSchema = this._applySchemaCompat(structuredOutput); | ||
| llmSpan?.update({ | ||
| input: { | ||
| messages, | ||
| schema: processedSchema | ||
| } | ||
| }); | ||
| const argsForExecute = { | ||
| ...rest, | ||
| model, | ||
| onFinish: async (props) => { | ||
| llmSpan?.end({ | ||
| output: { | ||
| text: props?.text, | ||
| object: props?.object, | ||
| reasoning: props?.reasoningDetails, | ||
| reasoningText: props?.reasoning, | ||
| files: props?.files, | ||
| sources: props?.sources, | ||
| warnings: props?.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage | ||
| } | ||
| }); | ||
| try { | ||
| await onFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_ON_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| toolCalls: "", | ||
| toolResults: "", | ||
| finishReason: "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.trackException(mastraError); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Object stream finished", { | ||
| usage: props?.usage, | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }); | ||
| }, | ||
| onError: ({ error }) => { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_AI_SDK_STREAMING_ERROR", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| error | ||
| ); | ||
| this.logger.error("Stream object error", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| }, | ||
| messages, | ||
| output, | ||
| schema: processedSchema | ||
| }; | ||
| try { | ||
| return streamObject(argsForExecute); | ||
| } catch (e) { | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_AI_SDK_EXECUTION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Stream object failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } catch (e) { | ||
| if (e instanceof MastraError) { | ||
| llmSpan?.error({ error: e }); | ||
| throw e; | ||
| } | ||
| const mastraError = new MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_AI_SDK_SCHEMA_CONVERSION_FAILED", | ||
| domain: ErrorDomain.LLM, | ||
| category: ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Stream object schema conversion failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| convertToMessages(messages) { | ||
| if (Array.isArray(messages)) { | ||
| return messages.map((m) => { | ||
| if (typeof m === "string") { | ||
| return { | ||
| role: "user", | ||
| content: m | ||
| }; | ||
| } | ||
| return m; | ||
| }); | ||
| } | ||
| return [ | ||
| { | ||
| role: "user", | ||
| content: messages | ||
| } | ||
| ]; | ||
| } | ||
| async generate(messages, args) { | ||
| const msgs = this.convertToMessages(messages); | ||
| const { output, ...rest } = args ?? {}; | ||
| if (!output) { | ||
| return await this.__text({ | ||
| messages: msgs, | ||
| ...rest | ||
| }); | ||
| } | ||
| return await this.__textObject({ | ||
| messages: msgs, | ||
| structuredOutput: output, | ||
| ...rest | ||
| }); | ||
| } | ||
| stream(messages, args) { | ||
| const msgs = this.convertToMessages(messages); | ||
| const { output, ...rest } = args ?? {}; | ||
| if (!output) { | ||
| const { | ||
| maxSteps = 5, | ||
| onFinish: onFinish2, | ||
| ...streamRest | ||
| } = rest; | ||
| return this.__stream({ | ||
| messages: msgs, | ||
| maxSteps, | ||
| onFinish: onFinish2, | ||
| ...streamRest | ||
| }); | ||
| } | ||
| const { onFinish, ...objectRest } = rest; | ||
| return this.__streamObject({ | ||
| messages: msgs, | ||
| structuredOutput: output, | ||
| onFinish, | ||
| ...objectRest | ||
| }); | ||
| } | ||
| }; | ||
| function createStreamFromGenerateResult(result) { | ||
| return new ReadableStream({ | ||
| start(controller) { | ||
| controller.enqueue({ type: "stream-start", warnings: result.warnings }); | ||
| controller.enqueue({ | ||
| type: "response-metadata", | ||
| id: result.response?.id, | ||
| modelId: result.response?.modelId, | ||
| timestamp: result.response?.timestamp | ||
| }); | ||
| const toolCallMeta = {}; | ||
| for (const message of result.content) { | ||
| if (message.type === "tool-call") { | ||
| const toolCall = message; | ||
| toolCallMeta[toolCall.toolCallId] = { providerExecuted: toolCall.providerExecuted }; | ||
| controller.enqueue({ | ||
| type: "tool-input-start", | ||
| id: toolCall.toolCallId, | ||
| toolName: toolCall.toolName, | ||
| providerExecuted: toolCall.providerExecuted, | ||
| dynamic: toolCall.dynamic, | ||
| providerMetadata: toolCall.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "tool-input-delta", | ||
| id: toolCall.toolCallId, | ||
| delta: toolCall.input, | ||
| providerMetadata: toolCall.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "tool-input-end", | ||
| id: toolCall.toolCallId, | ||
| providerMetadata: toolCall.providerMetadata | ||
| }); | ||
| controller.enqueue(toolCall); | ||
| } else if (message.type === "tool-result") { | ||
| const toolResult = message; | ||
| const meta = toolCallMeta[toolResult.toolCallId]; | ||
| if (meta?.providerExecuted) { | ||
| controller.enqueue({ ...toolResult, providerExecuted: meta.providerExecuted }); | ||
| } else { | ||
| controller.enqueue(message); | ||
| } | ||
| } else if (message.type === "text") { | ||
| const text = message; | ||
| const id = `msg_${randomUUID()}`; | ||
| controller.enqueue({ | ||
| type: "text-start", | ||
| id, | ||
| providerMetadata: text.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "text-delta", | ||
| id, | ||
| delta: text.text | ||
| }); | ||
| controller.enqueue({ | ||
| type: "text-end", | ||
| id | ||
| }); | ||
| } else if (message.type === "reasoning") { | ||
| const id = `reasoning_${randomUUID()}`; | ||
| const reasoning = message; | ||
| controller.enqueue({ | ||
| type: "reasoning-start", | ||
| id, | ||
| providerMetadata: reasoning.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "reasoning-delta", | ||
| id, | ||
| delta: reasoning.text, | ||
| providerMetadata: reasoning.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "reasoning-end", | ||
| id, | ||
| providerMetadata: reasoning.providerMetadata | ||
| }); | ||
| } else if (message.type === "file") { | ||
| const file = message; | ||
| controller.enqueue({ | ||
| type: "file", | ||
| mediaType: file.mediaType, | ||
| data: file.data | ||
| }); | ||
| } else if (message.type === "source") { | ||
| const source = message; | ||
| if (source.sourceType === "url") { | ||
| controller.enqueue({ | ||
| type: "source", | ||
| id: source.id, | ||
| sourceType: "url", | ||
| url: source.url, | ||
| title: source.title, | ||
| providerMetadata: source.providerMetadata | ||
| }); | ||
| } else { | ||
| controller.enqueue({ | ||
| type: "source", | ||
| id: source.id, | ||
| sourceType: "document", | ||
| mediaType: source.mediaType, | ||
| filename: source.filename, | ||
| title: source.title, | ||
| providerMetadata: source.providerMetadata | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| controller.enqueue({ | ||
| type: "finish", | ||
| finishReason: result.finishReason, | ||
| usage: result.usage, | ||
| providerMetadata: result.providerMetadata | ||
| }); | ||
| controller.close(); | ||
| } | ||
| }); | ||
| } | ||
| // src/llm/model/aisdk/v5/model.ts | ||
| function applyStrictForV2(options) { | ||
| if (!options.tools?.length) { | ||
| return options; | ||
| } | ||
| let hasStrictTool = false; | ||
| const sanitizedTools = options.tools.map((tool) => { | ||
| if (tool.type !== "function" || !("strict" in tool)) { | ||
| return tool; | ||
| } | ||
| if (tool.strict === true) { | ||
| hasStrictTool = true; | ||
| } | ||
| const { strict: _strict, ...rest } = tool; | ||
| return rest; | ||
| }); | ||
| let result = { | ||
| ...options, | ||
| tools: sanitizedTools | ||
| }; | ||
| if (hasStrictTool) { | ||
| const existingOpenai = options.providerOptions?.openai ?? {}; | ||
| if (existingOpenai.strictJsonSchema == null) { | ||
| result = { | ||
| ...result, | ||
| providerOptions: { | ||
| ...options.providerOptions, | ||
| openai: { | ||
| ...existingOpenai, | ||
| strictJsonSchema: true | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| var AISDKV5LanguageModel = class { | ||
| /** | ||
| * The language model must specify which language model interface version it implements. | ||
| */ | ||
| specificationVersion = "v2"; | ||
| /** | ||
| * Name of the provider for logging purposes. | ||
| */ | ||
| provider; | ||
| /** | ||
| * Provider-specific model ID for logging purposes. | ||
| */ | ||
| modelId; | ||
| gatewayId; | ||
| /** | ||
| * Supported URL patterns by media type for the provider. | ||
| * | ||
| * The keys are media type patterns or full media types (e.g. `*\/*` for everything, `audio/*`, `video/*`, or `application/pdf`). | ||
| * and the values are arrays of regular expressions that match the URL paths. | ||
| * The matching should be against lower-case URLs. | ||
| * Matched URLs are supported natively by the model and are not downloaded. | ||
| * @returns A map of supported URL patterns by media type (as a promise or a plain object). | ||
| */ | ||
| supportedUrls; | ||
| #model; | ||
| constructor(config) { | ||
| this.#model = config; | ||
| this.provider = this.#model.provider; | ||
| this.modelId = this.#model.modelId; | ||
| this.gatewayId = config.gatewayId; | ||
| this.supportedUrls = this.#model.supportedUrls; | ||
| } | ||
| async doGenerate(options) { | ||
| const result = await this.#model.doGenerate(applyStrictForV2(options)); | ||
| return { | ||
| ...result, | ||
| request: result.request, | ||
| response: result.response, | ||
| stream: createStreamFromGenerateResult(result) | ||
| }; | ||
| } | ||
| async doStream(options) { | ||
| return await this.#model.doStream(applyStrictForV2(options)); | ||
| } | ||
| /** | ||
| * Custom serialization for tracing/observability spans. | ||
| * `#model` is already a true JS private field and not enumerable, so | ||
| * the wrapped provider SDK client can't leak. This method makes the | ||
| * safe shape explicit and avoids walking `supportedUrls` (a | ||
| * PromiseLike / regex map that isn't useful in spans). | ||
| */ | ||
| serializeForSpan() { | ||
| return { | ||
| specificationVersion: this.specificationVersion, | ||
| modelId: this.modelId, | ||
| provider: this.provider, | ||
| gatewayId: this.gatewayId | ||
| }; | ||
| } | ||
| }; | ||
| export { AISDKV5LanguageModel, MastraLLMV1, createStreamFromGenerateResult }; | ||
| //# sourceMappingURL=chunk-NXJLLKMC.js.map | ||
| //# sourceMappingURL=chunk-NXJLLKMC.js.map |
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunkLZIIAAGJ_cjs = require('./chunk-LZIIAAGJ.cjs'); | ||
| var chunkPUEQNTX6_cjs = require('./chunk-PUEQNTX6.cjs'); | ||
| var web = require('stream/web'); | ||
| var EventEmitter = require('events'); | ||
| function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } | ||
| var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter); | ||
| var MastraAgentNetworkStream = class extends web.ReadableStream { | ||
| #usageCount = { | ||
| inputTokens: 0, | ||
| outputTokens: 0, | ||
| totalTokens: 0, | ||
| cachedInputTokens: 0, | ||
| cacheCreationInputTokens: 0, | ||
| reasoningTokens: 0 | ||
| }; | ||
| #streamPromise; | ||
| #objectPromise; | ||
| #objectStreamController = null; | ||
| #objectStream = null; | ||
| #run; | ||
| runId; | ||
| constructor({ | ||
| createStream, | ||
| run | ||
| }) { | ||
| const deferredPromise = { | ||
| promise: null, | ||
| resolve: null, | ||
| reject: null | ||
| }; | ||
| deferredPromise.promise = new Promise((resolve, reject) => { | ||
| deferredPromise.resolve = resolve; | ||
| deferredPromise.reject = reject; | ||
| }); | ||
| const objectDeferredPromise = { | ||
| promise: null, | ||
| resolve: null, | ||
| reject: null | ||
| }; | ||
| objectDeferredPromise.promise = new Promise((resolve, reject) => { | ||
| objectDeferredPromise.resolve = resolve; | ||
| objectDeferredPromise.reject = reject; | ||
| }); | ||
| let objectStreamController = null; | ||
| const updateUsageCount = (usage) => { | ||
| this.#usageCount.inputTokens += parseInt(usage?.inputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.outputTokens += parseInt(usage?.outputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.totalTokens += parseInt(usage?.totalTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.reasoningTokens += parseInt(usage?.reasoningTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.cachedInputTokens += parseInt(usage?.cachedInputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.cacheCreationInputTokens += parseInt(usage?.cacheCreationInputTokens?.toString() ?? "0", 10); | ||
| }; | ||
| super({ | ||
| start: async (controller) => { | ||
| try { | ||
| const writer = new WritableStream({ | ||
| write: (chunk) => { | ||
| if (chunk.type === "step-output" && chunk.payload?.output?.from === "AGENT" && chunk.payload?.output?.type === "finish" || chunk.type === "step-output" && chunk.payload?.output?.from === "WORKFLOW" && chunk.payload?.output?.type === "finish") { | ||
| const output = chunk.payload?.output; | ||
| if (output && "payload" in output && output.payload) { | ||
| const finishPayload = output.payload; | ||
| if ("usage" in finishPayload && finishPayload.usage) { | ||
| updateUsageCount(finishPayload.usage); | ||
| } else if ("output" in finishPayload && finishPayload.output) { | ||
| const outputPayload = finishPayload.output; | ||
| if ("usage" in outputPayload && outputPayload.usage) { | ||
| updateUsageCount(outputPayload.usage); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| controller.enqueue(chunk); | ||
| } | ||
| }); | ||
| const stream = await createStream(writer); | ||
| const getInnerChunk = (chunk) => { | ||
| if (chunk.type === "workflow-step-output") { | ||
| return getInnerChunk(chunk.payload.output); | ||
| } | ||
| return chunk; | ||
| }; | ||
| let objectResolved = false; | ||
| for await (const chunk of stream) { | ||
| if (chunk.type === "workflow-step-output") { | ||
| const innerChunk = getInnerChunk(chunk); | ||
| if (innerChunk.type === "routing-agent-end" || innerChunk.type === "agent-execution-end" || innerChunk.type === "workflow-execution-end") { | ||
| if (innerChunk.payload?.usage) { | ||
| updateUsageCount(innerChunk.payload.usage); | ||
| } | ||
| } | ||
| if (innerChunk.type === "network-object") { | ||
| if (objectStreamController) { | ||
| objectStreamController.enqueue(innerChunk.payload?.object); | ||
| } | ||
| controller.enqueue(innerChunk); | ||
| } else if (innerChunk.type === "network-object-result") { | ||
| if (!objectResolved) { | ||
| objectResolved = true; | ||
| objectDeferredPromise.resolve(innerChunk.payload?.object); | ||
| if (objectStreamController) { | ||
| objectStreamController.close(); | ||
| } | ||
| } | ||
| controller.enqueue(innerChunk); | ||
| } else if (innerChunk.type === "network-execution-event-finish") { | ||
| const finishPayload = { | ||
| ...innerChunk.payload, | ||
| usage: this.#usageCount | ||
| }; | ||
| controller.enqueue({ ...innerChunk, payload: finishPayload }); | ||
| } else { | ||
| controller.enqueue(innerChunk); | ||
| } | ||
| } | ||
| } | ||
| if (!objectResolved) { | ||
| objectDeferredPromise.resolve(void 0); | ||
| if (objectStreamController) { | ||
| objectStreamController.close(); | ||
| } | ||
| } | ||
| controller.close(); | ||
| deferredPromise.resolve(); | ||
| } catch (error) { | ||
| controller.error(error); | ||
| deferredPromise.reject(error); | ||
| objectDeferredPromise.reject(error); | ||
| if (objectStreamController) { | ||
| objectStreamController.error(error); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| this.#run = run; | ||
| this.#streamPromise = deferredPromise; | ||
| this.runId = run.runId; | ||
| this.#objectPromise = objectDeferredPromise; | ||
| this.#objectStream = new web.ReadableStream({ | ||
| start: (ctrl) => { | ||
| objectStreamController = ctrl; | ||
| this.#objectStreamController = ctrl; | ||
| } | ||
| }); | ||
| } | ||
| get status() { | ||
| return this.#streamPromise.promise.then(() => this.#run._getExecutionResults()).then((res) => res.status); | ||
| } | ||
| get result() { | ||
| return this.#streamPromise.promise.then(() => this.#run._getExecutionResults()); | ||
| } | ||
| get usage() { | ||
| return this.#streamPromise.promise.then(() => this.#usageCount); | ||
| } | ||
| /** | ||
| * Returns a promise that resolves to the structured output object. | ||
| * Only available when structuredOutput option is provided to network(). | ||
| * Resolves to undefined if no structuredOutput was requested. | ||
| */ | ||
| get object() { | ||
| return this.#objectPromise.promise; | ||
| } | ||
| /** | ||
| * Returns a ReadableStream of partial objects during structured output generation. | ||
| * Useful for streaming partial results as they're being generated. | ||
| */ | ||
| get objectStream() { | ||
| return this.#objectStream; | ||
| } | ||
| }; | ||
| // src/stream/aisdk/v5/compat/ui-message.ts | ||
| function convertFullStreamChunkToUIMessageStream({ | ||
| part, | ||
| messageMetadataValue, | ||
| sendReasoning, | ||
| sendSources, | ||
| onError, | ||
| sendStart, | ||
| sendFinish, | ||
| responseMessageId | ||
| }) { | ||
| const partType = part.type; | ||
| switch (partType) { | ||
| case "text-start": { | ||
| return { | ||
| type: "text-start", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "text-delta": { | ||
| return { | ||
| type: "text-delta", | ||
| id: part.id, | ||
| delta: part.text, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "text-end": { | ||
| return { | ||
| type: "text-end", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "reasoning-start": { | ||
| return { | ||
| type: "reasoning-start", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "reasoning-delta": { | ||
| if (sendReasoning) { | ||
| return { | ||
| type: "reasoning-delta", | ||
| id: part.id, | ||
| delta: part.text, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "reasoning-end": { | ||
| return { | ||
| type: "reasoning-end", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "file": { | ||
| return { | ||
| type: "file", | ||
| mediaType: part.file.mediaType, | ||
| url: `data:${part.file.mediaType};base64,${part.file.base64}` | ||
| }; | ||
| } | ||
| case "source": { | ||
| if (sendSources && part.sourceType === "url") { | ||
| return { | ||
| type: "source-url", | ||
| sourceId: part.id, | ||
| url: part.url, | ||
| title: part.title, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| if (sendSources && part.sourceType === "document") { | ||
| return { | ||
| type: "source-document", | ||
| sourceId: part.id, | ||
| mediaType: part.mediaType, | ||
| title: part.title, | ||
| filename: part.filename, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "tool-input-start": { | ||
| return { | ||
| type: "tool-input-start", | ||
| toolCallId: part.id, | ||
| toolName: part.toolName, | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "tool-input-delta": { | ||
| return { | ||
| type: "tool-input-delta", | ||
| toolCallId: part.id, | ||
| inputTextDelta: part.delta | ||
| }; | ||
| } | ||
| case "tool-call": { | ||
| return { | ||
| type: "tool-input-available", | ||
| toolCallId: part.toolCallId, | ||
| toolName: part.toolName, | ||
| input: part.input, | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "tool-result": { | ||
| return { | ||
| type: "tool-output-available", | ||
| toolCallId: part.toolCallId, | ||
| output: part.output, | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "tool-output": { | ||
| return { | ||
| ...part.output | ||
| }; | ||
| } | ||
| case "tool-error": { | ||
| return { | ||
| type: "tool-output-error", | ||
| toolCallId: part.toolCallId, | ||
| errorText: onError(part.error), | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "error": { | ||
| return { | ||
| type: "error", | ||
| errorText: onError(part.error) | ||
| }; | ||
| } | ||
| case "start-step": { | ||
| return { type: "start-step" }; | ||
| } | ||
| case "finish-step": { | ||
| return { type: "finish-step" }; | ||
| } | ||
| case "start": { | ||
| if (sendStart) { | ||
| return { | ||
| type: "start", | ||
| ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {}, | ||
| ...responseMessageId != null ? { messageId: responseMessageId } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "finish": { | ||
| if (sendFinish) { | ||
| return { | ||
| type: "finish", | ||
| ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "abort": { | ||
| return part; | ||
| } | ||
| case "tool-input-end": { | ||
| return; | ||
| } | ||
| case "raw": { | ||
| return; | ||
| } | ||
| default: { | ||
| const exhaustiveCheck = partType; | ||
| throw new Error(`Unknown chunk type: ${exhaustiveCheck}`); | ||
| } | ||
| } | ||
| } | ||
| // src/stream/base/consume-stream.ts | ||
| async function consumeStream({ | ||
| stream, | ||
| onError | ||
| }) { | ||
| const reader = stream.getReader(); | ||
| try { | ||
| while (true) { | ||
| const { done } = await reader.read(); | ||
| if (done) break; | ||
| } | ||
| } catch (error) { | ||
| onError == null ? void 0 : onError(error); | ||
| } finally { | ||
| reader.releaseLock(); | ||
| } | ||
| } | ||
| // src/stream/RunOutput.ts | ||
| var WorkflowRunOutput = class { | ||
| #status = "running"; | ||
| #tripwireData; | ||
| #usageCount = { | ||
| inputTokens: 0, | ||
| outputTokens: 0, | ||
| totalTokens: 0, | ||
| cachedInputTokens: 0, | ||
| cacheCreationInputTokens: 0, | ||
| reasoningTokens: 0 | ||
| }; | ||
| #consumptionStarted = false; | ||
| #baseStream; | ||
| #emitter = new EventEmitter__default.default(); | ||
| #bufferedChunks = []; | ||
| #streamFinished = false; | ||
| #streamError; | ||
| #delayedPromises = { | ||
| usage: new chunkLZIIAAGJ_cjs.DelayedPromise(), | ||
| result: new chunkLZIIAAGJ_cjs.DelayedPromise() | ||
| }; | ||
| /** | ||
| * Unique identifier for this workflow run | ||
| */ | ||
| runId; | ||
| /** | ||
| * Unique identifier for this workflow | ||
| */ | ||
| workflowId; | ||
| constructor({ | ||
| runId, | ||
| workflowId, | ||
| stream | ||
| }) { | ||
| const self = this; | ||
| this.runId = runId; | ||
| this.workflowId = workflowId; | ||
| this.#baseStream = stream; | ||
| stream.pipeTo( | ||
| new web.WritableStream({ | ||
| start() { | ||
| const chunk = { | ||
| type: "workflow-start", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowId: self.workflowId | ||
| } | ||
| }; | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| }, | ||
| write(chunk) { | ||
| if (chunk.type !== "workflow-step-finish") { | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| } | ||
| if (chunk.type === "workflow-step-output") { | ||
| if ("output" in chunk.payload && chunk.payload.output) { | ||
| const output = chunk.payload.output; | ||
| if (output.type === "finish") { | ||
| if (output.payload && "usage" in output.payload && output.payload.usage) { | ||
| self.#updateUsageCount(output.payload.usage); | ||
| } else if (output.payload && "output" in output.payload && output.payload.output) { | ||
| const outputPayload = output.payload.output; | ||
| if ("usage" in outputPayload && outputPayload.usage) { | ||
| self.#updateUsageCount(outputPayload.usage); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } else if (chunk.type === "workflow-canceled") { | ||
| self.#status = "canceled"; | ||
| } else if (chunk.type === "workflow-step-suspended") { | ||
| self.#status = "suspended"; | ||
| } else if (chunk.type === "workflow-step-result" && chunk.payload.status === "failed") { | ||
| if (chunk.payload.tripwire) { | ||
| self.#status = "tripwire"; | ||
| self.#tripwireData = chunk.payload.tripwire; | ||
| } else { | ||
| self.#status = "failed"; | ||
| } | ||
| } else if (chunk.type === "workflow-paused") { | ||
| self.#status = "paused"; | ||
| } | ||
| }, | ||
| close() { | ||
| if (self.#status === "running") { | ||
| self.#status = "success"; | ||
| } | ||
| self.#emitter.emit("chunk", { | ||
| type: "workflow-finish", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowStatus: self.#status, | ||
| metadata: self.#streamError ? { | ||
| error: self.#streamError, | ||
| errorMessage: self.#streamError?.message | ||
| } : {}, | ||
| output: { | ||
| usage: self.#usageCount | ||
| }, | ||
| // Include tripwire data when status is 'tripwire' | ||
| ...self.#status === "tripwire" && self.#tripwireData ? { tripwire: self.#tripwireData } : {} | ||
| } | ||
| }); | ||
| self.#delayedPromises.usage.resolve(self.#usageCount); | ||
| Object.entries(self.#delayedPromises).forEach(([key, promise]) => { | ||
| if (promise.status.type === "pending") { | ||
| promise.reject(new Error(`promise '${key}' was not resolved or rejected when stream finished`)); | ||
| } | ||
| }); | ||
| self.#streamFinished = true; | ||
| self.#emitter.emit("finish"); | ||
| } | ||
| }) | ||
| ).catch((reason) => { | ||
| console.log(" something went wrong", reason); | ||
| }); | ||
| } | ||
| #getDelayedPromise(promise) { | ||
| if (!this.#consumptionStarted) { | ||
| void this.consumeStream(); | ||
| } | ||
| return promise.promise; | ||
| } | ||
| #updateUsageCount(usage) { | ||
| let totalUsage = { | ||
| inputTokens: this.#usageCount.inputTokens ?? 0, | ||
| outputTokens: this.#usageCount.outputTokens ?? 0, | ||
| totalTokens: this.#usageCount.totalTokens ?? 0, | ||
| reasoningTokens: this.#usageCount.reasoningTokens ?? 0, | ||
| cachedInputTokens: this.#usageCount.cachedInputTokens ?? 0, | ||
| cacheCreationInputTokens: this.#usageCount.cacheCreationInputTokens ?? 0 | ||
| }; | ||
| if ("inputTokens" in usage) { | ||
| totalUsage.inputTokens += parseInt(usage?.inputTokens?.toString() ?? "0", 10); | ||
| totalUsage.outputTokens += parseInt(usage?.outputTokens?.toString() ?? "0", 10); | ||
| } else if ("promptTokens" in usage) { | ||
| totalUsage.inputTokens += parseInt(usage?.promptTokens?.toString() ?? "0", 10); | ||
| totalUsage.outputTokens += parseInt(usage?.completionTokens?.toString() ?? "0", 10); | ||
| } | ||
| totalUsage.totalTokens += parseInt(usage?.totalTokens?.toString() ?? "0", 10); | ||
| totalUsage.reasoningTokens += parseInt(usage?.reasoningTokens?.toString() ?? "0", 10); | ||
| totalUsage.cachedInputTokens += parseInt(usage?.cachedInputTokens?.toString() ?? "0", 10); | ||
| totalUsage.cacheCreationInputTokens += parseInt(usage?.cacheCreationInputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount = totalUsage; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| updateResults(results) { | ||
| this.#delayedPromises.result.resolve(results); | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| rejectResults(error) { | ||
| this.#delayedPromises.result.reject(error); | ||
| this.#status = "failed"; | ||
| this.#streamError = error; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| resume(stream) { | ||
| this.#baseStream = stream; | ||
| this.#streamFinished = false; | ||
| this.#consumptionStarted = false; | ||
| this.#status = "running"; | ||
| this.#delayedPromises = { | ||
| usage: new chunkLZIIAAGJ_cjs.DelayedPromise(), | ||
| result: new chunkLZIIAAGJ_cjs.DelayedPromise() | ||
| }; | ||
| const self = this; | ||
| stream.pipeTo( | ||
| new web.WritableStream({ | ||
| start() { | ||
| const chunk = { | ||
| type: "workflow-start", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowId: self.workflowId | ||
| } | ||
| }; | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| }, | ||
| write(chunk) { | ||
| if (chunk.type !== "workflow-step-finish") { | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| } | ||
| if (chunk.type === "workflow-step-output") { | ||
| if ("output" in chunk.payload && chunk.payload.output) { | ||
| const output = chunk.payload.output; | ||
| if (output.type === "finish") { | ||
| if (output.payload && "usage" in output.payload && output.payload.usage) { | ||
| self.#updateUsageCount(output.payload.usage); | ||
| } else if (output.payload && "output" in output.payload && output.payload.output) { | ||
| const outputPayload = output.payload.output; | ||
| if ("usage" in outputPayload && outputPayload.usage) { | ||
| self.#updateUsageCount(outputPayload.usage); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } else if (chunk.type === "workflow-canceled") { | ||
| self.#status = "canceled"; | ||
| } else if (chunk.type === "workflow-step-suspended") { | ||
| self.#status = "suspended"; | ||
| } else if (chunk.type === "workflow-step-result" && chunk.payload.status === "failed") { | ||
| if (chunk.payload.tripwire) { | ||
| self.#status = "tripwire"; | ||
| self.#tripwireData = chunk.payload.tripwire; | ||
| } else { | ||
| self.#status = "failed"; | ||
| } | ||
| } else if (chunk.type === "workflow-paused") { | ||
| self.#status = "paused"; | ||
| } | ||
| }, | ||
| close() { | ||
| if (self.#status === "running") { | ||
| self.#status = "success"; | ||
| } | ||
| self.#emitter.emit("chunk", { | ||
| type: "workflow-finish", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowStatus: self.#status, | ||
| metadata: self.#streamError ? { | ||
| error: self.#streamError, | ||
| errorMessage: self.#streamError?.message | ||
| } : {}, | ||
| output: { | ||
| usage: self.#usageCount | ||
| }, | ||
| // Include tripwire data when status is 'tripwire' | ||
| ...self.#status === "tripwire" && self.#tripwireData ? { tripwire: self.#tripwireData } : {} | ||
| } | ||
| }); | ||
| self.#streamFinished = true; | ||
| self.#emitter.emit("finish"); | ||
| } | ||
| }) | ||
| ).catch((reason) => { | ||
| console.log(" something went wrong", reason); | ||
| }); | ||
| } | ||
| async consumeStream(options) { | ||
| if (this.#consumptionStarted) { | ||
| return; | ||
| } | ||
| this.#consumptionStarted = true; | ||
| try { | ||
| await consumeStream({ | ||
| stream: this.#baseStream, | ||
| onError: options?.onError | ||
| }); | ||
| } catch (error) { | ||
| options?.onError?.(error); | ||
| } | ||
| } | ||
| get fullStream() { | ||
| const self = this; | ||
| return new web.ReadableStream({ | ||
| start(controller) { | ||
| self.#bufferedChunks.forEach((chunk) => { | ||
| controller.enqueue(chunk); | ||
| }); | ||
| if (self.#streamFinished) { | ||
| controller.close(); | ||
| return; | ||
| } | ||
| const chunkHandler = (chunk) => { | ||
| controller.enqueue(chunk); | ||
| }; | ||
| const finishHandler = () => { | ||
| self.#emitter.off("chunk", chunkHandler); | ||
| self.#emitter.off("finish", finishHandler); | ||
| controller.close(); | ||
| }; | ||
| self.#emitter.on("chunk", chunkHandler); | ||
| self.#emitter.on("finish", finishHandler); | ||
| }, | ||
| pull(_controller) { | ||
| if (!self.#consumptionStarted) { | ||
| void self.consumeStream(); | ||
| } | ||
| }, | ||
| cancel() { | ||
| self.#emitter.removeAllListeners(); | ||
| } | ||
| }); | ||
| } | ||
| get status() { | ||
| return this.#status; | ||
| } | ||
| get result() { | ||
| return this.#getDelayedPromise(this.#delayedPromises.result); | ||
| } | ||
| get usage() { | ||
| return this.#getDelayedPromise(this.#delayedPromises.usage); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.locked` instead | ||
| */ | ||
| get locked() { | ||
| console.warn("WorkflowRunOutput.locked is deprecated. Use fullStream.locked instead."); | ||
| return this.fullStream.locked; | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.cancel()` instead | ||
| */ | ||
| cancel(reason) { | ||
| console.warn("WorkflowRunOutput.cancel() is deprecated. Use fullStream.cancel() instead."); | ||
| return this.fullStream.cancel(reason); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.getReader()` instead | ||
| */ | ||
| getReader(options) { | ||
| console.warn("WorkflowRunOutput.getReader() is deprecated. Use fullStream.getReader() instead."); | ||
| return this.fullStream.getReader(options); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.pipeThrough()` instead | ||
| */ | ||
| pipeThrough(transform, options) { | ||
| console.warn("WorkflowRunOutput.pipeThrough() is deprecated. Use fullStream.pipeThrough() instead."); | ||
| return this.fullStream.pipeThrough(transform, options); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.pipeTo()` instead | ||
| */ | ||
| pipeTo(destination, options) { | ||
| console.warn("WorkflowRunOutput.pipeTo() is deprecated. Use fullStream.pipeTo() instead."); | ||
| return this.fullStream.pipeTo(destination, options); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.tee()` instead | ||
| */ | ||
| tee() { | ||
| console.warn("WorkflowRunOutput.tee() is deprecated. Use fullStream.tee() instead."); | ||
| return this.fullStream.tee(); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream[Symbol.asyncIterator]()` instead | ||
| */ | ||
| [Symbol.asyncIterator]() { | ||
| console.warn( | ||
| "WorkflowRunOutput[Symbol.asyncIterator]() is deprecated. Use fullStream[Symbol.asyncIterator]() instead." | ||
| ); | ||
| return this.fullStream[Symbol.asyncIterator](); | ||
| } | ||
| /** | ||
| * Helper method to treat this object as a ReadableStream | ||
| * @deprecated Use `fullStream` directly instead | ||
| */ | ||
| toReadableStream() { | ||
| console.warn("WorkflowRunOutput.toReadableStream() is deprecated. Use fullStream directly instead."); | ||
| return this.fullStream; | ||
| } | ||
| }; | ||
| // src/stream/aisdk/v5/transform.ts | ||
| function sanitizeToolCallInput(input) { | ||
| try { | ||
| JSON.parse(input); | ||
| return input; | ||
| } catch { | ||
| return input.replace(/[\s]*<\|[^|]*\|>[\s]*/g, "").trim(); | ||
| } | ||
| } | ||
| function tryRepairJson(input) { | ||
| let repaired = input.trim(); | ||
| repaired = repaired.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)"/g, (match, prefix, name) => { | ||
| if (prefix.trimEnd().endsWith('"')) { | ||
| return match; | ||
| } | ||
| return `${prefix}"${name}"`; | ||
| }); | ||
| repaired = repaired.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g, '$1"$2":'); | ||
| repaired = repaired.replace(/'/g, '"'); | ||
| repaired = repaired.replace(/,(\s*[}\]])/g, "$1"); | ||
| repaired = repaired.replace(/:\s*(\d{4}-\d{2}-\d{2}(?:T[\d:]+)?)\s*([,}])/g, ': "$1"$2'); | ||
| try { | ||
| return JSON.parse(repaired); | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
| function convertFullStreamChunkToMastra(value, ctx) { | ||
| switch (value.type) { | ||
| case "response-metadata": | ||
| return { | ||
| type: "response-metadata", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { ...value } | ||
| }; | ||
| case "text-start": | ||
| return { | ||
| type: "text-start", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "text-delta": | ||
| if (value.delta) { | ||
| return { | ||
| type: "text-delta", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata, | ||
| text: value.delta | ||
| } | ||
| }; | ||
| } | ||
| return; | ||
| case "text-end": | ||
| return { | ||
| type: "text-end", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: value | ||
| }; | ||
| case "reasoning-start": | ||
| return { | ||
| type: "reasoning-start", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "reasoning-delta": | ||
| return { | ||
| type: "reasoning-delta", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata, | ||
| text: value.delta | ||
| } | ||
| }; | ||
| case "reasoning-end": | ||
| return { | ||
| type: "reasoning-end", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "source": | ||
| return { | ||
| type: "source", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| sourceType: value.sourceType, | ||
| title: value.title || "", | ||
| mimeType: value.sourceType === "document" ? value.mediaType : void 0, | ||
| filename: value.sourceType === "document" ? value.filename : void 0, | ||
| url: value.sourceType === "url" ? value.url : void 0, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "file": { | ||
| const pm = value.providerMetadata; | ||
| return { | ||
| type: "file", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| data: value.data, | ||
| base64: typeof value.data === "string" ? value.data : void 0, | ||
| mimeType: value.mediaType, | ||
| ...pm != null ? { providerMetadata: pm } : {} | ||
| } | ||
| }; | ||
| } | ||
| case "tool-call": { | ||
| let toolCallInput = void 0; | ||
| if (value.input) { | ||
| const sanitized = sanitizeToolCallInput(value.input); | ||
| if (sanitized) { | ||
| try { | ||
| toolCallInput = JSON.parse(sanitized); | ||
| } catch { | ||
| const repaired = tryRepairJson(sanitized); | ||
| if (repaired) { | ||
| toolCallInput = repaired; | ||
| } else { | ||
| console.error("Error converting tool call input to JSON", { | ||
| input: value.input | ||
| }); | ||
| toolCallInput = void 0; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return { | ||
| type: "tool-call", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.toolCallId, | ||
| toolName: value.toolName, | ||
| args: toolCallInput, | ||
| providerExecuted: value.providerExecuted, | ||
| providerMetadata: value.providerMetadata, | ||
| ...value.observability ? { observability: value.observability } : {} | ||
| } | ||
| }; | ||
| } | ||
| case "tool-result": | ||
| return { | ||
| type: "tool-result", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.toolCallId, | ||
| toolName: value.toolName, | ||
| result: value.result, | ||
| isError: value.isError, | ||
| providerExecuted: value.providerExecuted, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "tool-input-start": | ||
| return { | ||
| type: "tool-call-input-streaming-start", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.id, | ||
| toolName: value.toolName, | ||
| providerExecuted: value.providerExecuted, | ||
| providerMetadata: value.providerMetadata, | ||
| dynamic: value.dynamic, | ||
| ...value.observability ? { observability: value.observability } : {} | ||
| } | ||
| }; | ||
| case "tool-input-delta": | ||
| if (value.delta) { | ||
| return { | ||
| type: "tool-call-delta", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| argsTextDelta: value.delta, | ||
| toolCallId: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| } | ||
| return; | ||
| case "tool-input-end": | ||
| return { | ||
| type: "tool-call-input-streaming-end", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "finish": | ||
| const { finishReason, usage, providerMetadata, messages, ...rest } = value; | ||
| return { | ||
| type: "finish", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| providerMetadata: value.providerMetadata, | ||
| stepResult: { | ||
| reason: normalizeFinishReason(value.finishReason) | ||
| }, | ||
| output: { | ||
| // Normalize usage to handle both V2 (flat) and V3 (nested) formats | ||
| usage: normalizeUsage(value.usage) | ||
| }, | ||
| metadata: { | ||
| providerMetadata: value.providerMetadata | ||
| }, | ||
| messages: messages ?? { | ||
| all: [], | ||
| user: [], | ||
| nonUser: [] | ||
| }, | ||
| ...rest | ||
| } | ||
| }; | ||
| case "error": | ||
| return { | ||
| type: "error", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: value | ||
| }; | ||
| case "raw": | ||
| return { | ||
| type: "raw", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: value.rawValue | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| function convertMastraChunkToAISDKv5({ | ||
| chunk, | ||
| mode = "stream" | ||
| }) { | ||
| switch (chunk.type) { | ||
| case "start": | ||
| return { | ||
| type: "start" | ||
| }; | ||
| case "step-start": | ||
| const { messageId: _messageId, ...rest } = chunk.payload; | ||
| return { | ||
| type: "start-step", | ||
| request: rest.request, | ||
| warnings: rest.warnings || [] | ||
| }; | ||
| case "raw": | ||
| return { | ||
| type: "raw", | ||
| rawValue: chunk.payload | ||
| }; | ||
| case "finish": { | ||
| return { | ||
| type: "finish", | ||
| // Cast needed: Mastra extends reason with 'tripwire' | 'retry' for processor scenarios | ||
| finishReason: chunk.payload.stepResult.reason, | ||
| // Cast needed: Mastra's LanguageModelUsage has optional properties, V2 has required-but-nullable | ||
| totalUsage: chunk.payload.output.usage | ||
| }; | ||
| } | ||
| case "reasoning-start": | ||
| return { | ||
| type: "reasoning-start", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "reasoning-delta": | ||
| return { | ||
| type: "reasoning-delta", | ||
| id: chunk.payload.id, | ||
| text: chunk.payload.text, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "reasoning-signature": | ||
| throw new Error('AISDKv5 chunk type "reasoning-signature" not supported'); | ||
| case "redacted-reasoning": | ||
| throw new Error('AISDKv5 chunk type "redacted-reasoning" not supported'); | ||
| case "reasoning-end": | ||
| return { | ||
| type: "reasoning-end", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "source": | ||
| if (chunk.payload.sourceType === "url") { | ||
| return { | ||
| type: "source", | ||
| sourceType: "url", | ||
| id: chunk.payload.id, | ||
| url: chunk.payload.url, | ||
| title: chunk.payload.title, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| } else { | ||
| return { | ||
| type: "source", | ||
| sourceType: "document", | ||
| id: chunk.payload.id, | ||
| mediaType: chunk.payload.mimeType, | ||
| title: chunk.payload.title, | ||
| filename: chunk.payload.filename, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| } | ||
| case "file": { | ||
| const filePart = mode === "generate" ? { | ||
| type: "file", | ||
| file: new chunkPUEQNTX6_cjs.DefaultGeneratedFile({ | ||
| data: chunk.payload.data, | ||
| mediaType: chunk.payload.mimeType | ||
| }) | ||
| } : { | ||
| type: "file", | ||
| file: new chunkPUEQNTX6_cjs.DefaultGeneratedFileWithType({ | ||
| data: chunk.payload.data, | ||
| mediaType: chunk.payload.mimeType | ||
| }) | ||
| }; | ||
| if (chunk.payload.providerMetadata) { | ||
| filePart.providerMetadata = chunk.payload.providerMetadata; | ||
| } | ||
| return filePart; | ||
| } | ||
| case "tool-call": { | ||
| const toolCallPart = { | ||
| type: "tool-call", | ||
| toolCallId: chunk.payload.toolCallId, | ||
| providerMetadata: chunk.payload.providerMetadata, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| toolName: chunk.payload.toolName, | ||
| input: chunk.payload.args | ||
| }; | ||
| if (chunk.payload.observability) { | ||
| toolCallPart.observability = chunk.payload.observability; | ||
| } | ||
| return toolCallPart; | ||
| } | ||
| case "tool-call-input-streaming-start": | ||
| return { | ||
| type: "tool-input-start", | ||
| id: chunk.payload.toolCallId, | ||
| toolName: chunk.payload.toolName, | ||
| dynamic: !!chunk.payload.dynamic, | ||
| providerMetadata: chunk.payload.providerMetadata, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| ...chunk.payload.observability ? { observability: chunk.payload.observability } : {} | ||
| }; | ||
| case "tool-call-input-streaming-end": | ||
| return { | ||
| type: "tool-input-end", | ||
| id: chunk.payload.toolCallId, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "tool-call-delta": | ||
| return { | ||
| type: "tool-input-delta", | ||
| id: chunk.payload.toolCallId, | ||
| delta: chunk.payload.argsTextDelta, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "step-finish": { | ||
| const { request: _request, providerMetadata: metadataProviderMetadata, ...rest2 } = chunk.payload.metadata; | ||
| return { | ||
| type: "finish-step", | ||
| response: { | ||
| id: chunk.payload.id || "", | ||
| timestamp: /* @__PURE__ */ new Date(), | ||
| modelId: rest2.modelId || "", | ||
| ...rest2 | ||
| }, | ||
| usage: chunk.payload.output.usage, | ||
| finishReason: chunk.payload.stepResult.reason, | ||
| providerMetadata: metadataProviderMetadata ?? chunk.payload.providerMetadata | ||
| }; | ||
| } | ||
| case "text-delta": | ||
| return { | ||
| type: "text-delta", | ||
| id: chunk.payload.id, | ||
| text: chunk.payload.text, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "text-end": | ||
| return { | ||
| type: "text-end", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "text-start": | ||
| return { | ||
| type: "text-start", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "tool-result": | ||
| return { | ||
| type: "tool-result", | ||
| input: chunk.payload.args, | ||
| toolCallId: chunk.payload.toolCallId, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| toolName: chunk.payload.toolName, | ||
| output: chunk.payload.result | ||
| // providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this? | ||
| }; | ||
| case "tool-error": | ||
| return { | ||
| type: "tool-error", | ||
| error: chunk.payload.error, | ||
| input: chunk.payload.args, | ||
| toolCallId: chunk.payload.toolCallId, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| toolName: chunk.payload.toolName | ||
| // providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this? | ||
| }; | ||
| case "abort": | ||
| return { | ||
| type: "abort" | ||
| }; | ||
| case "error": | ||
| return { | ||
| type: "error", | ||
| error: chunk.payload.error | ||
| }; | ||
| case "object": | ||
| return { | ||
| type: "object", | ||
| object: chunk.object | ||
| }; | ||
| default: | ||
| if (chunk.type && "payload" in chunk && chunk.payload) { | ||
| return { | ||
| type: chunk.type, | ||
| ...chunk.payload || {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| } | ||
| function isV3Usage(usage) { | ||
| if (!usage || typeof usage !== "object") return false; | ||
| const u = usage; | ||
| return typeof u.inputTokens === "object" && u.inputTokens !== null && "total" in u.inputTokens && typeof u.outputTokens === "object" && u.outputTokens !== null && "total" in u.outputTokens; | ||
| } | ||
| function normalizeUsage(usage) { | ||
| if (!usage) { | ||
| return { | ||
| inputTokens: void 0, | ||
| outputTokens: void 0, | ||
| totalTokens: void 0, | ||
| reasoningTokens: void 0, | ||
| cachedInputTokens: void 0, | ||
| cacheCreationInputTokens: void 0, | ||
| raw: void 0 | ||
| }; | ||
| } | ||
| if (isV3Usage(usage)) { | ||
| const inputTokens = usage.inputTokens.total; | ||
| const outputTokens = usage.outputTokens.total; | ||
| return { | ||
| inputTokens, | ||
| outputTokens, | ||
| totalTokens: (inputTokens ?? 0) + (outputTokens ?? 0), | ||
| reasoningTokens: usage.outputTokens.reasoning, | ||
| cachedInputTokens: usage.inputTokens.cacheRead, | ||
| cacheCreationInputTokens: usage.inputTokens.cacheWrite, | ||
| raw: usage | ||
| }; | ||
| } | ||
| const v2Usage = usage; | ||
| return { | ||
| inputTokens: v2Usage.inputTokens, | ||
| outputTokens: v2Usage.outputTokens, | ||
| totalTokens: v2Usage.totalTokens ?? (v2Usage.inputTokens ?? 0) + (v2Usage.outputTokens ?? 0), | ||
| reasoningTokens: v2Usage.reasoningTokens, | ||
| cachedInputTokens: v2Usage.cachedInputTokens, | ||
| cacheCreationInputTokens: v2Usage.cacheCreationInputTokens, | ||
| raw: usage | ||
| }; | ||
| } | ||
| function isV3FinishReason(finishReason) { | ||
| return typeof finishReason === "object" && finishReason !== null && "unified" in finishReason; | ||
| } | ||
| function normalizeFinishReason(finishReason) { | ||
| if (!finishReason) { | ||
| return "other"; | ||
| } | ||
| if (finishReason === "tripwire" || finishReason === "retry") { | ||
| return finishReason; | ||
| } | ||
| if (isV3FinishReason(finishReason)) { | ||
| return finishReason.unified; | ||
| } | ||
| return finishReason === "unknown" ? "other" : finishReason; | ||
| } | ||
| // src/stream/caching-transform-stream.ts | ||
| function createCachingTransformStream(options) { | ||
| const { cache, cacheKey, serialize = (x) => x, deserialize = (x) => x } = options; | ||
| const transform = new TransformStream({ | ||
| transform(chunk, controller) { | ||
| const serialized = serialize(chunk); | ||
| cache.listPush(cacheKey, serialized).catch(() => { | ||
| }); | ||
| controller.enqueue(chunk); | ||
| } | ||
| }); | ||
| const getHistory = async (offset = 0) => { | ||
| const cached = await cache.listFromTo(cacheKey, offset); | ||
| return cached.map((item) => deserialize(item)); | ||
| }; | ||
| const clearCache = async () => { | ||
| await cache.delete(cacheKey); | ||
| }; | ||
| return { transform, getHistory, clearCache }; | ||
| } | ||
| function createReplayStream(options) { | ||
| const { history, liveSource, cache, cacheKey, serialize = (x) => x } = options; | ||
| let historyIndex = 0; | ||
| let liveReader = null; | ||
| let historyComplete = false; | ||
| return new ReadableStream({ | ||
| async pull(controller) { | ||
| if (!historyComplete) { | ||
| if (historyIndex < history.length) { | ||
| controller.enqueue(history[historyIndex]); | ||
| historyIndex++; | ||
| return; | ||
| } | ||
| historyComplete = true; | ||
| liveReader = liveSource.getReader(); | ||
| } | ||
| if (liveReader) { | ||
| try { | ||
| const { done, value } = await liveReader.read(); | ||
| if (done) { | ||
| controller.close(); | ||
| return; | ||
| } | ||
| if (cache && cacheKey) { | ||
| const serialized = serialize(value); | ||
| cache.listPush(cacheKey, serialized).catch(() => { | ||
| }); | ||
| } | ||
| controller.enqueue(value); | ||
| } catch (error) { | ||
| controller.error(error); | ||
| } | ||
| } | ||
| }, | ||
| cancel() { | ||
| if (liveReader) { | ||
| void liveReader.cancel(); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| function withStreamCaching(options) { | ||
| const { cache, cacheKey, serialize, deserialize } = options; | ||
| return { | ||
| pipeThrough: () => { | ||
| const { transform } = createCachingTransformStream({ cache, cacheKey, serialize, deserialize }); | ||
| return transform; | ||
| }, | ||
| getHistory: async (offset = 0) => { | ||
| const deserializeFn = deserialize ?? ((x) => x); | ||
| const cached = await cache.listFromTo(cacheKey, offset); | ||
| return cached.map((item) => deserializeFn(item)); | ||
| }, | ||
| clearCache: async () => { | ||
| await cache.delete(cacheKey); | ||
| } | ||
| }; | ||
| } | ||
| exports.MastraAgentNetworkStream = MastraAgentNetworkStream; | ||
| exports.WorkflowRunOutput = WorkflowRunOutput; | ||
| exports.convertFullStreamChunkToMastra = convertFullStreamChunkToMastra; | ||
| exports.convertFullStreamChunkToUIMessageStream = convertFullStreamChunkToUIMessageStream; | ||
| exports.convertMastraChunkToAISDKv5 = convertMastraChunkToAISDKv5; | ||
| exports.createCachingTransformStream = createCachingTransformStream; | ||
| exports.createReplayStream = createReplayStream; | ||
| exports.withStreamCaching = withStreamCaching; | ||
| //# sourceMappingURL=chunk-NYZSFMD6.cjs.map | ||
| //# sourceMappingURL=chunk-NYZSFMD6.cjs.map |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { DelayedPromise } from './chunk-HCSJNNEN.js'; | ||
| import { DefaultGeneratedFile, DefaultGeneratedFileWithType } from './chunk-HHYICF3X.js'; | ||
| import { ReadableStream as ReadableStream$1, WritableStream as WritableStream$1 } from 'stream/web'; | ||
| import EventEmitter from 'events'; | ||
| var MastraAgentNetworkStream = class extends ReadableStream$1 { | ||
| #usageCount = { | ||
| inputTokens: 0, | ||
| outputTokens: 0, | ||
| totalTokens: 0, | ||
| cachedInputTokens: 0, | ||
| cacheCreationInputTokens: 0, | ||
| reasoningTokens: 0 | ||
| }; | ||
| #streamPromise; | ||
| #objectPromise; | ||
| #objectStreamController = null; | ||
| #objectStream = null; | ||
| #run; | ||
| runId; | ||
| constructor({ | ||
| createStream, | ||
| run | ||
| }) { | ||
| const deferredPromise = { | ||
| promise: null, | ||
| resolve: null, | ||
| reject: null | ||
| }; | ||
| deferredPromise.promise = new Promise((resolve, reject) => { | ||
| deferredPromise.resolve = resolve; | ||
| deferredPromise.reject = reject; | ||
| }); | ||
| const objectDeferredPromise = { | ||
| promise: null, | ||
| resolve: null, | ||
| reject: null | ||
| }; | ||
| objectDeferredPromise.promise = new Promise((resolve, reject) => { | ||
| objectDeferredPromise.resolve = resolve; | ||
| objectDeferredPromise.reject = reject; | ||
| }); | ||
| let objectStreamController = null; | ||
| const updateUsageCount = (usage) => { | ||
| this.#usageCount.inputTokens += parseInt(usage?.inputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.outputTokens += parseInt(usage?.outputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.totalTokens += parseInt(usage?.totalTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.reasoningTokens += parseInt(usage?.reasoningTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.cachedInputTokens += parseInt(usage?.cachedInputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount.cacheCreationInputTokens += parseInt(usage?.cacheCreationInputTokens?.toString() ?? "0", 10); | ||
| }; | ||
| super({ | ||
| start: async (controller) => { | ||
| try { | ||
| const writer = new WritableStream({ | ||
| write: (chunk) => { | ||
| if (chunk.type === "step-output" && chunk.payload?.output?.from === "AGENT" && chunk.payload?.output?.type === "finish" || chunk.type === "step-output" && chunk.payload?.output?.from === "WORKFLOW" && chunk.payload?.output?.type === "finish") { | ||
| const output = chunk.payload?.output; | ||
| if (output && "payload" in output && output.payload) { | ||
| const finishPayload = output.payload; | ||
| if ("usage" in finishPayload && finishPayload.usage) { | ||
| updateUsageCount(finishPayload.usage); | ||
| } else if ("output" in finishPayload && finishPayload.output) { | ||
| const outputPayload = finishPayload.output; | ||
| if ("usage" in outputPayload && outputPayload.usage) { | ||
| updateUsageCount(outputPayload.usage); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| controller.enqueue(chunk); | ||
| } | ||
| }); | ||
| const stream = await createStream(writer); | ||
| const getInnerChunk = (chunk) => { | ||
| if (chunk.type === "workflow-step-output") { | ||
| return getInnerChunk(chunk.payload.output); | ||
| } | ||
| return chunk; | ||
| }; | ||
| let objectResolved = false; | ||
| for await (const chunk of stream) { | ||
| if (chunk.type === "workflow-step-output") { | ||
| const innerChunk = getInnerChunk(chunk); | ||
| if (innerChunk.type === "routing-agent-end" || innerChunk.type === "agent-execution-end" || innerChunk.type === "workflow-execution-end") { | ||
| if (innerChunk.payload?.usage) { | ||
| updateUsageCount(innerChunk.payload.usage); | ||
| } | ||
| } | ||
| if (innerChunk.type === "network-object") { | ||
| if (objectStreamController) { | ||
| objectStreamController.enqueue(innerChunk.payload?.object); | ||
| } | ||
| controller.enqueue(innerChunk); | ||
| } else if (innerChunk.type === "network-object-result") { | ||
| if (!objectResolved) { | ||
| objectResolved = true; | ||
| objectDeferredPromise.resolve(innerChunk.payload?.object); | ||
| if (objectStreamController) { | ||
| objectStreamController.close(); | ||
| } | ||
| } | ||
| controller.enqueue(innerChunk); | ||
| } else if (innerChunk.type === "network-execution-event-finish") { | ||
| const finishPayload = { | ||
| ...innerChunk.payload, | ||
| usage: this.#usageCount | ||
| }; | ||
| controller.enqueue({ ...innerChunk, payload: finishPayload }); | ||
| } else { | ||
| controller.enqueue(innerChunk); | ||
| } | ||
| } | ||
| } | ||
| if (!objectResolved) { | ||
| objectDeferredPromise.resolve(void 0); | ||
| if (objectStreamController) { | ||
| objectStreamController.close(); | ||
| } | ||
| } | ||
| controller.close(); | ||
| deferredPromise.resolve(); | ||
| } catch (error) { | ||
| controller.error(error); | ||
| deferredPromise.reject(error); | ||
| objectDeferredPromise.reject(error); | ||
| if (objectStreamController) { | ||
| objectStreamController.error(error); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| this.#run = run; | ||
| this.#streamPromise = deferredPromise; | ||
| this.runId = run.runId; | ||
| this.#objectPromise = objectDeferredPromise; | ||
| this.#objectStream = new ReadableStream$1({ | ||
| start: (ctrl) => { | ||
| objectStreamController = ctrl; | ||
| this.#objectStreamController = ctrl; | ||
| } | ||
| }); | ||
| } | ||
| get status() { | ||
| return this.#streamPromise.promise.then(() => this.#run._getExecutionResults()).then((res) => res.status); | ||
| } | ||
| get result() { | ||
| return this.#streamPromise.promise.then(() => this.#run._getExecutionResults()); | ||
| } | ||
| get usage() { | ||
| return this.#streamPromise.promise.then(() => this.#usageCount); | ||
| } | ||
| /** | ||
| * Returns a promise that resolves to the structured output object. | ||
| * Only available when structuredOutput option is provided to network(). | ||
| * Resolves to undefined if no structuredOutput was requested. | ||
| */ | ||
| get object() { | ||
| return this.#objectPromise.promise; | ||
| } | ||
| /** | ||
| * Returns a ReadableStream of partial objects during structured output generation. | ||
| * Useful for streaming partial results as they're being generated. | ||
| */ | ||
| get objectStream() { | ||
| return this.#objectStream; | ||
| } | ||
| }; | ||
| // src/stream/aisdk/v5/compat/ui-message.ts | ||
| function convertFullStreamChunkToUIMessageStream({ | ||
| part, | ||
| messageMetadataValue, | ||
| sendReasoning, | ||
| sendSources, | ||
| onError, | ||
| sendStart, | ||
| sendFinish, | ||
| responseMessageId | ||
| }) { | ||
| const partType = part.type; | ||
| switch (partType) { | ||
| case "text-start": { | ||
| return { | ||
| type: "text-start", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "text-delta": { | ||
| return { | ||
| type: "text-delta", | ||
| id: part.id, | ||
| delta: part.text, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "text-end": { | ||
| return { | ||
| type: "text-end", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "reasoning-start": { | ||
| return { | ||
| type: "reasoning-start", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "reasoning-delta": { | ||
| if (sendReasoning) { | ||
| return { | ||
| type: "reasoning-delta", | ||
| id: part.id, | ||
| delta: part.text, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "reasoning-end": { | ||
| return { | ||
| type: "reasoning-end", | ||
| id: part.id, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| case "file": { | ||
| return { | ||
| type: "file", | ||
| mediaType: part.file.mediaType, | ||
| url: `data:${part.file.mediaType};base64,${part.file.base64}` | ||
| }; | ||
| } | ||
| case "source": { | ||
| if (sendSources && part.sourceType === "url") { | ||
| return { | ||
| type: "source-url", | ||
| sourceId: part.id, | ||
| url: part.url, | ||
| title: part.title, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| if (sendSources && part.sourceType === "document") { | ||
| return { | ||
| type: "source-document", | ||
| sourceId: part.id, | ||
| mediaType: part.mediaType, | ||
| title: part.title, | ||
| filename: part.filename, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "tool-input-start": { | ||
| return { | ||
| type: "tool-input-start", | ||
| toolCallId: part.id, | ||
| toolName: part.toolName, | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "tool-input-delta": { | ||
| return { | ||
| type: "tool-input-delta", | ||
| toolCallId: part.id, | ||
| inputTextDelta: part.delta | ||
| }; | ||
| } | ||
| case "tool-call": { | ||
| return { | ||
| type: "tool-input-available", | ||
| toolCallId: part.toolCallId, | ||
| toolName: part.toolName, | ||
| input: part.input, | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "tool-result": { | ||
| return { | ||
| type: "tool-output-available", | ||
| toolCallId: part.toolCallId, | ||
| output: part.output, | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "tool-output": { | ||
| return { | ||
| ...part.output | ||
| }; | ||
| } | ||
| case "tool-error": { | ||
| return { | ||
| type: "tool-output-error", | ||
| toolCallId: part.toolCallId, | ||
| errorText: onError(part.error), | ||
| ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, | ||
| ...part.dynamic != null ? { dynamic: part.dynamic } : {} | ||
| }; | ||
| } | ||
| case "error": { | ||
| return { | ||
| type: "error", | ||
| errorText: onError(part.error) | ||
| }; | ||
| } | ||
| case "start-step": { | ||
| return { type: "start-step" }; | ||
| } | ||
| case "finish-step": { | ||
| return { type: "finish-step" }; | ||
| } | ||
| case "start": { | ||
| if (sendStart) { | ||
| return { | ||
| type: "start", | ||
| ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {}, | ||
| ...responseMessageId != null ? { messageId: responseMessageId } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "finish": { | ||
| if (sendFinish) { | ||
| return { | ||
| type: "finish", | ||
| ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| case "abort": { | ||
| return part; | ||
| } | ||
| case "tool-input-end": { | ||
| return; | ||
| } | ||
| case "raw": { | ||
| return; | ||
| } | ||
| default: { | ||
| const exhaustiveCheck = partType; | ||
| throw new Error(`Unknown chunk type: ${exhaustiveCheck}`); | ||
| } | ||
| } | ||
| } | ||
| // src/stream/base/consume-stream.ts | ||
| async function consumeStream({ | ||
| stream, | ||
| onError | ||
| }) { | ||
| const reader = stream.getReader(); | ||
| try { | ||
| while (true) { | ||
| const { done } = await reader.read(); | ||
| if (done) break; | ||
| } | ||
| } catch (error) { | ||
| onError == null ? void 0 : onError(error); | ||
| } finally { | ||
| reader.releaseLock(); | ||
| } | ||
| } | ||
| // src/stream/RunOutput.ts | ||
| var WorkflowRunOutput = class { | ||
| #status = "running"; | ||
| #tripwireData; | ||
| #usageCount = { | ||
| inputTokens: 0, | ||
| outputTokens: 0, | ||
| totalTokens: 0, | ||
| cachedInputTokens: 0, | ||
| cacheCreationInputTokens: 0, | ||
| reasoningTokens: 0 | ||
| }; | ||
| #consumptionStarted = false; | ||
| #baseStream; | ||
| #emitter = new EventEmitter(); | ||
| #bufferedChunks = []; | ||
| #streamFinished = false; | ||
| #streamError; | ||
| #delayedPromises = { | ||
| usage: new DelayedPromise(), | ||
| result: new DelayedPromise() | ||
| }; | ||
| /** | ||
| * Unique identifier for this workflow run | ||
| */ | ||
| runId; | ||
| /** | ||
| * Unique identifier for this workflow | ||
| */ | ||
| workflowId; | ||
| constructor({ | ||
| runId, | ||
| workflowId, | ||
| stream | ||
| }) { | ||
| const self = this; | ||
| this.runId = runId; | ||
| this.workflowId = workflowId; | ||
| this.#baseStream = stream; | ||
| stream.pipeTo( | ||
| new WritableStream$1({ | ||
| start() { | ||
| const chunk = { | ||
| type: "workflow-start", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowId: self.workflowId | ||
| } | ||
| }; | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| }, | ||
| write(chunk) { | ||
| if (chunk.type !== "workflow-step-finish") { | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| } | ||
| if (chunk.type === "workflow-step-output") { | ||
| if ("output" in chunk.payload && chunk.payload.output) { | ||
| const output = chunk.payload.output; | ||
| if (output.type === "finish") { | ||
| if (output.payload && "usage" in output.payload && output.payload.usage) { | ||
| self.#updateUsageCount(output.payload.usage); | ||
| } else if (output.payload && "output" in output.payload && output.payload.output) { | ||
| const outputPayload = output.payload.output; | ||
| if ("usage" in outputPayload && outputPayload.usage) { | ||
| self.#updateUsageCount(outputPayload.usage); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } else if (chunk.type === "workflow-canceled") { | ||
| self.#status = "canceled"; | ||
| } else if (chunk.type === "workflow-step-suspended") { | ||
| self.#status = "suspended"; | ||
| } else if (chunk.type === "workflow-step-result" && chunk.payload.status === "failed") { | ||
| if (chunk.payload.tripwire) { | ||
| self.#status = "tripwire"; | ||
| self.#tripwireData = chunk.payload.tripwire; | ||
| } else { | ||
| self.#status = "failed"; | ||
| } | ||
| } else if (chunk.type === "workflow-paused") { | ||
| self.#status = "paused"; | ||
| } | ||
| }, | ||
| close() { | ||
| if (self.#status === "running") { | ||
| self.#status = "success"; | ||
| } | ||
| self.#emitter.emit("chunk", { | ||
| type: "workflow-finish", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowStatus: self.#status, | ||
| metadata: self.#streamError ? { | ||
| error: self.#streamError, | ||
| errorMessage: self.#streamError?.message | ||
| } : {}, | ||
| output: { | ||
| usage: self.#usageCount | ||
| }, | ||
| // Include tripwire data when status is 'tripwire' | ||
| ...self.#status === "tripwire" && self.#tripwireData ? { tripwire: self.#tripwireData } : {} | ||
| } | ||
| }); | ||
| self.#delayedPromises.usage.resolve(self.#usageCount); | ||
| Object.entries(self.#delayedPromises).forEach(([key, promise]) => { | ||
| if (promise.status.type === "pending") { | ||
| promise.reject(new Error(`promise '${key}' was not resolved or rejected when stream finished`)); | ||
| } | ||
| }); | ||
| self.#streamFinished = true; | ||
| self.#emitter.emit("finish"); | ||
| } | ||
| }) | ||
| ).catch((reason) => { | ||
| console.log(" something went wrong", reason); | ||
| }); | ||
| } | ||
| #getDelayedPromise(promise) { | ||
| if (!this.#consumptionStarted) { | ||
| void this.consumeStream(); | ||
| } | ||
| return promise.promise; | ||
| } | ||
| #updateUsageCount(usage) { | ||
| let totalUsage = { | ||
| inputTokens: this.#usageCount.inputTokens ?? 0, | ||
| outputTokens: this.#usageCount.outputTokens ?? 0, | ||
| totalTokens: this.#usageCount.totalTokens ?? 0, | ||
| reasoningTokens: this.#usageCount.reasoningTokens ?? 0, | ||
| cachedInputTokens: this.#usageCount.cachedInputTokens ?? 0, | ||
| cacheCreationInputTokens: this.#usageCount.cacheCreationInputTokens ?? 0 | ||
| }; | ||
| if ("inputTokens" in usage) { | ||
| totalUsage.inputTokens += parseInt(usage?.inputTokens?.toString() ?? "0", 10); | ||
| totalUsage.outputTokens += parseInt(usage?.outputTokens?.toString() ?? "0", 10); | ||
| } else if ("promptTokens" in usage) { | ||
| totalUsage.inputTokens += parseInt(usage?.promptTokens?.toString() ?? "0", 10); | ||
| totalUsage.outputTokens += parseInt(usage?.completionTokens?.toString() ?? "0", 10); | ||
| } | ||
| totalUsage.totalTokens += parseInt(usage?.totalTokens?.toString() ?? "0", 10); | ||
| totalUsage.reasoningTokens += parseInt(usage?.reasoningTokens?.toString() ?? "0", 10); | ||
| totalUsage.cachedInputTokens += parseInt(usage?.cachedInputTokens?.toString() ?? "0", 10); | ||
| totalUsage.cacheCreationInputTokens += parseInt(usage?.cacheCreationInputTokens?.toString() ?? "0", 10); | ||
| this.#usageCount = totalUsage; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| updateResults(results) { | ||
| this.#delayedPromises.result.resolve(results); | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| rejectResults(error) { | ||
| this.#delayedPromises.result.reject(error); | ||
| this.#status = "failed"; | ||
| this.#streamError = error; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| resume(stream) { | ||
| this.#baseStream = stream; | ||
| this.#streamFinished = false; | ||
| this.#consumptionStarted = false; | ||
| this.#status = "running"; | ||
| this.#delayedPromises = { | ||
| usage: new DelayedPromise(), | ||
| result: new DelayedPromise() | ||
| }; | ||
| const self = this; | ||
| stream.pipeTo( | ||
| new WritableStream$1({ | ||
| start() { | ||
| const chunk = { | ||
| type: "workflow-start", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowId: self.workflowId | ||
| } | ||
| }; | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| }, | ||
| write(chunk) { | ||
| if (chunk.type !== "workflow-step-finish") { | ||
| self.#bufferedChunks.push(chunk); | ||
| self.#emitter.emit("chunk", chunk); | ||
| } | ||
| if (chunk.type === "workflow-step-output") { | ||
| if ("output" in chunk.payload && chunk.payload.output) { | ||
| const output = chunk.payload.output; | ||
| if (output.type === "finish") { | ||
| if (output.payload && "usage" in output.payload && output.payload.usage) { | ||
| self.#updateUsageCount(output.payload.usage); | ||
| } else if (output.payload && "output" in output.payload && output.payload.output) { | ||
| const outputPayload = output.payload.output; | ||
| if ("usage" in outputPayload && outputPayload.usage) { | ||
| self.#updateUsageCount(outputPayload.usage); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } else if (chunk.type === "workflow-canceled") { | ||
| self.#status = "canceled"; | ||
| } else if (chunk.type === "workflow-step-suspended") { | ||
| self.#status = "suspended"; | ||
| } else if (chunk.type === "workflow-step-result" && chunk.payload.status === "failed") { | ||
| if (chunk.payload.tripwire) { | ||
| self.#status = "tripwire"; | ||
| self.#tripwireData = chunk.payload.tripwire; | ||
| } else { | ||
| self.#status = "failed"; | ||
| } | ||
| } else if (chunk.type === "workflow-paused") { | ||
| self.#status = "paused"; | ||
| } | ||
| }, | ||
| close() { | ||
| if (self.#status === "running") { | ||
| self.#status = "success"; | ||
| } | ||
| self.#emitter.emit("chunk", { | ||
| type: "workflow-finish", | ||
| runId: self.runId, | ||
| from: "WORKFLOW" /* WORKFLOW */, | ||
| payload: { | ||
| workflowStatus: self.#status, | ||
| metadata: self.#streamError ? { | ||
| error: self.#streamError, | ||
| errorMessage: self.#streamError?.message | ||
| } : {}, | ||
| output: { | ||
| usage: self.#usageCount | ||
| }, | ||
| // Include tripwire data when status is 'tripwire' | ||
| ...self.#status === "tripwire" && self.#tripwireData ? { tripwire: self.#tripwireData } : {} | ||
| } | ||
| }); | ||
| self.#streamFinished = true; | ||
| self.#emitter.emit("finish"); | ||
| } | ||
| }) | ||
| ).catch((reason) => { | ||
| console.log(" something went wrong", reason); | ||
| }); | ||
| } | ||
| async consumeStream(options) { | ||
| if (this.#consumptionStarted) { | ||
| return; | ||
| } | ||
| this.#consumptionStarted = true; | ||
| try { | ||
| await consumeStream({ | ||
| stream: this.#baseStream, | ||
| onError: options?.onError | ||
| }); | ||
| } catch (error) { | ||
| options?.onError?.(error); | ||
| } | ||
| } | ||
| get fullStream() { | ||
| const self = this; | ||
| return new ReadableStream$1({ | ||
| start(controller) { | ||
| self.#bufferedChunks.forEach((chunk) => { | ||
| controller.enqueue(chunk); | ||
| }); | ||
| if (self.#streamFinished) { | ||
| controller.close(); | ||
| return; | ||
| } | ||
| const chunkHandler = (chunk) => { | ||
| controller.enqueue(chunk); | ||
| }; | ||
| const finishHandler = () => { | ||
| self.#emitter.off("chunk", chunkHandler); | ||
| self.#emitter.off("finish", finishHandler); | ||
| controller.close(); | ||
| }; | ||
| self.#emitter.on("chunk", chunkHandler); | ||
| self.#emitter.on("finish", finishHandler); | ||
| }, | ||
| pull(_controller) { | ||
| if (!self.#consumptionStarted) { | ||
| void self.consumeStream(); | ||
| } | ||
| }, | ||
| cancel() { | ||
| self.#emitter.removeAllListeners(); | ||
| } | ||
| }); | ||
| } | ||
| get status() { | ||
| return this.#status; | ||
| } | ||
| get result() { | ||
| return this.#getDelayedPromise(this.#delayedPromises.result); | ||
| } | ||
| get usage() { | ||
| return this.#getDelayedPromise(this.#delayedPromises.usage); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.locked` instead | ||
| */ | ||
| get locked() { | ||
| console.warn("WorkflowRunOutput.locked is deprecated. Use fullStream.locked instead."); | ||
| return this.fullStream.locked; | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.cancel()` instead | ||
| */ | ||
| cancel(reason) { | ||
| console.warn("WorkflowRunOutput.cancel() is deprecated. Use fullStream.cancel() instead."); | ||
| return this.fullStream.cancel(reason); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.getReader()` instead | ||
| */ | ||
| getReader(options) { | ||
| console.warn("WorkflowRunOutput.getReader() is deprecated. Use fullStream.getReader() instead."); | ||
| return this.fullStream.getReader(options); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.pipeThrough()` instead | ||
| */ | ||
| pipeThrough(transform, options) { | ||
| console.warn("WorkflowRunOutput.pipeThrough() is deprecated. Use fullStream.pipeThrough() instead."); | ||
| return this.fullStream.pipeThrough(transform, options); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.pipeTo()` instead | ||
| */ | ||
| pipeTo(destination, options) { | ||
| console.warn("WorkflowRunOutput.pipeTo() is deprecated. Use fullStream.pipeTo() instead."); | ||
| return this.fullStream.pipeTo(destination, options); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream.tee()` instead | ||
| */ | ||
| tee() { | ||
| console.warn("WorkflowRunOutput.tee() is deprecated. Use fullStream.tee() instead."); | ||
| return this.fullStream.tee(); | ||
| } | ||
| /** | ||
| * @deprecated Use `fullStream[Symbol.asyncIterator]()` instead | ||
| */ | ||
| [Symbol.asyncIterator]() { | ||
| console.warn( | ||
| "WorkflowRunOutput[Symbol.asyncIterator]() is deprecated. Use fullStream[Symbol.asyncIterator]() instead." | ||
| ); | ||
| return this.fullStream[Symbol.asyncIterator](); | ||
| } | ||
| /** | ||
| * Helper method to treat this object as a ReadableStream | ||
| * @deprecated Use `fullStream` directly instead | ||
| */ | ||
| toReadableStream() { | ||
| console.warn("WorkflowRunOutput.toReadableStream() is deprecated. Use fullStream directly instead."); | ||
| return this.fullStream; | ||
| } | ||
| }; | ||
| // src/stream/aisdk/v5/transform.ts | ||
| function sanitizeToolCallInput(input) { | ||
| try { | ||
| JSON.parse(input); | ||
| return input; | ||
| } catch { | ||
| return input.replace(/[\s]*<\|[^|]*\|>[\s]*/g, "").trim(); | ||
| } | ||
| } | ||
| function tryRepairJson(input) { | ||
| let repaired = input.trim(); | ||
| repaired = repaired.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)"/g, (match, prefix, name) => { | ||
| if (prefix.trimEnd().endsWith('"')) { | ||
| return match; | ||
| } | ||
| return `${prefix}"${name}"`; | ||
| }); | ||
| repaired = repaired.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g, '$1"$2":'); | ||
| repaired = repaired.replace(/'/g, '"'); | ||
| repaired = repaired.replace(/,(\s*[}\]])/g, "$1"); | ||
| repaired = repaired.replace(/:\s*(\d{4}-\d{2}-\d{2}(?:T[\d:]+)?)\s*([,}])/g, ': "$1"$2'); | ||
| try { | ||
| return JSON.parse(repaired); | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
| function convertFullStreamChunkToMastra(value, ctx) { | ||
| switch (value.type) { | ||
| case "response-metadata": | ||
| return { | ||
| type: "response-metadata", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { ...value } | ||
| }; | ||
| case "text-start": | ||
| return { | ||
| type: "text-start", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "text-delta": | ||
| if (value.delta) { | ||
| return { | ||
| type: "text-delta", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata, | ||
| text: value.delta | ||
| } | ||
| }; | ||
| } | ||
| return; | ||
| case "text-end": | ||
| return { | ||
| type: "text-end", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: value | ||
| }; | ||
| case "reasoning-start": | ||
| return { | ||
| type: "reasoning-start", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "reasoning-delta": | ||
| return { | ||
| type: "reasoning-delta", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata, | ||
| text: value.delta | ||
| } | ||
| }; | ||
| case "reasoning-end": | ||
| return { | ||
| type: "reasoning-end", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "source": | ||
| return { | ||
| type: "source", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| id: value.id, | ||
| sourceType: value.sourceType, | ||
| title: value.title || "", | ||
| mimeType: value.sourceType === "document" ? value.mediaType : void 0, | ||
| filename: value.sourceType === "document" ? value.filename : void 0, | ||
| url: value.sourceType === "url" ? value.url : void 0, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "file": { | ||
| const pm = value.providerMetadata; | ||
| return { | ||
| type: "file", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| data: value.data, | ||
| base64: typeof value.data === "string" ? value.data : void 0, | ||
| mimeType: value.mediaType, | ||
| ...pm != null ? { providerMetadata: pm } : {} | ||
| } | ||
| }; | ||
| } | ||
| case "tool-call": { | ||
| let toolCallInput = void 0; | ||
| if (value.input) { | ||
| const sanitized = sanitizeToolCallInput(value.input); | ||
| if (sanitized) { | ||
| try { | ||
| toolCallInput = JSON.parse(sanitized); | ||
| } catch { | ||
| const repaired = tryRepairJson(sanitized); | ||
| if (repaired) { | ||
| toolCallInput = repaired; | ||
| } else { | ||
| console.error("Error converting tool call input to JSON", { | ||
| input: value.input | ||
| }); | ||
| toolCallInput = void 0; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return { | ||
| type: "tool-call", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.toolCallId, | ||
| toolName: value.toolName, | ||
| args: toolCallInput, | ||
| providerExecuted: value.providerExecuted, | ||
| providerMetadata: value.providerMetadata, | ||
| ...value.observability ? { observability: value.observability } : {} | ||
| } | ||
| }; | ||
| } | ||
| case "tool-result": | ||
| return { | ||
| type: "tool-result", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.toolCallId, | ||
| toolName: value.toolName, | ||
| result: value.result, | ||
| isError: value.isError, | ||
| providerExecuted: value.providerExecuted, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "tool-input-start": | ||
| return { | ||
| type: "tool-call-input-streaming-start", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.id, | ||
| toolName: value.toolName, | ||
| providerExecuted: value.providerExecuted, | ||
| providerMetadata: value.providerMetadata, | ||
| dynamic: value.dynamic, | ||
| ...value.observability ? { observability: value.observability } : {} | ||
| } | ||
| }; | ||
| case "tool-input-delta": | ||
| if (value.delta) { | ||
| return { | ||
| type: "tool-call-delta", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| argsTextDelta: value.delta, | ||
| toolCallId: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| } | ||
| return; | ||
| case "tool-input-end": | ||
| return { | ||
| type: "tool-call-input-streaming-end", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| toolCallId: value.id, | ||
| providerMetadata: value.providerMetadata | ||
| } | ||
| }; | ||
| case "finish": | ||
| const { finishReason, usage, providerMetadata, messages, ...rest } = value; | ||
| return { | ||
| type: "finish", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: { | ||
| providerMetadata: value.providerMetadata, | ||
| stepResult: { | ||
| reason: normalizeFinishReason(value.finishReason) | ||
| }, | ||
| output: { | ||
| // Normalize usage to handle both V2 (flat) and V3 (nested) formats | ||
| usage: normalizeUsage(value.usage) | ||
| }, | ||
| metadata: { | ||
| providerMetadata: value.providerMetadata | ||
| }, | ||
| messages: messages ?? { | ||
| all: [], | ||
| user: [], | ||
| nonUser: [] | ||
| }, | ||
| ...rest | ||
| } | ||
| }; | ||
| case "error": | ||
| return { | ||
| type: "error", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: value | ||
| }; | ||
| case "raw": | ||
| return { | ||
| type: "raw", | ||
| runId: ctx.runId, | ||
| from: "AGENT" /* AGENT */, | ||
| payload: value.rawValue | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| function convertMastraChunkToAISDKv5({ | ||
| chunk, | ||
| mode = "stream" | ||
| }) { | ||
| switch (chunk.type) { | ||
| case "start": | ||
| return { | ||
| type: "start" | ||
| }; | ||
| case "step-start": | ||
| const { messageId: _messageId, ...rest } = chunk.payload; | ||
| return { | ||
| type: "start-step", | ||
| request: rest.request, | ||
| warnings: rest.warnings || [] | ||
| }; | ||
| case "raw": | ||
| return { | ||
| type: "raw", | ||
| rawValue: chunk.payload | ||
| }; | ||
| case "finish": { | ||
| return { | ||
| type: "finish", | ||
| // Cast needed: Mastra extends reason with 'tripwire' | 'retry' for processor scenarios | ||
| finishReason: chunk.payload.stepResult.reason, | ||
| // Cast needed: Mastra's LanguageModelUsage has optional properties, V2 has required-but-nullable | ||
| totalUsage: chunk.payload.output.usage | ||
| }; | ||
| } | ||
| case "reasoning-start": | ||
| return { | ||
| type: "reasoning-start", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "reasoning-delta": | ||
| return { | ||
| type: "reasoning-delta", | ||
| id: chunk.payload.id, | ||
| text: chunk.payload.text, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "reasoning-signature": | ||
| throw new Error('AISDKv5 chunk type "reasoning-signature" not supported'); | ||
| case "redacted-reasoning": | ||
| throw new Error('AISDKv5 chunk type "redacted-reasoning" not supported'); | ||
| case "reasoning-end": | ||
| return { | ||
| type: "reasoning-end", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "source": | ||
| if (chunk.payload.sourceType === "url") { | ||
| return { | ||
| type: "source", | ||
| sourceType: "url", | ||
| id: chunk.payload.id, | ||
| url: chunk.payload.url, | ||
| title: chunk.payload.title, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| } else { | ||
| return { | ||
| type: "source", | ||
| sourceType: "document", | ||
| id: chunk.payload.id, | ||
| mediaType: chunk.payload.mimeType, | ||
| title: chunk.payload.title, | ||
| filename: chunk.payload.filename, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| } | ||
| case "file": { | ||
| const filePart = mode === "generate" ? { | ||
| type: "file", | ||
| file: new DefaultGeneratedFile({ | ||
| data: chunk.payload.data, | ||
| mediaType: chunk.payload.mimeType | ||
| }) | ||
| } : { | ||
| type: "file", | ||
| file: new DefaultGeneratedFileWithType({ | ||
| data: chunk.payload.data, | ||
| mediaType: chunk.payload.mimeType | ||
| }) | ||
| }; | ||
| if (chunk.payload.providerMetadata) { | ||
| filePart.providerMetadata = chunk.payload.providerMetadata; | ||
| } | ||
| return filePart; | ||
| } | ||
| case "tool-call": { | ||
| const toolCallPart = { | ||
| type: "tool-call", | ||
| toolCallId: chunk.payload.toolCallId, | ||
| providerMetadata: chunk.payload.providerMetadata, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| toolName: chunk.payload.toolName, | ||
| input: chunk.payload.args | ||
| }; | ||
| if (chunk.payload.observability) { | ||
| toolCallPart.observability = chunk.payload.observability; | ||
| } | ||
| return toolCallPart; | ||
| } | ||
| case "tool-call-input-streaming-start": | ||
| return { | ||
| type: "tool-input-start", | ||
| id: chunk.payload.toolCallId, | ||
| toolName: chunk.payload.toolName, | ||
| dynamic: !!chunk.payload.dynamic, | ||
| providerMetadata: chunk.payload.providerMetadata, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| ...chunk.payload.observability ? { observability: chunk.payload.observability } : {} | ||
| }; | ||
| case "tool-call-input-streaming-end": | ||
| return { | ||
| type: "tool-input-end", | ||
| id: chunk.payload.toolCallId, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "tool-call-delta": | ||
| return { | ||
| type: "tool-input-delta", | ||
| id: chunk.payload.toolCallId, | ||
| delta: chunk.payload.argsTextDelta, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "step-finish": { | ||
| const { request: _request, providerMetadata: metadataProviderMetadata, ...rest2 } = chunk.payload.metadata; | ||
| return { | ||
| type: "finish-step", | ||
| response: { | ||
| id: chunk.payload.id || "", | ||
| timestamp: /* @__PURE__ */ new Date(), | ||
| modelId: rest2.modelId || "", | ||
| ...rest2 | ||
| }, | ||
| usage: chunk.payload.output.usage, | ||
| finishReason: chunk.payload.stepResult.reason, | ||
| providerMetadata: metadataProviderMetadata ?? chunk.payload.providerMetadata | ||
| }; | ||
| } | ||
| case "text-delta": | ||
| return { | ||
| type: "text-delta", | ||
| id: chunk.payload.id, | ||
| text: chunk.payload.text, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "text-end": | ||
| return { | ||
| type: "text-end", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "text-start": | ||
| return { | ||
| type: "text-start", | ||
| id: chunk.payload.id, | ||
| providerMetadata: chunk.payload.providerMetadata | ||
| }; | ||
| case "tool-result": | ||
| return { | ||
| type: "tool-result", | ||
| input: chunk.payload.args, | ||
| toolCallId: chunk.payload.toolCallId, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| toolName: chunk.payload.toolName, | ||
| output: chunk.payload.result | ||
| // providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this? | ||
| }; | ||
| case "tool-error": | ||
| return { | ||
| type: "tool-error", | ||
| error: chunk.payload.error, | ||
| input: chunk.payload.args, | ||
| toolCallId: chunk.payload.toolCallId, | ||
| providerExecuted: chunk.payload.providerExecuted, | ||
| toolName: chunk.payload.toolName | ||
| // providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this? | ||
| }; | ||
| case "abort": | ||
| return { | ||
| type: "abort" | ||
| }; | ||
| case "error": | ||
| return { | ||
| type: "error", | ||
| error: chunk.payload.error | ||
| }; | ||
| case "object": | ||
| return { | ||
| type: "object", | ||
| object: chunk.object | ||
| }; | ||
| default: | ||
| if (chunk.type && "payload" in chunk && chunk.payload) { | ||
| return { | ||
| type: chunk.type, | ||
| ...chunk.payload || {} | ||
| }; | ||
| } | ||
| return; | ||
| } | ||
| } | ||
| function isV3Usage(usage) { | ||
| if (!usage || typeof usage !== "object") return false; | ||
| const u = usage; | ||
| return typeof u.inputTokens === "object" && u.inputTokens !== null && "total" in u.inputTokens && typeof u.outputTokens === "object" && u.outputTokens !== null && "total" in u.outputTokens; | ||
| } | ||
| function normalizeUsage(usage) { | ||
| if (!usage) { | ||
| return { | ||
| inputTokens: void 0, | ||
| outputTokens: void 0, | ||
| totalTokens: void 0, | ||
| reasoningTokens: void 0, | ||
| cachedInputTokens: void 0, | ||
| cacheCreationInputTokens: void 0, | ||
| raw: void 0 | ||
| }; | ||
| } | ||
| if (isV3Usage(usage)) { | ||
| const inputTokens = usage.inputTokens.total; | ||
| const outputTokens = usage.outputTokens.total; | ||
| return { | ||
| inputTokens, | ||
| outputTokens, | ||
| totalTokens: (inputTokens ?? 0) + (outputTokens ?? 0), | ||
| reasoningTokens: usage.outputTokens.reasoning, | ||
| cachedInputTokens: usage.inputTokens.cacheRead, | ||
| cacheCreationInputTokens: usage.inputTokens.cacheWrite, | ||
| raw: usage | ||
| }; | ||
| } | ||
| const v2Usage = usage; | ||
| return { | ||
| inputTokens: v2Usage.inputTokens, | ||
| outputTokens: v2Usage.outputTokens, | ||
| totalTokens: v2Usage.totalTokens ?? (v2Usage.inputTokens ?? 0) + (v2Usage.outputTokens ?? 0), | ||
| reasoningTokens: v2Usage.reasoningTokens, | ||
| cachedInputTokens: v2Usage.cachedInputTokens, | ||
| cacheCreationInputTokens: v2Usage.cacheCreationInputTokens, | ||
| raw: usage | ||
| }; | ||
| } | ||
| function isV3FinishReason(finishReason) { | ||
| return typeof finishReason === "object" && finishReason !== null && "unified" in finishReason; | ||
| } | ||
| function normalizeFinishReason(finishReason) { | ||
| if (!finishReason) { | ||
| return "other"; | ||
| } | ||
| if (finishReason === "tripwire" || finishReason === "retry") { | ||
| return finishReason; | ||
| } | ||
| if (isV3FinishReason(finishReason)) { | ||
| return finishReason.unified; | ||
| } | ||
| return finishReason === "unknown" ? "other" : finishReason; | ||
| } | ||
| // src/stream/caching-transform-stream.ts | ||
| function createCachingTransformStream(options) { | ||
| const { cache, cacheKey, serialize = (x) => x, deserialize = (x) => x } = options; | ||
| const transform = new TransformStream({ | ||
| transform(chunk, controller) { | ||
| const serialized = serialize(chunk); | ||
| cache.listPush(cacheKey, serialized).catch(() => { | ||
| }); | ||
| controller.enqueue(chunk); | ||
| } | ||
| }); | ||
| const getHistory = async (offset = 0) => { | ||
| const cached = await cache.listFromTo(cacheKey, offset); | ||
| return cached.map((item) => deserialize(item)); | ||
| }; | ||
| const clearCache = async () => { | ||
| await cache.delete(cacheKey); | ||
| }; | ||
| return { transform, getHistory, clearCache }; | ||
| } | ||
| function createReplayStream(options) { | ||
| const { history, liveSource, cache, cacheKey, serialize = (x) => x } = options; | ||
| let historyIndex = 0; | ||
| let liveReader = null; | ||
| let historyComplete = false; | ||
| return new ReadableStream({ | ||
| async pull(controller) { | ||
| if (!historyComplete) { | ||
| if (historyIndex < history.length) { | ||
| controller.enqueue(history[historyIndex]); | ||
| historyIndex++; | ||
| return; | ||
| } | ||
| historyComplete = true; | ||
| liveReader = liveSource.getReader(); | ||
| } | ||
| if (liveReader) { | ||
| try { | ||
| const { done, value } = await liveReader.read(); | ||
| if (done) { | ||
| controller.close(); | ||
| return; | ||
| } | ||
| if (cache && cacheKey) { | ||
| const serialized = serialize(value); | ||
| cache.listPush(cacheKey, serialized).catch(() => { | ||
| }); | ||
| } | ||
| controller.enqueue(value); | ||
| } catch (error) { | ||
| controller.error(error); | ||
| } | ||
| } | ||
| }, | ||
| cancel() { | ||
| if (liveReader) { | ||
| void liveReader.cancel(); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| function withStreamCaching(options) { | ||
| const { cache, cacheKey, serialize, deserialize } = options; | ||
| return { | ||
| pipeThrough: () => { | ||
| const { transform } = createCachingTransformStream({ cache, cacheKey, serialize, deserialize }); | ||
| return transform; | ||
| }, | ||
| getHistory: async (offset = 0) => { | ||
| const deserializeFn = deserialize ?? ((x) => x); | ||
| const cached = await cache.listFromTo(cacheKey, offset); | ||
| return cached.map((item) => deserializeFn(item)); | ||
| }, | ||
| clearCache: async () => { | ||
| await cache.delete(cacheKey); | ||
| } | ||
| }; | ||
| } | ||
| export { MastraAgentNetworkStream, WorkflowRunOutput, convertFullStreamChunkToMastra, convertFullStreamChunkToUIMessageStream, convertMastraChunkToAISDKv5, createCachingTransformStream, createReplayStream, withStreamCaching }; | ||
| //# sourceMappingURL=chunk-OP6KXMTE.js.map | ||
| //# sourceMappingURL=chunk-OP6KXMTE.js.map |
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('./chunk-GSWZYCY4.cjs'); | ||
| // src/signals/task-signal-provider.ts | ||
| var TaskSignalProvider = class extends chunkGSWZYCY4_cjs.SignalProvider { | ||
| id = "task-signals"; | ||
| #processor = new chunkGSWZYCY4_cjs.TaskStateProcessor(); | ||
| getInputProcessors() { | ||
| return [this.#processor]; | ||
| } | ||
| getTools() { | ||
| return { | ||
| task_write: chunkGSWZYCY4_cjs.taskWriteTool, | ||
| task_update: chunkGSWZYCY4_cjs.taskUpdateTool, | ||
| task_complete: chunkGSWZYCY4_cjs.taskCompleteTool, | ||
| task_check: chunkGSWZYCY4_cjs.taskCheckTool | ||
| }; | ||
| } | ||
| }; | ||
| exports.TaskSignalProvider = TaskSignalProvider; | ||
| //# sourceMappingURL=chunk-ORIBHWNH.cjs.map | ||
| //# sourceMappingURL=chunk-ORIBHWNH.cjs.map |
| {"version":3,"sources":["../src/signals/task-signal-provider.ts"],"names":["SignalProvider","TaskStateProcessor","taskWriteTool","taskUpdateTool","taskCompleteTool","taskCheckTool"],"mappings":";;;;;AA0CO,IAAM,kBAAA,GAAN,cAAiCA,gCAAA,CAA+B;AAAA,EAC5D,EAAA,GAAK,cAAA;AAAA,EAEL,UAAA,GAAa,IAAIC,oCAAA,EAAmB;AAAA,EAE7C,kBAAA,GAAiD;AAC/C,IAAA,OAAO,CAAC,KAAK,UAAU,CAAA;AAAA,EACzB;AAAA,EAEA,QAAA,GAAW;AACT,IAAA,OAAO;AAAA,MACL,UAAA,EAAYC,+BAAA;AAAA,MACZ,WAAA,EAAaC,gCAAA;AAAA,MACb,aAAA,EAAeC,kCAAA;AAAA,MACf,UAAA,EAAYC;AAAA,KACd;AAAA,EACF;AACF","file":"chunk-ORIBHWNH.cjs","sourcesContent":["import type { InputProcessorOrWorkflow } from '../processors';\nimport { TaskStateProcessor } from '../tools/builtin/task-state-processor';\nimport { taskCheckTool, taskCompleteTool, taskUpdateTool, taskWriteTool } from '../tools/builtin/task-tools';\n\nimport { SignalProvider } from './signal-provider';\n\n/**\n * Bundles the built-in task tools and the {@link TaskStateProcessor} behind a\n * single agent registration.\n *\n * The task list is held in the thread-scoped `tasks` storage domain (the\n * TaskStore) and projected onto the agent state-signal lane by\n * `TaskStateProcessor`. Wiring task tracking by hand means registering all four\n * task tools **and** the processor, and keeping them in sync — forget the\n * processor and the tools work for a single turn but silently lose the list\n * across turns. This provider wires both together so that cannot happen.\n *\n * Task tracking requires a memory-backed thread (`threadId` + `resourceId`) and\n * a Mastra `storage` instance (the `tasks` domain is always wired in-memory by\n * default). Without memory the tools no-op and report that task tracking\n * requires agent memory.\n *\n * @example\n * ```ts\n * import { Agent } from '@mastra/core/agent';\n * import { TaskSignalProvider } from '@mastra/core/signals';\n *\n * const agent = new Agent({\n * name: 'coder',\n * instructions: '...',\n * model,\n * memory,\n * signals: [new TaskSignalProvider()],\n * });\n * ```\n *\n * The Agent automatically merges the tools into its toolset and registers the\n * processor on its input-processor chain (which propagates the Mastra instance\n * so the processor can resolve the TaskStore).\n *\n * @experimental Agent signals are experimental and may change in a future release.\n */\nexport class TaskSignalProvider extends SignalProvider<'task-signals'> {\n readonly id = 'task-signals';\n\n readonly #processor = new TaskStateProcessor();\n\n getInputProcessors(): InputProcessorOrWorkflow[] {\n return [this.#processor];\n }\n\n getTools() {\n return {\n task_write: taskWriteTool,\n task_update: taskUpdateTool,\n task_complete: taskCompleteTool,\n task_check: taskCheckTool,\n };\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { MastraModelGateway, createOpenAICompatible, MASTRA_USER_AGENT, createAnthropic, createGoogleGenerativeAI, createOpenAI } from './chunk-XM3ZHT2Q.js'; | ||
| import { InMemoryServerCache } from './chunk-366PLPDH.js'; | ||
| import { MastraError } from './chunk-M7RBQNFP.js'; | ||
| // src/llm/model/gateways/netlify.ts | ||
| var NetlifyGateway = class extends MastraModelGateway { | ||
| id = "netlify"; | ||
| name = "Netlify AI Gateway"; | ||
| tokenCache = new InMemoryServerCache(); | ||
| async fetchProviders() { | ||
| const response = await fetch("https://api.netlify.com/api/v1/ai-gateway/providers"); | ||
| if (!response.ok) { | ||
| throw new Error(`Failed to fetch from Netlify: ${response.statusText}`); | ||
| } | ||
| const data = await response.json(); | ||
| const config = { | ||
| apiKeyEnvVar: ["NETLIFY_TOKEN", "NETLIFY_SITE_ID"], | ||
| apiKeyHeader: "Authorization", | ||
| name: `Netlify`, | ||
| gateway: `netlify`, | ||
| models: [], | ||
| docUrl: "https://docs.netlify.com/build/ai-gateway/overview/" | ||
| }; | ||
| for (const [providerId, provider] of Object.entries(data.providers)) { | ||
| for (const model of provider.models) { | ||
| config.models.push(`${providerId}/${model}`); | ||
| } | ||
| } | ||
| return { netlify: config }; | ||
| } | ||
| async buildUrl(routerId, envVars) { | ||
| const siteId = envVars?.["NETLIFY_SITE_ID"] || process.env["NETLIFY_SITE_ID"]; | ||
| const netlifyToken = envVars?.["NETLIFY_TOKEN"] || process.env["NETLIFY_TOKEN"]; | ||
| if (!netlifyToken) { | ||
| throw new MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_TOKEN", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_TOKEN environment variable required for model: ${routerId}` | ||
| }); | ||
| } | ||
| if (!siteId) { | ||
| throw new MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_SITE_ID", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_SITE_ID environment variable required for model: ${routerId}` | ||
| }); | ||
| } | ||
| try { | ||
| const tokenData = await this.getOrFetchToken(siteId, netlifyToken); | ||
| return tokenData.url.endsWith(`/`) ? tokenData.url.substring(0, tokenData.url.length - 1) : tokenData.url; | ||
| } catch (error) { | ||
| throw new MastraError({ | ||
| id: "NETLIFY_GATEWAY_TOKEN_ERROR", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Failed to get Netlify AI Gateway token for model ${routerId}: ${error instanceof Error ? error.message : String(error)}` | ||
| }); | ||
| } | ||
| } | ||
| /** | ||
| * Get cached token or fetch a new site-specific AI Gateway token from Netlify | ||
| */ | ||
| async getOrFetchToken(siteId, netlifyToken) { | ||
| const cacheKey = `netlify-token:${siteId}:${netlifyToken}`; | ||
| const cached = await this.tokenCache.get(cacheKey); | ||
| if (cached && cached.expiresAt > Date.now() / 1e3 + 60) { | ||
| return { token: cached.token, url: cached.url }; | ||
| } | ||
| const response = await fetch(`https://api.netlify.com/api/v1/sites/${siteId}/ai-gateway/token`, { | ||
| method: "GET", | ||
| headers: { | ||
| Authorization: `Bearer ${netlifyToken}` | ||
| } | ||
| }); | ||
| if (!response.ok) { | ||
| const error = await response.text(); | ||
| throw new Error(`Failed to get Netlify AI Gateway token: ${response.status} ${error}`); | ||
| } | ||
| const tokenResponse = await response.json(); | ||
| await this.tokenCache.set(cacheKey, { | ||
| token: tokenResponse.token, | ||
| url: tokenResponse.url, | ||
| expiresAt: tokenResponse.expires_at | ||
| }); | ||
| return { token: tokenResponse.token, url: tokenResponse.url }; | ||
| } | ||
| /** | ||
| * Get cached token or fetch a new site-specific AI Gateway token from Netlify | ||
| */ | ||
| async getApiKey(modelId) { | ||
| const siteId = process.env["NETLIFY_SITE_ID"]; | ||
| const netlifyToken = process.env["NETLIFY_TOKEN"]; | ||
| if (!netlifyToken) { | ||
| throw new MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_TOKEN", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_TOKEN environment variable required for model: ${modelId}` | ||
| }); | ||
| } | ||
| if (!siteId) { | ||
| throw new MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_SITE_ID", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_SITE_ID environment variable required for model: ${modelId}` | ||
| }); | ||
| } | ||
| try { | ||
| return (await this.getOrFetchToken(siteId, netlifyToken)).token; | ||
| } catch (error) { | ||
| throw new MastraError({ | ||
| id: "NETLIFY_GATEWAY_TOKEN_ERROR", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Failed to get Netlify AI Gateway token for model ${modelId}: ${error instanceof Error ? error.message : String(error)}` | ||
| }); | ||
| } | ||
| } | ||
| async resolveLanguageModel({ | ||
| modelId, | ||
| providerId, | ||
| apiKey, | ||
| headers | ||
| }) { | ||
| const baseURL = await this.buildUrl(`${providerId}/${modelId}`); | ||
| const mastraHeaders = { "User-Agent": MASTRA_USER_AGENT, ...headers }; | ||
| switch (providerId) { | ||
| case "openai": | ||
| return createOpenAI({ apiKey, baseURL, headers: mastraHeaders }).responses(modelId); | ||
| case "gemini": | ||
| return createGoogleGenerativeAI({ | ||
| baseURL: `${baseURL}/v1beta/`, | ||
| apiKey, | ||
| headers: { | ||
| "user-agent": "google-genai-sdk/", | ||
| ...mastraHeaders | ||
| } | ||
| }).chat(modelId); | ||
| case "anthropic": | ||
| return createAnthropic({ | ||
| apiKey, | ||
| baseURL: `${baseURL}/v1/`, | ||
| headers: { | ||
| "anthropic-version": "2023-06-01", | ||
| ...mastraHeaders | ||
| } | ||
| })(modelId); | ||
| default: | ||
| return createOpenAICompatible({ | ||
| name: providerId, | ||
| apiKey, | ||
| baseURL, | ||
| headers: mastraHeaders, | ||
| supportsStructuredOutputs: true | ||
| }).chatModel(modelId); | ||
| } | ||
| } | ||
| }; | ||
| export { NetlifyGateway }; | ||
| //# sourceMappingURL=chunk-RZKMXUCM.js.map | ||
| //# sourceMappingURL=chunk-RZKMXUCM.js.map |
| {"version":3,"sources":["../src/llm/model/gateways/netlify.ts"],"names":[],"mappings":";;;;;AAoCO,IAAM,cAAA,GAAN,cAA6B,kBAAA,CAAmB;AAAA,EAC5C,EAAA,GAAK,SAAA;AAAA,EACL,IAAA,GAAO,oBAAA;AAAA,EACR,UAAA,GAAa,IAAI,mBAAA,EAAoB;AAAA,EAE7C,MAAM,cAAA,GAA0D;AAC9D,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,qDAAqD,CAAA;AAClF,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,IACxE;AACA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,MAAM,MAAA,GAAyB;AAAA,MAC7B,YAAA,EAAc,CAAC,eAAA,EAAiB,iBAAiB,CAAA;AAAA,MACjD,YAAA,EAAc,eAAA;AAAA,MACd,IAAA,EAAM,CAAA,OAAA,CAAA;AAAA,MACN,OAAA,EAAS,CAAA,OAAA,CAAA;AAAA,MACT,QAAQ,EAAC;AAAA,MACT,MAAA,EAAQ;AAAA,KACV;AAEA,IAAA,KAAA,MAAW,CAAC,YAAY,QAAQ,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,SAAS,CAAA,EAAG;AACnE,MAAA,KAAA,MAAW,KAAA,IAAS,SAAS,MAAA,EAAQ;AACnC,QAAA,MAAA,CAAO,OAAO,IAAA,CAAK,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,KAAK,CAAA,CAAE,CAAA;AAAA,MAC7C;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,SAAS,MAAA,EAAO;AAAA,EAC3B;AAAA,EAEA,MAAM,QAAA,CAAS,QAAA,EAAkB,OAAA,EAA+C;AAE9E,IAAA,MAAM,SAAS,OAAA,GAAU,iBAAiB,CAAA,IAAK,OAAA,CAAQ,IAAI,iBAAiB,CAAA;AAC5E,IAAA,MAAM,eAAe,OAAA,GAAU,eAAe,CAAA,IAAK,OAAA,CAAQ,IAAI,eAAe,CAAA;AAE9E,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,EAAA,EAAI,0BAAA;AAAA,QACJ,MAAA,EAAQ,KAAA;AAAA,QACR,QAAA,EAAU,SAAA;AAAA,QACV,IAAA,EAAM,kEAAkE,QAAQ,CAAA;AAAA,OACjF,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,EAAA,EAAI,4BAAA;AAAA,QACJ,MAAA,EAAQ,KAAA;AAAA,QACR,QAAA,EAAU,SAAA;AAAA,QACV,IAAA,EAAM,oEAAoE,QAAQ,CAAA;AAAA,OACnF,CAAA;AAAA,IACH;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,eAAA,CAAgB,QAAQ,YAAY,CAAA;AACjE,MAAA,OAAO,SAAA,CAAU,GAAA,CAAI,QAAA,CAAS,CAAA,CAAA,CAAG,IAAI,SAAA,CAAU,GAAA,CAAI,SAAA,CAAU,CAAA,EAAG,SAAA,CAAU,GAAA,CAAI,MAAA,GAAS,CAAC,IAAI,SAAA,CAAU,GAAA;AAAA,IACxG,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,EAAA,EAAI,6BAAA;AAAA,QACJ,MAAA,EAAQ,KAAA;AAAA,QACR,QAAA,EAAU,SAAA;AAAA,QACV,IAAA,EAAM,CAAA,iDAAA,EAAoD,QAAQ,CAAA,EAAA,EAAK,KAAA,YAAiB,QAAQ,KAAA,CAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,OAC9H,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAA,CAAgB,MAAA,EAAgB,YAAA,EAA0C;AACtF,IAAA,MAAM,QAAA,GAAW,CAAA,cAAA,EAAiB,MAAM,CAAA,CAAA,EAAI,YAAY,CAAA,CAAA;AAGxD,IAAA,MAAM,MAAA,GAAU,MAAM,IAAA,CAAK,UAAA,CAAW,IAAI,QAAQ,CAAA;AAClD,IAAA,IAAI,UAAU,MAAA,CAAO,SAAA,GAAY,KAAK,GAAA,EAAI,GAAI,MAAO,EAAA,EAAI;AAEvD,MAAA,OAAO,EAAE,KAAA,EAAO,MAAA,CAAO,KAAA,EAAO,GAAA,EAAK,OAAO,GAAA,EAAI;AAAA,IAChD;AAGA,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,CAAA,qCAAA,EAAwC,MAAM,CAAA,iBAAA,CAAA,EAAqB;AAAA,MAC9F,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,aAAA,EAAe,UAAU,YAAY,CAAA;AAAA;AACvC,KACD,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wCAAA,EAA2C,SAAS,MAAM,CAAA,CAAA,EAAI,KAAK,CAAA,CAAE,CAAA;AAAA,IACvF;AAEA,IAAA,MAAM,aAAA,GAAiB,MAAM,QAAA,CAAS,IAAA,EAAK;AAG3C,IAAA,MAAM,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAA,EAAU;AAAA,MAClC,OAAO,aAAA,CAAc,KAAA;AAAA,MACrB,KAAK,aAAA,CAAc,GAAA;AAAA,MACnB,WAAW,aAAA,CAAc;AAAA,KAC1B,CAAA;AAED,IAAA,OAAO,EAAE,KAAA,EAAO,aAAA,CAAc,KAAA,EAAO,GAAA,EAAK,cAAc,GAAA,EAAI;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,OAAA,EAAkC;AAChD,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,iBAAiB,CAAA;AAC5C,IAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,GAAA,CAAI,eAAe,CAAA;AAEhD,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,EAAA,EAAI,0BAAA;AAAA,QACJ,MAAA,EAAQ,KAAA;AAAA,QACR,QAAA,EAAU,SAAA;AAAA,QACV,IAAA,EAAM,kEAAkE,OAAO,CAAA;AAAA,OAChF,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,EAAA,EAAI,4BAAA;AAAA,QACJ,MAAA,EAAQ,KAAA;AAAA,QACR,QAAA,EAAU,SAAA;AAAA,QACV,IAAA,EAAM,oEAAoE,OAAO,CAAA;AAAA,OAClF,CAAA;AAAA,IACH;AAEA,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,MAAM,IAAA,CAAK,eAAA,CAAgB,MAAA,EAAQ,YAAY,CAAA,EAAG,KAAA;AAAA,IAC5D,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,EAAA,EAAI,6BAAA;AAAA,QACJ,MAAA,EAAQ,KAAA;AAAA,QACR,QAAA,EAAU,SAAA;AAAA,QACV,IAAA,EAAM,CAAA,iDAAA,EAAoD,OAAO,CAAA,EAAA,EAAK,KAAA,YAAiB,QAAQ,KAAA,CAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,OAC7H,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,oBAAA,CAAqB;AAAA,IACzB,OAAA;AAAA,IACA,UAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF,EAKkC;AAChC,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,QAAA,CAAS,GAAG,UAAU,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAA;AAE9D,IAAA,MAAM,aAAA,GAAgB,EAAE,YAAA,EAAc,iBAAA,EAAmB,GAAG,OAAA,EAAQ;AAEpE,IAAA,QAAQ,UAAA;AAAY,MAClB,KAAK,QAAA;AACH,QAAA,OAAO,YAAA,CAAa,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAS,aAAA,EAAe,CAAA,CAAE,SAAA,CAAU,OAAO,CAAA;AAAA,MACpF,KAAK,QAAA;AACH,QAAA,OAAO,wBAAA,CAAyB;AAAA,UAC9B,OAAA,EAAS,GAAG,OAAO,CAAA,QAAA,CAAA;AAAA,UACnB,MAAA;AAAA,UACA,OAAA,EAAS;AAAA,YACP,YAAA,EAAc,mBAAA;AAAA,YACd,GAAG;AAAA;AACL,SACD,CAAA,CAAE,IAAA,CAAK,OAAO,CAAA;AAAA,MACjB,KAAK,WAAA;AACH,QAAA,OAAO,eAAA,CAAgB;AAAA,UACrB,MAAA;AAAA,UACA,OAAA,EAAS,GAAG,OAAO,CAAA,IAAA,CAAA;AAAA,UACnB,OAAA,EAAS;AAAA,YACP,mBAAA,EAAqB,YAAA;AAAA,YACrB,GAAG;AAAA;AACL,SACD,EAAE,OAAO,CAAA;AAAA,MACZ;AACE,QAAA,OAAO,sBAAA,CAAuB;AAAA,UAC5B,IAAA,EAAM,UAAA;AAAA,UACN,MAAA;AAAA,UACA,OAAA;AAAA,UACA,OAAA,EAAS,aAAA;AAAA,UACT,yBAAA,EAA2B;AAAA,SAC5B,CAAA,CAAE,SAAA,CAAU,OAAO,CAAA;AAAA;AACxB,EACF;AACF","file":"chunk-RZKMXUCM.js","sourcesContent":["import { createAnthropic } from '@ai-sdk/anthropic-v6';\nimport { createGoogleGenerativeAI } from '@ai-sdk/google-v6';\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible-v5';\nimport { createOpenAI } from '@ai-sdk/openai-v6';\nimport { InMemoryServerCache } from '../../../cache/inmemory.js';\nimport { MastraError } from '../../../error/index.js';\nimport { MastraModelGateway } from './base.js';\nimport type { ProviderConfig, GatewayLanguageModel } from './base.js';\nimport { MASTRA_USER_AGENT } from './constants.js';\n\ninterface NetlifyProviderResponse {\n token_env_var: string;\n url_env_var: string;\n models: string[];\n}\ninterface NetlifyResponse {\n providers: Record<string, NetlifyProviderResponse>;\n}\n\ninterface NetlifyTokenResponse {\n token: string;\n url: string;\n expires_at: number;\n}\n\ninterface CachedToken {\n token: string;\n url: string;\n expiresAt: number;\n}\n\ninterface TokenData {\n token: string;\n url: string;\n}\n\nexport class NetlifyGateway extends MastraModelGateway {\n readonly id = 'netlify';\n readonly name = 'Netlify AI Gateway';\n private tokenCache = new InMemoryServerCache();\n\n async fetchProviders(): Promise<Record<string, ProviderConfig>> {\n const response = await fetch('https://api.netlify.com/api/v1/ai-gateway/providers');\n if (!response.ok) {\n throw new Error(`Failed to fetch from Netlify: ${response.statusText}`);\n }\n const data = (await response.json()) as NetlifyResponse;\n const config: ProviderConfig = {\n apiKeyEnvVar: ['NETLIFY_TOKEN', 'NETLIFY_SITE_ID'],\n apiKeyHeader: 'Authorization',\n name: `Netlify`,\n gateway: `netlify`,\n models: [],\n docUrl: 'https://docs.netlify.com/build/ai-gateway/overview/',\n };\n // Convert Netlify format to our standard format\n for (const [providerId, provider] of Object.entries(data.providers)) {\n for (const model of provider.models) {\n config.models.push(`${providerId}/${model}`);\n }\n }\n // Return with gateway ID as key - registry generator will detect this and avoid doubling the prefix\n return { netlify: config };\n }\n\n async buildUrl(routerId: string, envVars?: typeof process.env): Promise<string> {\n // Check for Netlify site ID first (for token exchange)\n const siteId = envVars?.['NETLIFY_SITE_ID'] || process.env['NETLIFY_SITE_ID'];\n const netlifyToken = envVars?.['NETLIFY_TOKEN'] || process.env['NETLIFY_TOKEN'];\n\n if (!netlifyToken) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_TOKEN',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_TOKEN environment variable required for model: ${routerId}`,\n });\n }\n\n if (!siteId) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_SITE_ID',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_SITE_ID environment variable required for model: ${routerId}`,\n });\n }\n\n try {\n const tokenData = await this.getOrFetchToken(siteId, netlifyToken);\n return tokenData.url.endsWith(`/`) ? tokenData.url.substring(0, tokenData.url.length - 1) : tokenData.url;\n } catch (error) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_TOKEN_ERROR',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Failed to get Netlify AI Gateway token for model ${routerId}: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n\n /**\n * Get cached token or fetch a new site-specific AI Gateway token from Netlify\n */\n private async getOrFetchToken(siteId: string, netlifyToken: string): Promise<TokenData> {\n const cacheKey = `netlify-token:${siteId}:${netlifyToken}`;\n\n // Check cache first\n const cached = (await this.tokenCache.get(cacheKey)) as CachedToken | undefined;\n if (cached && cached.expiresAt > Date.now() / 1000 + 60) {\n // Return cached token if it won't expire in the next minute\n return { token: cached.token, url: cached.url };\n }\n\n // Fetch new token\n const response = await fetch(`https://api.netlify.com/api/v1/sites/${siteId}/ai-gateway/token`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${netlifyToken}`,\n },\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Failed to get Netlify AI Gateway token: ${response.status} ${error}`);\n }\n\n const tokenResponse = (await response.json()) as NetlifyTokenResponse;\n\n // Cache the token - InMemoryServerCache will handle the TTL\n await this.tokenCache.set(cacheKey, {\n token: tokenResponse.token,\n url: tokenResponse.url,\n expiresAt: tokenResponse.expires_at,\n });\n\n return { token: tokenResponse.token, url: tokenResponse.url };\n }\n\n /**\n * Get cached token or fetch a new site-specific AI Gateway token from Netlify\n */\n async getApiKey(modelId: string): Promise<string> {\n const siteId = process.env['NETLIFY_SITE_ID'];\n const netlifyToken = process.env['NETLIFY_TOKEN'];\n\n if (!netlifyToken) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_TOKEN',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_TOKEN environment variable required for model: ${modelId}`,\n });\n }\n\n if (!siteId) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_SITE_ID',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_SITE_ID environment variable required for model: ${modelId}`,\n });\n }\n\n try {\n return (await this.getOrFetchToken(siteId, netlifyToken)).token;\n } catch (error) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_TOKEN_ERROR',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Failed to get Netlify AI Gateway token for model ${modelId}: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n\n async resolveLanguageModel({\n modelId,\n providerId,\n apiKey,\n headers,\n }: {\n modelId: string;\n providerId: string;\n apiKey: string;\n headers?: Record<string, string>;\n }): Promise<GatewayLanguageModel> {\n const baseURL = await this.buildUrl(`${providerId}/${modelId}`);\n\n const mastraHeaders = { 'User-Agent': MASTRA_USER_AGENT, ...headers };\n\n switch (providerId) {\n case 'openai':\n return createOpenAI({ apiKey, baseURL, headers: mastraHeaders }).responses(modelId);\n case 'gemini':\n return createGoogleGenerativeAI({\n baseURL: `${baseURL}/v1beta/`,\n apiKey,\n headers: {\n 'user-agent': 'google-genai-sdk/',\n ...mastraHeaders,\n },\n }).chat(modelId);\n case 'anthropic':\n return createAnthropic({\n apiKey,\n baseURL: `${baseURL}/v1/`,\n headers: {\n 'anthropic-version': '2023-06-01',\n ...mastraHeaders,\n },\n })(modelId);\n default:\n return createOpenAICompatible({\n name: providerId,\n apiKey,\n baseURL,\n headers: mastraHeaders,\n supportsStructuredOutputs: true,\n }).chatModel(modelId);\n }\n }\n}\n"]} |
| 'use strict'; | ||
| var chunk6OAFM3KL_cjs = require('./chunk-6OAFM3KL.cjs'); | ||
| var chunk6QR4RQID_cjs = require('./chunk-6QR4RQID.cjs'); | ||
| var chunkXSOONORA_cjs = require('./chunk-XSOONORA.cjs'); | ||
| // src/llm/model/gateways/netlify.ts | ||
| var NetlifyGateway = class extends chunk6OAFM3KL_cjs.MastraModelGateway { | ||
| id = "netlify"; | ||
| name = "Netlify AI Gateway"; | ||
| tokenCache = new chunk6QR4RQID_cjs.InMemoryServerCache(); | ||
| async fetchProviders() { | ||
| const response = await fetch("https://api.netlify.com/api/v1/ai-gateway/providers"); | ||
| if (!response.ok) { | ||
| throw new Error(`Failed to fetch from Netlify: ${response.statusText}`); | ||
| } | ||
| const data = await response.json(); | ||
| const config = { | ||
| apiKeyEnvVar: ["NETLIFY_TOKEN", "NETLIFY_SITE_ID"], | ||
| apiKeyHeader: "Authorization", | ||
| name: `Netlify`, | ||
| gateway: `netlify`, | ||
| models: [], | ||
| docUrl: "https://docs.netlify.com/build/ai-gateway/overview/" | ||
| }; | ||
| for (const [providerId, provider] of Object.entries(data.providers)) { | ||
| for (const model of provider.models) { | ||
| config.models.push(`${providerId}/${model}`); | ||
| } | ||
| } | ||
| return { netlify: config }; | ||
| } | ||
| async buildUrl(routerId, envVars) { | ||
| const siteId = envVars?.["NETLIFY_SITE_ID"] || process.env["NETLIFY_SITE_ID"]; | ||
| const netlifyToken = envVars?.["NETLIFY_TOKEN"] || process.env["NETLIFY_TOKEN"]; | ||
| if (!netlifyToken) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_TOKEN", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_TOKEN environment variable required for model: ${routerId}` | ||
| }); | ||
| } | ||
| if (!siteId) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_SITE_ID", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_SITE_ID environment variable required for model: ${routerId}` | ||
| }); | ||
| } | ||
| try { | ||
| const tokenData = await this.getOrFetchToken(siteId, netlifyToken); | ||
| return tokenData.url.endsWith(`/`) ? tokenData.url.substring(0, tokenData.url.length - 1) : tokenData.url; | ||
| } catch (error) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "NETLIFY_GATEWAY_TOKEN_ERROR", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Failed to get Netlify AI Gateway token for model ${routerId}: ${error instanceof Error ? error.message : String(error)}` | ||
| }); | ||
| } | ||
| } | ||
| /** | ||
| * Get cached token or fetch a new site-specific AI Gateway token from Netlify | ||
| */ | ||
| async getOrFetchToken(siteId, netlifyToken) { | ||
| const cacheKey = `netlify-token:${siteId}:${netlifyToken}`; | ||
| const cached = await this.tokenCache.get(cacheKey); | ||
| if (cached && cached.expiresAt > Date.now() / 1e3 + 60) { | ||
| return { token: cached.token, url: cached.url }; | ||
| } | ||
| const response = await fetch(`https://api.netlify.com/api/v1/sites/${siteId}/ai-gateway/token`, { | ||
| method: "GET", | ||
| headers: { | ||
| Authorization: `Bearer ${netlifyToken}` | ||
| } | ||
| }); | ||
| if (!response.ok) { | ||
| const error = await response.text(); | ||
| throw new Error(`Failed to get Netlify AI Gateway token: ${response.status} ${error}`); | ||
| } | ||
| const tokenResponse = await response.json(); | ||
| await this.tokenCache.set(cacheKey, { | ||
| token: tokenResponse.token, | ||
| url: tokenResponse.url, | ||
| expiresAt: tokenResponse.expires_at | ||
| }); | ||
| return { token: tokenResponse.token, url: tokenResponse.url }; | ||
| } | ||
| /** | ||
| * Get cached token or fetch a new site-specific AI Gateway token from Netlify | ||
| */ | ||
| async getApiKey(modelId) { | ||
| const siteId = process.env["NETLIFY_SITE_ID"]; | ||
| const netlifyToken = process.env["NETLIFY_TOKEN"]; | ||
| if (!netlifyToken) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_TOKEN", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_TOKEN environment variable required for model: ${modelId}` | ||
| }); | ||
| } | ||
| if (!siteId) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "NETLIFY_GATEWAY_NO_SITE_ID", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Missing NETLIFY_SITE_ID environment variable required for model: ${modelId}` | ||
| }); | ||
| } | ||
| try { | ||
| return (await this.getOrFetchToken(siteId, netlifyToken)).token; | ||
| } catch (error) { | ||
| throw new chunkXSOONORA_cjs.MastraError({ | ||
| id: "NETLIFY_GATEWAY_TOKEN_ERROR", | ||
| domain: "LLM", | ||
| category: "UNKNOWN", | ||
| text: `Failed to get Netlify AI Gateway token for model ${modelId}: ${error instanceof Error ? error.message : String(error)}` | ||
| }); | ||
| } | ||
| } | ||
| async resolveLanguageModel({ | ||
| modelId, | ||
| providerId, | ||
| apiKey, | ||
| headers | ||
| }) { | ||
| const baseURL = await this.buildUrl(`${providerId}/${modelId}`); | ||
| const mastraHeaders = { "User-Agent": chunk6OAFM3KL_cjs.MASTRA_USER_AGENT, ...headers }; | ||
| switch (providerId) { | ||
| case "openai": | ||
| return chunk6OAFM3KL_cjs.createOpenAI({ apiKey, baseURL, headers: mastraHeaders }).responses(modelId); | ||
| case "gemini": | ||
| return chunk6OAFM3KL_cjs.createGoogleGenerativeAI({ | ||
| baseURL: `${baseURL}/v1beta/`, | ||
| apiKey, | ||
| headers: { | ||
| "user-agent": "google-genai-sdk/", | ||
| ...mastraHeaders | ||
| } | ||
| }).chat(modelId); | ||
| case "anthropic": | ||
| return chunk6OAFM3KL_cjs.createAnthropic({ | ||
| apiKey, | ||
| baseURL: `${baseURL}/v1/`, | ||
| headers: { | ||
| "anthropic-version": "2023-06-01", | ||
| ...mastraHeaders | ||
| } | ||
| })(modelId); | ||
| default: | ||
| return chunk6OAFM3KL_cjs.createOpenAICompatible({ | ||
| name: providerId, | ||
| apiKey, | ||
| baseURL, | ||
| headers: mastraHeaders, | ||
| supportsStructuredOutputs: true | ||
| }).chatModel(modelId); | ||
| } | ||
| } | ||
| }; | ||
| exports.NetlifyGateway = NetlifyGateway; | ||
| //# sourceMappingURL=chunk-S5VPX3LQ.cjs.map | ||
| //# sourceMappingURL=chunk-S5VPX3LQ.cjs.map |
| {"version":3,"sources":["../src/llm/model/gateways/netlify.ts"],"names":["MastraModelGateway","InMemoryServerCache","MastraError","MASTRA_USER_AGENT","createOpenAI","createGoogleGenerativeAI","createAnthropic","createOpenAICompatible"],"mappings":"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","file":"chunk-S5VPX3LQ.cjs","sourcesContent":["import { createAnthropic } from '@ai-sdk/anthropic-v6';\nimport { createGoogleGenerativeAI } from '@ai-sdk/google-v6';\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible-v5';\nimport { createOpenAI } from '@ai-sdk/openai-v6';\nimport { InMemoryServerCache } from '../../../cache/inmemory.js';\nimport { MastraError } from '../../../error/index.js';\nimport { MastraModelGateway } from './base.js';\nimport type { ProviderConfig, GatewayLanguageModel } from './base.js';\nimport { MASTRA_USER_AGENT } from './constants.js';\n\ninterface NetlifyProviderResponse {\n token_env_var: string;\n url_env_var: string;\n models: string[];\n}\ninterface NetlifyResponse {\n providers: Record<string, NetlifyProviderResponse>;\n}\n\ninterface NetlifyTokenResponse {\n token: string;\n url: string;\n expires_at: number;\n}\n\ninterface CachedToken {\n token: string;\n url: string;\n expiresAt: number;\n}\n\ninterface TokenData {\n token: string;\n url: string;\n}\n\nexport class NetlifyGateway extends MastraModelGateway {\n readonly id = 'netlify';\n readonly name = 'Netlify AI Gateway';\n private tokenCache = new InMemoryServerCache();\n\n async fetchProviders(): Promise<Record<string, ProviderConfig>> {\n const response = await fetch('https://api.netlify.com/api/v1/ai-gateway/providers');\n if (!response.ok) {\n throw new Error(`Failed to fetch from Netlify: ${response.statusText}`);\n }\n const data = (await response.json()) as NetlifyResponse;\n const config: ProviderConfig = {\n apiKeyEnvVar: ['NETLIFY_TOKEN', 'NETLIFY_SITE_ID'],\n apiKeyHeader: 'Authorization',\n name: `Netlify`,\n gateway: `netlify`,\n models: [],\n docUrl: 'https://docs.netlify.com/build/ai-gateway/overview/',\n };\n // Convert Netlify format to our standard format\n for (const [providerId, provider] of Object.entries(data.providers)) {\n for (const model of provider.models) {\n config.models.push(`${providerId}/${model}`);\n }\n }\n // Return with gateway ID as key - registry generator will detect this and avoid doubling the prefix\n return { netlify: config };\n }\n\n async buildUrl(routerId: string, envVars?: typeof process.env): Promise<string> {\n // Check for Netlify site ID first (for token exchange)\n const siteId = envVars?.['NETLIFY_SITE_ID'] || process.env['NETLIFY_SITE_ID'];\n const netlifyToken = envVars?.['NETLIFY_TOKEN'] || process.env['NETLIFY_TOKEN'];\n\n if (!netlifyToken) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_TOKEN',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_TOKEN environment variable required for model: ${routerId}`,\n });\n }\n\n if (!siteId) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_SITE_ID',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_SITE_ID environment variable required for model: ${routerId}`,\n });\n }\n\n try {\n const tokenData = await this.getOrFetchToken(siteId, netlifyToken);\n return tokenData.url.endsWith(`/`) ? tokenData.url.substring(0, tokenData.url.length - 1) : tokenData.url;\n } catch (error) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_TOKEN_ERROR',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Failed to get Netlify AI Gateway token for model ${routerId}: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n\n /**\n * Get cached token or fetch a new site-specific AI Gateway token from Netlify\n */\n private async getOrFetchToken(siteId: string, netlifyToken: string): Promise<TokenData> {\n const cacheKey = `netlify-token:${siteId}:${netlifyToken}`;\n\n // Check cache first\n const cached = (await this.tokenCache.get(cacheKey)) as CachedToken | undefined;\n if (cached && cached.expiresAt > Date.now() / 1000 + 60) {\n // Return cached token if it won't expire in the next minute\n return { token: cached.token, url: cached.url };\n }\n\n // Fetch new token\n const response = await fetch(`https://api.netlify.com/api/v1/sites/${siteId}/ai-gateway/token`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${netlifyToken}`,\n },\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Failed to get Netlify AI Gateway token: ${response.status} ${error}`);\n }\n\n const tokenResponse = (await response.json()) as NetlifyTokenResponse;\n\n // Cache the token - InMemoryServerCache will handle the TTL\n await this.tokenCache.set(cacheKey, {\n token: tokenResponse.token,\n url: tokenResponse.url,\n expiresAt: tokenResponse.expires_at,\n });\n\n return { token: tokenResponse.token, url: tokenResponse.url };\n }\n\n /**\n * Get cached token or fetch a new site-specific AI Gateway token from Netlify\n */\n async getApiKey(modelId: string): Promise<string> {\n const siteId = process.env['NETLIFY_SITE_ID'];\n const netlifyToken = process.env['NETLIFY_TOKEN'];\n\n if (!netlifyToken) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_TOKEN',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_TOKEN environment variable required for model: ${modelId}`,\n });\n }\n\n if (!siteId) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_NO_SITE_ID',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Missing NETLIFY_SITE_ID environment variable required for model: ${modelId}`,\n });\n }\n\n try {\n return (await this.getOrFetchToken(siteId, netlifyToken)).token;\n } catch (error) {\n throw new MastraError({\n id: 'NETLIFY_GATEWAY_TOKEN_ERROR',\n domain: 'LLM',\n category: 'UNKNOWN',\n text: `Failed to get Netlify AI Gateway token for model ${modelId}: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n\n async resolveLanguageModel({\n modelId,\n providerId,\n apiKey,\n headers,\n }: {\n modelId: string;\n providerId: string;\n apiKey: string;\n headers?: Record<string, string>;\n }): Promise<GatewayLanguageModel> {\n const baseURL = await this.buildUrl(`${providerId}/${modelId}`);\n\n const mastraHeaders = { 'User-Agent': MASTRA_USER_AGENT, ...headers };\n\n switch (providerId) {\n case 'openai':\n return createOpenAI({ apiKey, baseURL, headers: mastraHeaders }).responses(modelId);\n case 'gemini':\n return createGoogleGenerativeAI({\n baseURL: `${baseURL}/v1beta/`,\n apiKey,\n headers: {\n 'user-agent': 'google-genai-sdk/',\n ...mastraHeaders,\n },\n }).chat(modelId);\n case 'anthropic':\n return createAnthropic({\n apiKey,\n baseURL: `${baseURL}/v1/`,\n headers: {\n 'anthropic-version': '2023-06-01',\n ...mastraHeaders,\n },\n })(modelId);\n default:\n return createOpenAICompatible({\n name: providerId,\n apiKey,\n baseURL,\n headers: mastraHeaders,\n supportsStructuredOutputs: true,\n }).chatModel(modelId);\n }\n }\n}\n"]} |
| 'use strict'; | ||
| var chunk2UAP4LDC_cjs = require('./chunk-2UAP4LDC.cjs'); | ||
| var chunkB3SPPQQ3_cjs = require('./chunk-B3SPPQQ3.cjs'); | ||
| // src/storage/domains/scorer-definitions/base.ts | ||
| var ScorerDefinitionsStorage = class extends chunk2UAP4LDC_cjs.VersionedStorageDomain { | ||
| listKey = "scorerDefinitions"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "scorerDefinitionId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "SCORER_DEFINITIONS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/scorer-definitions/inmemory.ts | ||
| var InMemoryScorerDefinitionsStorage = class extends ScorerDefinitionsStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.scorerDefinitions.clear(); | ||
| this.db.scorerDefinitionVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Scorer Definition CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const scorer = this.db.scorerDefinitions.get(id); | ||
| return scorer ? this.deepCopyScorer(scorer) : null; | ||
| } | ||
| async create(input) { | ||
| const { scorerDefinition } = input; | ||
| if (this.db.scorerDefinitions.has(scorerDefinition.id)) { | ||
| throw new Error(`Scorer definition with id ${scorerDefinition.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newScorer = { | ||
| id: scorerDefinition.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: scorerDefinition.authorId, | ||
| metadata: scorerDefinition.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.scorerDefinitions.set(scorerDefinition.id, newScorer); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| scorerDefinitionId: scorerDefinition.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyScorer(newScorer); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingScorer = this.db.scorerDefinitions.get(id); | ||
| if (!existingScorer) { | ||
| throw new Error(`Scorer definition with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedScorer = { | ||
| ...existingScorer, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingScorer.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.scorerDefinitions.set(id, updatedScorer); | ||
| return this.deepCopyScorer(updatedScorer); | ||
| } | ||
| async delete(id) { | ||
| this.db.scorerDefinitions.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let scorers = Array.from(this.db.scorerDefinitions.values()); | ||
| if (status) { | ||
| scorers = scorers.filter((scorer) => scorer.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| scorers = scorers.filter((scorer) => scorer.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| scorers = scorers.filter((scorer) => { | ||
| if (!scorer.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => chunkB3SPPQQ3_cjs.deepEqual(scorer.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedScorers = this.sortScorers(scorers, field, direction); | ||
| const clonedScorers = sortedScorers.map((scorer) => this.deepCopyScorer(scorer)); | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| scorerDefinitions: clonedScorers.slice(offset, offset + perPage), | ||
| total: clonedScorers.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedScorers.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Scorer Definition Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.scorerDefinitionVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.scorerDefinitionVersions.values()) { | ||
| if (version2.scorerDefinitionId === input.scorerDefinitionId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error( | ||
| `Version number ${input.versionNumber} already exists for scorer definition ${input.scorerDefinitionId}` | ||
| ); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.scorerDefinitionVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.scorerDefinitionVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(scorerDefinitionId, versionNumber) { | ||
| for (const version of this.db.scorerDefinitionVersions.values()) { | ||
| if (version.scorerDefinitionId === scorerDefinitionId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(scorerDefinitionId) { | ||
| let latest = null; | ||
| for (const version of this.db.scorerDefinitionVersions.values()) { | ||
| if (version.scorerDefinitionId === scorerDefinitionId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { scorerDefinitionId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.scorerDefinitionVersions.values()).filter( | ||
| (v) => v.scorerDefinitionId === scorerDefinitionId | ||
| ); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.scorerDefinitionVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.scorerDefinitionVersions.entries()) { | ||
| if (version.scorerDefinitionId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.scorerDefinitionVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(scorerDefinitionId) { | ||
| let count = 0; | ||
| for (const version of this.db.scorerDefinitionVersions.values()) { | ||
| if (version.scorerDefinitionId === scorerDefinitionId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyScorer(scorer) { | ||
| return { | ||
| ...scorer, | ||
| metadata: scorer.metadata ? { ...scorer.metadata } : scorer.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| model: version.model ? JSON.parse(JSON.stringify(version.model)) : version.model, | ||
| scoreRange: version.scoreRange ? JSON.parse(JSON.stringify(version.scoreRange)) : version.scoreRange, | ||
| presetConfig: version.presetConfig ? JSON.parse(JSON.stringify(version.presetConfig)) : version.presetConfig, | ||
| defaultSampling: version.defaultSampling ? JSON.parse(JSON.stringify(version.defaultSampling)) : version.defaultSampling, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortScorers(scorers, field, direction) { | ||
| return scorers.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/scorer-definitions/filesystem.ts | ||
| var FilesystemScorerDefinitionsStorage = class extends ScorerDefinitionsStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new chunk2UAP4LDC_cjs.FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "scorer-definitions.json", | ||
| parentIdField: "scorerDefinitionId", | ||
| name: "FilesystemScorerDefinitionsStorage", | ||
| versionMetadataFields: [ | ||
| "id", | ||
| "scorerDefinitionId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { scorerDefinition } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: scorerDefinition.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: scorerDefinition.authorId, | ||
| metadata: scorerDefinition.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(scorerDefinition.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| scorerDefinitionId: scorerDefinition.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "scorerDefinitions", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(scorerDefinitionId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(scorerDefinitionId, versionNumber); | ||
| } | ||
| async getLatestVersion(scorerDefinitionId) { | ||
| return this.helpers.getLatestVersion(scorerDefinitionId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "scorerDefinitionId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(scorerDefinitionId) { | ||
| return this.helpers.countVersions(scorerDefinitionId); | ||
| } | ||
| }; | ||
| exports.FilesystemScorerDefinitionsStorage = FilesystemScorerDefinitionsStorage; | ||
| exports.InMemoryScorerDefinitionsStorage = InMemoryScorerDefinitionsStorage; | ||
| exports.ScorerDefinitionsStorage = ScorerDefinitionsStorage; | ||
| //# sourceMappingURL=chunk-SK5EI32N.cjs.map | ||
| //# sourceMappingURL=chunk-SK5EI32N.cjs.map |
| {"version":3,"sources":["../src/storage/domains/scorer-definitions/base.ts","../src/storage/domains/scorer-definitions/inmemory.ts","../src/storage/domains/scorer-definitions/filesystem.ts"],"names":["VersionedStorageDomain","normalizePerPage","deepEqual","calculatePagination","version","FilesystemVersionedHelpers"],"mappings":"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","file":"chunk-SK5EI32N.cjs","sourcesContent":["import type {\n StorageScorerDefinitionType,\n StorageScorerDefinitionSnapshotType,\n StorageResolvedScorerDefinitionType,\n StorageCreateScorerDefinitionInput,\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput,\n StorageListScorerDefinitionsOutput,\n StorageListScorerDefinitionsResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// Scorer Definition Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of a scorer definition's content.\n * Config fields are top-level on the version row (no nested snapshot object).\n */\nexport interface ScorerDefinitionVersion extends StorageScorerDefinitionSnapshotType, VersionBase {\n /** ID of the scorer definition this version belongs to */\n scorerDefinitionId: string;\n}\n\n/**\n * Input for creating a new scorer definition version.\n * Config fields are top-level (no nested snapshot object).\n */\nexport interface CreateScorerDefinitionVersionInput\n extends StorageScorerDefinitionSnapshotType, CreateVersionInputBase {\n /** ID of the scorer definition this version belongs to */\n scorerDefinitionId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type ScorerDefinitionVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type ScorerDefinitionVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing scorer definition versions with pagination and sorting.\n */\nexport interface ListScorerDefinitionVersionsInput extends ListVersionsInputBase {\n /** ID of the scorer definition to list versions for */\n scorerDefinitionId: string;\n}\n\n/**\n * Output for listing scorer definition versions with pagination info.\n */\nexport interface ListScorerDefinitionVersionsOutput extends ListVersionsOutputBase<ScorerDefinitionVersion> {}\n\n// ============================================================================\n// ScorerDefinitionsStorage Base Class\n// ============================================================================\n\nexport abstract class ScorerDefinitionsStorage extends VersionedStorageDomain<\n StorageScorerDefinitionType,\n StorageScorerDefinitionSnapshotType,\n StorageResolvedScorerDefinitionType,\n ScorerDefinitionVersion,\n CreateScorerDefinitionVersionInput,\n ListScorerDefinitionVersionsInput,\n ListScorerDefinitionVersionsOutput,\n { scorerDefinition: StorageCreateScorerDefinitionInput },\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput | undefined,\n StorageListScorerDefinitionsOutput,\n StorageListScorerDefinitionsResolvedOutput\n> {\n protected readonly listKey = 'scorerDefinitions';\n protected readonly versionMetadataFields = [\n 'id',\n 'scorerDefinitionId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof ScorerDefinitionVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'SCORER_DEFINITIONS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageScorerDefinitionType,\n StorageCreateScorerDefinitionInput,\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput,\n StorageListScorerDefinitionsOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n ScorerDefinitionVersion,\n CreateScorerDefinitionVersionInput,\n ListScorerDefinitionVersionsInput,\n ListScorerDefinitionVersionsOutput,\n ScorerDefinitionVersionOrderBy,\n ScorerDefinitionVersionSortDirection,\n} from './base';\nimport { ScorerDefinitionsStorage } from './base';\n\nexport class InMemoryScorerDefinitionsStorage extends ScorerDefinitionsStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.scorerDefinitions.clear();\n this.db.scorerDefinitionVersions.clear();\n }\n\n // ==========================================================================\n // Scorer Definition CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageScorerDefinitionType | null> {\n const scorer = this.db.scorerDefinitions.get(id);\n return scorer ? this.deepCopyScorer(scorer) : null;\n }\n\n async create(input: { scorerDefinition: StorageCreateScorerDefinitionInput }): Promise<StorageScorerDefinitionType> {\n const { scorerDefinition } = input;\n\n if (this.db.scorerDefinitions.has(scorerDefinition.id)) {\n throw new Error(`Scorer definition with id ${scorerDefinition.id} already exists`);\n }\n\n const now = new Date();\n const newScorer: StorageScorerDefinitionType = {\n id: scorerDefinition.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: scorerDefinition.authorId,\n metadata: scorerDefinition.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.scorerDefinitions.set(scorerDefinition.id, newScorer);\n\n // Extract config fields from the flat input (everything except scorer-record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n scorerDefinitionId: scorerDefinition.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin scorer record\n return this.deepCopyScorer(newScorer);\n }\n\n async update(input: StorageUpdateScorerDefinitionInput): Promise<StorageScorerDefinitionType> {\n const { id, ...updates } = input;\n\n const existingScorer = this.db.scorerDefinitions.get(id);\n if (!existingScorer) {\n throw new Error(`Scorer definition with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the scorer record\n const updatedScorer: StorageScorerDefinitionType = {\n ...existingScorer,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageScorerDefinitionType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingScorer.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated scorer record\n this.db.scorerDefinitions.set(id, updatedScorer);\n return this.deepCopyScorer(updatedScorer);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.scorerDefinitions.delete(id);\n // Also delete all versions for this scorer definition\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListScorerDefinitionsInput): Promise<StorageListScorerDefinitionsOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all scorer definitions and apply filters\n let scorers = Array.from(this.db.scorerDefinitions.values());\n\n // Filter by status\n if (status) {\n scorers = scorers.filter(scorer => scorer.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n scorers = scorers.filter(scorer => scorer.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n scorers = scorers.filter(scorer => {\n if (!scorer.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(scorer.metadata![key], value));\n });\n }\n\n // Sort filtered scorer definitions\n const sortedScorers = this.sortScorers(scorers, field, direction);\n\n // Deep clone scorers to avoid mutation\n const clonedScorers = sortedScorers.map(scorer => this.deepCopyScorer(scorer));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n scorerDefinitions: clonedScorers.slice(offset, offset + perPage),\n total: clonedScorers.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedScorers.length,\n };\n }\n\n // ==========================================================================\n // Scorer Definition Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateScorerDefinitionVersionInput): Promise<ScorerDefinitionVersion> {\n // Check if version with this ID already exists\n if (this.db.scorerDefinitionVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (scorerDefinitionId, versionNumber) pair\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === input.scorerDefinitionId && version.versionNumber === input.versionNumber) {\n throw new Error(\n `Version number ${input.versionNumber} already exists for scorer definition ${input.scorerDefinitionId}`,\n );\n }\n }\n\n const version: ScorerDefinitionVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.scorerDefinitionVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<ScorerDefinitionVersion | null> {\n const version = this.db.scorerDefinitionVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(scorerDefinitionId: string, versionNumber: number): Promise<ScorerDefinitionVersion | null> {\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === scorerDefinitionId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(scorerDefinitionId: string): Promise<ScorerDefinitionVersion | null> {\n let latest: ScorerDefinitionVersion | null = null;\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === scorerDefinitionId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListScorerDefinitionVersionsInput): Promise<ListScorerDefinitionVersionsOutput> {\n const { scorerDefinitionId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by scorerDefinitionId\n let versions = Array.from(this.db.scorerDefinitionVersions.values()).filter(\n v => v.scorerDefinitionId === scorerDefinitionId,\n );\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.scorerDefinitionVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.scorerDefinitionVersions.entries()) {\n if (version.scorerDefinitionId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.scorerDefinitionVersions.delete(id);\n }\n }\n\n async countVersions(scorerDefinitionId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.scorerDefinitionVersions.values()) {\n if (version.scorerDefinitionId === scorerDefinitionId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyScorer(scorer: StorageScorerDefinitionType): StorageScorerDefinitionType {\n return {\n ...scorer,\n metadata: scorer.metadata ? { ...scorer.metadata } : scorer.metadata,\n };\n }\n\n private deepCopyVersion(version: ScorerDefinitionVersion): ScorerDefinitionVersion {\n return {\n ...version,\n model: version.model ? JSON.parse(JSON.stringify(version.model)) : version.model,\n scoreRange: version.scoreRange ? JSON.parse(JSON.stringify(version.scoreRange)) : version.scoreRange,\n presetConfig: version.presetConfig ? JSON.parse(JSON.stringify(version.presetConfig)) : version.presetConfig,\n defaultSampling: version.defaultSampling\n ? JSON.parse(JSON.stringify(version.defaultSampling))\n : version.defaultSampling,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortScorers(\n scorers: StorageScorerDefinitionType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageScorerDefinitionType[] {\n return scorers.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: ScorerDefinitionVersion[],\n field: ScorerDefinitionVersionOrderBy,\n direction: ScorerDefinitionVersionSortDirection,\n ): ScorerDefinitionVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageScorerDefinitionType,\n StorageCreateScorerDefinitionInput,\n StorageUpdateScorerDefinitionInput,\n StorageListScorerDefinitionsInput,\n StorageListScorerDefinitionsOutput,\n} from '../../types';\nimport type {\n ScorerDefinitionVersion,\n CreateScorerDefinitionVersionInput,\n ListScorerDefinitionVersionsInput,\n ListScorerDefinitionVersionsOutput,\n} from './base';\nimport { ScorerDefinitionsStorage } from './base';\n\nexport class FilesystemScorerDefinitionsStorage extends ScorerDefinitionsStorage {\n private helpers: FilesystemVersionedHelpers<StorageScorerDefinitionType, ScorerDefinitionVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'scorer-definitions.json',\n parentIdField: 'scorerDefinitionId',\n name: 'FilesystemScorerDefinitionsStorage',\n versionMetadataFields: [\n 'id',\n 'scorerDefinitionId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageScorerDefinitionType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { scorerDefinition: StorageCreateScorerDefinitionInput }): Promise<StorageScorerDefinitionType> {\n const { scorerDefinition } = input;\n const now = new Date();\n const entity: StorageScorerDefinitionType = {\n id: scorerDefinition.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: scorerDefinition.authorId,\n metadata: scorerDefinition.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(scorerDefinition.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n scorerDefinitionId: scorerDefinition.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateScorerDefinitionVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateScorerDefinitionInput): Promise<StorageScorerDefinitionType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListScorerDefinitionsInput): Promise<StorageListScorerDefinitionsOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'scorerDefinitions',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListScorerDefinitionsOutput;\n }\n\n async createVersion(input: CreateScorerDefinitionVersionInput): Promise<ScorerDefinitionVersion> {\n return this.helpers.createVersion(input as ScorerDefinitionVersion);\n }\n\n async getVersion(id: string): Promise<ScorerDefinitionVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(scorerDefinitionId: string, versionNumber: number): Promise<ScorerDefinitionVersion | null> {\n return this.helpers.getVersionByNumber(scorerDefinitionId, versionNumber);\n }\n\n async getLatestVersion(scorerDefinitionId: string): Promise<ScorerDefinitionVersion | null> {\n return this.helpers.getLatestVersion(scorerDefinitionId);\n }\n\n async listVersions(input: ListScorerDefinitionVersionsInput): Promise<ListScorerDefinitionVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'scorerDefinitionId');\n return result as ListScorerDefinitionVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(scorerDefinitionId: string): Promise<number> {\n return this.helpers.countVersions(scorerDefinitionId);\n }\n}\n"]} |
| import { SignalProvider, TaskStateProcessor, taskCheckTool, taskCompleteTool, taskUpdateTool, taskWriteTool } from './chunk-MVA25X63.js'; | ||
| // src/signals/task-signal-provider.ts | ||
| var TaskSignalProvider = class extends SignalProvider { | ||
| id = "task-signals"; | ||
| #processor = new TaskStateProcessor(); | ||
| getInputProcessors() { | ||
| return [this.#processor]; | ||
| } | ||
| getTools() { | ||
| return { | ||
| task_write: taskWriteTool, | ||
| task_update: taskUpdateTool, | ||
| task_complete: taskCompleteTool, | ||
| task_check: taskCheckTool | ||
| }; | ||
| } | ||
| }; | ||
| export { TaskSignalProvider }; | ||
| //# sourceMappingURL=chunk-T27PG4IC.js.map | ||
| //# sourceMappingURL=chunk-T27PG4IC.js.map |
| {"version":3,"sources":["../src/signals/task-signal-provider.ts"],"names":[],"mappings":";;;AA0CO,IAAM,kBAAA,GAAN,cAAiC,cAAA,CAA+B;AAAA,EAC5D,EAAA,GAAK,cAAA;AAAA,EAEL,UAAA,GAAa,IAAI,kBAAA,EAAmB;AAAA,EAE7C,kBAAA,GAAiD;AAC/C,IAAA,OAAO,CAAC,KAAK,UAAU,CAAA;AAAA,EACzB;AAAA,EAEA,QAAA,GAAW;AACT,IAAA,OAAO;AAAA,MACL,UAAA,EAAY,aAAA;AAAA,MACZ,WAAA,EAAa,cAAA;AAAA,MACb,aAAA,EAAe,gBAAA;AAAA,MACf,UAAA,EAAY;AAAA,KACd;AAAA,EACF;AACF","file":"chunk-T27PG4IC.js","sourcesContent":["import type { InputProcessorOrWorkflow } from '../processors';\nimport { TaskStateProcessor } from '../tools/builtin/task-state-processor';\nimport { taskCheckTool, taskCompleteTool, taskUpdateTool, taskWriteTool } from '../tools/builtin/task-tools';\n\nimport { SignalProvider } from './signal-provider';\n\n/**\n * Bundles the built-in task tools and the {@link TaskStateProcessor} behind a\n * single agent registration.\n *\n * The task list is held in the thread-scoped `tasks` storage domain (the\n * TaskStore) and projected onto the agent state-signal lane by\n * `TaskStateProcessor`. Wiring task tracking by hand means registering all four\n * task tools **and** the processor, and keeping them in sync — forget the\n * processor and the tools work for a single turn but silently lose the list\n * across turns. This provider wires both together so that cannot happen.\n *\n * Task tracking requires a memory-backed thread (`threadId` + `resourceId`) and\n * a Mastra `storage` instance (the `tasks` domain is always wired in-memory by\n * default). Without memory the tools no-op and report that task tracking\n * requires agent memory.\n *\n * @example\n * ```ts\n * import { Agent } from '@mastra/core/agent';\n * import { TaskSignalProvider } from '@mastra/core/signals';\n *\n * const agent = new Agent({\n * name: 'coder',\n * instructions: '...',\n * model,\n * memory,\n * signals: [new TaskSignalProvider()],\n * });\n * ```\n *\n * The Agent automatically merges the tools into its toolset and registers the\n * processor on its input-processor chain (which propagates the Mastra instance\n * so the processor can resolve the TaskStore).\n *\n * @experimental Agent signals are experimental and may change in a future release.\n */\nexport class TaskSignalProvider extends SignalProvider<'task-signals'> {\n readonly id = 'task-signals';\n\n readonly #processor = new TaskStateProcessor();\n\n getInputProcessors(): InputProcessorOrWorkflow[] {\n return [this.#processor];\n }\n\n getTools() {\n return {\n task_write: taskWriteTool,\n task_update: taskUpdateTool,\n task_complete: taskCompleteTool,\n task_check: taskCheckTool,\n };\n }\n}\n"]} |
| 'use strict'; | ||
| var chunk2UAP4LDC_cjs = require('./chunk-2UAP4LDC.cjs'); | ||
| var chunkB3SPPQQ3_cjs = require('./chunk-B3SPPQQ3.cjs'); | ||
| // src/storage/domains/agents/base.ts | ||
| var AgentsStorage = class extends chunk2UAP4LDC_cjs.VersionedStorageDomain { | ||
| listKey = "agents"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "agentId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "AGENTS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/agents/inmemory.ts | ||
| var InMemoryAgentsStorage = class extends AgentsStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.agents.clear(); | ||
| this.db.agentVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Agent CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const agent = this.db.agents.get(id); | ||
| return agent ? this.deepCopyAgent(agent) : null; | ||
| } | ||
| async create(input) { | ||
| const { agent } = input; | ||
| if (this.db.agents.has(agent.id)) { | ||
| throw new Error(`Agent with id ${agent.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const visibility = agent.visibility ?? (agent.authorId ? "private" : void 0); | ||
| const newAgent = { | ||
| id: agent.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: agent.authorId, | ||
| visibility, | ||
| metadata: agent.metadata, | ||
| favoriteCount: 0, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.agents.set(agent.id, newAgent); | ||
| const { id: _id, authorId: _authorId, visibility: _visibility, metadata: _metadata, ...snapshotConfig } = agent; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| agentId: agent.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyAgent(newAgent); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingAgent = this.db.agents.get(id); | ||
| if (!existingAgent) { | ||
| throw new Error(`Agent with id ${id} not found`); | ||
| } | ||
| const { authorId, visibility, activeVersionId, metadata, status } = updates; | ||
| const updatedAgent = { | ||
| ...existingAgent, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...visibility !== void 0 && { visibility }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingAgent.metadata, ...metadata } | ||
| }, | ||
| ...status !== void 0 && { status }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.agents.set(id, updatedAgent); | ||
| return this.deepCopyAgent(updatedAgent); | ||
| } | ||
| async delete(id) { | ||
| this.db.agents.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { | ||
| page = 0, | ||
| perPage: perPageInput, | ||
| orderBy, | ||
| authorId, | ||
| visibility, | ||
| metadata, | ||
| status, | ||
| entityIds, | ||
| pinFavoritedFor, | ||
| favoritedOnly | ||
| } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let agents = Array.from(this.db.agents.values()); | ||
| if (entityIds !== void 0) { | ||
| if (entityIds.length === 0) { | ||
| return { | ||
| agents: [], | ||
| total: 0, | ||
| page, | ||
| perPage: perPageInput === false ? false : perPage, | ||
| hasMore: false | ||
| }; | ||
| } | ||
| const idSet = new Set(entityIds); | ||
| agents = agents.filter((agent) => idSet.has(agent.id)); | ||
| } | ||
| if (status) { | ||
| agents = agents.filter((agent) => agent.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| agents = agents.filter((agent) => agent.authorId === authorId); | ||
| } | ||
| if (visibility !== void 0) { | ||
| agents = agents.filter((agent) => agent.visibility === visibility); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| agents = agents.filter((agent) => { | ||
| if (!agent.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => chunkB3SPPQQ3_cjs.deepEqual(agent.metadata[key], value)); | ||
| }); | ||
| } | ||
| const favoritedIds = pinFavoritedFor ? this.collectFavoritedIdsFor(pinFavoritedFor) : void 0; | ||
| if (favoritedOnly) { | ||
| if (favoritedIds) { | ||
| agents = agents.filter((agent) => favoritedIds.has(agent.id)); | ||
| } else { | ||
| agents = []; | ||
| } | ||
| } | ||
| const sortedAgents = this.sortAgents(agents, field, direction, favoritedIds); | ||
| const clonedAgents = sortedAgents.map((agent) => this.deepCopyAgent(agent)); | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| agents: clonedAgents.slice(offset, offset + perPage), | ||
| total: clonedAgents.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedAgents.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Agent Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.agentVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.agentVersions.values()) { | ||
| if (version2.agentId === input.agentId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for agent ${input.agentId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.agentVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.agentVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(agentId, versionNumber) { | ||
| for (const version of this.db.agentVersions.values()) { | ||
| if (version.agentId === agentId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(agentId) { | ||
| let latest = null; | ||
| for (const version of this.db.agentVersions.values()) { | ||
| if (version.agentId === agentId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { agentId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.agentVersions.values()).filter((v) => v.agentId === agentId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.agentVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.agentVersions.entries()) { | ||
| if (version.agentId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.agentVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(agentId) { | ||
| let count = 0; | ||
| for (const version of this.db.agentVersions.values()) { | ||
| if (version.agentId === agentId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| /** | ||
| * Deep copy a thin agent record to prevent external mutation of stored data | ||
| */ | ||
| deepCopyAgent(agent) { | ||
| return { | ||
| ...agent, | ||
| metadata: agent.metadata ? { ...agent.metadata } : agent.metadata | ||
| }; | ||
| } | ||
| /** | ||
| * Deep copy a version to prevent external mutation of stored data | ||
| */ | ||
| deepCopyVersion(version) { | ||
| return structuredClone(version); | ||
| } | ||
| sortAgents(agents, field, direction, favoritedIds) { | ||
| return agents.sort((a, b) => { | ||
| if (favoritedIds) { | ||
| const aFav = favoritedIds.has(a.id) ? 1 : 0; | ||
| const bFav = favoritedIds.has(b.id) ? 1 : 0; | ||
| if (aFav !== bFav) return bFav - aFav; | ||
| } | ||
| const aValue = new Date(a[field]).getTime(); | ||
| const bValue = new Date(b[field]).getTime(); | ||
| if (aValue !== bValue) { | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| } | ||
| return a.id < b.id ? -1 : a.id > b.id ? 1 : 0; | ||
| }); | ||
| } | ||
| /** | ||
| * Collect the set of agent IDs favorited by the given user. Returns an empty | ||
| * Set when the favorites domain is not wired or the user has no favorites. | ||
| */ | ||
| collectFavoritedIdsFor(userId) { | ||
| const favorited = /* @__PURE__ */ new Set(); | ||
| for (const row of this.db.favorites.values()) { | ||
| if (row.userId === userId && row.entityType === "agent") { | ||
| favorited.add(row.entityId); | ||
| } | ||
| } | ||
| return favorited; | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/inmemory-db.ts | ||
| var InMemoryDB = class { | ||
| threads = /* @__PURE__ */ new Map(); | ||
| messages = /* @__PURE__ */ new Map(); | ||
| resources = /* @__PURE__ */ new Map(); | ||
| workflows = /* @__PURE__ */ new Map(); | ||
| scores = /* @__PURE__ */ new Map(); | ||
| traces = /* @__PURE__ */ new Map(); | ||
| metricRecords = []; | ||
| logRecords = []; | ||
| scoreRecords = []; | ||
| feedbackRecords = []; | ||
| observabilityNextCursorId = 1; | ||
| traceCursorIds = /* @__PURE__ */ new Map(); | ||
| branchCursorIds = /* @__PURE__ */ new Map(); | ||
| metricCursorIds = /* @__PURE__ */ new Map(); | ||
| logCursorIds = /* @__PURE__ */ new Map(); | ||
| scoreCursorIds = /* @__PURE__ */ new Map(); | ||
| feedbackCursorIds = /* @__PURE__ */ new Map(); | ||
| agents = /* @__PURE__ */ new Map(); | ||
| agentVersions = /* @__PURE__ */ new Map(); | ||
| promptBlocks = /* @__PURE__ */ new Map(); | ||
| promptBlockVersions = /* @__PURE__ */ new Map(); | ||
| scorerDefinitions = /* @__PURE__ */ new Map(); | ||
| scorerDefinitionVersions = /* @__PURE__ */ new Map(); | ||
| mcpClients = /* @__PURE__ */ new Map(); | ||
| mcpClientVersions = /* @__PURE__ */ new Map(); | ||
| mcpServers = /* @__PURE__ */ new Map(); | ||
| mcpServerVersions = /* @__PURE__ */ new Map(); | ||
| workspaces = /* @__PURE__ */ new Map(); | ||
| workspaceVersions = /* @__PURE__ */ new Map(); | ||
| skills = /* @__PURE__ */ new Map(); | ||
| skillVersions = /* @__PURE__ */ new Map(); | ||
| /** | ||
| * Favorites keyed by `${userId}\u0000${entityType}\u0000${entityId}`. The | ||
| * favorites domain owns reads/writes; this Map lives on InMemoryDB so the | ||
| * favorites domain can also mutate `agents` / `skills` `favoriteCount` atomically | ||
| * within the same synchronous block. | ||
| */ | ||
| favorites = /* @__PURE__ */ new Map(); | ||
| /** Observational memory records, keyed by resourceId, each holding array of records (generations) */ | ||
| observationalMemory = /* @__PURE__ */ new Map(); | ||
| // Dataset domain maps | ||
| datasets = /* @__PURE__ */ new Map(); | ||
| datasetItems = /* @__PURE__ */ new Map(); | ||
| datasetVersions = /* @__PURE__ */ new Map(); | ||
| // Experiment domain maps | ||
| experiments = /* @__PURE__ */ new Map(); | ||
| experimentResults = /* @__PURE__ */ new Map(); | ||
| // Background tasks domain | ||
| backgroundTasks = /* @__PURE__ */ new Map(); | ||
| // Schedules domain | ||
| schedules = /* @__PURE__ */ new Map(); | ||
| scheduleTriggers = []; | ||
| /** | ||
| * Tool provider connections keyed by `${authorId}\u0000${providerId}\u0000${connectionId}`. | ||
| */ | ||
| toolProviderConnections = /* @__PURE__ */ new Map(); | ||
| /** | ||
| * Clears all data from all collections. | ||
| * Useful for testing. | ||
| */ | ||
| clear() { | ||
| this.threads.clear(); | ||
| this.messages.clear(); | ||
| this.resources.clear(); | ||
| this.workflows.clear(); | ||
| this.scores.clear(); | ||
| this.traces.clear(); | ||
| this.metricRecords.length = 0; | ||
| this.logRecords.length = 0; | ||
| this.scoreRecords.length = 0; | ||
| this.feedbackRecords.length = 0; | ||
| this.observabilityNextCursorId = 1; | ||
| this.traceCursorIds.clear(); | ||
| this.branchCursorIds.clear(); | ||
| this.metricCursorIds.clear(); | ||
| this.logCursorIds.clear(); | ||
| this.scoreCursorIds.clear(); | ||
| this.feedbackCursorIds.clear(); | ||
| this.agents.clear(); | ||
| this.agentVersions.clear(); | ||
| this.promptBlocks.clear(); | ||
| this.promptBlockVersions.clear(); | ||
| this.scorerDefinitions.clear(); | ||
| this.scorerDefinitionVersions.clear(); | ||
| this.mcpClients.clear(); | ||
| this.mcpClientVersions.clear(); | ||
| this.mcpServers.clear(); | ||
| this.mcpServerVersions.clear(); | ||
| this.workspaces.clear(); | ||
| this.workspaceVersions.clear(); | ||
| this.skills.clear(); | ||
| this.skillVersions.clear(); | ||
| this.favorites.clear(); | ||
| this.observationalMemory.clear(); | ||
| this.datasets.clear(); | ||
| this.datasetItems.clear(); | ||
| this.datasetVersions.clear(); | ||
| this.experiments.clear(); | ||
| this.experimentResults.clear(); | ||
| this.backgroundTasks.clear(); | ||
| this.schedules.clear(); | ||
| this.scheduleTriggers.length = 0; | ||
| this.toolProviderConnections.clear(); | ||
| } | ||
| }; | ||
| // src/storage/domains/agents/filesystem.ts | ||
| var PERSISTED_SNAPSHOT_FIELDS = /* @__PURE__ */ new Set([ | ||
| "name", | ||
| "instructions", | ||
| "model", | ||
| "tools", | ||
| "integrationTools", | ||
| "toolProviders", | ||
| "mcpClients", | ||
| "requestContextSchema" | ||
| ]); | ||
| var CODE_MODE_EXCLUDED_FIELDS = /* @__PURE__ */ new Set(["model", "name"]); | ||
| var OWNED_FIELDS_BY_GROUP = { | ||
| instructions: ["instructions"], | ||
| tools: ["tools", "integrationTools", "mcpClients"] | ||
| }; | ||
| function ownershipFromEditorConfig(editorConfig) { | ||
| if (editorConfig === false) { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| if (editorConfig === void 0 || editorConfig === null) { | ||
| return { ownsInstructions: true, ownsTools: true }; | ||
| } | ||
| if (typeof editorConfig !== "object") { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| const cfg = editorConfig; | ||
| const ownsInstructions = cfg.instructions === true; | ||
| const toolsCfg = cfg.tools; | ||
| const ownsTools = toolsCfg === true || typeof toolsCfg === "object" && toolsCfg !== null && toolsCfg.description === true; | ||
| return { ownsInstructions, ownsTools }; | ||
| } | ||
| function stripUnusedFields(obj) { | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| if (PERSISTED_SNAPSHOT_FIELDS.has(key)) { | ||
| result[key] = value; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function isAgentNotFoundError(error, entityId) { | ||
| if (!error || typeof error !== "object") return false; | ||
| const maybeError = error; | ||
| return maybeError.id === "MASTRA_GET_AGENT_BY_AGENT_ID_NOT_FOUND" || maybeError.details?.status === 404 && maybeError.details?.agentId === entityId || maybeError.message === `Agent with id ${entityId} not found`; | ||
| } | ||
| var FilesystemAgentsStorage = class extends AgentsStorage { | ||
| helpers; | ||
| storageMastra; | ||
| constructor({ db }) { | ||
| super(); | ||
| const getCodeAgent = (entityId) => { | ||
| try { | ||
| const agent = this.storageMastra?.getAgentById?.(entityId); | ||
| return agent?.source === "code" ? agent : void 0; | ||
| } catch (error) { | ||
| if (isAgentNotFoundError(error, entityId)) { | ||
| return void 0; | ||
| } | ||
| throw error; | ||
| } | ||
| }; | ||
| const isCodeAgent = (entityId) => Boolean(getCodeAgent(entityId)); | ||
| const editorConfigFor = (entityId) => getCodeAgent(entityId)?.__getEditorConfig?.(); | ||
| this.helpers = new chunk2UAP4LDC_cjs.FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "agents.json", | ||
| parentIdField: "agentId", | ||
| name: "FilesystemAgentsStorage", | ||
| versionMetadataFields: ["id", "agentId", "versionNumber", "changedFields", "changeMessage", "createdAt"], | ||
| perEntityFilesDir: "agents", | ||
| // Per-entity layout is used only for code-mode agents — i.e. agents | ||
| // that are declared in code (`source === 'code'`). For db-mode and | ||
| // user-created stored agents we keep the shared `agents.json` layout. | ||
| shouldPersistToPerEntityFile: (entity) => isCodeAgent(entity.id), | ||
| perEntitySnapshotFilter: (snapshot, entity) => { | ||
| const { ownsInstructions, ownsTools } = ownershipFromEditorConfig(editorConfigFor(entity.id)); | ||
| const excludedByOwnership = /* @__PURE__ */ new Set(); | ||
| if (!ownsInstructions) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP.instructions) excludedByOwnership.add(field); | ||
| } | ||
| if (!ownsTools) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP.tools) excludedByOwnership.add(field); | ||
| } | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(snapshot)) { | ||
| if (CODE_MODE_EXCLUDED_FIELDS.has(key)) continue; | ||
| if (excludedByOwnership.has(key)) continue; | ||
| result[key] = value; | ||
| } | ||
| return result; | ||
| } | ||
| }); | ||
| } | ||
| __registerMastra(mastra) { | ||
| this.storageMastra = mastra; | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { agent } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const visibility = agent.visibility ?? (agent.authorId ? "private" : void 0); | ||
| const entity = { | ||
| id: agent.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: agent.authorId, | ||
| visibility, | ||
| metadata: agent.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(agent.id, entity); | ||
| const { id: _id, authorId: _authorId, visibility: _visibility, metadata: _metadata, ...snapshotConfig } = agent; | ||
| const filtered = stripUnusedFields(snapshotConfig); | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| agentId: agent.id, | ||
| versionNumber: 1, | ||
| ...filtered, | ||
| changedFields: Object.keys(filtered), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const entityUpdates = {}; | ||
| const entityFields = /* @__PURE__ */ new Set(["authorId", "visibility", "metadata", "activeVersionId", "status"]); | ||
| for (const [key, value] of Object.entries(updates)) { | ||
| if (entityFields.has(key)) { | ||
| entityUpdates[key] = value; | ||
| } | ||
| } | ||
| return this.helpers.updateEntity(id, entityUpdates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, visibility, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "agents", | ||
| filters: { authorId, visibility, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| const { id, agentId, versionNumber, changedFields, changeMessage, ...snapshotFields } = input; | ||
| const filtered = stripUnusedFields(snapshotFields); | ||
| return this.helpers.createVersion({ | ||
| id, | ||
| agentId, | ||
| versionNumber, | ||
| changedFields, | ||
| changeMessage, | ||
| ...filtered | ||
| }); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(agentId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(agentId, versionNumber); | ||
| } | ||
| async getLatestVersion(agentId) { | ||
| return this.helpers.getLatestVersion(agentId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "agentId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(agentId) { | ||
| return this.helpers.countVersions(agentId); | ||
| } | ||
| }; | ||
| // src/storage/domains/agents/source.ts | ||
| var SOURCE_VERSION_PREFIX = "source:"; | ||
| var COMMON_EXCLUDED_FIELDS = /* @__PURE__ */ new Set([ | ||
| "id", | ||
| "model", | ||
| "scorers", | ||
| "skills", | ||
| "workflows", | ||
| "agents", | ||
| "integrationTools", | ||
| "toolProviders", | ||
| "inputProcessors", | ||
| "outputProcessors", | ||
| "memory", | ||
| "mcpClients", | ||
| "workspace", | ||
| "browser", | ||
| "defaultOptions" | ||
| ]); | ||
| var CODE_SOURCE_EXCLUDED_FIELDS = /* @__PURE__ */ new Set(["name"]); | ||
| var OWNED_FIELDS_BY_GROUP2 = { | ||
| instructions: ["instructions"], | ||
| tools: ["tools"] | ||
| }; | ||
| function ownershipFromEditorConfig2(editorConfig) { | ||
| if (editorConfig === false) { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| if (editorConfig === void 0 || editorConfig === null) { | ||
| return { ownsInstructions: true, ownsTools: true }; | ||
| } | ||
| if (typeof editorConfig !== "object") { | ||
| return { ownsInstructions: false, ownsTools: false }; | ||
| } | ||
| const cfg = editorConfig; | ||
| const ownsInstructions = cfg.instructions === true; | ||
| const toolsCfg = cfg.tools; | ||
| const ownsTools = toolsCfg === true || typeof toolsCfg === "object" && toolsCfg !== null && toolsCfg.description === true; | ||
| return { ownsInstructions, ownsTools }; | ||
| } | ||
| function snapshotFromVersion(version) { | ||
| const { id, agentId, versionNumber, changedFields, changeMessage, createdAt, ...snapshot } = version; | ||
| return snapshot; | ||
| } | ||
| function filterSourceSnapshot(snapshot, editorConfig, isCodeDefinedAgent) { | ||
| const excludedByOwnership = /* @__PURE__ */ new Set(); | ||
| if (isCodeDefinedAgent) { | ||
| const { ownsInstructions, ownsTools } = ownershipFromEditorConfig2(editorConfig); | ||
| if (!ownsInstructions) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP2.instructions) excludedByOwnership.add(field); | ||
| } | ||
| if (!ownsTools) { | ||
| for (const field of OWNED_FIELDS_BY_GROUP2.tools) excludedByOwnership.add(field); | ||
| } | ||
| } | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(snapshot)) { | ||
| if (COMMON_EXCLUDED_FIELDS.has(key)) continue; | ||
| if (isCodeDefinedAgent && CODE_SOURCE_EXCLUDED_FIELDS.has(key)) continue; | ||
| if (excludedByOwnership.has(key)) continue; | ||
| if (value === void 0) continue; | ||
| result[key] = value; | ||
| } | ||
| return result; | ||
| } | ||
| function parseJsonObject(content) { | ||
| try { | ||
| const parsed = JSON.parse(content); | ||
| return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null; | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
| function stableStringify(value) { | ||
| if (Array.isArray(value)) { | ||
| return `[${value.map(stableStringify).join(",")}]`; | ||
| } | ||
| if (value && typeof value === "object") { | ||
| const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([a], [b]) => a.localeCompare(b)); | ||
| return `{${entries.map(([key, entryValue]) => `${JSON.stringify(key)}:${stableStringify(entryValue)}`).join(",")}}`; | ||
| } | ||
| return JSON.stringify(value); | ||
| } | ||
| function agentIdFromSourcePath(path) { | ||
| const prefix = `${chunk2UAP4LDC_cjs.SOURCE_CONTROL_AGENTS_DIR}/`; | ||
| if (!path.startsWith(prefix) || !path.endsWith(".json")) return void 0; | ||
| const filename = path.slice(prefix.length, -".json".length); | ||
| if (!filename || filename.includes("/")) return void 0; | ||
| try { | ||
| return decodeURIComponent(filename); | ||
| } catch { | ||
| return filename; | ||
| } | ||
| } | ||
| var SourceAgentsSourceControl = class extends AgentsStorage { | ||
| provider; | ||
| knownAgentIds; | ||
| db = new InMemoryDB(); | ||
| memory = new InMemoryAgentsStorage({ db: this.db }); | ||
| storageMastra; | ||
| providerVersions = /* @__PURE__ */ new Map(); | ||
| loadedHistory = /* @__PURE__ */ new Set(); | ||
| hydratedAgents = /* @__PURE__ */ new Set(); | ||
| activeRefs = /* @__PURE__ */ new Map(); | ||
| providerAgentIdsDiscovered = false; | ||
| constructor({ provider, agentIds = [] }) { | ||
| super(); | ||
| this.provider = provider; | ||
| this.knownAgentIds = new Set(agentIds); | ||
| } | ||
| __registerMastra(mastra) { | ||
| this.storageMastra = mastra; | ||
| } | ||
| async init() { | ||
| const capabilities = await this.provider.getCapabilities(); | ||
| if (!capabilities.canRead) { | ||
| throw new Error(capabilities.reason ?? `Source provider ${this.provider.displayName} cannot read files`); | ||
| } | ||
| this.refreshKnownAgentIds(); | ||
| await this.discoverProviderAgentIds(); | ||
| await Promise.all([...this.knownAgentIds].map((agentId) => this.hydrateAgent(agentId))); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.hydratedAgents.clear(); | ||
| this.loadedHistory.clear(); | ||
| this.providerVersions.clear(); | ||
| this.activeRefs.clear(); | ||
| this.providerAgentIdsDiscovered = false; | ||
| await this.memory.dangerouslyClearAll(); | ||
| } | ||
| async useProviderRef(agentId, ref) { | ||
| this.activeRefs.set(agentId, ref); | ||
| this.hydratedAgents.delete(agentId); | ||
| this.loadedHistory.delete(agentId); | ||
| for (const [versionId, version] of this.providerVersions.entries()) { | ||
| if (version.agentId === agentId) { | ||
| this.providerVersions.delete(versionId); | ||
| } | ||
| } | ||
| await this.memory.delete(agentId); | ||
| await this.hydrateAgent(agentId); | ||
| } | ||
| async getById(id) { | ||
| await this.hydrateAgent(id); | ||
| return this.memory.getById(id); | ||
| } | ||
| async create(input) { | ||
| await this.hydrateAgent(input.agent.id); | ||
| const existing = await this.memory.getById(input.agent.id); | ||
| if (existing) { | ||
| throw new Error(`Agent with id ${input.agent.id} already exists`); | ||
| } | ||
| await this.persistSnapshot(input.agent.id, { ...input.agent }, "Initial version"); | ||
| const created = await this.memory.create(input); | ||
| this.knownAgentIds.add(input.agent.id); | ||
| return created; | ||
| } | ||
| async update(input) { | ||
| await this.hydrateAgent(input.id); | ||
| return this.memory.update(input); | ||
| } | ||
| async delete(id) { | ||
| this.knownAgentIds.delete(id); | ||
| this.hydratedAgents.delete(id); | ||
| this.loadedHistory.delete(id); | ||
| for (const versionId of this.providerVersions.keys()) { | ||
| if (this.providerVersions.get(versionId)?.agentId === id) { | ||
| this.providerVersions.delete(versionId); | ||
| } | ||
| } | ||
| await this.memory.delete(id); | ||
| } | ||
| async list(args) { | ||
| this.refreshKnownAgentIds(); | ||
| await this.discoverProviderAgentIds(); | ||
| await Promise.all([...this.knownAgentIds].map((agentId) => this.hydrateAgent(agentId))); | ||
| return this.memory.list(args); | ||
| } | ||
| async createVersion(input) { | ||
| await this.hydrateAgent(input.agentId); | ||
| const existingVersion = await this.memory.getVersion(input.id); | ||
| if (existingVersion) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| const existingVersionNumber = await this.memory.getVersionByNumber(input.agentId, input.versionNumber); | ||
| if (existingVersionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for agent ${input.agentId}`); | ||
| } | ||
| const snapshot = snapshotFromVersion({ ...input, createdAt: /* @__PURE__ */ new Date() }); | ||
| const result = await this.persistSnapshot(input.agentId, snapshot, input.changeMessage); | ||
| const version = await this.memory.createVersion(input); | ||
| this.rememberProviderVersion(input.agentId, version, result); | ||
| return version; | ||
| } | ||
| async getVersion(id) { | ||
| const providerVersion = this.providerVersions.get(id); | ||
| if (providerVersion) { | ||
| return structuredClone(providerVersion); | ||
| } | ||
| return this.memory.getVersion(id); | ||
| } | ||
| async getVersionByNumber(agentId, versionNumber) { | ||
| await this.loadHistory(agentId); | ||
| const providerVersion = [...this.providerVersions.values()].find( | ||
| (version) => version.agentId === agentId && version.versionNumber === versionNumber | ||
| ); | ||
| if (providerVersion) { | ||
| return structuredClone(providerVersion); | ||
| } | ||
| return this.memory.getVersionByNumber(agentId, versionNumber); | ||
| } | ||
| async getLatestVersion(agentId) { | ||
| await this.loadHistory(agentId); | ||
| const providerLatest = [...this.providerVersions.values()].filter((version) => version.agentId === agentId).sort((a, b) => b.versionNumber - a.versionNumber)[0]; | ||
| if (providerLatest) { | ||
| return structuredClone(providerLatest); | ||
| } | ||
| return this.memory.getLatestVersion(agentId); | ||
| } | ||
| async listVersions(input) { | ||
| await this.loadHistory(input.agentId); | ||
| const providerVersions = [...this.providerVersions.values()].filter((version) => version.agentId === input.agentId); | ||
| if (providerVersions.length === 0) { | ||
| return this.memory.listVersions(input); | ||
| } | ||
| const { page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| const sortedVersions = this.sortVersions(providerVersions, field, direction).map( | ||
| (version) => structuredClone(version) | ||
| ); | ||
| const total = sortedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| versions: sortedVersions.slice(offset, offset + perPage), | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.providerVersions.delete(id); | ||
| await this.memory.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| for (const [versionId, version] of this.providerVersions.entries()) { | ||
| if (version.agentId === entityId) { | ||
| this.providerVersions.delete(versionId); | ||
| } | ||
| } | ||
| await this.memory.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(entityId) { | ||
| await this.loadHistory(entityId); | ||
| const providerCount = [...this.providerVersions.values()].filter((version) => version.agentId === entityId).length; | ||
| return providerCount || this.memory.countVersions(entityId); | ||
| } | ||
| refreshKnownAgentIds() { | ||
| const agents = this.storageMastra?.listAgents?.(); | ||
| if (!agents) return; | ||
| for (const agent of Object.values(agents)) { | ||
| if (agent.source === "code") { | ||
| this.knownAgentIds.add(agent.id); | ||
| } | ||
| } | ||
| } | ||
| async discoverProviderAgentIds() { | ||
| if (this.providerAgentIdsDiscovered || !this.provider.listFiles) return; | ||
| const files = await this.provider.listFiles({ path: chunk2UAP4LDC_cjs.SOURCE_CONTROL_AGENTS_DIR }); | ||
| for (const file of files) { | ||
| const agentId = agentIdFromSourcePath(file.path); | ||
| if (agentId) { | ||
| this.knownAgentIds.add(agentId); | ||
| } | ||
| } | ||
| this.providerAgentIdsDiscovered = true; | ||
| } | ||
| async hydrateAgent(agentId) { | ||
| if (this.hydratedAgents.has(agentId)) return; | ||
| const ref = this.activeRefs.get(agentId); | ||
| const file = await this.provider.readFile({ path: chunk2UAP4LDC_cjs.getSourceAgentFilePath(agentId), ref }); | ||
| if (!file) { | ||
| this.hydratedAgents.add(agentId); | ||
| return; | ||
| } | ||
| const snapshot = parseJsonObject(file.content); | ||
| if (!snapshot) { | ||
| this.hydratedAgents.add(agentId); | ||
| return; | ||
| } | ||
| this.knownAgentIds.add(agentId); | ||
| this.hydratedAgents.add(agentId); | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const versionId = `hydrated-${agentId}-v1`; | ||
| this.db.agents.set(agentId, { | ||
| id: agentId, | ||
| status: "published", | ||
| activeVersionId: versionId, | ||
| favoriteCount: 0, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }); | ||
| this.db.agentVersions.set(versionId, { | ||
| id: versionId, | ||
| agentId, | ||
| versionNumber: 1, | ||
| ...snapshot, | ||
| createdAt: now | ||
| }); | ||
| } | ||
| getCodeDefinedAgent(agentId) { | ||
| try { | ||
| const agent = this.storageMastra?.getAgentById?.(agentId); | ||
| return agent?.source === "code" ? agent : void 0; | ||
| } catch { | ||
| return void 0; | ||
| } | ||
| } | ||
| async persistSnapshot(agentId, snapshot, message) { | ||
| const capabilities = await this.provider.getCapabilities(); | ||
| if (!capabilities.canWrite) { | ||
| throw new Error(capabilities.reason ?? `Source provider ${this.provider.displayName} cannot write files`); | ||
| } | ||
| const agent = this.getCodeDefinedAgent(agentId); | ||
| const filtered = filterSourceSnapshot(snapshot, agent?.__getEditorConfig?.(), Boolean(agent)); | ||
| return this.provider.writeFile({ | ||
| path: chunk2UAP4LDC_cjs.getSourceAgentFilePath(agentId), | ||
| ref: this.activeRefs.get(agentId), | ||
| content: `${stableStringify(filtered)} | ||
| `, | ||
| message | ||
| }); | ||
| } | ||
| async loadHistory(agentId) { | ||
| if (this.loadedHistory.has(agentId)) return; | ||
| const capabilities = await this.provider.getCapabilities(); | ||
| if (!capabilities.canListHistory) { | ||
| this.loadedHistory.add(agentId); | ||
| return; | ||
| } | ||
| const activeRef = this.activeRefs.get(agentId); | ||
| const entries = await this.provider.listFileHistory({ path: chunk2UAP4LDC_cjs.getSourceAgentFilePath(agentId), ref: activeRef }); | ||
| const orderedEntries = [...entries].reverse(); | ||
| const versions = /* @__PURE__ */ new Map(); | ||
| let versionNumber = 0; | ||
| for (const entry of orderedEntries) { | ||
| const file = await this.provider.readFile({ path: chunk2UAP4LDC_cjs.getSourceAgentFilePath(agentId), ref: entry.ref ?? entry.id }); | ||
| if (!file) continue; | ||
| const snapshot = parseJsonObject(file.content); | ||
| if (!snapshot) continue; | ||
| versionNumber += 1; | ||
| const version = this.versionFromHistoryEntry(agentId, entry, versionNumber, snapshot); | ||
| versions.set(version.id, version); | ||
| } | ||
| for (const [versionId, version] of versions) { | ||
| this.providerVersions.set(versionId, version); | ||
| } | ||
| this.loadedHistory.add(agentId); | ||
| } | ||
| rememberProviderVersion(agentId, version, result) { | ||
| const versionId = result.commitSha ? `${SOURCE_VERSION_PREFIX}${result.commitSha}:${agentId}` : version.id; | ||
| this.providerVersions.set(versionId, { | ||
| ...structuredClone(version), | ||
| id: versionId, | ||
| agentId, | ||
| versionNumber: this.nextProviderVersionNumber(agentId) | ||
| }); | ||
| } | ||
| versionFromHistoryEntry(agentId, entry, versionNumber, snapshot) { | ||
| return { | ||
| id: `${SOURCE_VERSION_PREFIX}${entry.id}:${agentId}`, | ||
| agentId, | ||
| versionNumber, | ||
| changeMessage: entry.message, | ||
| ...snapshot, | ||
| createdAt: new Date(entry.createdAt) | ||
| }; | ||
| } | ||
| nextProviderVersionNumber(agentId) { | ||
| const latest = [...this.providerVersions.values()].filter((version) => version.agentId === agentId).sort((a, b) => b.versionNumber - a.versionNumber)[0]; | ||
| return (latest?.versionNumber ?? 0) + 1; | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| const aVal = field === "createdAt" ? a.createdAt.getTime() : a.versionNumber; | ||
| const bVal = field === "createdAt" ? b.createdAt.getTime() : b.versionNumber; | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| exports.AgentsStorage = AgentsStorage; | ||
| exports.FilesystemAgentsStorage = FilesystemAgentsStorage; | ||
| exports.InMemoryAgentsStorage = InMemoryAgentsStorage; | ||
| exports.InMemoryDB = InMemoryDB; | ||
| exports.SourceAgentsSourceControl = SourceAgentsSourceControl; | ||
| //# sourceMappingURL=chunk-W62XF4LN.cjs.map | ||
| //# sourceMappingURL=chunk-W62XF4LN.cjs.map |
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunk2UAP4LDC_cjs = require('./chunk-2UAP4LDC.cjs'); | ||
| var chunkB3SPPQQ3_cjs = require('./chunk-B3SPPQQ3.cjs'); | ||
| // src/storage/domains/mcp-servers/base.ts | ||
| var MCPServersStorage = class extends chunk2UAP4LDC_cjs.VersionedStorageDomain { | ||
| listKey = "mcpServers"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "mcpServerId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "MCP_SERVERS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-servers/inmemory.ts | ||
| var InMemoryMCPServersStorage = class extends MCPServersStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.mcpServers.clear(); | ||
| this.db.mcpServerVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // MCP Server CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const config = this.db.mcpServers.get(id); | ||
| return config ? this.deepCopyConfig(config) : null; | ||
| } | ||
| async create(input) { | ||
| const { mcpServer } = input; | ||
| if (this.db.mcpServers.has(mcpServer.id)) { | ||
| throw new Error(`MCP server with id ${mcpServer.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newConfig = { | ||
| id: mcpServer.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpServer.authorId, | ||
| metadata: mcpServer.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.mcpServers.set(mcpServer.id, newConfig); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpServerId: mcpServer.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyConfig(newConfig); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingConfig = this.db.mcpServers.get(id); | ||
| if (!existingConfig) { | ||
| throw new Error(`MCP server with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedConfig = { | ||
| ...existingConfig, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingConfig.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpServers.set(id, updatedConfig); | ||
| return this.deepCopyConfig(updatedConfig); | ||
| } | ||
| async delete(id) { | ||
| this.db.mcpServers.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status = "published" } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let configs = Array.from(this.db.mcpServers.values()); | ||
| if (status) { | ||
| configs = configs.filter((config) => config.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| configs = configs.filter((config) => config.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| configs = configs.filter((config) => { | ||
| if (!config.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => chunkB3SPPQQ3_cjs.deepEqual(config.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedConfigs = this.sortConfigs(configs, field, direction); | ||
| const clonedConfigs = sortedConfigs.map((config) => this.deepCopyConfig(config)); | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| mcpServers: clonedConfigs.slice(offset, offset + perPage), | ||
| total: clonedConfigs.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedConfigs.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // MCP Server Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.mcpServerVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.mcpServerVersions.values()) { | ||
| if (version2.mcpServerId === input.mcpServerId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for MCP server ${input.mcpServerId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpServerVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.mcpServerVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(mcpServerId, versionNumber) { | ||
| for (const version of this.db.mcpServerVersions.values()) { | ||
| if (version.mcpServerId === mcpServerId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(mcpServerId) { | ||
| let latest = null; | ||
| for (const version of this.db.mcpServerVersions.values()) { | ||
| if (version.mcpServerId === mcpServerId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { mcpServerId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = chunk2UAP4LDC_cjs.normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.mcpServerVersions.values()).filter((v) => v.mcpServerId === mcpServerId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = chunk2UAP4LDC_cjs.calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.mcpServerVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.mcpServerVersions.entries()) { | ||
| if (version.mcpServerId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.mcpServerVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(mcpServerId) { | ||
| let count = 0; | ||
| for (const version of this.db.mcpServerVersions.values()) { | ||
| if (version.mcpServerId === mcpServerId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyConfig(config) { | ||
| return { | ||
| ...config, | ||
| metadata: config.metadata ? { ...config.metadata } : config.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| tools: version.tools ? JSON.parse(JSON.stringify(version.tools)) : version.tools, | ||
| agents: version.agents ? JSON.parse(JSON.stringify(version.agents)) : version.agents, | ||
| workflows: version.workflows ? JSON.parse(JSON.stringify(version.workflows)) : version.workflows, | ||
| repository: version.repository ? { ...version.repository } : version.repository, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortConfigs(configs, field, direction) { | ||
| return configs.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-servers/filesystem.ts | ||
| var FilesystemMCPServersStorage = class extends MCPServersStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new chunk2UAP4LDC_cjs.FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "mcp-servers.json", | ||
| parentIdField: "mcpServerId", | ||
| name: "FilesystemMCPServersStorage", | ||
| versionMetadataFields: ["id", "mcpServerId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { mcpServer } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: mcpServer.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpServer.authorId, | ||
| metadata: mcpServer.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(mcpServer.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpServerId: mcpServer.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "mcpServers", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(mcpServerId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(mcpServerId, versionNumber); | ||
| } | ||
| async getLatestVersion(mcpServerId) { | ||
| return this.helpers.getLatestVersion(mcpServerId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "mcpServerId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(mcpServerId) { | ||
| return this.helpers.countVersions(mcpServerId); | ||
| } | ||
| }; | ||
| exports.FilesystemMCPServersStorage = FilesystemMCPServersStorage; | ||
| exports.InMemoryMCPServersStorage = InMemoryMCPServersStorage; | ||
| exports.MCPServersStorage = MCPServersStorage; | ||
| //# sourceMappingURL=chunk-WMV636D2.cjs.map | ||
| //# sourceMappingURL=chunk-WMV636D2.cjs.map |
| {"version":3,"sources":["../src/storage/domains/mcp-servers/base.ts","../src/storage/domains/mcp-servers/inmemory.ts","../src/storage/domains/mcp-servers/filesystem.ts"],"names":["VersionedStorageDomain","normalizePerPage","deepEqual","calculatePagination","version","FilesystemVersionedHelpers"],"mappings":"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","file":"chunk-WMV636D2.cjs","sourcesContent":["import type {\n StorageMCPServerType,\n StorageMCPServerSnapshotType,\n StorageResolvedMCPServerType,\n StorageCreateMCPServerInput,\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput,\n StorageListMCPServersOutput,\n StorageListMCPServersResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// MCP Server Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of an MCP server's content.\n * Server fields are top-level on the version row (no nested snapshot object).\n */\nexport interface MCPServerVersion extends StorageMCPServerSnapshotType, VersionBase {\n /** ID of the MCP server this version belongs to */\n mcpServerId: string;\n}\n\n/**\n * Input for creating a new MCP server version.\n * Server fields are top-level (no nested snapshot object).\n */\nexport interface CreateMCPServerVersionInput extends StorageMCPServerSnapshotType, CreateVersionInputBase {\n /** ID of the MCP server this version belongs to */\n mcpServerId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type MCPServerVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type MCPServerVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing MCP server versions with pagination and sorting.\n */\nexport interface ListMCPServerVersionsInput extends ListVersionsInputBase {\n /** ID of the MCP server to list versions for */\n mcpServerId: string;\n}\n\n/**\n * Output for listing MCP server versions with pagination info.\n */\nexport interface ListMCPServerVersionsOutput extends ListVersionsOutputBase<MCPServerVersion> {}\n\n// ============================================================================\n// MCPServersStorage Base Class\n// ============================================================================\n\nexport abstract class MCPServersStorage extends VersionedStorageDomain<\n StorageMCPServerType,\n StorageMCPServerSnapshotType,\n StorageResolvedMCPServerType,\n MCPServerVersion,\n CreateMCPServerVersionInput,\n ListMCPServerVersionsInput,\n ListMCPServerVersionsOutput,\n { mcpServer: StorageCreateMCPServerInput },\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput | undefined,\n StorageListMCPServersOutput,\n StorageListMCPServersResolvedOutput\n> {\n protected readonly listKey = 'mcpServers';\n protected readonly versionMetadataFields = [\n 'id',\n 'mcpServerId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof MCPServerVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'MCP_SERVERS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageMCPServerType,\n StorageCreateMCPServerInput,\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput,\n StorageListMCPServersOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n MCPServerVersion,\n CreateMCPServerVersionInput,\n ListMCPServerVersionsInput,\n ListMCPServerVersionsOutput,\n MCPServerVersionOrderBy,\n MCPServerVersionSortDirection,\n} from './base';\nimport { MCPServersStorage } from './base';\n\nexport class InMemoryMCPServersStorage extends MCPServersStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.mcpServers.clear();\n this.db.mcpServerVersions.clear();\n }\n\n // ==========================================================================\n // MCP Server CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageMCPServerType | null> {\n const config = this.db.mcpServers.get(id);\n return config ? this.deepCopyConfig(config) : null;\n }\n\n async create(input: { mcpServer: StorageCreateMCPServerInput }): Promise<StorageMCPServerType> {\n const { mcpServer } = input;\n\n if (this.db.mcpServers.has(mcpServer.id)) {\n throw new Error(`MCP server with id ${mcpServer.id} already exists`);\n }\n\n const now = new Date();\n const newConfig: StorageMCPServerType = {\n id: mcpServer.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpServer.authorId,\n metadata: mcpServer.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.mcpServers.set(mcpServer.id, newConfig);\n\n // Extract config fields from the flat input (everything except record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpServerId: mcpServer.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin record\n return this.deepCopyConfig(newConfig);\n }\n\n async update(input: StorageUpdateMCPServerInput): Promise<StorageMCPServerType> {\n const { id, ...updates } = input;\n\n const existingConfig = this.db.mcpServers.get(id);\n if (!existingConfig) {\n throw new Error(`MCP server with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the record\n const updatedConfig: StorageMCPServerType = {\n ...existingConfig,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageMCPServerType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingConfig.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated record\n this.db.mcpServers.set(id, updatedConfig);\n return this.deepCopyConfig(updatedConfig);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.mcpServers.delete(id);\n // Also delete all versions for this server\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListMCPServersInput): Promise<StorageListMCPServersOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status = 'published' } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all MCP servers and apply filters\n let configs = Array.from(this.db.mcpServers.values());\n\n // Filter by status\n if (status) {\n configs = configs.filter(config => config.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n configs = configs.filter(config => config.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n configs = configs.filter(config => {\n if (!config.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata![key], value));\n });\n }\n\n // Sort filtered configs\n const sortedConfigs = this.sortConfigs(configs, field, direction);\n\n // Deep clone to avoid mutation\n const clonedConfigs = sortedConfigs.map(config => this.deepCopyConfig(config));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n mcpServers: clonedConfigs.slice(offset, offset + perPage),\n total: clonedConfigs.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedConfigs.length,\n };\n }\n\n // ==========================================================================\n // MCP Server Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateMCPServerVersionInput): Promise<MCPServerVersion> {\n // Check if version with this ID already exists\n if (this.db.mcpServerVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (mcpServerId, versionNumber) pair\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === input.mcpServerId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for MCP server ${input.mcpServerId}`);\n }\n }\n\n const version: MCPServerVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.mcpServerVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<MCPServerVersion | null> {\n const version = this.db.mcpServerVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(mcpServerId: string, versionNumber: number): Promise<MCPServerVersion | null> {\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === mcpServerId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(mcpServerId: string): Promise<MCPServerVersion | null> {\n let latest: MCPServerVersion | null = null;\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === mcpServerId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListMCPServerVersionsInput): Promise<ListMCPServerVersionsOutput> {\n const { mcpServerId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by mcpServerId\n let versions = Array.from(this.db.mcpServerVersions.values()).filter(v => v.mcpServerId === mcpServerId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.mcpServerVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.mcpServerVersions.entries()) {\n if (version.mcpServerId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.mcpServerVersions.delete(id);\n }\n }\n\n async countVersions(mcpServerId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.mcpServerVersions.values()) {\n if (version.mcpServerId === mcpServerId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyConfig(config: StorageMCPServerType): StorageMCPServerType {\n return {\n ...config,\n metadata: config.metadata ? { ...config.metadata } : config.metadata,\n };\n }\n\n private deepCopyVersion(version: MCPServerVersion): MCPServerVersion {\n return {\n ...version,\n tools: version.tools ? JSON.parse(JSON.stringify(version.tools)) : version.tools,\n agents: version.agents ? JSON.parse(JSON.stringify(version.agents)) : version.agents,\n workflows: version.workflows ? JSON.parse(JSON.stringify(version.workflows)) : version.workflows,\n repository: version.repository ? { ...version.repository } : version.repository,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortConfigs(\n configs: StorageMCPServerType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageMCPServerType[] {\n return configs.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: MCPServerVersion[],\n field: MCPServerVersionOrderBy,\n direction: MCPServerVersionSortDirection,\n ): MCPServerVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageMCPServerType,\n StorageCreateMCPServerInput,\n StorageUpdateMCPServerInput,\n StorageListMCPServersInput,\n StorageListMCPServersOutput,\n} from '../../types';\nimport type {\n MCPServerVersion,\n CreateMCPServerVersionInput,\n ListMCPServerVersionsInput,\n ListMCPServerVersionsOutput,\n} from './base';\nimport { MCPServersStorage } from './base';\n\nexport class FilesystemMCPServersStorage extends MCPServersStorage {\n private helpers: FilesystemVersionedHelpers<StorageMCPServerType, MCPServerVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'mcp-servers.json',\n parentIdField: 'mcpServerId',\n name: 'FilesystemMCPServersStorage',\n versionMetadataFields: ['id', 'mcpServerId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageMCPServerType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { mcpServer: StorageCreateMCPServerInput }): Promise<StorageMCPServerType> {\n const { mcpServer } = input;\n const now = new Date();\n const entity: StorageMCPServerType = {\n id: mcpServer.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpServer.authorId,\n metadata: mcpServer.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(mcpServer.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpServerId: mcpServer.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateMCPServerVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateMCPServerInput): Promise<StorageMCPServerType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListMCPServersInput): Promise<StorageListMCPServersOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'mcpServers',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListMCPServersOutput;\n }\n\n async createVersion(input: CreateMCPServerVersionInput): Promise<MCPServerVersion> {\n return this.helpers.createVersion(input as MCPServerVersion);\n }\n\n async getVersion(id: string): Promise<MCPServerVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(mcpServerId: string, versionNumber: number): Promise<MCPServerVersion | null> {\n return this.helpers.getVersionByNumber(mcpServerId, versionNumber);\n }\n\n async getLatestVersion(mcpServerId: string): Promise<MCPServerVersion | null> {\n return this.helpers.getLatestVersion(mcpServerId);\n }\n\n async listVersions(input: ListMCPServerVersionsInput): Promise<ListMCPServerVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'mcpServerId');\n return result as ListMCPServerVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(mcpServerId: string): Promise<number> {\n return this.helpers.countVersions(mcpServerId);\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| 'use strict'; | ||
| var chunkB3SPPQQ3_cjs = require('./chunk-B3SPPQQ3.cjs'); | ||
| var chunkXB4FLS7A_cjs = require('./chunk-XB4FLS7A.cjs'); | ||
| var chunkCMKSC37Z_cjs = require('./chunk-CMKSC37Z.cjs'); | ||
| var chunkSZ2THGT4_cjs = require('./chunk-SZ2THGT4.cjs'); | ||
| var chunkLP4WZA6D_cjs = require('./chunk-LP4WZA6D.cjs'); | ||
| var chunkWSD4JNMB_cjs = require('./chunk-WSD4JNMB.cjs'); | ||
| var chunkI4YELKDU_cjs = require('./chunk-I4YELKDU.cjs'); | ||
| var chunkXSOONORA_cjs = require('./chunk-XSOONORA.cjs'); | ||
| var schemaCompat = require('@mastra/schema-compat'); | ||
| var crypto = require('crypto'); | ||
| // src/stream/aisdk/v4/usage.ts | ||
| function convertV4Usage(usage) { | ||
| if (!usage) { | ||
| return {}; | ||
| } | ||
| return { | ||
| inputTokens: usage.promptTokens, | ||
| outputTokens: usage.completionTokens | ||
| }; | ||
| } | ||
| // src/llm/model/model.ts | ||
| var MastraLLMV1 = class extends chunkWSD4JNMB_cjs.MastraBase { | ||
| #model; | ||
| #mastra; | ||
| #options; | ||
| constructor({ model, mastra, options }) { | ||
| super({ name: "aisdk" }); | ||
| this.#model = model; | ||
| this.#options = options; | ||
| if (mastra) { | ||
| this.#mastra = mastra; | ||
| if (mastra.getLogger()) { | ||
| this.__setLogger(this.#mastra.getLogger()); | ||
| } | ||
| } | ||
| } | ||
| __registerPrimitives(p) { | ||
| if (p.logger) { | ||
| this.__setLogger(p.logger); | ||
| } | ||
| } | ||
| __registerMastra(p) { | ||
| this.#mastra = p; | ||
| } | ||
| getProvider() { | ||
| return this.#model.provider; | ||
| } | ||
| getModelId() { | ||
| return this.#model.modelId; | ||
| } | ||
| getModel() { | ||
| return this.#model; | ||
| } | ||
| _applySchemaCompat(schema) { | ||
| const model = this.#model; | ||
| const schemaCompatLayers = []; | ||
| if (model) { | ||
| const modelInfo = { | ||
| modelId: model.modelId, | ||
| supportsStructuredOutputs: model.supportsStructuredOutputs ?? false, | ||
| provider: model.provider | ||
| }; | ||
| schemaCompatLayers.push( | ||
| new schemaCompat.OpenAIReasoningSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.OpenAISchemaCompatLayer(modelInfo), | ||
| new schemaCompat.GoogleSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.AnthropicSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.DeepSeekSchemaCompatLayer(modelInfo), | ||
| new schemaCompat.MetaSchemaCompatLayer(modelInfo) | ||
| ); | ||
| } | ||
| return schemaCompat.applyCompatLayer({ | ||
| schema, | ||
| compatLayers: schemaCompatLayers, | ||
| mode: "aiSdkSchema" | ||
| }); | ||
| } | ||
| async __text({ | ||
| runId, | ||
| messages, | ||
| maxSteps = 5, | ||
| tools = {}, | ||
| temperature, | ||
| toolChoice = "auto", | ||
| onStepFinish, | ||
| experimental_output, | ||
| threadId, | ||
| resourceId, | ||
| requestContext, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = chunkSZ2THGT4_cjs.resolveObservabilityContext(rest); | ||
| this.logger.debug("Generating text", { | ||
| runId, | ||
| messages, | ||
| maxSteps, | ||
| threadId, | ||
| resourceId, | ||
| tools: Object.keys(tools) | ||
| }); | ||
| let schema = void 0; | ||
| if (experimental_output) { | ||
| this.logger.debug("Using experimental output", { | ||
| runId | ||
| }); | ||
| if (chunkB3SPPQQ3_cjs.isZodType(experimental_output)) { | ||
| schema = experimental_output; | ||
| if (chunkCMKSC37Z_cjs.isZodArray(schema)) { | ||
| schema = chunkCMKSC37Z_cjs.getZodDef(schema).type; | ||
| } | ||
| const standardSchema = chunkXB4FLS7A_cjs.toStandardSchema(schema); | ||
| const jsonSchemaToUse = chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(standardSchema); | ||
| schema = schemaCompat.jsonSchema(jsonSchemaToUse); | ||
| } else { | ||
| schema = schemaCompat.jsonSchema(experimental_output); | ||
| } | ||
| } | ||
| if (tools && Object.keys(tools).length > 0) { | ||
| for (const tool of Object.values(tools)) { | ||
| if (tool.parameters) { | ||
| if ("validate" in tool.parameters) { | ||
| tool.parameters = tool.parameters; | ||
| } else if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(tool.parameters)) { | ||
| tool.parameters = schemaCompat.jsonSchema(chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(tool.parameters)); | ||
| } else { | ||
| tool.parameters = schemaCompat.jsonSchema(tool.parameters); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages, | ||
| schema | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: false | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| const argsForExecute = { | ||
| ...rest, | ||
| messages, | ||
| model, | ||
| temperature, | ||
| tools: { | ||
| ...tools | ||
| }, | ||
| toolChoice, | ||
| maxSteps, | ||
| onStepFinish: async (props) => { | ||
| try { | ||
| await onStepFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_TEXT_ON_STEP_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| finishReason: props?.finishReason, | ||
| toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "", | ||
| toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Text step change", { | ||
| text: props?.text, | ||
| toolCalls: props?.toolCalls, | ||
| toolResults: props?.toolResults, | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage, | ||
| runId | ||
| }); | ||
| const remainingTokens = parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"] ?? "", 10); | ||
| if (!isNaN(remainingTokens) && remainingTokens > 0 && remainingTokens < 2e3) { | ||
| this.logger.warn("Rate limit approaching, waiting 10 seconds", { runId, remainingTokens }); | ||
| const rateLimitSpan = llmSpan?.createChildSpan({ | ||
| name: "rate-limit-sleep", | ||
| type: "generic" /* GENERIC */, | ||
| metadata: { remainingTokens, delayMs: 1e4 } | ||
| }); | ||
| await chunkB3SPPQQ3_cjs.delay(10 * 1e3); | ||
| rateLimitSpan?.end(); | ||
| } | ||
| }, | ||
| experimental_output: schema ? chunkI4YELKDU_cjs.output_exports.object({ | ||
| schema | ||
| }) : void 0 | ||
| }; | ||
| try { | ||
| const result = await chunkLP4WZA6D_cjs.executeWithContext({ | ||
| span: llmSpan, | ||
| fn: () => chunkI4YELKDU_cjs.generateText(argsForExecute) | ||
| }); | ||
| if (schema && result.finishReason === "stop") { | ||
| result.object = result.experimental_output; | ||
| } | ||
| llmSpan?.end({ | ||
| output: { | ||
| text: result.text, | ||
| object: result.object, | ||
| reasoning: result.reasoningDetails, | ||
| reasoningText: result.reasoning, | ||
| files: result.files, | ||
| sources: result.sources, | ||
| toolCalls: result.toolCalls, | ||
| warnings: result.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: result.finishReason, | ||
| responseId: result.response?.id, | ||
| responseModel: result.response?.modelId, | ||
| usage: convertV4Usage(result.usage) | ||
| } | ||
| }); | ||
| return result; | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_GENERATE_TEXT_AI_SDK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Generate text failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| async __textObject({ | ||
| messages, | ||
| structuredOutput, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| requestContext, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = chunkSZ2THGT4_cjs.resolveObservabilityContext(rest); | ||
| this.logger.debug("Generating text object", { runId }); | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature: rest.temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: false | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| try { | ||
| let output = "object"; | ||
| if (chunkCMKSC37Z_cjs.isZodArray(structuredOutput)) { | ||
| output = "array"; | ||
| const zodDef = chunkCMKSC37Z_cjs.getZodDef(structuredOutput); | ||
| if ("element" in zodDef) { | ||
| structuredOutput = zodDef.element; | ||
| } else { | ||
| structuredOutput = zodDef.type; | ||
| } | ||
| } | ||
| const processedSchema = this._applySchemaCompat(structuredOutput); | ||
| llmSpan?.update({ | ||
| input: { | ||
| messages, | ||
| schema: processedSchema | ||
| } | ||
| }); | ||
| const argsForExecute = { | ||
| ...rest, | ||
| messages, | ||
| model, | ||
| output, | ||
| schema: processedSchema | ||
| }; | ||
| try { | ||
| const result = await chunkI4YELKDU_cjs.generateObject(argsForExecute); | ||
| llmSpan?.end({ | ||
| output: { | ||
| object: result.object, | ||
| warnings: result.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: result.finishReason, | ||
| responseId: result.response?.id, | ||
| responseModel: result.response?.modelId, | ||
| usage: convertV4Usage(result.usage) | ||
| } | ||
| }); | ||
| return result; | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_GENERATE_OBJECT_AI_SDK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Generate object failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } catch (e) { | ||
| if (e instanceof chunkXSOONORA_cjs.MastraError) { | ||
| throw e; | ||
| } | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_GENERATE_OBJECT_AI_SDK_SCHEMA_CONVERSION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Generate object schema conversion failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| __stream({ | ||
| messages, | ||
| onStepFinish, | ||
| onFinish, | ||
| maxSteps = 5, | ||
| tools = {}, | ||
| runId, | ||
| temperature, | ||
| toolChoice = "auto", | ||
| experimental_output, | ||
| threadId, | ||
| resourceId, | ||
| requestContext, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = chunkSZ2THGT4_cjs.resolveObservabilityContext(rest); | ||
| let schema; | ||
| if (experimental_output) { | ||
| if (typeof experimental_output.parse === "function") { | ||
| schema = experimental_output; | ||
| if (chunkCMKSC37Z_cjs.isZodArray(schema)) { | ||
| schema = chunkCMKSC37Z_cjs.getZodDef(schema).type; | ||
| } | ||
| } else { | ||
| schema = schemaCompat.jsonSchema(experimental_output); | ||
| } | ||
| } | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: true | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| if (llmSpan) { | ||
| chunkLP4WZA6D_cjs.executeWithContextSync({ | ||
| span: llmSpan, | ||
| fn: () => this.logger.debug("Streaming text", { | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| messages, | ||
| maxSteps, | ||
| tools: Object.keys(tools || {}) | ||
| }) | ||
| }); | ||
| } | ||
| if (tools && Object.keys(tools).length > 0) { | ||
| for (const tool of Object.values(tools)) { | ||
| if (tool.parameters) { | ||
| if ("validate" in tool.parameters) { | ||
| tool.parameters = tool.parameters; | ||
| } else if (chunkXB4FLS7A_cjs.isStandardSchemaWithJSON(tool.parameters)) { | ||
| tool.parameters = schemaCompat.jsonSchema(chunkXB4FLS7A_cjs.standardSchemaToJSONSchema(tool.parameters)); | ||
| } else { | ||
| tool.parameters = schemaCompat.jsonSchema(tool.parameters); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| const argsForExecute = { | ||
| model, | ||
| temperature, | ||
| tools: { | ||
| ...tools | ||
| }, | ||
| maxSteps, | ||
| toolChoice, | ||
| onStepFinish: async (props) => { | ||
| try { | ||
| await onStepFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_ON_STEP_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| finishReason: props?.finishReason, | ||
| toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "", | ||
| toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.trackException(mastraError); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Stream step change", { | ||
| text: props?.text, | ||
| toolCalls: props?.toolCalls, | ||
| toolResults: props?.toolResults, | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage, | ||
| runId | ||
| }); | ||
| const remainingTokens = parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"] ?? "", 10); | ||
| if (!isNaN(remainingTokens) && remainingTokens > 0 && remainingTokens < 2e3) { | ||
| this.logger.warn("Rate limit approaching, waiting 10 seconds", { runId, remainingTokens }); | ||
| const rateLimitSpan = llmSpan?.createChildSpan({ | ||
| name: "rate-limit-sleep", | ||
| type: "generic" /* GENERIC */, | ||
| metadata: { remainingTokens, delayMs: 1e4 } | ||
| }); | ||
| await chunkB3SPPQQ3_cjs.delay(10 * 1e3); | ||
| rateLimitSpan?.end(); | ||
| } | ||
| }, | ||
| onFinish: async (props) => { | ||
| llmSpan?.end({ | ||
| output: { | ||
| text: props?.text, | ||
| reasoning: props?.reasoningDetails, | ||
| reasoningText: props?.reasoning, | ||
| files: props?.files, | ||
| sources: props?.sources, | ||
| toolCalls: props?.toolCalls, | ||
| warnings: props?.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: props?.finishReason, | ||
| usage: convertV4Usage(props?.usage) | ||
| } | ||
| }); | ||
| try { | ||
| await onFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_ON_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| finishReason: props?.finishReason, | ||
| toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "", | ||
| toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| llmSpan?.error({ error: mastraError }); | ||
| this.logger.trackException(mastraError); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Stream finished", { | ||
| text: props?.text, | ||
| toolCalls: props?.toolCalls, | ||
| toolResults: props?.toolResults, | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage, | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }); | ||
| }, | ||
| onError: ({ error }) => { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_TEXT_AI_SDK_STREAMING_ERROR", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| error | ||
| ); | ||
| this.logger.error("Stream text error", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| }, | ||
| ...rest, | ||
| messages, | ||
| experimental_output: schema ? chunkI4YELKDU_cjs.output_exports.object({ | ||
| schema | ||
| }) : void 0 | ||
| }; | ||
| try { | ||
| return chunkLP4WZA6D_cjs.executeWithContextSync({ span: llmSpan, fn: () => chunkI4YELKDU_cjs.streamText(argsForExecute) }); | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_TEXT_AI_SDK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Stream text failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| __streamObject({ | ||
| messages, | ||
| runId, | ||
| requestContext, | ||
| threadId, | ||
| resourceId, | ||
| onFinish, | ||
| structuredOutput, | ||
| ...rest | ||
| }) { | ||
| const model = this.#model; | ||
| const observabilityContext = chunkSZ2THGT4_cjs.resolveObservabilityContext(rest); | ||
| this.logger.debug("Streaming structured output", { | ||
| runId, | ||
| messages | ||
| }); | ||
| const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({ | ||
| name: `llm: '${model.modelId}'`, | ||
| type: "model_generation" /* MODEL_GENERATION */, | ||
| input: { | ||
| messages | ||
| }, | ||
| attributes: { | ||
| model: model.modelId, | ||
| provider: model.provider, | ||
| parameters: { | ||
| temperature: rest.temperature, | ||
| maxOutputTokens: rest.maxTokens, | ||
| topP: rest.topP, | ||
| frequencyPenalty: rest.frequencyPenalty, | ||
| presencePenalty: rest.presencePenalty | ||
| }, | ||
| streaming: true | ||
| }, | ||
| metadata: { | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }, | ||
| tracingPolicy: this.#options?.tracingPolicy, | ||
| requestContext | ||
| }); | ||
| try { | ||
| let output = "object"; | ||
| if (chunkCMKSC37Z_cjs.isZodArray(structuredOutput)) { | ||
| output = "array"; | ||
| structuredOutput = chunkCMKSC37Z_cjs.getZodDef(structuredOutput).type; | ||
| } | ||
| const processedSchema = this._applySchemaCompat(structuredOutput); | ||
| llmSpan?.update({ | ||
| input: { | ||
| messages, | ||
| schema: processedSchema | ||
| } | ||
| }); | ||
| const argsForExecute = { | ||
| ...rest, | ||
| model, | ||
| onFinish: async (props) => { | ||
| llmSpan?.end({ | ||
| output: { | ||
| text: props?.text, | ||
| object: props?.object, | ||
| reasoning: props?.reasoningDetails, | ||
| reasoningText: props?.reasoning, | ||
| files: props?.files, | ||
| sources: props?.sources, | ||
| warnings: props?.warnings | ||
| }, | ||
| attributes: { | ||
| finishReason: props?.finishReason, | ||
| usage: props?.usage | ||
| } | ||
| }); | ||
| try { | ||
| await onFinish?.({ ...props, runId }); | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_ON_FINISH_CALLBACK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown", | ||
| toolCalls: "", | ||
| toolResults: "", | ||
| finishReason: "", | ||
| usage: props?.usage ? JSON.stringify(props.usage) : "" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.trackException(mastraError); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| this.logger.debug("Object stream finished", { | ||
| usage: props?.usage, | ||
| runId, | ||
| threadId, | ||
| resourceId | ||
| }); | ||
| }, | ||
| onError: ({ error }) => { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_AI_SDK_STREAMING_ERROR", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| error | ||
| ); | ||
| this.logger.error("Stream object error", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| }, | ||
| messages, | ||
| output, | ||
| schema: processedSchema | ||
| }; | ||
| try { | ||
| return chunkI4YELKDU_cjs.streamObject(argsForExecute); | ||
| } catch (e) { | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_AI_SDK_EXECUTION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.THIRD_PARTY, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Stream object failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } catch (e) { | ||
| if (e instanceof chunkXSOONORA_cjs.MastraError) { | ||
| llmSpan?.error({ error: e }); | ||
| throw e; | ||
| } | ||
| const mastraError = new chunkXSOONORA_cjs.MastraError( | ||
| { | ||
| id: "LLM_STREAM_OBJECT_AI_SDK_SCHEMA_CONVERSION_FAILED", | ||
| domain: chunkXSOONORA_cjs.ErrorDomain.LLM, | ||
| category: chunkXSOONORA_cjs.ErrorCategory.USER, | ||
| details: { | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider, | ||
| runId: runId ?? "unknown", | ||
| threadId: threadId ?? "unknown", | ||
| resourceId: resourceId ?? "unknown" | ||
| } | ||
| }, | ||
| e | ||
| ); | ||
| this.logger.error("Stream object schema conversion failed", { | ||
| error: mastraError, | ||
| runId, | ||
| threadId, | ||
| resourceId, | ||
| modelId: model.modelId, | ||
| modelProvider: model.provider | ||
| }); | ||
| llmSpan?.error({ error: mastraError }); | ||
| throw mastraError; | ||
| } | ||
| } | ||
| convertToMessages(messages) { | ||
| if (Array.isArray(messages)) { | ||
| return messages.map((m) => { | ||
| if (typeof m === "string") { | ||
| return { | ||
| role: "user", | ||
| content: m | ||
| }; | ||
| } | ||
| return m; | ||
| }); | ||
| } | ||
| return [ | ||
| { | ||
| role: "user", | ||
| content: messages | ||
| } | ||
| ]; | ||
| } | ||
| async generate(messages, args) { | ||
| const msgs = this.convertToMessages(messages); | ||
| const { output, ...rest } = args ?? {}; | ||
| if (!output) { | ||
| return await this.__text({ | ||
| messages: msgs, | ||
| ...rest | ||
| }); | ||
| } | ||
| return await this.__textObject({ | ||
| messages: msgs, | ||
| structuredOutput: output, | ||
| ...rest | ||
| }); | ||
| } | ||
| stream(messages, args) { | ||
| const msgs = this.convertToMessages(messages); | ||
| const { output, ...rest } = args ?? {}; | ||
| if (!output) { | ||
| const { | ||
| maxSteps = 5, | ||
| onFinish: onFinish2, | ||
| ...streamRest | ||
| } = rest; | ||
| return this.__stream({ | ||
| messages: msgs, | ||
| maxSteps, | ||
| onFinish: onFinish2, | ||
| ...streamRest | ||
| }); | ||
| } | ||
| const { onFinish, ...objectRest } = rest; | ||
| return this.__streamObject({ | ||
| messages: msgs, | ||
| structuredOutput: output, | ||
| onFinish, | ||
| ...objectRest | ||
| }); | ||
| } | ||
| }; | ||
| function createStreamFromGenerateResult(result) { | ||
| return new ReadableStream({ | ||
| start(controller) { | ||
| controller.enqueue({ type: "stream-start", warnings: result.warnings }); | ||
| controller.enqueue({ | ||
| type: "response-metadata", | ||
| id: result.response?.id, | ||
| modelId: result.response?.modelId, | ||
| timestamp: result.response?.timestamp | ||
| }); | ||
| const toolCallMeta = {}; | ||
| for (const message of result.content) { | ||
| if (message.type === "tool-call") { | ||
| const toolCall = message; | ||
| toolCallMeta[toolCall.toolCallId] = { providerExecuted: toolCall.providerExecuted }; | ||
| controller.enqueue({ | ||
| type: "tool-input-start", | ||
| id: toolCall.toolCallId, | ||
| toolName: toolCall.toolName, | ||
| providerExecuted: toolCall.providerExecuted, | ||
| dynamic: toolCall.dynamic, | ||
| providerMetadata: toolCall.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "tool-input-delta", | ||
| id: toolCall.toolCallId, | ||
| delta: toolCall.input, | ||
| providerMetadata: toolCall.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "tool-input-end", | ||
| id: toolCall.toolCallId, | ||
| providerMetadata: toolCall.providerMetadata | ||
| }); | ||
| controller.enqueue(toolCall); | ||
| } else if (message.type === "tool-result") { | ||
| const toolResult = message; | ||
| const meta = toolCallMeta[toolResult.toolCallId]; | ||
| if (meta?.providerExecuted) { | ||
| controller.enqueue({ ...toolResult, providerExecuted: meta.providerExecuted }); | ||
| } else { | ||
| controller.enqueue(message); | ||
| } | ||
| } else if (message.type === "text") { | ||
| const text = message; | ||
| const id = `msg_${crypto.randomUUID()}`; | ||
| controller.enqueue({ | ||
| type: "text-start", | ||
| id, | ||
| providerMetadata: text.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "text-delta", | ||
| id, | ||
| delta: text.text | ||
| }); | ||
| controller.enqueue({ | ||
| type: "text-end", | ||
| id | ||
| }); | ||
| } else if (message.type === "reasoning") { | ||
| const id = `reasoning_${crypto.randomUUID()}`; | ||
| const reasoning = message; | ||
| controller.enqueue({ | ||
| type: "reasoning-start", | ||
| id, | ||
| providerMetadata: reasoning.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "reasoning-delta", | ||
| id, | ||
| delta: reasoning.text, | ||
| providerMetadata: reasoning.providerMetadata | ||
| }); | ||
| controller.enqueue({ | ||
| type: "reasoning-end", | ||
| id, | ||
| providerMetadata: reasoning.providerMetadata | ||
| }); | ||
| } else if (message.type === "file") { | ||
| const file = message; | ||
| controller.enqueue({ | ||
| type: "file", | ||
| mediaType: file.mediaType, | ||
| data: file.data | ||
| }); | ||
| } else if (message.type === "source") { | ||
| const source = message; | ||
| if (source.sourceType === "url") { | ||
| controller.enqueue({ | ||
| type: "source", | ||
| id: source.id, | ||
| sourceType: "url", | ||
| url: source.url, | ||
| title: source.title, | ||
| providerMetadata: source.providerMetadata | ||
| }); | ||
| } else { | ||
| controller.enqueue({ | ||
| type: "source", | ||
| id: source.id, | ||
| sourceType: "document", | ||
| mediaType: source.mediaType, | ||
| filename: source.filename, | ||
| title: source.title, | ||
| providerMetadata: source.providerMetadata | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| controller.enqueue({ | ||
| type: "finish", | ||
| finishReason: result.finishReason, | ||
| usage: result.usage, | ||
| providerMetadata: result.providerMetadata | ||
| }); | ||
| controller.close(); | ||
| } | ||
| }); | ||
| } | ||
| // src/llm/model/aisdk/v5/model.ts | ||
| function applyStrictForV2(options) { | ||
| if (!options.tools?.length) { | ||
| return options; | ||
| } | ||
| let hasStrictTool = false; | ||
| const sanitizedTools = options.tools.map((tool) => { | ||
| if (tool.type !== "function" || !("strict" in tool)) { | ||
| return tool; | ||
| } | ||
| if (tool.strict === true) { | ||
| hasStrictTool = true; | ||
| } | ||
| const { strict: _strict, ...rest } = tool; | ||
| return rest; | ||
| }); | ||
| let result = { | ||
| ...options, | ||
| tools: sanitizedTools | ||
| }; | ||
| if (hasStrictTool) { | ||
| const existingOpenai = options.providerOptions?.openai ?? {}; | ||
| if (existingOpenai.strictJsonSchema == null) { | ||
| result = { | ||
| ...result, | ||
| providerOptions: { | ||
| ...options.providerOptions, | ||
| openai: { | ||
| ...existingOpenai, | ||
| strictJsonSchema: true | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| var AISDKV5LanguageModel = class { | ||
| /** | ||
| * The language model must specify which language model interface version it implements. | ||
| */ | ||
| specificationVersion = "v2"; | ||
| /** | ||
| * Name of the provider for logging purposes. | ||
| */ | ||
| provider; | ||
| /** | ||
| * Provider-specific model ID for logging purposes. | ||
| */ | ||
| modelId; | ||
| gatewayId; | ||
| /** | ||
| * Supported URL patterns by media type for the provider. | ||
| * | ||
| * The keys are media type patterns or full media types (e.g. `*\/*` for everything, `audio/*`, `video/*`, or `application/pdf`). | ||
| * and the values are arrays of regular expressions that match the URL paths. | ||
| * The matching should be against lower-case URLs. | ||
| * Matched URLs are supported natively by the model and are not downloaded. | ||
| * @returns A map of supported URL patterns by media type (as a promise or a plain object). | ||
| */ | ||
| supportedUrls; | ||
| #model; | ||
| constructor(config) { | ||
| this.#model = config; | ||
| this.provider = this.#model.provider; | ||
| this.modelId = this.#model.modelId; | ||
| this.gatewayId = config.gatewayId; | ||
| this.supportedUrls = this.#model.supportedUrls; | ||
| } | ||
| async doGenerate(options) { | ||
| const result = await this.#model.doGenerate(applyStrictForV2(options)); | ||
| return { | ||
| ...result, | ||
| request: result.request, | ||
| response: result.response, | ||
| stream: createStreamFromGenerateResult(result) | ||
| }; | ||
| } | ||
| async doStream(options) { | ||
| return await this.#model.doStream(applyStrictForV2(options)); | ||
| } | ||
| /** | ||
| * Custom serialization for tracing/observability spans. | ||
| * `#model` is already a true JS private field and not enumerable, so | ||
| * the wrapped provider SDK client can't leak. This method makes the | ||
| * safe shape explicit and avoids walking `supportedUrls` (a | ||
| * PromiseLike / regex map that isn't useful in spans). | ||
| */ | ||
| serializeForSpan() { | ||
| return { | ||
| specificationVersion: this.specificationVersion, | ||
| modelId: this.modelId, | ||
| provider: this.provider, | ||
| gatewayId: this.gatewayId | ||
| }; | ||
| } | ||
| }; | ||
| exports.AISDKV5LanguageModel = AISDKV5LanguageModel; | ||
| exports.MastraLLMV1 = MastraLLMV1; | ||
| exports.createStreamFromGenerateResult = createStreamFromGenerateResult; | ||
| //# sourceMappingURL=chunk-WXG3GO2S.cjs.map | ||
| //# sourceMappingURL=chunk-WXG3GO2S.cjs.map |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { VersionedStorageDomain, normalizePerPage, calculatePagination, FilesystemVersionedHelpers } from './chunk-SKZRHFF3.js'; | ||
| import { deepEqual } from './chunk-MVLICRVY.js'; | ||
| // src/storage/domains/mcp-clients/base.ts | ||
| var MCPClientsStorage = class extends VersionedStorageDomain { | ||
| listKey = "mcpClients"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "mcpClientId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "MCP_CLIENTS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-clients/inmemory.ts | ||
| var InMemoryMCPClientsStorage = class extends MCPClientsStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.mcpClients.clear(); | ||
| this.db.mcpClientVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // MCP Client CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const config = this.db.mcpClients.get(id); | ||
| return config ? this.deepCopyConfig(config) : null; | ||
| } | ||
| async create(input) { | ||
| const { mcpClient } = input; | ||
| if (this.db.mcpClients.has(mcpClient.id)) { | ||
| throw new Error(`MCP client with id ${mcpClient.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newConfig = { | ||
| id: mcpClient.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpClient.authorId, | ||
| metadata: mcpClient.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.mcpClients.set(mcpClient.id, newConfig); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpClientId: mcpClient.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyConfig(newConfig); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingConfig = this.db.mcpClients.get(id); | ||
| if (!existingConfig) { | ||
| throw new Error(`MCP client with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedConfig = { | ||
| ...existingConfig, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingConfig.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpClients.set(id, updatedConfig); | ||
| return this.deepCopyConfig(updatedConfig); | ||
| } | ||
| async delete(id) { | ||
| this.db.mcpClients.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let configs = Array.from(this.db.mcpClients.values()); | ||
| if (status) { | ||
| configs = configs.filter((config) => config.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| configs = configs.filter((config) => config.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| configs = configs.filter((config) => { | ||
| if (!config.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedConfigs = this.sortConfigs(configs, field, direction); | ||
| const clonedConfigs = sortedConfigs.map((config) => this.deepCopyConfig(config)); | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| mcpClients: clonedConfigs.slice(offset, offset + perPage), | ||
| total: clonedConfigs.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedConfigs.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // MCP Client Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.mcpClientVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.mcpClientVersions.values()) { | ||
| if (version2.mcpClientId === input.mcpClientId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for MCP client ${input.mcpClientId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.mcpClientVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.mcpClientVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(mcpClientId, versionNumber) { | ||
| for (const version of this.db.mcpClientVersions.values()) { | ||
| if (version.mcpClientId === mcpClientId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(mcpClientId) { | ||
| let latest = null; | ||
| for (const version of this.db.mcpClientVersions.values()) { | ||
| if (version.mcpClientId === mcpClientId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { mcpClientId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.mcpClientVersions.values()).filter((v) => v.mcpClientId === mcpClientId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.mcpClientVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.mcpClientVersions.entries()) { | ||
| if (version.mcpClientId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.mcpClientVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(mcpClientId) { | ||
| let count = 0; | ||
| for (const version of this.db.mcpClientVersions.values()) { | ||
| if (version.mcpClientId === mcpClientId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyConfig(config) { | ||
| return { | ||
| ...config, | ||
| metadata: config.metadata ? { ...config.metadata } : config.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| servers: version.servers ? JSON.parse(JSON.stringify(version.servers)) : version.servers, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortConfigs(configs, field, direction) { | ||
| return configs.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/mcp-clients/filesystem.ts | ||
| var FilesystemMCPClientsStorage = class extends MCPClientsStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "mcp-clients.json", | ||
| parentIdField: "mcpClientId", | ||
| name: "FilesystemMCPClientsStorage", | ||
| versionMetadataFields: ["id", "mcpClientId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { mcpClient } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: mcpClient.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: mcpClient.authorId, | ||
| metadata: mcpClient.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(mcpClient.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| mcpClientId: mcpClient.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "mcpClients", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(mcpClientId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(mcpClientId, versionNumber); | ||
| } | ||
| async getLatestVersion(mcpClientId) { | ||
| return this.helpers.getLatestVersion(mcpClientId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "mcpClientId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(mcpClientId) { | ||
| return this.helpers.countVersions(mcpClientId); | ||
| } | ||
| }; | ||
| export { FilesystemMCPClientsStorage, InMemoryMCPClientsStorage, MCPClientsStorage }; | ||
| //# sourceMappingURL=chunk-XMHU3JJ7.js.map | ||
| //# sourceMappingURL=chunk-XMHU3JJ7.js.map |
| {"version":3,"sources":["../src/storage/domains/mcp-clients/base.ts","../src/storage/domains/mcp-clients/inmemory.ts","../src/storage/domains/mcp-clients/filesystem.ts"],"names":["version"],"mappings":"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","file":"chunk-XMHU3JJ7.js","sourcesContent":["import type {\n StorageMCPClientType,\n StorageMCPClientSnapshotType,\n StorageResolvedMCPClientType,\n StorageCreateMCPClientInput,\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput,\n StorageListMCPClientsOutput,\n StorageListMCPClientsResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// MCP Client Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of an MCP client's content.\n * Client fields are top-level on the version row (no nested snapshot object).\n */\nexport interface MCPClientVersion extends StorageMCPClientSnapshotType, VersionBase {\n /** ID of the MCP client this version belongs to */\n mcpClientId: string;\n}\n\n/**\n * Input for creating a new MCP client version.\n * Client fields are top-level (no nested snapshot object).\n */\nexport interface CreateMCPClientVersionInput extends StorageMCPClientSnapshotType, CreateVersionInputBase {\n /** ID of the MCP client this version belongs to */\n mcpClientId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type MCPClientVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type MCPClientVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing MCP client versions with pagination and sorting.\n */\nexport interface ListMCPClientVersionsInput extends ListVersionsInputBase {\n /** ID of the MCP client to list versions for */\n mcpClientId: string;\n}\n\n/**\n * Output for listing MCP client versions with pagination info.\n */\nexport interface ListMCPClientVersionsOutput extends ListVersionsOutputBase<MCPClientVersion> {}\n\n// ============================================================================\n// MCPClientsStorage Base Class\n// ============================================================================\n\nexport abstract class MCPClientsStorage extends VersionedStorageDomain<\n StorageMCPClientType,\n StorageMCPClientSnapshotType,\n StorageResolvedMCPClientType,\n MCPClientVersion,\n CreateMCPClientVersionInput,\n ListMCPClientVersionsInput,\n ListMCPClientVersionsOutput,\n { mcpClient: StorageCreateMCPClientInput },\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput | undefined,\n StorageListMCPClientsOutput,\n StorageListMCPClientsResolvedOutput\n> {\n protected readonly listKey = 'mcpClients';\n protected readonly versionMetadataFields = [\n 'id',\n 'mcpClientId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof MCPClientVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'MCP_CLIENTS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StorageMCPClientType,\n StorageCreateMCPClientInput,\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput,\n StorageListMCPClientsOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n MCPClientVersion,\n CreateMCPClientVersionInput,\n ListMCPClientVersionsInput,\n ListMCPClientVersionsOutput,\n MCPClientVersionOrderBy,\n MCPClientVersionSortDirection,\n} from './base';\nimport { MCPClientsStorage } from './base';\n\nexport class InMemoryMCPClientsStorage extends MCPClientsStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.mcpClients.clear();\n this.db.mcpClientVersions.clear();\n }\n\n // ==========================================================================\n // MCP Client CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StorageMCPClientType | null> {\n const config = this.db.mcpClients.get(id);\n return config ? this.deepCopyConfig(config) : null;\n }\n\n async create(input: { mcpClient: StorageCreateMCPClientInput }): Promise<StorageMCPClientType> {\n const { mcpClient } = input;\n\n if (this.db.mcpClients.has(mcpClient.id)) {\n throw new Error(`MCP client with id ${mcpClient.id} already exists`);\n }\n\n const now = new Date();\n const newConfig: StorageMCPClientType = {\n id: mcpClient.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpClient.authorId,\n metadata: mcpClient.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.mcpClients.set(mcpClient.id, newConfig);\n\n // Extract config fields from the flat input (everything except record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpClientId: mcpClient.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin record\n return this.deepCopyConfig(newConfig);\n }\n\n async update(input: StorageUpdateMCPClientInput): Promise<StorageMCPClientType> {\n const { id, ...updates } = input;\n\n const existingConfig = this.db.mcpClients.get(id);\n if (!existingConfig) {\n throw new Error(`MCP client with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the record\n const updatedConfig: StorageMCPClientType = {\n ...existingConfig,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StorageMCPClientType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingConfig.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated record\n this.db.mcpClients.set(id, updatedConfig);\n return this.deepCopyConfig(updatedConfig);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.mcpClients.delete(id);\n // Also delete all versions for this client\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListMCPClientsInput): Promise<StorageListMCPClientsOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all MCP clients and apply filters\n let configs = Array.from(this.db.mcpClients.values());\n\n // Filter by status\n if (status) {\n configs = configs.filter(config => config.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n configs = configs.filter(config => config.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n configs = configs.filter(config => {\n if (!config.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(config.metadata![key], value));\n });\n }\n\n // Sort filtered configs\n const sortedConfigs = this.sortConfigs(configs, field, direction);\n\n // Deep clone to avoid mutation\n const clonedConfigs = sortedConfigs.map(config => this.deepCopyConfig(config));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n mcpClients: clonedConfigs.slice(offset, offset + perPage),\n total: clonedConfigs.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedConfigs.length,\n };\n }\n\n // ==========================================================================\n // MCP Client Version Methods\n // ==========================================================================\n\n async createVersion(input: CreateMCPClientVersionInput): Promise<MCPClientVersion> {\n // Check if version with this ID already exists\n if (this.db.mcpClientVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (mcpClientId, versionNumber) pair\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === input.mcpClientId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for MCP client ${input.mcpClientId}`);\n }\n }\n\n const version: MCPClientVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.mcpClientVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<MCPClientVersion | null> {\n const version = this.db.mcpClientVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(mcpClientId: string, versionNumber: number): Promise<MCPClientVersion | null> {\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === mcpClientId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(mcpClientId: string): Promise<MCPClientVersion | null> {\n let latest: MCPClientVersion | null = null;\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === mcpClientId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListMCPClientVersionsInput): Promise<ListMCPClientVersionsOutput> {\n const { mcpClientId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by mcpClientId\n let versions = Array.from(this.db.mcpClientVersions.values()).filter(v => v.mcpClientId === mcpClientId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.mcpClientVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.mcpClientVersions.entries()) {\n if (version.mcpClientId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.mcpClientVersions.delete(id);\n }\n }\n\n async countVersions(mcpClientId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.mcpClientVersions.values()) {\n if (version.mcpClientId === mcpClientId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyConfig(config: StorageMCPClientType): StorageMCPClientType {\n return {\n ...config,\n metadata: config.metadata ? { ...config.metadata } : config.metadata,\n };\n }\n\n private deepCopyVersion(version: MCPClientVersion): MCPClientVersion {\n return {\n ...version,\n servers: version.servers ? JSON.parse(JSON.stringify(version.servers)) : version.servers,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortConfigs(\n configs: StorageMCPClientType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StorageMCPClientType[] {\n return configs.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: MCPClientVersion[],\n field: MCPClientVersionOrderBy,\n direction: MCPClientVersionSortDirection,\n ): MCPClientVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StorageMCPClientType,\n StorageCreateMCPClientInput,\n StorageUpdateMCPClientInput,\n StorageListMCPClientsInput,\n StorageListMCPClientsOutput,\n} from '../../types';\nimport type {\n MCPClientVersion,\n CreateMCPClientVersionInput,\n ListMCPClientVersionsInput,\n ListMCPClientVersionsOutput,\n} from './base';\nimport { MCPClientsStorage } from './base';\n\nexport class FilesystemMCPClientsStorage extends MCPClientsStorage {\n private helpers: FilesystemVersionedHelpers<StorageMCPClientType, MCPClientVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'mcp-clients.json',\n parentIdField: 'mcpClientId',\n name: 'FilesystemMCPClientsStorage',\n versionMetadataFields: ['id', 'mcpClientId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StorageMCPClientType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { mcpClient: StorageCreateMCPClientInput }): Promise<StorageMCPClientType> {\n const { mcpClient } = input;\n const now = new Date();\n const entity: StorageMCPClientType = {\n id: mcpClient.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: mcpClient.authorId,\n metadata: mcpClient.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(mcpClient.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n mcpClientId: mcpClient.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreateMCPClientVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdateMCPClientInput): Promise<StorageMCPClientType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListMCPClientsInput): Promise<StorageListMCPClientsOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'mcpClients',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListMCPClientsOutput;\n }\n\n async createVersion(input: CreateMCPClientVersionInput): Promise<MCPClientVersion> {\n return this.helpers.createVersion(input as MCPClientVersion);\n }\n\n async getVersion(id: string): Promise<MCPClientVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(mcpClientId: string, versionNumber: number): Promise<MCPClientVersion | null> {\n return this.helpers.getVersionByNumber(mcpClientId, versionNumber);\n }\n\n async getLatestVersion(mcpClientId: string): Promise<MCPClientVersion | null> {\n return this.helpers.getLatestVersion(mcpClientId);\n }\n\n async listVersions(input: ListMCPClientVersionsInput): Promise<ListMCPClientVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'mcpClientId');\n return result as ListMCPClientVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(mcpClientId: string): Promise<number> {\n return this.helpers.countVersions(mcpClientId);\n }\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import { VersionedStorageDomain, normalizePerPage, calculatePagination, FilesystemVersionedHelpers } from './chunk-SKZRHFF3.js'; | ||
| import { deepEqual } from './chunk-MVLICRVY.js'; | ||
| // src/storage/domains/prompt-blocks/base.ts | ||
| var PromptBlocksStorage = class extends VersionedStorageDomain { | ||
| listKey = "promptBlocks"; | ||
| versionMetadataFields = [ | ||
| "id", | ||
| "blockId", | ||
| "versionNumber", | ||
| "changedFields", | ||
| "changeMessage", | ||
| "createdAt" | ||
| ]; | ||
| constructor() { | ||
| super({ | ||
| component: "STORAGE", | ||
| name: "PROMPT_BLOCKS" | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/prompt-blocks/inmemory.ts | ||
| var InMemoryPromptBlocksStorage = class extends PromptBlocksStorage { | ||
| db; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.db = db; | ||
| } | ||
| async dangerouslyClearAll() { | ||
| this.db.promptBlocks.clear(); | ||
| this.db.promptBlockVersions.clear(); | ||
| } | ||
| // ========================================================================== | ||
| // Prompt Block CRUD Methods | ||
| // ========================================================================== | ||
| async getById(id) { | ||
| const block = this.db.promptBlocks.get(id); | ||
| return block ? this.deepCopyBlock(block) : null; | ||
| } | ||
| async create(input) { | ||
| const { promptBlock } = input; | ||
| if (this.db.promptBlocks.has(promptBlock.id)) { | ||
| throw new Error(`Prompt block with id ${promptBlock.id} already exists`); | ||
| } | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const newBlock = { | ||
| id: promptBlock.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: promptBlock.authorId, | ||
| metadata: promptBlock.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| this.db.promptBlocks.set(promptBlock.id, newBlock); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| blockId: promptBlock.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return this.deepCopyBlock(newBlock); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| const existingBlock = this.db.promptBlocks.get(id); | ||
| if (!existingBlock) { | ||
| throw new Error(`Prompt block with id ${id} not found`); | ||
| } | ||
| const { authorId, activeVersionId, metadata, status } = updates; | ||
| const updatedBlock = { | ||
| ...existingBlock, | ||
| ...authorId !== void 0 && { authorId }, | ||
| ...activeVersionId !== void 0 && { activeVersionId }, | ||
| ...status !== void 0 && { status }, | ||
| ...metadata !== void 0 && { | ||
| metadata: { ...existingBlock.metadata, ...metadata } | ||
| }, | ||
| updatedAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.promptBlocks.set(id, updatedBlock); | ||
| return this.deepCopyBlock(updatedBlock); | ||
| } | ||
| async delete(id) { | ||
| this.db.promptBlocks.delete(id); | ||
| await this.deleteVersionsByParentId(id); | ||
| } | ||
| async list(args) { | ||
| const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {}; | ||
| const { field, direction } = this.parseOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 100); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let blocks = Array.from(this.db.promptBlocks.values()); | ||
| if (status) { | ||
| blocks = blocks.filter((block) => block.status === status); | ||
| } | ||
| if (authorId !== void 0) { | ||
| blocks = blocks.filter((block) => block.authorId === authorId); | ||
| } | ||
| if (metadata && Object.keys(metadata).length > 0) { | ||
| blocks = blocks.filter((block) => { | ||
| if (!block.metadata) return false; | ||
| return Object.entries(metadata).every(([key, value]) => deepEqual(block.metadata[key], value)); | ||
| }); | ||
| } | ||
| const sortedBlocks = this.sortBlocks(blocks, field, direction); | ||
| const clonedBlocks = sortedBlocks.map((block) => this.deepCopyBlock(block)); | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| return { | ||
| promptBlocks: clonedBlocks.slice(offset, offset + perPage), | ||
| total: clonedBlocks.length, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < clonedBlocks.length | ||
| }; | ||
| } | ||
| // ========================================================================== | ||
| // Prompt Block Version Methods | ||
| // ========================================================================== | ||
| async createVersion(input) { | ||
| if (this.db.promptBlockVersions.has(input.id)) { | ||
| throw new Error(`Version with id ${input.id} already exists`); | ||
| } | ||
| for (const version2 of this.db.promptBlockVersions.values()) { | ||
| if (version2.blockId === input.blockId && version2.versionNumber === input.versionNumber) { | ||
| throw new Error(`Version number ${input.versionNumber} already exists for prompt block ${input.blockId}`); | ||
| } | ||
| } | ||
| const version = { | ||
| ...input, | ||
| createdAt: /* @__PURE__ */ new Date() | ||
| }; | ||
| this.db.promptBlockVersions.set(input.id, this.deepCopyVersion(version)); | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| async getVersion(id) { | ||
| const version = this.db.promptBlockVersions.get(id); | ||
| return version ? this.deepCopyVersion(version) : null; | ||
| } | ||
| async getVersionByNumber(blockId, versionNumber) { | ||
| for (const version of this.db.promptBlockVersions.values()) { | ||
| if (version.blockId === blockId && version.versionNumber === versionNumber) { | ||
| return this.deepCopyVersion(version); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| async getLatestVersion(blockId) { | ||
| let latest = null; | ||
| for (const version of this.db.promptBlockVersions.values()) { | ||
| if (version.blockId === blockId) { | ||
| if (!latest || version.versionNumber > latest.versionNumber) { | ||
| latest = version; | ||
| } | ||
| } | ||
| } | ||
| return latest ? this.deepCopyVersion(latest) : null; | ||
| } | ||
| async listVersions(input) { | ||
| const { blockId, page = 0, perPage: perPageInput, orderBy } = input; | ||
| const { field, direction } = this.parseVersionOrderBy(orderBy); | ||
| const perPage = normalizePerPage(perPageInput, 20); | ||
| if (page < 0) { | ||
| throw new Error("page must be >= 0"); | ||
| } | ||
| const maxOffset = Number.MAX_SAFE_INTEGER / 2; | ||
| if (page * perPage > maxOffset) { | ||
| throw new Error("page value too large"); | ||
| } | ||
| let versions = Array.from(this.db.promptBlockVersions.values()).filter((v) => v.blockId === blockId); | ||
| versions = this.sortVersions(versions, field, direction); | ||
| const clonedVersions = versions.map((v) => this.deepCopyVersion(v)); | ||
| const total = clonedVersions.length; | ||
| const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage); | ||
| const paginatedVersions = clonedVersions.slice(offset, offset + perPage); | ||
| return { | ||
| versions: paginatedVersions, | ||
| total, | ||
| page, | ||
| perPage: perPageForResponse, | ||
| hasMore: offset + perPage < total | ||
| }; | ||
| } | ||
| async deleteVersion(id) { | ||
| this.db.promptBlockVersions.delete(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| const idsToDelete = []; | ||
| for (const [id, version] of this.db.promptBlockVersions.entries()) { | ||
| if (version.blockId === entityId) { | ||
| idsToDelete.push(id); | ||
| } | ||
| } | ||
| for (const id of idsToDelete) { | ||
| this.db.promptBlockVersions.delete(id); | ||
| } | ||
| } | ||
| async countVersions(blockId) { | ||
| let count = 0; | ||
| for (const version of this.db.promptBlockVersions.values()) { | ||
| if (version.blockId === blockId) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
| // ========================================================================== | ||
| // Private Helper Methods | ||
| // ========================================================================== | ||
| deepCopyBlock(block) { | ||
| return { | ||
| ...block, | ||
| metadata: block.metadata ? { ...block.metadata } : block.metadata | ||
| }; | ||
| } | ||
| deepCopyVersion(version) { | ||
| return { | ||
| ...version, | ||
| rules: version.rules ? JSON.parse(JSON.stringify(version.rules)) : version.rules, | ||
| changedFields: version.changedFields ? [...version.changedFields] : version.changedFields | ||
| }; | ||
| } | ||
| sortBlocks(blocks, field, direction) { | ||
| return blocks.sort((a, b) => { | ||
| const aValue = a[field].getTime(); | ||
| const bValue = b[field].getTime(); | ||
| return direction === "ASC" ? aValue - bValue : bValue - aValue; | ||
| }); | ||
| } | ||
| sortVersions(versions, field, direction) { | ||
| return versions.sort((a, b) => { | ||
| let aVal; | ||
| let bVal; | ||
| if (field === "createdAt") { | ||
| aVal = a.createdAt.getTime(); | ||
| bVal = b.createdAt.getTime(); | ||
| } else { | ||
| aVal = a.versionNumber; | ||
| bVal = b.versionNumber; | ||
| } | ||
| return direction === "ASC" ? aVal - bVal : bVal - aVal; | ||
| }); | ||
| } | ||
| }; | ||
| // src/storage/domains/prompt-blocks/filesystem.ts | ||
| var FilesystemPromptBlocksStorage = class extends PromptBlocksStorage { | ||
| helpers; | ||
| constructor({ db }) { | ||
| super(); | ||
| this.helpers = new FilesystemVersionedHelpers({ | ||
| db, | ||
| entitiesFile: "prompt-blocks.json", | ||
| parentIdField: "blockId", | ||
| name: "FilesystemPromptBlocksStorage", | ||
| versionMetadataFields: ["id", "blockId", "versionNumber", "changedFields", "changeMessage", "createdAt"] | ||
| }); | ||
| } | ||
| async init() { | ||
| await this.helpers.db.init(); | ||
| } | ||
| async dangerouslyClearAll() { | ||
| await this.helpers.dangerouslyClearAll(); | ||
| } | ||
| async getById(id) { | ||
| return this.helpers.getById(id); | ||
| } | ||
| async create(input) { | ||
| const { promptBlock } = input; | ||
| const now = /* @__PURE__ */ new Date(); | ||
| const entity = { | ||
| id: promptBlock.id, | ||
| status: "draft", | ||
| activeVersionId: void 0, | ||
| authorId: promptBlock.authorId, | ||
| metadata: promptBlock.metadata, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }; | ||
| await this.helpers.createEntity(promptBlock.id, entity); | ||
| const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock; | ||
| const versionId = crypto.randomUUID(); | ||
| await this.createVersion({ | ||
| id: versionId, | ||
| blockId: promptBlock.id, | ||
| versionNumber: 1, | ||
| ...snapshotConfig, | ||
| changedFields: Object.keys(snapshotConfig), | ||
| changeMessage: "Initial version" | ||
| }); | ||
| return structuredClone(entity); | ||
| } | ||
| async update(input) { | ||
| const { id, ...updates } = input; | ||
| return this.helpers.updateEntity(id, updates); | ||
| } | ||
| async delete(id) { | ||
| await this.helpers.deleteEntity(id); | ||
| } | ||
| async list(args) { | ||
| const { page, perPage, orderBy, authorId, metadata, status } = args || {}; | ||
| const result = await this.helpers.listEntities({ | ||
| page, | ||
| perPage, | ||
| orderBy, | ||
| listKey: "promptBlocks", | ||
| filters: { authorId, metadata, status } | ||
| }); | ||
| return result; | ||
| } | ||
| async createVersion(input) { | ||
| return this.helpers.createVersion(input); | ||
| } | ||
| async getVersion(id) { | ||
| return this.helpers.getVersion(id); | ||
| } | ||
| async getVersionByNumber(blockId, versionNumber) { | ||
| return this.helpers.getVersionByNumber(blockId, versionNumber); | ||
| } | ||
| async getLatestVersion(blockId) { | ||
| return this.helpers.getLatestVersion(blockId); | ||
| } | ||
| async listVersions(input) { | ||
| const result = await this.helpers.listVersions(input, "blockId"); | ||
| return result; | ||
| } | ||
| async deleteVersion(id) { | ||
| await this.helpers.deleteVersion(id); | ||
| } | ||
| async deleteVersionsByParentId(entityId) { | ||
| await this.helpers.deleteVersionsByParentId(entityId); | ||
| } | ||
| async countVersions(blockId) { | ||
| return this.helpers.countVersions(blockId); | ||
| } | ||
| }; | ||
| export { FilesystemPromptBlocksStorage, InMemoryPromptBlocksStorage, PromptBlocksStorage }; | ||
| //# sourceMappingURL=chunk-Z23TV6IV.js.map | ||
| //# sourceMappingURL=chunk-Z23TV6IV.js.map |
| {"version":3,"sources":["../src/storage/domains/prompt-blocks/base.ts","../src/storage/domains/prompt-blocks/inmemory.ts","../src/storage/domains/prompt-blocks/filesystem.ts"],"names":["version"],"mappings":"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","file":"chunk-Z23TV6IV.js","sourcesContent":["import type {\n StoragePromptBlockType,\n StoragePromptBlockSnapshotType,\n StorageResolvedPromptBlockType,\n StorageCreatePromptBlockInput,\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput,\n StorageListPromptBlocksOutput,\n StorageListPromptBlocksResolvedOutput,\n} from '../../types';\nimport { VersionedStorageDomain } from '../versioned';\nimport type { VersionBase, CreateVersionInputBase, ListVersionsInputBase, ListVersionsOutputBase } from '../versioned';\n\n// ============================================================================\n// Prompt Block Version Types\n// ============================================================================\n\n/**\n * Represents a stored version of a prompt block's content.\n * Config fields are top-level on the version row (no nested snapshot object).\n */\nexport interface PromptBlockVersion extends StoragePromptBlockSnapshotType, VersionBase {\n /** ID of the prompt block this version belongs to */\n blockId: string;\n}\n\n/**\n * Input for creating a new prompt block version.\n * Config fields are top-level (no nested snapshot object).\n */\nexport interface CreatePromptBlockVersionInput extends StoragePromptBlockSnapshotType, CreateVersionInputBase {\n /** ID of the prompt block this version belongs to */\n blockId: string;\n}\n\n/**\n * Sort direction for version listings.\n */\nexport type PromptBlockVersionSortDirection = 'ASC' | 'DESC';\n\n/**\n * Fields that can be used for ordering version listings.\n */\nexport type PromptBlockVersionOrderBy = 'versionNumber' | 'createdAt';\n\n/**\n * Input for listing prompt block versions with pagination and sorting.\n */\nexport interface ListPromptBlockVersionsInput extends ListVersionsInputBase {\n /** ID of the prompt block to list versions for */\n blockId: string;\n}\n\n/**\n * Output for listing prompt block versions with pagination info.\n */\nexport interface ListPromptBlockVersionsOutput extends ListVersionsOutputBase<PromptBlockVersion> {}\n\n// ============================================================================\n// PromptBlocksStorage Base Class\n// ============================================================================\n\nexport abstract class PromptBlocksStorage extends VersionedStorageDomain<\n StoragePromptBlockType,\n StoragePromptBlockSnapshotType,\n StorageResolvedPromptBlockType,\n PromptBlockVersion,\n CreatePromptBlockVersionInput,\n ListPromptBlockVersionsInput,\n ListPromptBlockVersionsOutput,\n { promptBlock: StorageCreatePromptBlockInput },\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput | undefined,\n StorageListPromptBlocksOutput,\n StorageListPromptBlocksResolvedOutput\n> {\n protected readonly listKey = 'promptBlocks';\n protected readonly versionMetadataFields = [\n 'id',\n 'blockId',\n 'versionNumber',\n 'changedFields',\n 'changeMessage',\n 'createdAt',\n ] satisfies (keyof PromptBlockVersion)[];\n\n constructor() {\n super({\n component: 'STORAGE',\n name: 'PROMPT_BLOCKS',\n });\n }\n}\n","import { deepEqual } from '../../../utils';\nimport { normalizePerPage, calculatePagination } from '../../base';\nimport type {\n StoragePromptBlockType,\n StorageCreatePromptBlockInput,\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput,\n StorageListPromptBlocksOutput,\n ThreadOrderBy,\n ThreadSortDirection,\n} from '../../types';\nimport type { InMemoryDB } from '../inmemory-db';\nimport type {\n PromptBlockVersion,\n CreatePromptBlockVersionInput,\n ListPromptBlockVersionsInput,\n ListPromptBlockVersionsOutput,\n PromptBlockVersionOrderBy,\n PromptBlockVersionSortDirection,\n} from './base';\nimport { PromptBlocksStorage } from './base';\n\nexport class InMemoryPromptBlocksStorage extends PromptBlocksStorage {\n private db: InMemoryDB;\n\n constructor({ db }: { db: InMemoryDB }) {\n super();\n this.db = db;\n }\n\n async dangerouslyClearAll(): Promise<void> {\n this.db.promptBlocks.clear();\n this.db.promptBlockVersions.clear();\n }\n\n // ==========================================================================\n // Prompt Block CRUD Methods\n // ==========================================================================\n\n async getById(id: string): Promise<StoragePromptBlockType | null> {\n const block = this.db.promptBlocks.get(id);\n return block ? this.deepCopyBlock(block) : null;\n }\n\n async create(input: { promptBlock: StorageCreatePromptBlockInput }): Promise<StoragePromptBlockType> {\n const { promptBlock } = input;\n\n if (this.db.promptBlocks.has(promptBlock.id)) {\n throw new Error(`Prompt block with id ${promptBlock.id} already exists`);\n }\n\n const now = new Date();\n const newBlock: StoragePromptBlockType = {\n id: promptBlock.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: promptBlock.authorId,\n metadata: promptBlock.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.promptBlocks.set(promptBlock.id, newBlock);\n\n // Extract config fields from the flat input (everything except block-record fields)\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock;\n\n // Create version 1 from the config\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n blockId: promptBlock.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n });\n\n // Return the thin block record\n return this.deepCopyBlock(newBlock);\n }\n\n async update(input: StorageUpdatePromptBlockInput): Promise<StoragePromptBlockType> {\n const { id, ...updates } = input;\n\n const existingBlock = this.db.promptBlocks.get(id);\n if (!existingBlock) {\n throw new Error(`Prompt block with id ${id} not found`);\n }\n\n // Separate metadata fields from config fields\n const { authorId, activeVersionId, metadata, status } = updates;\n\n // Update metadata fields on the block record\n const updatedBlock: StoragePromptBlockType = {\n ...existingBlock,\n ...(authorId !== undefined && { authorId }),\n ...(activeVersionId !== undefined && { activeVersionId }),\n ...(status !== undefined && { status: status as StoragePromptBlockType['status'] }),\n ...(metadata !== undefined && {\n metadata: { ...existingBlock.metadata, ...metadata },\n }),\n updatedAt: new Date(),\n };\n\n // Save the updated block record\n this.db.promptBlocks.set(id, updatedBlock);\n return this.deepCopyBlock(updatedBlock);\n }\n\n async delete(id: string): Promise<void> {\n // Idempotent delete\n this.db.promptBlocks.delete(id);\n // Also delete all versions for this block\n await this.deleteVersionsByParentId(id);\n }\n\n async list(args?: StorageListPromptBlocksInput): Promise<StorageListPromptBlocksOutput> {\n const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};\n const { field, direction } = this.parseOrderBy(orderBy);\n\n // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n const perPage = normalizePerPage(perPageInput, 100);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n // Prevent unreasonably large page values\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Get all blocks and apply filters\n let blocks = Array.from(this.db.promptBlocks.values());\n\n // Filter by status\n if (status) {\n blocks = blocks.filter(block => block.status === status);\n }\n\n // Filter by authorId if provided\n if (authorId !== undefined) {\n blocks = blocks.filter(block => block.authorId === authorId);\n }\n\n // Filter by metadata if provided (AND logic)\n if (metadata && Object.keys(metadata).length > 0) {\n blocks = blocks.filter(block => {\n if (!block.metadata) return false;\n return Object.entries(metadata).every(([key, value]) => deepEqual(block.metadata![key], value));\n });\n }\n\n // Sort filtered blocks\n const sortedBlocks = this.sortBlocks(blocks, field, direction);\n\n // Deep clone blocks to avoid mutation\n const clonedBlocks = sortedBlocks.map(block => this.deepCopyBlock(block));\n\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n return {\n promptBlocks: clonedBlocks.slice(offset, offset + perPage),\n total: clonedBlocks.length,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < clonedBlocks.length,\n };\n }\n\n // ==========================================================================\n // Prompt Block Version Methods\n // ==========================================================================\n\n async createVersion(input: CreatePromptBlockVersionInput): Promise<PromptBlockVersion> {\n // Check if version with this ID already exists\n if (this.db.promptBlockVersions.has(input.id)) {\n throw new Error(`Version with id ${input.id} already exists`);\n }\n\n // Check for duplicate (blockId, versionNumber) pair\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === input.blockId && version.versionNumber === input.versionNumber) {\n throw new Error(`Version number ${input.versionNumber} already exists for prompt block ${input.blockId}`);\n }\n }\n\n const version: PromptBlockVersion = {\n ...input,\n createdAt: new Date(),\n };\n\n // Deep clone before storing\n this.db.promptBlockVersions.set(input.id, this.deepCopyVersion(version));\n return this.deepCopyVersion(version);\n }\n\n async getVersion(id: string): Promise<PromptBlockVersion | null> {\n const version = this.db.promptBlockVersions.get(id);\n return version ? this.deepCopyVersion(version) : null;\n }\n\n async getVersionByNumber(blockId: string, versionNumber: number): Promise<PromptBlockVersion | null> {\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === blockId && version.versionNumber === versionNumber) {\n return this.deepCopyVersion(version);\n }\n }\n return null;\n }\n\n async getLatestVersion(blockId: string): Promise<PromptBlockVersion | null> {\n let latest: PromptBlockVersion | null = null;\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === blockId) {\n if (!latest || version.versionNumber > latest.versionNumber) {\n latest = version;\n }\n }\n }\n return latest ? this.deepCopyVersion(latest) : null;\n }\n\n async listVersions(input: ListPromptBlockVersionsInput): Promise<ListPromptBlockVersionsOutput> {\n const { blockId, page = 0, perPage: perPageInput, orderBy } = input;\n const { field, direction } = this.parseVersionOrderBy(orderBy);\n\n // Normalize perPage (false -> MAX_SAFE_INTEGER, 0 -> 0, undefined -> 20)\n const perPage = normalizePerPage(perPageInput, 20);\n\n if (page < 0) {\n throw new Error('page must be >= 0');\n }\n\n const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n if (page * perPage > maxOffset) {\n throw new Error('page value too large');\n }\n\n // Filter versions by blockId\n let versions = Array.from(this.db.promptBlockVersions.values()).filter(v => v.blockId === blockId);\n\n // Sort versions\n versions = this.sortVersions(versions, field, direction);\n\n // Deep clone\n const clonedVersions = versions.map(v => this.deepCopyVersion(v));\n\n const total = clonedVersions.length;\n const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n const paginatedVersions = clonedVersions.slice(offset, offset + perPage);\n\n return {\n versions: paginatedVersions,\n total,\n page,\n perPage: perPageForResponse,\n hasMore: offset + perPage < total,\n };\n }\n\n async deleteVersion(id: string): Promise<void> {\n this.db.promptBlockVersions.delete(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n const idsToDelete: string[] = [];\n for (const [id, version] of this.db.promptBlockVersions.entries()) {\n if (version.blockId === entityId) {\n idsToDelete.push(id);\n }\n }\n\n for (const id of idsToDelete) {\n this.db.promptBlockVersions.delete(id);\n }\n }\n\n async countVersions(blockId: string): Promise<number> {\n let count = 0;\n for (const version of this.db.promptBlockVersions.values()) {\n if (version.blockId === blockId) {\n count++;\n }\n }\n return count;\n }\n\n // ==========================================================================\n // Private Helper Methods\n // ==========================================================================\n\n private deepCopyBlock(block: StoragePromptBlockType): StoragePromptBlockType {\n return {\n ...block,\n metadata: block.metadata ? { ...block.metadata } : block.metadata,\n };\n }\n\n private deepCopyVersion(version: PromptBlockVersion): PromptBlockVersion {\n return {\n ...version,\n rules: version.rules ? JSON.parse(JSON.stringify(version.rules)) : version.rules,\n changedFields: version.changedFields ? [...version.changedFields] : version.changedFields,\n };\n }\n\n private sortBlocks(\n blocks: StoragePromptBlockType[],\n field: ThreadOrderBy,\n direction: ThreadSortDirection,\n ): StoragePromptBlockType[] {\n return blocks.sort((a, b) => {\n const aValue = a[field].getTime();\n const bValue = b[field].getTime();\n\n return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n });\n }\n\n private sortVersions(\n versions: PromptBlockVersion[],\n field: PromptBlockVersionOrderBy,\n direction: PromptBlockVersionSortDirection,\n ): PromptBlockVersion[] {\n return versions.sort((a, b) => {\n let aVal: number;\n let bVal: number;\n\n if (field === 'createdAt') {\n aVal = a.createdAt.getTime();\n bVal = b.createdAt.getTime();\n } else {\n // versionNumber\n aVal = a.versionNumber;\n bVal = b.versionNumber;\n }\n\n return direction === 'ASC' ? aVal - bVal : bVal - aVal;\n });\n }\n}\n","import type { FilesystemDB } from '../../filesystem-db';\nimport { FilesystemVersionedHelpers } from '../../filesystem-versioned';\nimport type {\n StoragePromptBlockType,\n StorageCreatePromptBlockInput,\n StorageUpdatePromptBlockInput,\n StorageListPromptBlocksInput,\n StorageListPromptBlocksOutput,\n} from '../../types';\nimport type {\n PromptBlockVersion,\n CreatePromptBlockVersionInput,\n ListPromptBlockVersionsInput,\n ListPromptBlockVersionsOutput,\n} from './base';\nimport { PromptBlocksStorage } from './base';\n\nexport class FilesystemPromptBlocksStorage extends PromptBlocksStorage {\n private helpers: FilesystemVersionedHelpers<StoragePromptBlockType, PromptBlockVersion>;\n\n constructor({ db }: { db: FilesystemDB }) {\n super();\n this.helpers = new FilesystemVersionedHelpers({\n db,\n entitiesFile: 'prompt-blocks.json',\n parentIdField: 'blockId',\n name: 'FilesystemPromptBlocksStorage',\n versionMetadataFields: ['id', 'blockId', 'versionNumber', 'changedFields', 'changeMessage', 'createdAt'],\n });\n }\n\n override async init(): Promise<void> {\n await this.helpers.db.init();\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.helpers.dangerouslyClearAll();\n }\n\n async getById(id: string): Promise<StoragePromptBlockType | null> {\n return this.helpers.getById(id);\n }\n\n async create(input: { promptBlock: StorageCreatePromptBlockInput }): Promise<StoragePromptBlockType> {\n const { promptBlock } = input;\n const now = new Date();\n const entity: StoragePromptBlockType = {\n id: promptBlock.id,\n status: 'draft',\n activeVersionId: undefined,\n authorId: promptBlock.authorId,\n metadata: promptBlock.metadata,\n createdAt: now,\n updatedAt: now,\n };\n\n await this.helpers.createEntity(promptBlock.id, entity);\n\n const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock;\n const versionId = crypto.randomUUID();\n await this.createVersion({\n id: versionId,\n blockId: promptBlock.id,\n versionNumber: 1,\n ...snapshotConfig,\n changedFields: Object.keys(snapshotConfig),\n changeMessage: 'Initial version',\n } as CreatePromptBlockVersionInput);\n\n return structuredClone(entity);\n }\n\n async update(input: StorageUpdatePromptBlockInput): Promise<StoragePromptBlockType> {\n const { id, ...updates } = input;\n return this.helpers.updateEntity(id, updates);\n }\n\n async delete(id: string): Promise<void> {\n await this.helpers.deleteEntity(id);\n }\n\n async list(args?: StorageListPromptBlocksInput): Promise<StorageListPromptBlocksOutput> {\n const { page, perPage, orderBy, authorId, metadata, status } = args || {};\n const result = await this.helpers.listEntities({\n page,\n perPage,\n orderBy,\n listKey: 'promptBlocks',\n filters: { authorId, metadata, status },\n });\n return result as unknown as StorageListPromptBlocksOutput;\n }\n\n async createVersion(input: CreatePromptBlockVersionInput): Promise<PromptBlockVersion> {\n return this.helpers.createVersion(input as PromptBlockVersion);\n }\n\n async getVersion(id: string): Promise<PromptBlockVersion | null> {\n return this.helpers.getVersion(id);\n }\n\n async getVersionByNumber(blockId: string, versionNumber: number): Promise<PromptBlockVersion | null> {\n return this.helpers.getVersionByNumber(blockId, versionNumber);\n }\n\n async getLatestVersion(blockId: string): Promise<PromptBlockVersion | null> {\n return this.helpers.getLatestVersion(blockId);\n }\n\n async listVersions(input: ListPromptBlockVersionsInput): Promise<ListPromptBlockVersionsOutput> {\n const result = await this.helpers.listVersions(input, 'blockId');\n return result as ListPromptBlockVersionsOutput;\n }\n\n async deleteVersion(id: string): Promise<void> {\n await this.helpers.deleteVersion(id);\n }\n\n async deleteVersionsByParentId(entityId: string): Promise<void> {\n await this.helpers.deleteVersionsByParentId(entityId);\n }\n\n async countVersions(blockId: string): Promise<number> {\n return this.helpers.countVersions(blockId);\n }\n}\n"]} |
| export { MastraGateway } from './chunk-PL6DJRKR.js'; | ||
| //# sourceMappingURL=mastra-45YRC226.js.map | ||
| //# sourceMappingURL=mastra-45YRC226.js.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"mastra-45YRC226.js"} |
| 'use strict'; | ||
| var chunkMQ4ZJ5UC_cjs = require('./chunk-MQ4ZJ5UC.cjs'); | ||
| Object.defineProperty(exports, "MastraGateway", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.MastraGateway; } | ||
| }); | ||
| //# sourceMappingURL=mastra-HSNDQTVY.cjs.map | ||
| //# sourceMappingURL=mastra-HSNDQTVY.cjs.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"mastra-HSNDQTVY.cjs"} |
| 'use strict'; | ||
| var chunkYTZZBZ5Q_cjs = require('./chunk-YTZZBZ5Q.cjs'); | ||
| Object.defineProperty(exports, "ModelsDevGateway", { | ||
| enumerable: true, | ||
| get: function () { return chunkYTZZBZ5Q_cjs.ModelsDevGateway; } | ||
| }); | ||
| //# sourceMappingURL=models-dev-OJP3GQJB.cjs.map | ||
| //# sourceMappingURL=models-dev-OJP3GQJB.cjs.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"models-dev-OJP3GQJB.cjs"} |
| export { ModelsDevGateway } from './chunk-WPYY4VSL.js'; | ||
| //# sourceMappingURL=models-dev-VHFLTEKB.js.map | ||
| //# sourceMappingURL=models-dev-VHFLTEKB.js.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"models-dev-VHFLTEKB.js"} |
| export { NetlifyGateway } from './chunk-RZKMXUCM.js'; | ||
| //# sourceMappingURL=netlify-IU32N5QG.js.map | ||
| //# sourceMappingURL=netlify-IU32N5QG.js.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"netlify-IU32N5QG.js"} |
| 'use strict'; | ||
| var chunkS5VPX3LQ_cjs = require('./chunk-S5VPX3LQ.cjs'); | ||
| Object.defineProperty(exports, "NetlifyGateway", { | ||
| enumerable: true, | ||
| get: function () { return chunkS5VPX3LQ_cjs.NetlifyGateway; } | ||
| }); | ||
| //# sourceMappingURL=netlify-S5C5ADXC.cjs.map | ||
| //# sourceMappingURL=netlify-S5C5ADXC.cjs.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"netlify-S5C5ADXC.cjs"} |
| 'use strict'; | ||
| var chunkMQ4ZJ5UC_cjs = require('./chunk-MQ4ZJ5UC.cjs'); | ||
| Object.defineProperty(exports, "GatewayRegistry", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.GatewayRegistry; } | ||
| }); | ||
| Object.defineProperty(exports, "PROVIDER_MODELS", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.PROVIDER_MODELS; } | ||
| }); | ||
| Object.defineProperty(exports, "PROVIDER_REGISTRY", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.PROVIDER_REGISTRY; } | ||
| }); | ||
| Object.defineProperty(exports, "getProviderConfig", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.getProviderConfig; } | ||
| }); | ||
| Object.defineProperty(exports, "getRegisteredProviders", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.getRegisteredProviders; } | ||
| }); | ||
| Object.defineProperty(exports, "isOfflineMode", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.isOfflineMode; } | ||
| }); | ||
| Object.defineProperty(exports, "isProviderRegistered", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.isProviderRegistered; } | ||
| }); | ||
| Object.defineProperty(exports, "isValidModelId", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.isValidModelId; } | ||
| }); | ||
| Object.defineProperty(exports, "modelSupportsAttachments", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.modelSupportsAttachments; } | ||
| }); | ||
| Object.defineProperty(exports, "parseModelString", { | ||
| enumerable: true, | ||
| get: function () { return chunkMQ4ZJ5UC_cjs.parseModelString; } | ||
| }); | ||
| //# sourceMappingURL=provider-registry-S573S3LS.cjs.map | ||
| //# sourceMappingURL=provider-registry-S573S3LS.cjs.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"provider-registry-S573S3LS.cjs"} |
| export { GatewayRegistry, PROVIDER_MODELS, PROVIDER_REGISTRY, getProviderConfig, getRegisteredProviders, isOfflineMode, isProviderRegistered, isValidModelId, modelSupportsAttachments, parseModelString } from './chunk-PL6DJRKR.js'; | ||
| //# sourceMappingURL=provider-registry-TNBMPJAA.js.map | ||
| //# sourceMappingURL=provider-registry-TNBMPJAA.js.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"provider-registry-TNBMPJAA.js"} |
| 'use strict'; | ||
| var chunkMQ4ZJ5UC_cjs = require('./chunk-MQ4ZJ5UC.cjs'); | ||
| var fs = require('fs/promises'); | ||
| var path = require('path'); | ||
| function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } | ||
| var fs__default = /*#__PURE__*/_interopDefault(fs); | ||
| var path__default = /*#__PURE__*/_interopDefault(path); | ||
| function hasAttachmentCapabilities(gateway) { | ||
| return "getAttachmentCapabilities" in gateway && typeof gateway.getAttachmentCapabilities === "function"; | ||
| } | ||
| async function atomicWriteFile(filePath, content, encoding = "utf-8") { | ||
| const randomSuffix = Math.random().toString(36).substring(2, 15); | ||
| const tempPath = `${filePath}.${process.pid}.${Date.now()}.${randomSuffix}.tmp`; | ||
| try { | ||
| await fs__default.default.writeFile(tempPath, content, encoding); | ||
| await fs__default.default.rename(tempPath, filePath); | ||
| } catch (error) { | ||
| try { | ||
| await fs__default.default.unlink(tempPath); | ||
| } catch { | ||
| } | ||
| throw error; | ||
| } | ||
| } | ||
| async function fetchProvidersFromGateways(gateways) { | ||
| const enabledGateways = []; | ||
| for (const gateway of gateways) { | ||
| if (chunkMQ4ZJ5UC_cjs.shouldEnableGateway(gateway)) { | ||
| enabledGateways.push(gateway); | ||
| } | ||
| } | ||
| const allProviders = {}; | ||
| const allModels = {}; | ||
| const allAttachmentCapabilities = {}; | ||
| const failedGateways = []; | ||
| const maxRetries = 3; | ||
| for (const gateway of enabledGateways) { | ||
| let providers = null; | ||
| for (let attempt = 1; attempt <= maxRetries; attempt++) { | ||
| try { | ||
| providers = await gateway.fetchProviders(); | ||
| break; | ||
| } catch { | ||
| if (attempt < maxRetries) { | ||
| const delayMs = Math.min(1e3 * Math.pow(2, attempt - 1), 5e3); | ||
| await new Promise((resolve) => setTimeout(resolve, delayMs)); | ||
| } | ||
| } | ||
| } | ||
| if (!providers) { | ||
| failedGateways.push(chunkMQ4ZJ5UC_cjs.getGatewayId(gateway)); | ||
| continue; | ||
| } | ||
| const gatewayId = chunkMQ4ZJ5UC_cjs.getGatewayId(gateway); | ||
| const isProviderRegistry = gatewayId === "models.dev"; | ||
| const gatewayAttachmentCaps = hasAttachmentCapabilities(gateway) ? gateway.getAttachmentCapabilities() : void 0; | ||
| for (const [providerId, config] of Object.entries(providers)) { | ||
| const typeProviderId = isProviderRegistry ? providerId : providerId === gatewayId ? gatewayId : `${gatewayId}/${providerId}`; | ||
| allProviders[typeProviderId] = config; | ||
| allModels[typeProviderId] = config.models.sort(); | ||
| if (gatewayAttachmentCaps?.[providerId]) { | ||
| allAttachmentCapabilities[typeProviderId] = gatewayAttachmentCaps[providerId]; | ||
| } | ||
| } | ||
| } | ||
| return { | ||
| providers: allProviders, | ||
| models: allModels, | ||
| attachmentCapabilities: allAttachmentCapabilities, | ||
| failedGateways | ||
| }; | ||
| } | ||
| function generateTypesContent(models) { | ||
| const providerModelsEntries = Object.entries(models).map(([provider, modelList]) => { | ||
| const modelsList = modelList.map((m) => `'${m}'`); | ||
| const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(provider); | ||
| const providerKey = needsQuotes ? `'${provider}'` : provider; | ||
| const singleLine = ` readonly ${providerKey}: readonly [${modelsList.join(", ")}];`; | ||
| if (singleLine.length > 120) { | ||
| const formattedModels = modelList.map((m) => ` '${m}',`).join("\n"); | ||
| return ` readonly ${providerKey}: readonly [ | ||
| ${formattedModels} | ||
| ];`; | ||
| } | ||
| return singleLine; | ||
| }).join("\n"); | ||
| return `/** | ||
| * THIS FILE IS AUTO-GENERATED - DO NOT EDIT | ||
| * Generated from model gateway providers | ||
| */ | ||
| /** | ||
| * Provider models mapping type | ||
| * This is derived from the JSON data and provides type-safe access | ||
| */ | ||
| export type ProviderModelsMap = { | ||
| ${providerModelsEntries} | ||
| }; | ||
| /** | ||
| * Union type of all registered provider IDs | ||
| */ | ||
| export type Provider = keyof ProviderModelsMap; | ||
| /** | ||
| * Provider models mapping interface | ||
| */ | ||
| export interface ProviderModels { | ||
| [key: string]: string[]; | ||
| } | ||
| /** | ||
| * OpenAI-compatible model ID type | ||
| * Dynamically derived from ProviderModelsMap | ||
| * Full provider/model paths (e.g., "openai/gpt-4o", "anthropic/claude-3-5-sonnet-20241022") | ||
| */ | ||
| export type ModelRouterModelId = | ||
| | { | ||
| [P in Provider]: \`\${P}/\${ProviderModelsMap[P][number]}\`; | ||
| }[Provider] | ||
| | \`mastra/\${ProviderModelsMap['openrouter'][number]}\` | ||
| | (string & {}); | ||
| /** | ||
| * Extract the model part from a ModelRouterModelId for a specific provider | ||
| * Dynamically derived from ProviderModelsMap | ||
| * Example: ModelForProvider<'openai'> = 'gpt-4o' | 'gpt-4-turbo' | ... | ||
| */ | ||
| export type ModelForProvider<P extends Provider> = ProviderModelsMap[P][number]; | ||
| `; | ||
| } | ||
| async function writeRegistryFiles(jsonPath, typesPath, providers, models, attachmentCapabilities) { | ||
| const jsonDir = path__default.default.dirname(jsonPath); | ||
| const typesDir = path__default.default.dirname(typesPath); | ||
| await fs__default.default.mkdir(jsonDir, { recursive: true }); | ||
| await fs__default.default.mkdir(typesDir, { recursive: true }); | ||
| const registryData = { | ||
| providers, | ||
| models, | ||
| version: "1.0.0" | ||
| }; | ||
| await atomicWriteFile(jsonPath, JSON.stringify(registryData, null, 2), "utf-8"); | ||
| const typeContent = generateTypesContent(models); | ||
| await atomicWriteFile(typesPath, typeContent, "utf-8"); | ||
| if (attachmentCapabilities && Object.keys(attachmentCapabilities).length > 0) { | ||
| const capDir = path__default.default.join(jsonDir, "capabilities"); | ||
| await fs__default.default.mkdir(capDir, { recursive: true }); | ||
| try { | ||
| const existing = await fs__default.default.readdir(capDir); | ||
| for (const file of existing) { | ||
| if (file.endsWith(".json")) { | ||
| await fs__default.default.unlink(path__default.default.join(capDir, file)); | ||
| } | ||
| } | ||
| } catch { | ||
| } | ||
| for (const [provider, models2] of Object.entries(attachmentCapabilities)) { | ||
| const providerFile = path__default.default.join(capDir, `${provider}.json`); | ||
| await atomicWriteFile(providerFile, JSON.stringify({ attachment: models2 }, null, 2), "utf-8"); | ||
| } | ||
| } | ||
| } | ||
| exports.atomicWriteFile = atomicWriteFile; | ||
| exports.fetchProvidersFromGateways = fetchProvidersFromGateways; | ||
| exports.generateTypesContent = generateTypesContent; | ||
| exports.writeRegistryFiles = writeRegistryFiles; | ||
| //# sourceMappingURL=registry-generator-J6TNU6CO.cjs.map | ||
| //# sourceMappingURL=registry-generator-J6TNU6CO.cjs.map |
| {"version":3,"sources":["../src/llm/model/registry-generator.ts"],"names":["fs","shouldEnableGateway","getGatewayId","path","models"],"mappings":"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","file":"registry-generator-J6TNU6CO.cjs","sourcesContent":["/**\n * Shared provider registry generation logic\n * Used by both the CLI generation script and runtime refresh\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { AttachmentCapabilities, MastraModelGatewayInterface, ProviderConfig } from './gateways/base.js';\nimport { getGatewayId, shouldEnableGateway } from './gateways/index.js';\n\ninterface GatewayWithAttachmentCapabilities {\n getAttachmentCapabilities(): AttachmentCapabilities;\n}\n\nfunction hasAttachmentCapabilities(\n gateway: MastraModelGatewayInterface,\n): gateway is MastraModelGatewayInterface & GatewayWithAttachmentCapabilities {\n return (\n 'getAttachmentCapabilities' in gateway &&\n typeof (gateway as { getAttachmentCapabilities?: unknown }).getAttachmentCapabilities === 'function'\n );\n}\n\n/**\n * Write a file atomically using the write-to-temp-then-rename pattern.\n * This prevents file corruption when multiple processes write to the same file concurrently.\n *\n * The rename operation is atomic on POSIX systems when source and destination\n * are on the same filesystem.\n *\n * @param filePath - The target file path\n * @param content - The content to write\n * @param encoding - The encoding to use (default: 'utf-8')\n */\nexport async function atomicWriteFile(\n filePath: string,\n content: string,\n encoding: BufferEncoding = 'utf-8',\n): Promise<void> {\n // Create a unique temp file name using PID, timestamp, and random suffix to avoid collisions\n const randomSuffix = Math.random().toString(36).substring(2, 15);\n const tempPath = `${filePath}.${process.pid}.${Date.now()}.${randomSuffix}.tmp`;\n\n try {\n // Write to temp file first\n await fs.writeFile(tempPath, content, encoding);\n\n // Atomically rename temp file to target path\n // This is atomic on POSIX when both paths are on the same filesystem\n await fs.rename(tempPath, filePath);\n } catch (error) {\n // Clean up temp file if it exists\n try {\n await fs.unlink(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw error;\n }\n}\n\n/**\n * Fetch providers from all enabled gateways with silent retry logic.\n * Retries up to 3 times per gateway with exponential backoff. If all\n * retries are exhausted the gateway is silently skipped (no error logging)\n * since the bundled registry already contains all model data.\n * @param gateways - Array of gateway instances to fetch from\n * @returns Object containing providers and models records\n */\nexport async function fetchProvidersFromGateways(gateways: MastraModelGatewayInterface[]): Promise<{\n providers: Record<string, ProviderConfig>;\n models: Record<string, string[]>;\n attachmentCapabilities: AttachmentCapabilities;\n failedGateways: string[];\n}> {\n const enabledGateways: MastraModelGatewayInterface[] = [];\n\n for (const gateway of gateways) {\n if (shouldEnableGateway(gateway)) {\n enabledGateways.push(gateway);\n }\n }\n\n const allProviders: Record<string, ProviderConfig> = {};\n const allModels: Record<string, string[]> = {};\n const allAttachmentCapabilities: AttachmentCapabilities = {};\n const failedGateways: string[] = [];\n\n const maxRetries = 3;\n\n for (const gateway of enabledGateways) {\n let providers: Record<string, ProviderConfig> | null = null;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n providers = await gateway.fetchProviders();\n break;\n } catch {\n if (attempt < maxRetries) {\n const delayMs = Math.min(1000 * Math.pow(2, attempt - 1), 5000);\n await new Promise(resolve => setTimeout(resolve, delayMs));\n }\n }\n }\n\n if (!providers) {\n failedGateways.push(getGatewayId(gateway));\n continue;\n }\n\n const gatewayId = getGatewayId(gateway);\n // models.dev is a provider registry, not a true gateway - don't prefix its providers\n const isProviderRegistry = gatewayId === 'models.dev';\n\n // Collect attachment capabilities if the gateway exposes them\n const gatewayAttachmentCaps = hasAttachmentCapabilities(gateway) ? gateway.getAttachmentCapabilities() : undefined;\n\n for (const [providerId, config] of Object.entries(providers)) {\n // For true gateways, use gateway id as prefix (e.g., \"netlify/anthropic\")\n // Special case: if providerId matches gateway id, it's a unified gateway (e.g., azure-openai returning {azure-openai: {...}})\n // In this case, use just the gateway ID to avoid duplication (azure-openai, not azure-openai/azure-openai)\n const typeProviderId = isProviderRegistry\n ? providerId\n : providerId === gatewayId\n ? gatewayId\n : `${gatewayId}/${providerId}`;\n\n allProviders[typeProviderId] = config;\n // Sort models alphabetically for consistent ordering\n allModels[typeProviderId] = config.models.sort();\n\n // Merge attachment capabilities for this provider if available\n if (gatewayAttachmentCaps?.[providerId]) {\n allAttachmentCapabilities[typeProviderId] = gatewayAttachmentCaps[providerId];\n }\n }\n }\n\n return {\n providers: allProviders,\n models: allModels,\n attachmentCapabilities: allAttachmentCapabilities,\n failedGateways,\n };\n}\n\n/**\n * Generate TypeScript type definitions content\n * @param models - Record of provider IDs to model arrays\n * @returns Generated TypeScript type definitions as a string\n */\nexport function generateTypesContent(models: Record<string, string[]>): string {\n const providerModelsEntries = Object.entries(models)\n .map(([provider, modelList]) => {\n const modelsList = modelList.map(m => `'${m}'`);\n\n // Quote provider key if it's not a valid JavaScript identifier\n // Valid identifiers must start with a letter, underscore, or dollar sign\n const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(provider);\n const providerKey = needsQuotes ? `'${provider}'` : provider;\n\n // Format array based on length (prettier printWidth: 120)\n const singleLine = ` readonly ${providerKey}: readonly [${modelsList.join(', ')}];`;\n\n // If single line exceeds 120 chars, format as multi-line\n if (singleLine.length > 120) {\n const formattedModels = modelList.map(m => ` '${m}',`).join('\\n');\n return ` readonly ${providerKey}: readonly [\\n${formattedModels}\\n ];`;\n }\n\n return singleLine;\n })\n .join('\\n');\n\n return `/**\n * THIS FILE IS AUTO-GENERATED - DO NOT EDIT\n * Generated from model gateway providers\n */\n\n/**\n * Provider models mapping type\n * This is derived from the JSON data and provides type-safe access\n */\nexport type ProviderModelsMap = {\n${providerModelsEntries}\n};\n\n/**\n * Union type of all registered provider IDs\n */\nexport type Provider = keyof ProviderModelsMap;\n\n/**\n * Provider models mapping interface\n */\nexport interface ProviderModels {\n [key: string]: string[];\n}\n\n/**\n * OpenAI-compatible model ID type\n * Dynamically derived from ProviderModelsMap\n * Full provider/model paths (e.g., \"openai/gpt-4o\", \"anthropic/claude-3-5-sonnet-20241022\")\n */\nexport type ModelRouterModelId =\n | {\n [P in Provider]: \\`\\${P}/\\${ProviderModelsMap[P][number]}\\`;\n }[Provider]\n | \\`mastra/\\${ProviderModelsMap['openrouter'][number]}\\`\n | (string & {});\n\n/**\n * Extract the model part from a ModelRouterModelId for a specific provider\n * Dynamically derived from ProviderModelsMap\n * Example: ModelForProvider<'openai'> = 'gpt-4o' | 'gpt-4-turbo' | ...\n */\nexport type ModelForProvider<P extends Provider> = ProviderModelsMap[P][number];\n`;\n}\n\n/**\n * Write registry files to disk (JSON and .d.ts)\n * @param jsonPath - Path to write the JSON file\n * @param typesPath - Path to write the .d.ts file\n * @param providers - Provider configurations\n * @param models - Model lists by provider\n */\nexport async function writeRegistryFiles(\n jsonPath: string,\n typesPath: string,\n providers: Record<string, ProviderConfig>,\n models: Record<string, string[]>,\n attachmentCapabilities?: AttachmentCapabilities,\n): Promise<void> {\n // 0. Ensure directories exist\n const jsonDir = path.dirname(jsonPath);\n const typesDir = path.dirname(typesPath);\n await fs.mkdir(jsonDir, { recursive: true });\n await fs.mkdir(typesDir, { recursive: true });\n\n // 1. Write JSON file atomically to prevent corruption from concurrent writes\n const registryData = {\n providers,\n models,\n version: '1.0.0',\n };\n\n await atomicWriteFile(jsonPath, JSON.stringify(registryData, null, 2), 'utf-8');\n\n // 2. Generate .d.ts file with type-only declarations (also atomic)\n const typeContent = generateTypesContent(models);\n await atomicWriteFile(typesPath, typeContent, 'utf-8');\n\n // 3. Write per-provider capability files into a capabilities/ directory\n if (attachmentCapabilities && Object.keys(attachmentCapabilities).length > 0) {\n const capDir = path.join(jsonDir, 'capabilities');\n await fs.mkdir(capDir, { recursive: true });\n\n // Clean out stale provider files from previous runs\n try {\n const existing = await fs.readdir(capDir);\n for (const file of existing) {\n if (file.endsWith('.json')) {\n await fs.unlink(path.join(capDir, file));\n }\n }\n } catch {\n // Directory may not exist yet — ignore\n }\n\n for (const [provider, models] of Object.entries(attachmentCapabilities)) {\n const providerFile = path.join(capDir, `${provider}.json`);\n await atomicWriteFile(providerFile, JSON.stringify({ attachment: models }, null, 2), 'utf-8');\n }\n }\n}\n"]} |
| import { shouldEnableGateway, getGatewayId } from './chunk-PL6DJRKR.js'; | ||
| import fs from 'fs/promises'; | ||
| import path from 'path'; | ||
| function hasAttachmentCapabilities(gateway) { | ||
| return "getAttachmentCapabilities" in gateway && typeof gateway.getAttachmentCapabilities === "function"; | ||
| } | ||
| async function atomicWriteFile(filePath, content, encoding = "utf-8") { | ||
| const randomSuffix = Math.random().toString(36).substring(2, 15); | ||
| const tempPath = `${filePath}.${process.pid}.${Date.now()}.${randomSuffix}.tmp`; | ||
| try { | ||
| await fs.writeFile(tempPath, content, encoding); | ||
| await fs.rename(tempPath, filePath); | ||
| } catch (error) { | ||
| try { | ||
| await fs.unlink(tempPath); | ||
| } catch { | ||
| } | ||
| throw error; | ||
| } | ||
| } | ||
| async function fetchProvidersFromGateways(gateways) { | ||
| const enabledGateways = []; | ||
| for (const gateway of gateways) { | ||
| if (shouldEnableGateway(gateway)) { | ||
| enabledGateways.push(gateway); | ||
| } | ||
| } | ||
| const allProviders = {}; | ||
| const allModels = {}; | ||
| const allAttachmentCapabilities = {}; | ||
| const failedGateways = []; | ||
| const maxRetries = 3; | ||
| for (const gateway of enabledGateways) { | ||
| let providers = null; | ||
| for (let attempt = 1; attempt <= maxRetries; attempt++) { | ||
| try { | ||
| providers = await gateway.fetchProviders(); | ||
| break; | ||
| } catch { | ||
| if (attempt < maxRetries) { | ||
| const delayMs = Math.min(1e3 * Math.pow(2, attempt - 1), 5e3); | ||
| await new Promise((resolve) => setTimeout(resolve, delayMs)); | ||
| } | ||
| } | ||
| } | ||
| if (!providers) { | ||
| failedGateways.push(getGatewayId(gateway)); | ||
| continue; | ||
| } | ||
| const gatewayId = getGatewayId(gateway); | ||
| const isProviderRegistry = gatewayId === "models.dev"; | ||
| const gatewayAttachmentCaps = hasAttachmentCapabilities(gateway) ? gateway.getAttachmentCapabilities() : void 0; | ||
| for (const [providerId, config] of Object.entries(providers)) { | ||
| const typeProviderId = isProviderRegistry ? providerId : providerId === gatewayId ? gatewayId : `${gatewayId}/${providerId}`; | ||
| allProviders[typeProviderId] = config; | ||
| allModels[typeProviderId] = config.models.sort(); | ||
| if (gatewayAttachmentCaps?.[providerId]) { | ||
| allAttachmentCapabilities[typeProviderId] = gatewayAttachmentCaps[providerId]; | ||
| } | ||
| } | ||
| } | ||
| return { | ||
| providers: allProviders, | ||
| models: allModels, | ||
| attachmentCapabilities: allAttachmentCapabilities, | ||
| failedGateways | ||
| }; | ||
| } | ||
| function generateTypesContent(models) { | ||
| const providerModelsEntries = Object.entries(models).map(([provider, modelList]) => { | ||
| const modelsList = modelList.map((m) => `'${m}'`); | ||
| const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(provider); | ||
| const providerKey = needsQuotes ? `'${provider}'` : provider; | ||
| const singleLine = ` readonly ${providerKey}: readonly [${modelsList.join(", ")}];`; | ||
| if (singleLine.length > 120) { | ||
| const formattedModels = modelList.map((m) => ` '${m}',`).join("\n"); | ||
| return ` readonly ${providerKey}: readonly [ | ||
| ${formattedModels} | ||
| ];`; | ||
| } | ||
| return singleLine; | ||
| }).join("\n"); | ||
| return `/** | ||
| * THIS FILE IS AUTO-GENERATED - DO NOT EDIT | ||
| * Generated from model gateway providers | ||
| */ | ||
| /** | ||
| * Provider models mapping type | ||
| * This is derived from the JSON data and provides type-safe access | ||
| */ | ||
| export type ProviderModelsMap = { | ||
| ${providerModelsEntries} | ||
| }; | ||
| /** | ||
| * Union type of all registered provider IDs | ||
| */ | ||
| export type Provider = keyof ProviderModelsMap; | ||
| /** | ||
| * Provider models mapping interface | ||
| */ | ||
| export interface ProviderModels { | ||
| [key: string]: string[]; | ||
| } | ||
| /** | ||
| * OpenAI-compatible model ID type | ||
| * Dynamically derived from ProviderModelsMap | ||
| * Full provider/model paths (e.g., "openai/gpt-4o", "anthropic/claude-3-5-sonnet-20241022") | ||
| */ | ||
| export type ModelRouterModelId = | ||
| | { | ||
| [P in Provider]: \`\${P}/\${ProviderModelsMap[P][number]}\`; | ||
| }[Provider] | ||
| | \`mastra/\${ProviderModelsMap['openrouter'][number]}\` | ||
| | (string & {}); | ||
| /** | ||
| * Extract the model part from a ModelRouterModelId for a specific provider | ||
| * Dynamically derived from ProviderModelsMap | ||
| * Example: ModelForProvider<'openai'> = 'gpt-4o' | 'gpt-4-turbo' | ... | ||
| */ | ||
| export type ModelForProvider<P extends Provider> = ProviderModelsMap[P][number]; | ||
| `; | ||
| } | ||
| async function writeRegistryFiles(jsonPath, typesPath, providers, models, attachmentCapabilities) { | ||
| const jsonDir = path.dirname(jsonPath); | ||
| const typesDir = path.dirname(typesPath); | ||
| await fs.mkdir(jsonDir, { recursive: true }); | ||
| await fs.mkdir(typesDir, { recursive: true }); | ||
| const registryData = { | ||
| providers, | ||
| models, | ||
| version: "1.0.0" | ||
| }; | ||
| await atomicWriteFile(jsonPath, JSON.stringify(registryData, null, 2), "utf-8"); | ||
| const typeContent = generateTypesContent(models); | ||
| await atomicWriteFile(typesPath, typeContent, "utf-8"); | ||
| if (attachmentCapabilities && Object.keys(attachmentCapabilities).length > 0) { | ||
| const capDir = path.join(jsonDir, "capabilities"); | ||
| await fs.mkdir(capDir, { recursive: true }); | ||
| try { | ||
| const existing = await fs.readdir(capDir); | ||
| for (const file of existing) { | ||
| if (file.endsWith(".json")) { | ||
| await fs.unlink(path.join(capDir, file)); | ||
| } | ||
| } | ||
| } catch { | ||
| } | ||
| for (const [provider, models2] of Object.entries(attachmentCapabilities)) { | ||
| const providerFile = path.join(capDir, `${provider}.json`); | ||
| await atomicWriteFile(providerFile, JSON.stringify({ attachment: models2 }, null, 2), "utf-8"); | ||
| } | ||
| } | ||
| } | ||
| export { atomicWriteFile, fetchProvidersFromGateways, generateTypesContent, writeRegistryFiles }; | ||
| //# sourceMappingURL=registry-generator-KRDINXNF.js.map | ||
| //# sourceMappingURL=registry-generator-KRDINXNF.js.map |
| {"version":3,"sources":["../src/llm/model/registry-generator.ts"],"names":["models"],"mappings":"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","file":"registry-generator-KRDINXNF.js","sourcesContent":["/**\n * Shared provider registry generation logic\n * Used by both the CLI generation script and runtime refresh\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { AttachmentCapabilities, MastraModelGatewayInterface, ProviderConfig } from './gateways/base.js';\nimport { getGatewayId, shouldEnableGateway } from './gateways/index.js';\n\ninterface GatewayWithAttachmentCapabilities {\n getAttachmentCapabilities(): AttachmentCapabilities;\n}\n\nfunction hasAttachmentCapabilities(\n gateway: MastraModelGatewayInterface,\n): gateway is MastraModelGatewayInterface & GatewayWithAttachmentCapabilities {\n return (\n 'getAttachmentCapabilities' in gateway &&\n typeof (gateway as { getAttachmentCapabilities?: unknown }).getAttachmentCapabilities === 'function'\n );\n}\n\n/**\n * Write a file atomically using the write-to-temp-then-rename pattern.\n * This prevents file corruption when multiple processes write to the same file concurrently.\n *\n * The rename operation is atomic on POSIX systems when source and destination\n * are on the same filesystem.\n *\n * @param filePath - The target file path\n * @param content - The content to write\n * @param encoding - The encoding to use (default: 'utf-8')\n */\nexport async function atomicWriteFile(\n filePath: string,\n content: string,\n encoding: BufferEncoding = 'utf-8',\n): Promise<void> {\n // Create a unique temp file name using PID, timestamp, and random suffix to avoid collisions\n const randomSuffix = Math.random().toString(36).substring(2, 15);\n const tempPath = `${filePath}.${process.pid}.${Date.now()}.${randomSuffix}.tmp`;\n\n try {\n // Write to temp file first\n await fs.writeFile(tempPath, content, encoding);\n\n // Atomically rename temp file to target path\n // This is atomic on POSIX when both paths are on the same filesystem\n await fs.rename(tempPath, filePath);\n } catch (error) {\n // Clean up temp file if it exists\n try {\n await fs.unlink(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw error;\n }\n}\n\n/**\n * Fetch providers from all enabled gateways with silent retry logic.\n * Retries up to 3 times per gateway with exponential backoff. If all\n * retries are exhausted the gateway is silently skipped (no error logging)\n * since the bundled registry already contains all model data.\n * @param gateways - Array of gateway instances to fetch from\n * @returns Object containing providers and models records\n */\nexport async function fetchProvidersFromGateways(gateways: MastraModelGatewayInterface[]): Promise<{\n providers: Record<string, ProviderConfig>;\n models: Record<string, string[]>;\n attachmentCapabilities: AttachmentCapabilities;\n failedGateways: string[];\n}> {\n const enabledGateways: MastraModelGatewayInterface[] = [];\n\n for (const gateway of gateways) {\n if (shouldEnableGateway(gateway)) {\n enabledGateways.push(gateway);\n }\n }\n\n const allProviders: Record<string, ProviderConfig> = {};\n const allModels: Record<string, string[]> = {};\n const allAttachmentCapabilities: AttachmentCapabilities = {};\n const failedGateways: string[] = [];\n\n const maxRetries = 3;\n\n for (const gateway of enabledGateways) {\n let providers: Record<string, ProviderConfig> | null = null;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n providers = await gateway.fetchProviders();\n break;\n } catch {\n if (attempt < maxRetries) {\n const delayMs = Math.min(1000 * Math.pow(2, attempt - 1), 5000);\n await new Promise(resolve => setTimeout(resolve, delayMs));\n }\n }\n }\n\n if (!providers) {\n failedGateways.push(getGatewayId(gateway));\n continue;\n }\n\n const gatewayId = getGatewayId(gateway);\n // models.dev is a provider registry, not a true gateway - don't prefix its providers\n const isProviderRegistry = gatewayId === 'models.dev';\n\n // Collect attachment capabilities if the gateway exposes them\n const gatewayAttachmentCaps = hasAttachmentCapabilities(gateway) ? gateway.getAttachmentCapabilities() : undefined;\n\n for (const [providerId, config] of Object.entries(providers)) {\n // For true gateways, use gateway id as prefix (e.g., \"netlify/anthropic\")\n // Special case: if providerId matches gateway id, it's a unified gateway (e.g., azure-openai returning {azure-openai: {...}})\n // In this case, use just the gateway ID to avoid duplication (azure-openai, not azure-openai/azure-openai)\n const typeProviderId = isProviderRegistry\n ? providerId\n : providerId === gatewayId\n ? gatewayId\n : `${gatewayId}/${providerId}`;\n\n allProviders[typeProviderId] = config;\n // Sort models alphabetically for consistent ordering\n allModels[typeProviderId] = config.models.sort();\n\n // Merge attachment capabilities for this provider if available\n if (gatewayAttachmentCaps?.[providerId]) {\n allAttachmentCapabilities[typeProviderId] = gatewayAttachmentCaps[providerId];\n }\n }\n }\n\n return {\n providers: allProviders,\n models: allModels,\n attachmentCapabilities: allAttachmentCapabilities,\n failedGateways,\n };\n}\n\n/**\n * Generate TypeScript type definitions content\n * @param models - Record of provider IDs to model arrays\n * @returns Generated TypeScript type definitions as a string\n */\nexport function generateTypesContent(models: Record<string, string[]>): string {\n const providerModelsEntries = Object.entries(models)\n .map(([provider, modelList]) => {\n const modelsList = modelList.map(m => `'${m}'`);\n\n // Quote provider key if it's not a valid JavaScript identifier\n // Valid identifiers must start with a letter, underscore, or dollar sign\n const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(provider);\n const providerKey = needsQuotes ? `'${provider}'` : provider;\n\n // Format array based on length (prettier printWidth: 120)\n const singleLine = ` readonly ${providerKey}: readonly [${modelsList.join(', ')}];`;\n\n // If single line exceeds 120 chars, format as multi-line\n if (singleLine.length > 120) {\n const formattedModels = modelList.map(m => ` '${m}',`).join('\\n');\n return ` readonly ${providerKey}: readonly [\\n${formattedModels}\\n ];`;\n }\n\n return singleLine;\n })\n .join('\\n');\n\n return `/**\n * THIS FILE IS AUTO-GENERATED - DO NOT EDIT\n * Generated from model gateway providers\n */\n\n/**\n * Provider models mapping type\n * This is derived from the JSON data and provides type-safe access\n */\nexport type ProviderModelsMap = {\n${providerModelsEntries}\n};\n\n/**\n * Union type of all registered provider IDs\n */\nexport type Provider = keyof ProviderModelsMap;\n\n/**\n * Provider models mapping interface\n */\nexport interface ProviderModels {\n [key: string]: string[];\n}\n\n/**\n * OpenAI-compatible model ID type\n * Dynamically derived from ProviderModelsMap\n * Full provider/model paths (e.g., \"openai/gpt-4o\", \"anthropic/claude-3-5-sonnet-20241022\")\n */\nexport type ModelRouterModelId =\n | {\n [P in Provider]: \\`\\${P}/\\${ProviderModelsMap[P][number]}\\`;\n }[Provider]\n | \\`mastra/\\${ProviderModelsMap['openrouter'][number]}\\`\n | (string & {});\n\n/**\n * Extract the model part from a ModelRouterModelId for a specific provider\n * Dynamically derived from ProviderModelsMap\n * Example: ModelForProvider<'openai'> = 'gpt-4o' | 'gpt-4-turbo' | ...\n */\nexport type ModelForProvider<P extends Provider> = ProviderModelsMap[P][number];\n`;\n}\n\n/**\n * Write registry files to disk (JSON and .d.ts)\n * @param jsonPath - Path to write the JSON file\n * @param typesPath - Path to write the .d.ts file\n * @param providers - Provider configurations\n * @param models - Model lists by provider\n */\nexport async function writeRegistryFiles(\n jsonPath: string,\n typesPath: string,\n providers: Record<string, ProviderConfig>,\n models: Record<string, string[]>,\n attachmentCapabilities?: AttachmentCapabilities,\n): Promise<void> {\n // 0. Ensure directories exist\n const jsonDir = path.dirname(jsonPath);\n const typesDir = path.dirname(typesPath);\n await fs.mkdir(jsonDir, { recursive: true });\n await fs.mkdir(typesDir, { recursive: true });\n\n // 1. Write JSON file atomically to prevent corruption from concurrent writes\n const registryData = {\n providers,\n models,\n version: '1.0.0',\n };\n\n await atomicWriteFile(jsonPath, JSON.stringify(registryData, null, 2), 'utf-8');\n\n // 2. Generate .d.ts file with type-only declarations (also atomic)\n const typeContent = generateTypesContent(models);\n await atomicWriteFile(typesPath, typeContent, 'utf-8');\n\n // 3. Write per-provider capability files into a capabilities/ directory\n if (attachmentCapabilities && Object.keys(attachmentCapabilities).length > 0) {\n const capDir = path.join(jsonDir, 'capabilities');\n await fs.mkdir(capDir, { recursive: true });\n\n // Clean out stale provider files from previous runs\n try {\n const existing = await fs.readdir(capDir);\n for (const file of existing) {\n if (file.endsWith('.json')) {\n await fs.unlink(path.join(capDir, file));\n }\n }\n } catch {\n // Directory may not exist yet — ignore\n }\n\n for (const [provider, models] of Object.entries(attachmentCapabilities)) {\n const providerFile = path.join(capDir, `${provider}.json`);\n await atomicWriteFile(providerFile, JSON.stringify({ attachment: models }, null, 2), 'utf-8');\n }\n }\n}\n"]} |
| 'use strict'; | ||
| var chunkLZIIAAGJ_cjs = require('./chunk-LZIIAAGJ.cjs'); | ||
| Object.defineProperty(exports, "ProcessorRunner", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.ProcessorRunner; } | ||
| }); | ||
| Object.defineProperty(exports, "ProcessorState", { | ||
| enumerable: true, | ||
| get: function () { return chunkLZIIAAGJ_cjs.ProcessorState; } | ||
| }); | ||
| //# sourceMappingURL=runner-OAB4Y3WE.cjs.map | ||
| //# sourceMappingURL=runner-OAB4Y3WE.cjs.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"runner-OAB4Y3WE.cjs"} |
| export { ProcessorRunner, ProcessorState } from './chunk-HCSJNNEN.js'; | ||
| //# sourceMappingURL=runner-XNFCUA5I.js.map | ||
| //# sourceMappingURL=runner-XNFCUA5I.js.map |
| {"version":3,"sources":[],"names":[],"mappings":"","file":"runner-XNFCUA5I.js"} |
| import { createStep2, createWorkflow2 } from './chunk-MVA25X63.js'; | ||
| import { BACKGROUND_TASK_WORKFLOW_ID } from './chunk-MLZSPNYB.js'; | ||
| export { BACKGROUND_TASK_WORKFLOW_ID } from './chunk-MLZSPNYB.js'; | ||
| import { z } from 'zod'; | ||
| var inputSchema = z.object({ taskId: z.string() }); | ||
| var attemptOutcomeSchema = z.enum(["success", "retry", "cancelled", "timed_out"]); | ||
| var attemptOutputSchema = z.object({ | ||
| taskId: z.string(), | ||
| outcome: attemptOutcomeSchema, | ||
| result: z.unknown().optional(), | ||
| error: z.any().optional() | ||
| }); | ||
| var bodyIOSchema = z.object({ | ||
| taskId: z.string(), | ||
| done: z.boolean().optional(), | ||
| result: z.unknown().optional() | ||
| }); | ||
| var bodyOutputSchema = z.object({ | ||
| taskId: z.string(), | ||
| done: z.boolean(), | ||
| result: z.unknown().optional() | ||
| }); | ||
| var WORKFLOW_STATUS_TO_PERSIST = ["suspended", "pending", "paused", "waiting"]; | ||
| function buildBackgroundTaskWorkflow(manager) { | ||
| const runAttemptStep = createStep2({ | ||
| id: "run-attempt", | ||
| inputSchema: bodyIOSchema, | ||
| outputSchema: attemptOutputSchema, | ||
| execute: async ({ inputData, abortSignal: workflowAbortSignal, suspend, resumeData }) => { | ||
| const { taskId } = inputData; | ||
| const storage = await manager.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task || task.status === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, outcome: "cancelled" }; | ||
| } | ||
| const ctx = manager.taskContexts.get(taskId); | ||
| const executor = ctx?.executor ?? manager.getStaticExecutor(task.toolName); | ||
| if (!executor) { | ||
| const errorInfo = { | ||
| message: `No executor registered for tool "${task.toolName}". Register the tool on Mastra (so workers can resolve it cross-process) or run the task in the same process as the producer.` | ||
| }; | ||
| await storage.updateTask(taskId, { status: "failed", error: errorInfo, completedAt: /* @__PURE__ */ new Date() }); | ||
| const failedTask = await storage.getTask(taskId); | ||
| if (failedTask) { | ||
| await manager.runLocalCompletionHooks(failedTask, "failed", { error: errorInfo }); | ||
| await manager.publishLifecycleEvent("task.failed", failedTask); | ||
| } | ||
| manager.deregisterTaskContext(taskId); | ||
| throw new Error(errorInfo.message); | ||
| } | ||
| const progressThrottleMs = manager.config.progressThrottleMs; | ||
| const shouldThrottleProgress = typeof progressThrottleMs === "number" && Number.isFinite(progressThrottleMs) && progressThrottleMs > 0; | ||
| let lastProgressEmitMs; | ||
| const onProgress = async (chunk) => { | ||
| if (shouldThrottleProgress) { | ||
| const now = Date.now(); | ||
| if (lastProgressEmitMs !== void 0 && now - lastProgressEmitMs < progressThrottleMs) return; | ||
| lastProgressEmitMs = now; | ||
| } | ||
| await manager.publishLifecycleEvent("task.output", { ...task, chunk }); | ||
| }; | ||
| const abortController = new AbortController(); | ||
| manager.activeAbortControllers.set(taskId, abortController); | ||
| const onWorkflowAbort = () => abortController.abort(new Error("Task cancelled")); | ||
| if (workflowAbortSignal.aborted) { | ||
| abortController.abort(new Error("Task cancelled")); | ||
| } else { | ||
| workflowAbortSignal.addEventListener("abort", onWorkflowAbort, { once: true }); | ||
| } | ||
| const timeoutHandle = setTimeout(() => { | ||
| abortController.abort(new Error(`Task timed out after ${task.timeoutMs}ms`)); | ||
| }, task.timeoutMs); | ||
| let pendingSuspend; | ||
| const wrappedSuspend = async (data, suspendOptions) => { | ||
| await storage.updateTask(taskId, { | ||
| status: "suspended", | ||
| suspendPayload: data, | ||
| suspendedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| const suspendedTask = await storage.getTask(taskId); | ||
| if (suspendedTask) { | ||
| await manager.runLocalSuspendHooks(suspendedTask); | ||
| await manager.publishLifecycleEvent("task.suspended", suspendedTask); | ||
| } | ||
| pendingSuspend = { data, suspendOptions }; | ||
| }; | ||
| try { | ||
| const result = await executor.execute(task.args, { | ||
| abortSignal: abortController.signal, | ||
| onProgress, | ||
| suspend: wrappedSuspend, | ||
| // On resume the runtime populates `resumeData`; undefined on | ||
| // the initial run. | ||
| resumeData | ||
| }); | ||
| if (pendingSuspend) { | ||
| return suspend(pendingSuspend.data, pendingSuspend.suspendOptions); | ||
| } | ||
| return { taskId, outcome: "success", result }; | ||
| } catch (error) { | ||
| const currentTask = await storage.getTask(taskId); | ||
| if (!currentTask || currentTask.status === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, outcome: "cancelled" }; | ||
| } | ||
| if (abortController.signal.aborted || error?.name === "AbortError" || error?.message === "Task cancelled" || error?.message?.startsWith("Task timed out after ")) { | ||
| return { taskId, outcome: "timed_out" }; | ||
| } | ||
| return { | ||
| taskId, | ||
| outcome: "retry", | ||
| error: { message: error?.message ?? "Unknown error", stack: error?.stack } | ||
| }; | ||
| } finally { | ||
| clearTimeout(timeoutHandle); | ||
| workflowAbortSignal.removeEventListener("abort", onWorkflowAbort); | ||
| manager.activeAbortControllers.delete(taskId); | ||
| } | ||
| } | ||
| }); | ||
| const classifyOutcomeStep = createStep2({ | ||
| id: "classify-outcome", | ||
| inputSchema: attemptOutputSchema, | ||
| outputSchema: bodyOutputSchema, | ||
| execute: async ({ inputData }) => { | ||
| const { taskId, outcome, result, error } = inputData; | ||
| const storage = await manager.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task) return { taskId, done: true }; | ||
| if (outcome === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, done: true }; | ||
| } | ||
| if (outcome === "timed_out") { | ||
| const status = task.status; | ||
| if (status !== "timed_out" && status !== "cancelled") { | ||
| await storage.updateTask(taskId, { | ||
| status: "timed_out", | ||
| error: { message: `Task timed out after ${task.timeoutMs}ms` }, | ||
| completedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| const timedOutTask = await storage.getTask(taskId); | ||
| if (timedOutTask) await manager.publishLifecycleEvent("task.failed", timedOutTask); | ||
| } | ||
| return { taskId, done: true }; | ||
| } | ||
| if (outcome === "success") { | ||
| if (task.status === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, done: true }; | ||
| } | ||
| await storage.updateTask(taskId, { status: "completed", result, completedAt: /* @__PURE__ */ new Date() }); | ||
| const completedTask = await storage.getTask(taskId); | ||
| if (completedTask) { | ||
| await manager.runLocalCompletionHooks(completedTask, "completed", { result }); | ||
| await manager.publishLifecycleEvent("task.completed", completedTask); | ||
| } | ||
| return { taskId, done: true, result }; | ||
| } | ||
| if (task.retryCount < task.maxRetries) { | ||
| await storage.updateTask(taskId, { | ||
| retryCount: task.retryCount + 1, | ||
| error: void 0, | ||
| startedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| return { taskId, done: false }; | ||
| } | ||
| const errorInfo = error ?? { message: "Unknown error" }; | ||
| await storage.updateTask(taskId, { status: "failed", error: errorInfo, completedAt: /* @__PURE__ */ new Date() }); | ||
| const failedTask = await storage.getTask(taskId); | ||
| if (failedTask) { | ||
| await manager.runLocalCompletionHooks(failedTask, "failed", { error: errorInfo }); | ||
| await manager.publishLifecycleEvent("task.failed", failedTask); | ||
| } | ||
| const thrown = new Error(errorInfo.message); | ||
| if (errorInfo.stack) thrown.stack = errorInfo.stack; | ||
| throw thrown; | ||
| } | ||
| }); | ||
| const attemptBodyWorkflow = createWorkflow2({ | ||
| id: `${BACKGROUND_TASK_WORKFLOW_ID}__attempt`, | ||
| inputSchema: bodyIOSchema, | ||
| outputSchema: bodyOutputSchema, | ||
| steps: [runAttemptStep, classifyOutcomeStep], | ||
| options: { | ||
| // `dountil` feeds the prior iteration's output back in as input. The | ||
| // body's actual entry point only needs `taskId`, but the loop's | ||
| // feedback shape includes `done`/`result`/etc. Skip validation rather | ||
| // than widen every step's input schema. | ||
| validateInputs: false, | ||
| shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus), | ||
| // Internal scheduler plumbing — hide workflow spans from exported | ||
| // traces. The task body itself runs as user code and keeps its own | ||
| // spans. | ||
| tracingPolicy: { | ||
| internal: 1 /* WORKFLOW */ | ||
| } | ||
| } | ||
| }).then(runAttemptStep).then(classifyOutcomeStep).commit(); | ||
| return createWorkflow2({ | ||
| id: BACKGROUND_TASK_WORKFLOW_ID, | ||
| inputSchema, | ||
| outputSchema: bodyOutputSchema, | ||
| steps: [attemptBodyWorkflow], | ||
| options: { | ||
| shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus), | ||
| // Internal scheduler plumbing — see the inner workflow comment. | ||
| tracingPolicy: { | ||
| internal: 1 /* WORKFLOW */ | ||
| } | ||
| } | ||
| }).dountil(attemptBodyWorkflow, async ({ inputData }) => inputData?.done === true).commit(); | ||
| } | ||
| export { buildBackgroundTaskWorkflow }; | ||
| //# sourceMappingURL=workflow-636ISDPH.js.map | ||
| //# sourceMappingURL=workflow-636ISDPH.js.map |
| {"version":3,"sources":["../src/background-tasks/workflow.ts"],"names":["createStep","createWorkflow"],"mappings":"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","file":"workflow-636ISDPH.js","sourcesContent":["import { z } from 'zod';\nimport { InternalSpans } from '../observability';\nimport type { SuspendOptions } from '../workflows';\nimport { createStep, createWorkflow } from '../workflows/evented';\nimport type { BackgroundTaskManager } from './manager';\nimport type { BackgroundTaskStatus } from './types';\nimport { BACKGROUND_TASK_WORKFLOW_ID } from './workflow-id';\n\nexport { BACKGROUND_TASK_WORKFLOW_ID } from './workflow-id';\n\nconst inputSchema = z.object({ taskId: z.string() });\n\nconst attemptOutcomeSchema = z.enum(['success', 'retry', 'cancelled', 'timed_out']);\n\nconst attemptOutputSchema = z.object({\n taskId: z.string(),\n outcome: attemptOutcomeSchema,\n result: z.unknown().optional(),\n error: z.any().optional(),\n});\n\nconst bodyIOSchema = z.object({\n taskId: z.string(),\n done: z.boolean().optional(),\n result: z.unknown().optional(),\n});\n\nconst bodyOutputSchema = z.object({\n taskId: z.string(),\n done: z.boolean(),\n result: z.unknown().optional(),\n});\n\nconst WORKFLOW_STATUS_TO_PERSIST = ['suspended', 'pending', 'paused', 'waiting'];\n\n/**\n * Builds the per-task evented workflow that owns executor + retries.\n *\n * Shape: outer workflow runs an inner `[run-attempt, classify-outcome]`\n * workflow inside a `dountil` loop. `run-attempt` invokes the executor and\n * categorises the outcome; `classify-outcome` persists final state, advances\n * retry bookkeeping, and decides whether the loop is done. The dountil\n * predicate exits on `done === true`.\n *\n * The nested-workflow-as-loop-body path lives in\n * `processWorkflowEnd → processWorkflowLoop` and was fixed in PR #16312.\n * Suspend/resume routes through the runtime's nested-workflow auto-detect\n * (`processWorkflowStepRun` resume branch).\n *\n * Step bodies close over `manager` directly — the bg-tasks layer is the only\n * consumer of the `@internal` private fields.\n */\nexport function buildBackgroundTaskWorkflow(manager: BackgroundTaskManager) {\n const runAttemptStep = createStep({\n id: 'run-attempt',\n inputSchema: bodyIOSchema,\n outputSchema: attemptOutputSchema,\n execute: async ({ inputData, abortSignal: workflowAbortSignal, suspend, resumeData }) => {\n const { taskId } = inputData;\n const storage = await manager.getStorage();\n const task = await storage.getTask(taskId);\n if (!task || task.status === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, outcome: 'cancelled' as const };\n }\n\n // Resolve the executor. Two paths:\n // 1. Per-task `TaskContext` registered on the producer (in-process).\n // Carries closure-captured state (e.g. agent memory hooks) and\n // wins when present.\n // 2. Static executor registered by tool name. Used by remote workers\n // that received the dispatch via PubSub and don't have access to\n // the producer's per-task closure.\n const ctx = manager.taskContexts.get(taskId);\n const executor = ctx?.executor ?? manager.getStaticExecutor(task.toolName);\n if (!executor) {\n const errorInfo = {\n message:\n `No executor registered for tool \"${task.toolName}\". ` +\n `Register the tool on Mastra (so workers can resolve it cross-process) ` +\n `or run the task in the same process as the producer.`,\n };\n await storage.updateTask(taskId, { status: 'failed', error: errorInfo, completedAt: new Date() });\n const failedTask = await storage.getTask(taskId);\n if (failedTask) {\n await manager.runLocalCompletionHooks(failedTask, 'failed', { error: errorInfo });\n await manager.publishLifecycleEvent('task.failed', failedTask);\n }\n manager.deregisterTaskContext(taskId);\n throw new Error(errorInfo.message);\n }\n\n // Throttled progress publisher.\n const progressThrottleMs = manager.config.progressThrottleMs;\n const shouldThrottleProgress =\n typeof progressThrottleMs === 'number' && Number.isFinite(progressThrottleMs) && progressThrottleMs > 0;\n let lastProgressEmitMs: number | undefined;\n const onProgress = async (chunk: any) => {\n if (shouldThrottleProgress) {\n const now = Date.now();\n if (lastProgressEmitMs !== undefined && now - lastProgressEmitMs < progressThrottleMs!) return;\n lastProgressEmitMs = now;\n }\n await manager.publishLifecycleEvent('task.output', { ...task, chunk });\n };\n\n const abortController = new AbortController();\n manager.activeAbortControllers.set(taskId, abortController);\n // Wire the workflow's run-level abort signal into our local controller\n // so `workflow.getRun(taskId).cancel()` propagates to the executor.\n const onWorkflowAbort = () => abortController.abort(new Error('Task cancelled'));\n if (workflowAbortSignal.aborted) {\n abortController.abort(new Error('Task cancelled'));\n } else {\n workflowAbortSignal.addEventListener('abort', onWorkflowAbort, { once: true });\n }\n const timeoutHandle = setTimeout(() => {\n abortController.abort(new Error(`Task timed out after ${task.timeoutMs}ms`));\n }, task.timeoutMs);\n\n // Wrap the workflow runtime's `suspend` so we persist\n // `status: 'suspended'` + `suspendPayload`, fire the per-task\n // suspend hook (so the bg-task's `onResult` updates the agent's\n // message list), and publish the lifecycle event before\n // delegating. The runtime's `suspend` does not throw — it sets a\n // flag the step-executor reads after `execute` returns. We\n // capture the args here and call the runtime's suspend from the\n // step body after the executor returns, so `wrappedSuspend` can\n // safely run all its side effects synchronously inside the\n // tool's call.\n let pendingSuspend: { data?: unknown; suspendOptions?: SuspendOptions } | undefined;\n const wrappedSuspend = async (data?: unknown, suspendOptions?: SuspendOptions) => {\n await storage.updateTask(taskId, {\n status: 'suspended',\n suspendPayload: data,\n suspendedAt: new Date(),\n });\n const suspendedTask = await storage.getTask(taskId);\n if (suspendedTask) {\n // Suspend is non-terminal — DO NOT use `runLocalCompletionHooks`\n // here. That helper deregisters the task context in its `finally`\n // block, which would strand the resume call (the workflow step\n // body re-enters and looks up `manager.taskContexts.get(taskId)`).\n await manager.runLocalSuspendHooks(suspendedTask);\n await manager.publishLifecycleEvent('task.suspended', suspendedTask);\n }\n pendingSuspend = { data, suspendOptions };\n };\n\n try {\n const result = await executor.execute(task.args, {\n abortSignal: abortController.signal,\n onProgress,\n suspend: wrappedSuspend,\n // On resume the runtime populates `resumeData`; undefined on\n // the initial run.\n resumeData,\n });\n\n if (pendingSuspend) {\n return suspend(pendingSuspend.data, pendingSuspend.suspendOptions as SuspendOptions);\n }\n\n return { taskId, outcome: 'success' as const, result };\n } catch (error: any) {\n const currentTask = await storage.getTask(taskId);\n if (!currentTask || (currentTask.status as BackgroundTaskStatus) === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, outcome: 'cancelled' as const };\n }\n\n // Treat any aborted-signal exit as a timeout. The cancel path is\n // already handled by the storage-status check above, so if we reach\n // here with `signal.aborted`, it's the timeout abort. The\n // `AbortError` / message checks are belt-and-braces for executors\n // that throw their own abort error instead of propagating ours.\n if (\n abortController.signal.aborted ||\n error?.name === 'AbortError' ||\n error?.message === 'Task cancelled' ||\n error?.message?.startsWith('Task timed out after ')\n ) {\n return { taskId, outcome: 'timed_out' as const };\n }\n\n return {\n taskId,\n outcome: 'retry' as const,\n error: { message: error?.message ?? 'Unknown error', stack: error?.stack },\n };\n } finally {\n clearTimeout(timeoutHandle);\n workflowAbortSignal.removeEventListener('abort', onWorkflowAbort);\n manager.activeAbortControllers.delete(taskId);\n }\n },\n });\n\n const classifyOutcomeStep = createStep({\n id: 'classify-outcome',\n inputSchema: attemptOutputSchema,\n outputSchema: bodyOutputSchema,\n execute: async ({ inputData }) => {\n const { taskId, outcome, result, error } = inputData;\n const storage = await manager.getStorage();\n const task = await storage.getTask(taskId);\n if (!task) return { taskId, done: true };\n\n if (outcome === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, done: true };\n }\n\n if (outcome === 'timed_out') {\n const status = task.status as string;\n if (status !== 'timed_out' && status !== 'cancelled') {\n await storage.updateTask(taskId, {\n status: 'timed_out',\n error: { message: `Task timed out after ${task.timeoutMs}ms` },\n completedAt: new Date(),\n });\n const timedOutTask = await storage.getTask(taskId);\n if (timedOutTask) await manager.publishLifecycleEvent('task.failed', timedOutTask);\n }\n return { taskId, done: true };\n }\n\n if (outcome === 'success') {\n if ((task.status as BackgroundTaskStatus) === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, done: true };\n }\n await storage.updateTask(taskId, { status: 'completed', result, completedAt: new Date() });\n const completedTask = await storage.getTask(taskId);\n if (completedTask) {\n await manager.runLocalCompletionHooks(completedTask, 'completed', { result });\n await manager.publishLifecycleEvent('task.completed', completedTask);\n }\n return { taskId, done: true, result };\n }\n\n // outcome === 'retry'\n if (task.retryCount < task.maxRetries) {\n await storage.updateTask(taskId, {\n retryCount: task.retryCount + 1,\n error: undefined,\n startedAt: new Date(),\n });\n return { taskId, done: false };\n }\n\n // Retries exhausted: persist failure and throw so the workflow run ends\n // in `failed` rather than completing cleanly. Throw matches the prior\n // single-step behavior — workflow-run history stays accurate.\n const errorInfo = error ?? { message: 'Unknown error' };\n await storage.updateTask(taskId, { status: 'failed', error: errorInfo, completedAt: new Date() });\n const failedTask = await storage.getTask(taskId);\n if (failedTask) {\n await manager.runLocalCompletionHooks(failedTask, 'failed', { error: errorInfo });\n await manager.publishLifecycleEvent('task.failed', failedTask);\n }\n const thrown = new Error(errorInfo.message);\n if (errorInfo.stack) thrown.stack = errorInfo.stack;\n throw thrown;\n },\n });\n\n const attemptBodyWorkflow = createWorkflow({\n id: `${BACKGROUND_TASK_WORKFLOW_ID}__attempt`,\n inputSchema: bodyIOSchema,\n outputSchema: bodyOutputSchema,\n steps: [runAttemptStep, classifyOutcomeStep],\n options: {\n // `dountil` feeds the prior iteration's output back in as input. The\n // body's actual entry point only needs `taskId`, but the loop's\n // feedback shape includes `done`/`result`/etc. Skip validation rather\n // than widen every step's input schema.\n validateInputs: false,\n shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus),\n // Internal scheduler plumbing — hide workflow spans from exported\n // traces. The task body itself runs as user code and keeps its own\n // spans.\n tracingPolicy: {\n internal: InternalSpans.WORKFLOW,\n },\n },\n })\n .then(runAttemptStep)\n .then(classifyOutcomeStep)\n .commit();\n\n return createWorkflow({\n id: BACKGROUND_TASK_WORKFLOW_ID,\n inputSchema,\n outputSchema: bodyOutputSchema,\n steps: [attemptBodyWorkflow],\n options: {\n shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus),\n // Internal scheduler plumbing — see the inner workflow comment.\n tracingPolicy: {\n internal: InternalSpans.WORKFLOW,\n },\n },\n })\n .dountil(attemptBodyWorkflow, async ({ inputData }) => inputData?.done === true)\n .commit();\n}\n"]} |
| 'use strict'; | ||
| var chunkGSWZYCY4_cjs = require('./chunk-GSWZYCY4.cjs'); | ||
| var chunkBHNX447S_cjs = require('./chunk-BHNX447S.cjs'); | ||
| var zod = require('zod'); | ||
| var inputSchema = zod.z.object({ taskId: zod.z.string() }); | ||
| var attemptOutcomeSchema = zod.z.enum(["success", "retry", "cancelled", "timed_out"]); | ||
| var attemptOutputSchema = zod.z.object({ | ||
| taskId: zod.z.string(), | ||
| outcome: attemptOutcomeSchema, | ||
| result: zod.z.unknown().optional(), | ||
| error: zod.z.any().optional() | ||
| }); | ||
| var bodyIOSchema = zod.z.object({ | ||
| taskId: zod.z.string(), | ||
| done: zod.z.boolean().optional(), | ||
| result: zod.z.unknown().optional() | ||
| }); | ||
| var bodyOutputSchema = zod.z.object({ | ||
| taskId: zod.z.string(), | ||
| done: zod.z.boolean(), | ||
| result: zod.z.unknown().optional() | ||
| }); | ||
| var WORKFLOW_STATUS_TO_PERSIST = ["suspended", "pending", "paused", "waiting"]; | ||
| function buildBackgroundTaskWorkflow(manager) { | ||
| const runAttemptStep = chunkGSWZYCY4_cjs.createStep2({ | ||
| id: "run-attempt", | ||
| inputSchema: bodyIOSchema, | ||
| outputSchema: attemptOutputSchema, | ||
| execute: async ({ inputData, abortSignal: workflowAbortSignal, suspend, resumeData }) => { | ||
| const { taskId } = inputData; | ||
| const storage = await manager.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task || task.status === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, outcome: "cancelled" }; | ||
| } | ||
| const ctx = manager.taskContexts.get(taskId); | ||
| const executor = ctx?.executor ?? manager.getStaticExecutor(task.toolName); | ||
| if (!executor) { | ||
| const errorInfo = { | ||
| message: `No executor registered for tool "${task.toolName}". Register the tool on Mastra (so workers can resolve it cross-process) or run the task in the same process as the producer.` | ||
| }; | ||
| await storage.updateTask(taskId, { status: "failed", error: errorInfo, completedAt: /* @__PURE__ */ new Date() }); | ||
| const failedTask = await storage.getTask(taskId); | ||
| if (failedTask) { | ||
| await manager.runLocalCompletionHooks(failedTask, "failed", { error: errorInfo }); | ||
| await manager.publishLifecycleEvent("task.failed", failedTask); | ||
| } | ||
| manager.deregisterTaskContext(taskId); | ||
| throw new Error(errorInfo.message); | ||
| } | ||
| const progressThrottleMs = manager.config.progressThrottleMs; | ||
| const shouldThrottleProgress = typeof progressThrottleMs === "number" && Number.isFinite(progressThrottleMs) && progressThrottleMs > 0; | ||
| let lastProgressEmitMs; | ||
| const onProgress = async (chunk) => { | ||
| if (shouldThrottleProgress) { | ||
| const now = Date.now(); | ||
| if (lastProgressEmitMs !== void 0 && now - lastProgressEmitMs < progressThrottleMs) return; | ||
| lastProgressEmitMs = now; | ||
| } | ||
| await manager.publishLifecycleEvent("task.output", { ...task, chunk }); | ||
| }; | ||
| const abortController = new AbortController(); | ||
| manager.activeAbortControllers.set(taskId, abortController); | ||
| const onWorkflowAbort = () => abortController.abort(new Error("Task cancelled")); | ||
| if (workflowAbortSignal.aborted) { | ||
| abortController.abort(new Error("Task cancelled")); | ||
| } else { | ||
| workflowAbortSignal.addEventListener("abort", onWorkflowAbort, { once: true }); | ||
| } | ||
| const timeoutHandle = setTimeout(() => { | ||
| abortController.abort(new Error(`Task timed out after ${task.timeoutMs}ms`)); | ||
| }, task.timeoutMs); | ||
| let pendingSuspend; | ||
| const wrappedSuspend = async (data, suspendOptions) => { | ||
| await storage.updateTask(taskId, { | ||
| status: "suspended", | ||
| suspendPayload: data, | ||
| suspendedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| const suspendedTask = await storage.getTask(taskId); | ||
| if (suspendedTask) { | ||
| await manager.runLocalSuspendHooks(suspendedTask); | ||
| await manager.publishLifecycleEvent("task.suspended", suspendedTask); | ||
| } | ||
| pendingSuspend = { data, suspendOptions }; | ||
| }; | ||
| try { | ||
| const result = await executor.execute(task.args, { | ||
| abortSignal: abortController.signal, | ||
| onProgress, | ||
| suspend: wrappedSuspend, | ||
| // On resume the runtime populates `resumeData`; undefined on | ||
| // the initial run. | ||
| resumeData | ||
| }); | ||
| if (pendingSuspend) { | ||
| return suspend(pendingSuspend.data, pendingSuspend.suspendOptions); | ||
| } | ||
| return { taskId, outcome: "success", result }; | ||
| } catch (error) { | ||
| const currentTask = await storage.getTask(taskId); | ||
| if (!currentTask || currentTask.status === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, outcome: "cancelled" }; | ||
| } | ||
| if (abortController.signal.aborted || error?.name === "AbortError" || error?.message === "Task cancelled" || error?.message?.startsWith("Task timed out after ")) { | ||
| return { taskId, outcome: "timed_out" }; | ||
| } | ||
| return { | ||
| taskId, | ||
| outcome: "retry", | ||
| error: { message: error?.message ?? "Unknown error", stack: error?.stack } | ||
| }; | ||
| } finally { | ||
| clearTimeout(timeoutHandle); | ||
| workflowAbortSignal.removeEventListener("abort", onWorkflowAbort); | ||
| manager.activeAbortControllers.delete(taskId); | ||
| } | ||
| } | ||
| }); | ||
| const classifyOutcomeStep = chunkGSWZYCY4_cjs.createStep2({ | ||
| id: "classify-outcome", | ||
| inputSchema: attemptOutputSchema, | ||
| outputSchema: bodyOutputSchema, | ||
| execute: async ({ inputData }) => { | ||
| const { taskId, outcome, result, error } = inputData; | ||
| const storage = await manager.getStorage(); | ||
| const task = await storage.getTask(taskId); | ||
| if (!task) return { taskId, done: true }; | ||
| if (outcome === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, done: true }; | ||
| } | ||
| if (outcome === "timed_out") { | ||
| const status = task.status; | ||
| if (status !== "timed_out" && status !== "cancelled") { | ||
| await storage.updateTask(taskId, { | ||
| status: "timed_out", | ||
| error: { message: `Task timed out after ${task.timeoutMs}ms` }, | ||
| completedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| const timedOutTask = await storage.getTask(taskId); | ||
| if (timedOutTask) await manager.publishLifecycleEvent("task.failed", timedOutTask); | ||
| } | ||
| return { taskId, done: true }; | ||
| } | ||
| if (outcome === "success") { | ||
| if (task.status === "cancelled") { | ||
| manager.deregisterTaskContext(taskId); | ||
| return { taskId, done: true }; | ||
| } | ||
| await storage.updateTask(taskId, { status: "completed", result, completedAt: /* @__PURE__ */ new Date() }); | ||
| const completedTask = await storage.getTask(taskId); | ||
| if (completedTask) { | ||
| await manager.runLocalCompletionHooks(completedTask, "completed", { result }); | ||
| await manager.publishLifecycleEvent("task.completed", completedTask); | ||
| } | ||
| return { taskId, done: true, result }; | ||
| } | ||
| if (task.retryCount < task.maxRetries) { | ||
| await storage.updateTask(taskId, { | ||
| retryCount: task.retryCount + 1, | ||
| error: void 0, | ||
| startedAt: /* @__PURE__ */ new Date() | ||
| }); | ||
| return { taskId, done: false }; | ||
| } | ||
| const errorInfo = error ?? { message: "Unknown error" }; | ||
| await storage.updateTask(taskId, { status: "failed", error: errorInfo, completedAt: /* @__PURE__ */ new Date() }); | ||
| const failedTask = await storage.getTask(taskId); | ||
| if (failedTask) { | ||
| await manager.runLocalCompletionHooks(failedTask, "failed", { error: errorInfo }); | ||
| await manager.publishLifecycleEvent("task.failed", failedTask); | ||
| } | ||
| const thrown = new Error(errorInfo.message); | ||
| if (errorInfo.stack) thrown.stack = errorInfo.stack; | ||
| throw thrown; | ||
| } | ||
| }); | ||
| const attemptBodyWorkflow = chunkGSWZYCY4_cjs.createWorkflow2({ | ||
| id: `${chunkBHNX447S_cjs.BACKGROUND_TASK_WORKFLOW_ID}__attempt`, | ||
| inputSchema: bodyIOSchema, | ||
| outputSchema: bodyOutputSchema, | ||
| steps: [runAttemptStep, classifyOutcomeStep], | ||
| options: { | ||
| // `dountil` feeds the prior iteration's output back in as input. The | ||
| // body's actual entry point only needs `taskId`, but the loop's | ||
| // feedback shape includes `done`/`result`/etc. Skip validation rather | ||
| // than widen every step's input schema. | ||
| validateInputs: false, | ||
| shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus), | ||
| // Internal scheduler plumbing — hide workflow spans from exported | ||
| // traces. The task body itself runs as user code and keeps its own | ||
| // spans. | ||
| tracingPolicy: { | ||
| internal: 1 /* WORKFLOW */ | ||
| } | ||
| } | ||
| }).then(runAttemptStep).then(classifyOutcomeStep).commit(); | ||
| return chunkGSWZYCY4_cjs.createWorkflow2({ | ||
| id: chunkBHNX447S_cjs.BACKGROUND_TASK_WORKFLOW_ID, | ||
| inputSchema, | ||
| outputSchema: bodyOutputSchema, | ||
| steps: [attemptBodyWorkflow], | ||
| options: { | ||
| shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus), | ||
| // Internal scheduler plumbing — see the inner workflow comment. | ||
| tracingPolicy: { | ||
| internal: 1 /* WORKFLOW */ | ||
| } | ||
| } | ||
| }).dountil(attemptBodyWorkflow, async ({ inputData }) => inputData?.done === true).commit(); | ||
| } | ||
| Object.defineProperty(exports, "BACKGROUND_TASK_WORKFLOW_ID", { | ||
| enumerable: true, | ||
| get: function () { return chunkBHNX447S_cjs.BACKGROUND_TASK_WORKFLOW_ID; } | ||
| }); | ||
| exports.buildBackgroundTaskWorkflow = buildBackgroundTaskWorkflow; | ||
| //# sourceMappingURL=workflow-ZBZQHIFN.cjs.map | ||
| //# sourceMappingURL=workflow-ZBZQHIFN.cjs.map |
| {"version":3,"sources":["../src/background-tasks/workflow.ts"],"names":["z","createStep","createWorkflow","BACKGROUND_TASK_WORKFLOW_ID"],"mappings":"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","file":"workflow-ZBZQHIFN.cjs","sourcesContent":["import { z } from 'zod';\nimport { InternalSpans } from '../observability';\nimport type { SuspendOptions } from '../workflows';\nimport { createStep, createWorkflow } from '../workflows/evented';\nimport type { BackgroundTaskManager } from './manager';\nimport type { BackgroundTaskStatus } from './types';\nimport { BACKGROUND_TASK_WORKFLOW_ID } from './workflow-id';\n\nexport { BACKGROUND_TASK_WORKFLOW_ID } from './workflow-id';\n\nconst inputSchema = z.object({ taskId: z.string() });\n\nconst attemptOutcomeSchema = z.enum(['success', 'retry', 'cancelled', 'timed_out']);\n\nconst attemptOutputSchema = z.object({\n taskId: z.string(),\n outcome: attemptOutcomeSchema,\n result: z.unknown().optional(),\n error: z.any().optional(),\n});\n\nconst bodyIOSchema = z.object({\n taskId: z.string(),\n done: z.boolean().optional(),\n result: z.unknown().optional(),\n});\n\nconst bodyOutputSchema = z.object({\n taskId: z.string(),\n done: z.boolean(),\n result: z.unknown().optional(),\n});\n\nconst WORKFLOW_STATUS_TO_PERSIST = ['suspended', 'pending', 'paused', 'waiting'];\n\n/**\n * Builds the per-task evented workflow that owns executor + retries.\n *\n * Shape: outer workflow runs an inner `[run-attempt, classify-outcome]`\n * workflow inside a `dountil` loop. `run-attempt` invokes the executor and\n * categorises the outcome; `classify-outcome` persists final state, advances\n * retry bookkeeping, and decides whether the loop is done. The dountil\n * predicate exits on `done === true`.\n *\n * The nested-workflow-as-loop-body path lives in\n * `processWorkflowEnd → processWorkflowLoop` and was fixed in PR #16312.\n * Suspend/resume routes through the runtime's nested-workflow auto-detect\n * (`processWorkflowStepRun` resume branch).\n *\n * Step bodies close over `manager` directly — the bg-tasks layer is the only\n * consumer of the `@internal` private fields.\n */\nexport function buildBackgroundTaskWorkflow(manager: BackgroundTaskManager) {\n const runAttemptStep = createStep({\n id: 'run-attempt',\n inputSchema: bodyIOSchema,\n outputSchema: attemptOutputSchema,\n execute: async ({ inputData, abortSignal: workflowAbortSignal, suspend, resumeData }) => {\n const { taskId } = inputData;\n const storage = await manager.getStorage();\n const task = await storage.getTask(taskId);\n if (!task || task.status === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, outcome: 'cancelled' as const };\n }\n\n // Resolve the executor. Two paths:\n // 1. Per-task `TaskContext` registered on the producer (in-process).\n // Carries closure-captured state (e.g. agent memory hooks) and\n // wins when present.\n // 2. Static executor registered by tool name. Used by remote workers\n // that received the dispatch via PubSub and don't have access to\n // the producer's per-task closure.\n const ctx = manager.taskContexts.get(taskId);\n const executor = ctx?.executor ?? manager.getStaticExecutor(task.toolName);\n if (!executor) {\n const errorInfo = {\n message:\n `No executor registered for tool \"${task.toolName}\". ` +\n `Register the tool on Mastra (so workers can resolve it cross-process) ` +\n `or run the task in the same process as the producer.`,\n };\n await storage.updateTask(taskId, { status: 'failed', error: errorInfo, completedAt: new Date() });\n const failedTask = await storage.getTask(taskId);\n if (failedTask) {\n await manager.runLocalCompletionHooks(failedTask, 'failed', { error: errorInfo });\n await manager.publishLifecycleEvent('task.failed', failedTask);\n }\n manager.deregisterTaskContext(taskId);\n throw new Error(errorInfo.message);\n }\n\n // Throttled progress publisher.\n const progressThrottleMs = manager.config.progressThrottleMs;\n const shouldThrottleProgress =\n typeof progressThrottleMs === 'number' && Number.isFinite(progressThrottleMs) && progressThrottleMs > 0;\n let lastProgressEmitMs: number | undefined;\n const onProgress = async (chunk: any) => {\n if (shouldThrottleProgress) {\n const now = Date.now();\n if (lastProgressEmitMs !== undefined && now - lastProgressEmitMs < progressThrottleMs!) return;\n lastProgressEmitMs = now;\n }\n await manager.publishLifecycleEvent('task.output', { ...task, chunk });\n };\n\n const abortController = new AbortController();\n manager.activeAbortControllers.set(taskId, abortController);\n // Wire the workflow's run-level abort signal into our local controller\n // so `workflow.getRun(taskId).cancel()` propagates to the executor.\n const onWorkflowAbort = () => abortController.abort(new Error('Task cancelled'));\n if (workflowAbortSignal.aborted) {\n abortController.abort(new Error('Task cancelled'));\n } else {\n workflowAbortSignal.addEventListener('abort', onWorkflowAbort, { once: true });\n }\n const timeoutHandle = setTimeout(() => {\n abortController.abort(new Error(`Task timed out after ${task.timeoutMs}ms`));\n }, task.timeoutMs);\n\n // Wrap the workflow runtime's `suspend` so we persist\n // `status: 'suspended'` + `suspendPayload`, fire the per-task\n // suspend hook (so the bg-task's `onResult` updates the agent's\n // message list), and publish the lifecycle event before\n // delegating. The runtime's `suspend` does not throw — it sets a\n // flag the step-executor reads after `execute` returns. We\n // capture the args here and call the runtime's suspend from the\n // step body after the executor returns, so `wrappedSuspend` can\n // safely run all its side effects synchronously inside the\n // tool's call.\n let pendingSuspend: { data?: unknown; suspendOptions?: SuspendOptions } | undefined;\n const wrappedSuspend = async (data?: unknown, suspendOptions?: SuspendOptions) => {\n await storage.updateTask(taskId, {\n status: 'suspended',\n suspendPayload: data,\n suspendedAt: new Date(),\n });\n const suspendedTask = await storage.getTask(taskId);\n if (suspendedTask) {\n // Suspend is non-terminal — DO NOT use `runLocalCompletionHooks`\n // here. That helper deregisters the task context in its `finally`\n // block, which would strand the resume call (the workflow step\n // body re-enters and looks up `manager.taskContexts.get(taskId)`).\n await manager.runLocalSuspendHooks(suspendedTask);\n await manager.publishLifecycleEvent('task.suspended', suspendedTask);\n }\n pendingSuspend = { data, suspendOptions };\n };\n\n try {\n const result = await executor.execute(task.args, {\n abortSignal: abortController.signal,\n onProgress,\n suspend: wrappedSuspend,\n // On resume the runtime populates `resumeData`; undefined on\n // the initial run.\n resumeData,\n });\n\n if (pendingSuspend) {\n return suspend(pendingSuspend.data, pendingSuspend.suspendOptions as SuspendOptions);\n }\n\n return { taskId, outcome: 'success' as const, result };\n } catch (error: any) {\n const currentTask = await storage.getTask(taskId);\n if (!currentTask || (currentTask.status as BackgroundTaskStatus) === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, outcome: 'cancelled' as const };\n }\n\n // Treat any aborted-signal exit as a timeout. The cancel path is\n // already handled by the storage-status check above, so if we reach\n // here with `signal.aborted`, it's the timeout abort. The\n // `AbortError` / message checks are belt-and-braces for executors\n // that throw their own abort error instead of propagating ours.\n if (\n abortController.signal.aborted ||\n error?.name === 'AbortError' ||\n error?.message === 'Task cancelled' ||\n error?.message?.startsWith('Task timed out after ')\n ) {\n return { taskId, outcome: 'timed_out' as const };\n }\n\n return {\n taskId,\n outcome: 'retry' as const,\n error: { message: error?.message ?? 'Unknown error', stack: error?.stack },\n };\n } finally {\n clearTimeout(timeoutHandle);\n workflowAbortSignal.removeEventListener('abort', onWorkflowAbort);\n manager.activeAbortControllers.delete(taskId);\n }\n },\n });\n\n const classifyOutcomeStep = createStep({\n id: 'classify-outcome',\n inputSchema: attemptOutputSchema,\n outputSchema: bodyOutputSchema,\n execute: async ({ inputData }) => {\n const { taskId, outcome, result, error } = inputData;\n const storage = await manager.getStorage();\n const task = await storage.getTask(taskId);\n if (!task) return { taskId, done: true };\n\n if (outcome === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, done: true };\n }\n\n if (outcome === 'timed_out') {\n const status = task.status as string;\n if (status !== 'timed_out' && status !== 'cancelled') {\n await storage.updateTask(taskId, {\n status: 'timed_out',\n error: { message: `Task timed out after ${task.timeoutMs}ms` },\n completedAt: new Date(),\n });\n const timedOutTask = await storage.getTask(taskId);\n if (timedOutTask) await manager.publishLifecycleEvent('task.failed', timedOutTask);\n }\n return { taskId, done: true };\n }\n\n if (outcome === 'success') {\n if ((task.status as BackgroundTaskStatus) === 'cancelled') {\n manager.deregisterTaskContext(taskId);\n return { taskId, done: true };\n }\n await storage.updateTask(taskId, { status: 'completed', result, completedAt: new Date() });\n const completedTask = await storage.getTask(taskId);\n if (completedTask) {\n await manager.runLocalCompletionHooks(completedTask, 'completed', { result });\n await manager.publishLifecycleEvent('task.completed', completedTask);\n }\n return { taskId, done: true, result };\n }\n\n // outcome === 'retry'\n if (task.retryCount < task.maxRetries) {\n await storage.updateTask(taskId, {\n retryCount: task.retryCount + 1,\n error: undefined,\n startedAt: new Date(),\n });\n return { taskId, done: false };\n }\n\n // Retries exhausted: persist failure and throw so the workflow run ends\n // in `failed` rather than completing cleanly. Throw matches the prior\n // single-step behavior — workflow-run history stays accurate.\n const errorInfo = error ?? { message: 'Unknown error' };\n await storage.updateTask(taskId, { status: 'failed', error: errorInfo, completedAt: new Date() });\n const failedTask = await storage.getTask(taskId);\n if (failedTask) {\n await manager.runLocalCompletionHooks(failedTask, 'failed', { error: errorInfo });\n await manager.publishLifecycleEvent('task.failed', failedTask);\n }\n const thrown = new Error(errorInfo.message);\n if (errorInfo.stack) thrown.stack = errorInfo.stack;\n throw thrown;\n },\n });\n\n const attemptBodyWorkflow = createWorkflow({\n id: `${BACKGROUND_TASK_WORKFLOW_ID}__attempt`,\n inputSchema: bodyIOSchema,\n outputSchema: bodyOutputSchema,\n steps: [runAttemptStep, classifyOutcomeStep],\n options: {\n // `dountil` feeds the prior iteration's output back in as input. The\n // body's actual entry point only needs `taskId`, but the loop's\n // feedback shape includes `done`/`result`/etc. Skip validation rather\n // than widen every step's input schema.\n validateInputs: false,\n shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus),\n // Internal scheduler plumbing — hide workflow spans from exported\n // traces. The task body itself runs as user code and keeps its own\n // spans.\n tracingPolicy: {\n internal: InternalSpans.WORKFLOW,\n },\n },\n })\n .then(runAttemptStep)\n .then(classifyOutcomeStep)\n .commit();\n\n return createWorkflow({\n id: BACKGROUND_TASK_WORKFLOW_ID,\n inputSchema,\n outputSchema: bodyOutputSchema,\n steps: [attemptBodyWorkflow],\n options: {\n shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus),\n // Internal scheduler plumbing — see the inner workflow comment.\n tracingPolicy: {\n internal: InternalSpans.WORKFLOW,\n },\n },\n })\n .dountil(attemptBodyWorkflow, async ({ inputData }) => inputData?.done === true)\n .commit();\n}\n"]} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 2 instances
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 4 instances
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
64963466
0.03%0
-100%156
-1.27%+ Added
- Removed
Updated