@mastra/server 1.78.0 → 1.78.1-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{a2a-BeW8w9CL.cjs → a2a-D5CGFO8W.cjs} +2 -2
- package/dist/{a2a-BeW8w9CL.cjs.map → a2a-D5CGFO8W.cjs.map} +1 -1
- package/dist/{a2a-BWKuwXQY.js → a2a-Dg3ylOKc.js} +2 -2
- package/dist/{a2a-BWKuwXQY.js.map → a2a-Dg3ylOKc.js.map} +1 -1
- package/dist/{api-schema-manifest-C1XMN6QZ.cjs → api-schema-manifest-Dr8PM4Qj.cjs} +2 -2
- package/dist/{api-schema-manifest-C1XMN6QZ.cjs.map → api-schema-manifest-Dr8PM4Qj.cjs.map} +1 -1
- package/dist/{api-schema-manifest-BWXv2l4E.js → api-schema-manifest-aur2BK6a.js} +2 -2
- package/dist/{api-schema-manifest-BWXv2l4E.js.map → api-schema-manifest-aur2BK6a.js.map} +1 -1
- package/dist/{background-tasks-CP6TSFhc.cjs → background-tasks-BbYzMhlD.cjs} +2 -2
- package/dist/{background-tasks-CP6TSFhc.cjs.map → background-tasks-BbYzMhlD.cjs.map} +1 -1
- package/dist/{background-tasks-Clbud7G4.js → background-tasks-zvlIcbhg.js} +2 -2
- package/dist/{background-tasks-Clbud7G4.js.map → background-tasks-zvlIcbhg.js.map} +1 -1
- package/dist/{builder-registry-6A0b4EwP.js → builder-registry-1GwmVVwr.js} +2 -2
- package/dist/{builder-registry-6A0b4EwP.js.map → builder-registry-1GwmVVwr.js.map} +1 -1
- package/dist/{builder-registry-DbSG3HJ8.cjs → builder-registry-DagCZI4A.cjs} +2 -2
- package/dist/{builder-registry-DbSG3HJ8.cjs.map → builder-registry-DagCZI4A.cjs.map} +1 -1
- package/dist/{channels-DNWITrYK.cjs → channels-5J7CTFyY.cjs} +2 -2
- package/dist/{channels-DNWITrYK.cjs.map → channels-5J7CTFyY.cjs.map} +1 -1
- package/dist/{channels-DjOa1rPQ.js → channels-B3aoI-f1.js} +2 -2
- package/dist/{channels-DjOa1rPQ.js.map → channels-B3aoI-f1.js.map} +1 -1
- package/dist/{constants-C631oS02.js → constants-DazK_RZj.js} +9 -4
- package/dist/constants-DazK_RZj.js.map +1 -0
- package/dist/{constants-epIL4td4.cjs → constants-e7aaPCLj.cjs} +14 -3
- package/dist/constants-e7aaPCLj.cjs.map +1 -0
- package/dist/{dist-BRej8vIF.cjs → dist-B8rA8_Wt.cjs} +18 -7
- package/dist/{dist-BRej8vIF.cjs.map → dist-B8rA8_Wt.cjs.map} +1 -1
- package/dist/{dist-CPHBJa2G.js → dist-CdMzvOLk.js} +18 -7
- package/dist/{dist-CPHBJa2G.js.map → dist-CdMzvOLk.js.map} +1 -1
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/{helpers-C_FYiA-F.js → helpers-DLhX1fqc.js} +2 -2
- package/dist/{helpers-C_FYiA-F.js.map → helpers-DLhX1fqc.js.map} +1 -1
- package/dist/{helpers-59ZdrW8t.cjs → helpers-ElhPeCSK.cjs} +2 -2
- package/dist/{helpers-59ZdrW8t.cjs.map → helpers-ElhPeCSK.cjs.map} +1 -1
- package/dist/{observability-new-endpoints-CJMR84MD.cjs → observability-new-endpoints-BoALDMSi.cjs} +2 -2
- package/dist/{observability-new-endpoints-CJMR84MD.cjs.map → observability-new-endpoints-BoALDMSi.cjs.map} +1 -1
- package/dist/{observability-new-endpoints-D9MEJyaw.js → observability-new-endpoints-CB7T6Z7c.js} +2 -2
- package/dist/{observability-new-endpoints-D9MEJyaw.js.map → observability-new-endpoints-CB7T6Z7c.js.map} +1 -1
- package/dist/{routes-CH2PZ0PI.js → routes-BhI1lW_W.js} +12 -12
- package/dist/{routes-CH2PZ0PI.js.map → routes-BhI1lW_W.js.map} +1 -1
- package/dist/{routes-BpxhmR6Y.cjs → routes-CuJPLAh8.cjs} +12 -12
- package/dist/{routes-BpxhmR6Y.cjs.map → routes-CuJPLAh8.cjs.map} +1 -1
- package/dist/{schedules-DvLXX2nW.cjs → schedules-B0g72u5Y.cjs} +2 -2
- package/dist/{schedules-DvLXX2nW.cjs.map → schedules-B0g72u5Y.cjs.map} +1 -1
- package/dist/{schedules-BRdVmFYi.js → schedules-CrAmZ2gu.js} +2 -2
- package/dist/{schedules-BRdVmFYi.js.map → schedules-CrAmZ2gu.js.map} +1 -1
- package/dist/server/auth/index.cjs +2 -2
- package/dist/server/auth/index.js +2 -2
- package/dist/server/constants.d.ts +5 -0
- package/dist/server/constants.d.ts.map +1 -1
- package/dist/server/handlers/a2a.cjs +1 -1
- package/dist/server/handlers/a2a.js +1 -1
- package/dist/server/handlers/agent-builder.cjs +2 -2
- package/dist/server/handlers/agent-builder.js +2 -2
- package/dist/server/handlers/agent-controller.cjs +2 -2
- package/dist/server/handlers/agent-controller.js +2 -2
- package/dist/server/handlers/agent-versions.cjs +1 -1
- package/dist/server/handlers/agent-versions.js +1 -1
- package/dist/server/handlers/agents.cjs +3 -3
- package/dist/server/handlers/agents.js +3 -3
- package/dist/server/handlers/auth.cjs +2 -2
- package/dist/server/handlers/auth.js +2 -2
- package/dist/server/handlers/authorship.cjs +1 -1
- package/dist/server/handlers/authorship.js +1 -1
- package/dist/server/handlers/background-tasks.cjs +1 -1
- package/dist/server/handlers/background-tasks.js +1 -1
- package/dist/server/handlers/builder-registry.cjs +1 -1
- package/dist/server/handlers/builder-registry.js +1 -1
- package/dist/server/handlers/channels.cjs +1 -1
- package/dist/server/handlers/channels.js +1 -1
- package/dist/server/handlers/conversations.cjs +1 -1
- package/dist/server/handlers/conversations.js +1 -1
- package/dist/server/handlers/datasets.cjs +1 -1
- package/dist/server/handlers/datasets.js +1 -1
- package/dist/server/handlers/logs.cjs +1 -1
- package/dist/server/handlers/logs.js +1 -1
- package/dist/server/handlers/mcp-client-versions.cjs +2 -2
- package/dist/server/handlers/mcp-client-versions.js +2 -2
- package/dist/server/handlers/memory.cjs +1 -1
- package/dist/server/handlers/memory.js +1 -1
- package/dist/server/handlers/observability-new-endpoints.cjs +1 -1
- package/dist/server/handlers/observability-new-endpoints.js +1 -1
- package/dist/server/handlers/observability.cjs +1 -1
- package/dist/server/handlers/observability.js +1 -1
- package/dist/server/handlers/plans.cjs +1 -1
- package/dist/server/handlers/plans.js +1 -1
- package/dist/server/handlers/prompt-block-versions.cjs +2 -2
- package/dist/server/handlers/prompt-block-versions.js +2 -2
- package/dist/server/handlers/responses.cjs +1 -1
- package/dist/server/handlers/responses.js +1 -1
- package/dist/server/handlers/responses.storage.cjs +1 -1
- package/dist/server/handlers/responses.storage.js +1 -1
- package/dist/server/handlers/schedules.cjs +1 -1
- package/dist/server/handlers/schedules.js +1 -1
- package/dist/server/handlers/scorer-versions.cjs +2 -2
- package/dist/server/handlers/scorer-versions.js +2 -2
- package/dist/server/handlers/stored-agent-favorites.cjs +1 -1
- package/dist/server/handlers/stored-agent-favorites.js +1 -1
- package/dist/server/handlers/stored-agents.cjs +2 -2
- package/dist/server/handlers/stored-agents.js +2 -2
- package/dist/server/handlers/stored-mcp-clients.cjs +2 -2
- package/dist/server/handlers/stored-mcp-clients.js +2 -2
- package/dist/server/handlers/stored-prompt-blocks.cjs +2 -2
- package/dist/server/handlers/stored-prompt-blocks.js +2 -2
- package/dist/server/handlers/stored-scorers.cjs +2 -2
- package/dist/server/handlers/stored-scorers.js +2 -2
- package/dist/server/handlers/stored-skill-favorites.cjs +2 -2
- package/dist/server/handlers/stored-skill-favorites.js +2 -2
- package/dist/server/handlers/stored-skills.cjs +2 -2
- package/dist/server/handlers/stored-skills.js +2 -2
- package/dist/server/handlers/stored-workspaces.cjs +1 -1
- package/dist/server/handlers/stored-workspaces.js +1 -1
- package/dist/server/handlers/system.cjs +1 -1
- package/dist/server/handlers/system.js +1 -1
- package/dist/server/handlers/tool-providers.cjs +1 -1
- package/dist/server/handlers/tool-providers.js +1 -1
- package/dist/server/handlers/tools.cjs +2 -2
- package/dist/server/handlers/tools.js +2 -2
- package/dist/server/handlers/utils.cjs +1 -1
- package/dist/server/handlers/utils.js +1 -1
- package/dist/server/handlers/validate-agent-instructions.cjs +1 -1
- package/dist/server/handlers/validate-agent-instructions.js +1 -1
- package/dist/server/handlers/workflow-builder.cjs +1 -1
- package/dist/server/handlers/workflow-builder.js +1 -1
- package/dist/server/handlers/workflows.cjs +2 -2
- package/dist/server/handlers/workflows.js +2 -2
- package/dist/server/handlers.cjs +1 -1
- package/dist/server/handlers.js +1 -1
- package/dist/server/schemas/index.cjs +6 -6
- package/dist/server/schemas/index.js +6 -6
- package/dist/server/server-adapter/index.cjs +5 -4
- package/dist/server/server-adapter/index.cjs.map +1 -1
- package/dist/server/server-adapter/index.d.ts +1 -1
- package/dist/server/server-adapter/index.d.ts.map +1 -1
- package/dist/server/server-adapter/index.js +5 -5
- package/dist/server/server-adapter/index.js.map +1 -1
- package/dist/{utils-CJxnYdr3.cjs → utils-BZdnPmsW.cjs} +2 -2
- package/dist/{utils-CJxnYdr3.cjs.map → utils-BZdnPmsW.cjs.map} +1 -1
- package/dist/{utils-DdGLbkOl.cjs → utils-CczRcgHQ.cjs} +2 -2
- package/dist/{utils-DdGLbkOl.cjs.map → utils-CczRcgHQ.cjs.map} +1 -1
- package/dist/{utils-mIFmRM_j.js → utils-D5DHrO3K.js} +2 -2
- package/dist/{utils-mIFmRM_j.js.map → utils-D5DHrO3K.js.map} +1 -1
- package/dist/{utils-BpQY-tBr.js → utils-tmrFs-gf.js} +2 -2
- package/dist/{utils-BpQY-tBr.js.map → utils-tmrFs-gf.js.map} +1 -1
- package/dist/{workflow-builder-BnKKH8iT.js → workflow-builder-DJ0eeJuG.js} +2 -2
- package/dist/{workflow-builder-BnKKH8iT.js.map → workflow-builder-DJ0eeJuG.js.map} +1 -1
- package/dist/{workflow-builder-BM6Nen0q.cjs → workflow-builder-DdSutoga.cjs} +2 -2
- package/dist/{workflow-builder-BM6Nen0q.cjs.map → workflow-builder-DdSutoga.cjs.map} +1 -1
- package/package.json +8 -8
- package/dist/constants-C631oS02.js.map +0 -1
- package/dist/constants-epIL4td4.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channels-DNWITrYK.cjs","names":["z","coreFeatures","HTTPException","getCallerAuthorId","hasAdminBypass","hasScopedPermission","createRoute","handleError"],"sources":["../src/server/schemas/channels.ts","../src/server/handlers/channels.ts"],"sourcesContent":["import { z } from 'zod/v4';\n\n// ============================================================================\n// Path Parameter Schemas\n// ============================================================================\n\nexport const channelPlatformPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n});\n\nexport const channelAgentPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n agentId: z.string().describe('Agent identifier'),\n});\n\n// ============================================================================\n// Body Parameter Schemas\n// ============================================================================\n\nexport const connectChannelBodySchema = z.object({\n agentId: z.string().describe('Agent identifier to connect'),\n options: z.record(z.string(), z.unknown()).optional().describe('Platform-specific connection options'),\n});\n\n// ============================================================================\n// Response Schemas\n// ============================================================================\n\nconst channelPlatformInfoSchema = z.object({\n id: z.string().describe('Platform identifier'),\n name: z.string().describe('Human-readable platform name'),\n isConfigured: z.boolean().describe('Whether the platform is ready to connect agents'),\n connectOptionsSchema: z.record(z.string(), z.unknown()).optional().describe('JSON Schema for connect options'),\n});\n\nconst channelInstallationInfoSchema = z.object({\n id: z.string().describe('Installation identifier'),\n platform: z.string().describe('Platform identifier'),\n agentId: z.string().describe('Connected agent identifier'),\n status: z.enum(['active', 'pending']).describe('Installation status'),\n displayName: z.string().optional().describe('Platform-specific display name'),\n installedAt: z.coerce.date().optional().describe('Installation timestamp'),\n});\n\nconst channelConnectOAuthSchema = z.object({\n type: z.literal('oauth').describe('OAuth-based connection requiring browser redirect'),\n authorizationUrl: z.string().describe('OAuth authorization URL for user redirect'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectDeepLinkSchema = z.object({\n type: z.literal('deep_link').describe('Deep-link connection requiring native app interaction'),\n url: z.string().describe('Deep link URL to open in platform app'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectImmediateSchema = z.object({\n type: z.literal('immediate').describe('Immediate connection with no user interaction needed'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectResultSchema = z.discriminatedUnion('type', [\n channelConnectOAuthSchema,\n channelConnectDeepLinkSchema,\n channelConnectImmediateSchema,\n]);\n\nexport const listChannelPlatformsResponseSchema = z.array(channelPlatformInfoSchema);\n\nexport const listChannelInstallationsResponseSchema = z.array(channelInstallationInfoSchema);\n\nexport const connectChannelResponseSchema = channelConnectResultSchema;\n\nexport const disconnectChannelResponseSchema = z.object({\n success: z.boolean(),\n});\n\nexport const reconcileChannelResponseSchema = channelInstallationInfoSchema\n .nullable()\n .describe('The reconciled installation, or null when the agent has none (or the platform does not reconcile)');\n","import type { Mastra } from '@mastra/core';\nimport type { ChannelProvider } from '@mastra/core/channels';\nimport type { RequestContext } from '@mastra/core/di';\nimport { coreFeatures } from '@mastra/core/features';\n\nimport { MASTRA_USER_KEY } from '../constants';\nimport { HTTPException } from '../http-exception';\nimport {\n channelPlatformPathParams,\n channelAgentPathParams,\n connectChannelBodySchema,\n listChannelPlatformsResponseSchema,\n listChannelInstallationsResponseSchema,\n connectChannelResponseSchema,\n disconnectChannelResponseSchema,\n reconcileChannelResponseSchema,\n} from '../schemas/channels';\nimport { createRoute } from '../server-adapter/routes/route-builder';\n\nimport { assertWriteAccess, getCallerAuthorId, hasAdminBypass, hasScopedPermission } from './authorship';\nimport { handleError } from './error';\n\n// ============================================================================\n// Feature gate + helpers\n// ============================================================================\n\nfunction assertChannelsAvailable(): void {\n if (!coreFeatures.has('channels')) {\n throw new HTTPException(501, { message: 'Channels require a newer version of @mastra/core' });\n }\n}\n\n/**\n * Resolves the current channel providers. Prefers `resolveChannels()` so a\n * live resolver (e.g. `channels()` from @mastra/connect) is consulted —\n * connections added after boot are picked up without a restart. Falls back to\n * the static snapshot on older @mastra/core versions without the method.\n */\nasync function resolveChannelProviders(mastra: Mastra): Promise<ChannelProvider[]> {\n const resolveChannels = (mastra as Mastra & { resolveChannels?: () => Promise<Record<string, ChannelProvider>> })\n .resolveChannels;\n const record = typeof resolveChannels === 'function' ? await resolveChannels.call(mastra) : (mastra.channels ?? {});\n return Object.values(record);\n}\n\nasync function getChannelOrThrow(mastra: Mastra, platform: string): Promise<ChannelProvider> {\n const channels = await resolveChannelProviders(mastra);\n const channel = channels.find(c => c.id === platform);\n if (!channel) {\n const available = channels.map(c => c.id).join(', ');\n throw new HTTPException(404, {\n message: `Channel \"${platform}\" is not registered. Available: ${available || 'none'}`,\n });\n }\n return channel;\n}\n\n/**\n * Unified connect/disconnect authorization.\n *\n * - Stored agent exists → same write access as editing the agent record.\n * - Code-defined agent (no stored record) → route's `requiresAuth` is the gate.\n * - Agent doesn't exist anywhere:\n * - connect → 404 (can't connect a channel to a non-existent agent)\n * - disconnect → orphan cleanup, gated on `channels:write`\n */\nasync function assertChannelAgentWriteAccess(\n mastra: Mastra,\n requestContext: RequestContext,\n agentId: string,\n action: 'connect' | 'disconnect',\n): Promise<void> {\n const storage = mastra.getStorage();\n const agentsStore = storage ? await storage.getStore('agents') : null;\n const stored = agentsStore ? await agentsStore.getById(agentId) : null;\n\n if (stored) {\n assertWriteAccess({\n requestContext,\n resource: 'agents',\n resourceId: agentId,\n action: 'edit',\n record: stored,\n });\n return;\n }\n\n // Not in stored-agents (or storage doesn't support it). Check the runtime\n // registry for a code-defined agent.\n const codeDefined = mastra.getAgentById(agentId);\n if (codeDefined) {\n // Code-defined agents have no owner/ACL — route's requiresAuth /\n // requiresPermission is the gate. Pass-through.\n return;\n }\n\n if (action === 'connect') {\n throw new HTTPException(404, { message: `Agent \"${agentId}\" not found` });\n }\n\n // Disconnect against an unknown agentId = orphan cleanup (stored agent was\n // deleted but the channel installation row is still around). Allow it, but\n // gate on channels:write so this isn't an \"any authenticated user\" backdoor.\n // Follow the same no-auth-configured pass-through as assertWriteAccess.\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n if (hasAdminBypass(requestContext, 'channels')) return;\n if (hasScopedPermission({ requestContext, resource: 'channels', action: 'write' })) return;\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n// ============================================================================\n// Route Definitions\n// ============================================================================\n\n/**\n * GET /channels/platforms - List available channel platforms\n */\nexport const LIST_CHANNEL_PLATFORMS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/platforms',\n responseType: 'json',\n responseSchema: listChannelPlatformsResponseSchema,\n summary: 'List channel platforms',\n description: 'Returns available channel platforms and their configuration status',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra }) => {\n assertChannelsAvailable();\n try {\n const channels = await resolveChannelProviders(mastra);\n return channels.map(channel => {\n if (channel.getInfo) {\n return channel.getInfo();\n }\n return {\n id: channel.id,\n name: channel.id.charAt(0).toUpperCase() + channel.id.slice(1),\n isConfigured: true,\n };\n });\n } catch (error) {\n return handleError(error, 'Error listing channel platforms');\n }\n },\n});\n\n/**\n * GET /channels/:platform/installations - List installations for a platform\n */\nexport const LIST_CHANNEL_INSTALLATIONS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/:platform/installations',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n responseSchema: listChannelInstallationsResponseSchema,\n summary: 'List channel installations',\n description: 'Returns all active and pending installations for a channel platform',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, platform }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n if (!channel.listInstallations) {\n return [];\n }\n\n return await channel.listInstallations();\n } catch (error) {\n return handleError(error, 'Error listing channel installations');\n }\n },\n});\n\n/**\n * POST /channels/:platform/connect - Connect an agent to a platform\n */\nexport const CONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/connect',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n bodySchema: connectChannelBodySchema,\n responseSchema: connectChannelResponseSchema,\n summary: 'Connect agent to channel',\n description: 'Creates a platform app for the agent and returns an OAuth authorization URL',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId, options }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n if (!channel.connect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic connection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'connect');\n\n return await channel.connect(agentId, options);\n } catch (error) {\n return handleError(error, 'Error connecting agent to channel');\n }\n },\n});\n\n/**\n * POST /channels/:platform/:agentId/reconcile - Reconcile an agent's installation\n *\n * The explicit write path for connect flows that complete out-of-band (e.g.\n * Discord's bot invite has no redirect back to the server). Listing stays a\n * pure read; Studio calls this on window focus while a connect is in flight.\n * Gated on the same write access as connect — reconciliation can activate the\n * agent's installation.\n */\nexport const RECONCILE_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/:agentId/reconcile',\n responseType: 'json',\n pathParamSchema: channelAgentPathParams,\n responseSchema: reconcileChannelResponseSchema,\n summary: 'Reconcile channel installation',\n description:\n 'Checks a pending installation against platform state and activates it if its connect flow has completed. Returns the installation, or null when the agent has none or the platform does not support reconciliation.',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n // Resolve the agent (404 on unknown) and authorize the write before the\n // capability check so unknown agents never read as a successful no-op.\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'connect');\n\n if (!channel.reconcileInstallation) {\n return null;\n }\n\n return await channel.reconcileInstallation(agentId);\n } catch (error) {\n return handleError(error, 'Error reconciling channel installation');\n }\n },\n});\n\n/**\n * POST /channels/:platform/:agentId/disconnect - Disconnect an agent from a platform\n */\nexport const DISCONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/:agentId/disconnect',\n responseType: 'json',\n pathParamSchema: channelAgentPathParams,\n responseSchema: disconnectChannelResponseSchema,\n summary: 'Disconnect agent from channel',\n description: 'Deletes the platform app and cleans up the installation',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n if (!channel.disconnect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic disconnection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'disconnect');\n\n await channel.disconnect(agentId);\n return { success: true };\n } catch (error) {\n return handleError(error, 'Error disconnecting agent from channel');\n }\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"channels-5J7CTFyY.cjs","names":["z","coreFeatures","HTTPException","getCallerAuthorId","hasAdminBypass","hasScopedPermission","createRoute","handleError"],"sources":["../src/server/schemas/channels.ts","../src/server/handlers/channels.ts"],"sourcesContent":["import { z } from 'zod/v4';\n\n// ============================================================================\n// Path Parameter Schemas\n// ============================================================================\n\nexport const channelPlatformPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n});\n\nexport const channelAgentPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n agentId: z.string().describe('Agent identifier'),\n});\n\n// ============================================================================\n// Body Parameter Schemas\n// ============================================================================\n\nexport const connectChannelBodySchema = z.object({\n agentId: z.string().describe('Agent identifier to connect'),\n options: z.record(z.string(), z.unknown()).optional().describe('Platform-specific connection options'),\n});\n\n// ============================================================================\n// Response Schemas\n// ============================================================================\n\nconst channelPlatformInfoSchema = z.object({\n id: z.string().describe('Platform identifier'),\n name: z.string().describe('Human-readable platform name'),\n isConfigured: z.boolean().describe('Whether the platform is ready to connect agents'),\n connectOptionsSchema: z.record(z.string(), z.unknown()).optional().describe('JSON Schema for connect options'),\n});\n\nconst channelInstallationInfoSchema = z.object({\n id: z.string().describe('Installation identifier'),\n platform: z.string().describe('Platform identifier'),\n agentId: z.string().describe('Connected agent identifier'),\n status: z.enum(['active', 'pending']).describe('Installation status'),\n displayName: z.string().optional().describe('Platform-specific display name'),\n installedAt: z.coerce.date().optional().describe('Installation timestamp'),\n});\n\nconst channelConnectOAuthSchema = z.object({\n type: z.literal('oauth').describe('OAuth-based connection requiring browser redirect'),\n authorizationUrl: z.string().describe('OAuth authorization URL for user redirect'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectDeepLinkSchema = z.object({\n type: z.literal('deep_link').describe('Deep-link connection requiring native app interaction'),\n url: z.string().describe('Deep link URL to open in platform app'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectImmediateSchema = z.object({\n type: z.literal('immediate').describe('Immediate connection with no user interaction needed'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectResultSchema = z.discriminatedUnion('type', [\n channelConnectOAuthSchema,\n channelConnectDeepLinkSchema,\n channelConnectImmediateSchema,\n]);\n\nexport const listChannelPlatformsResponseSchema = z.array(channelPlatformInfoSchema);\n\nexport const listChannelInstallationsResponseSchema = z.array(channelInstallationInfoSchema);\n\nexport const connectChannelResponseSchema = channelConnectResultSchema;\n\nexport const disconnectChannelResponseSchema = z.object({\n success: z.boolean(),\n});\n\nexport const reconcileChannelResponseSchema = channelInstallationInfoSchema\n .nullable()\n .describe('The reconciled installation, or null when the agent has none (or the platform does not reconcile)');\n","import type { Mastra } from '@mastra/core';\nimport type { ChannelProvider } from '@mastra/core/channels';\nimport type { RequestContext } from '@mastra/core/di';\nimport { coreFeatures } from '@mastra/core/features';\n\nimport { MASTRA_USER_KEY } from '../constants';\nimport { HTTPException } from '../http-exception';\nimport {\n channelPlatformPathParams,\n channelAgentPathParams,\n connectChannelBodySchema,\n listChannelPlatformsResponseSchema,\n listChannelInstallationsResponseSchema,\n connectChannelResponseSchema,\n disconnectChannelResponseSchema,\n reconcileChannelResponseSchema,\n} from '../schemas/channels';\nimport { createRoute } from '../server-adapter/routes/route-builder';\n\nimport { assertWriteAccess, getCallerAuthorId, hasAdminBypass, hasScopedPermission } from './authorship';\nimport { handleError } from './error';\n\n// ============================================================================\n// Feature gate + helpers\n// ============================================================================\n\nfunction assertChannelsAvailable(): void {\n if (!coreFeatures.has('channels')) {\n throw new HTTPException(501, { message: 'Channels require a newer version of @mastra/core' });\n }\n}\n\n/**\n * Resolves the current channel providers. Prefers `resolveChannels()` so a\n * live resolver (e.g. `channels()` from @mastra/connect) is consulted —\n * connections added after boot are picked up without a restart. Falls back to\n * the static snapshot on older @mastra/core versions without the method.\n */\nasync function resolveChannelProviders(mastra: Mastra): Promise<ChannelProvider[]> {\n const resolveChannels = (mastra as Mastra & { resolveChannels?: () => Promise<Record<string, ChannelProvider>> })\n .resolveChannels;\n const record = typeof resolveChannels === 'function' ? await resolveChannels.call(mastra) : (mastra.channels ?? {});\n return Object.values(record);\n}\n\nasync function getChannelOrThrow(mastra: Mastra, platform: string): Promise<ChannelProvider> {\n const channels = await resolveChannelProviders(mastra);\n const channel = channels.find(c => c.id === platform);\n if (!channel) {\n const available = channels.map(c => c.id).join(', ');\n throw new HTTPException(404, {\n message: `Channel \"${platform}\" is not registered. Available: ${available || 'none'}`,\n });\n }\n return channel;\n}\n\n/**\n * Unified connect/disconnect authorization.\n *\n * - Stored agent exists → same write access as editing the agent record.\n * - Code-defined agent (no stored record) → route's `requiresAuth` is the gate.\n * - Agent doesn't exist anywhere:\n * - connect → 404 (can't connect a channel to a non-existent agent)\n * - disconnect → orphan cleanup, gated on `channels:write`\n */\nasync function assertChannelAgentWriteAccess(\n mastra: Mastra,\n requestContext: RequestContext,\n agentId: string,\n action: 'connect' | 'disconnect',\n): Promise<void> {\n const storage = mastra.getStorage();\n const agentsStore = storage ? await storage.getStore('agents') : null;\n const stored = agentsStore ? await agentsStore.getById(agentId) : null;\n\n if (stored) {\n assertWriteAccess({\n requestContext,\n resource: 'agents',\n resourceId: agentId,\n action: 'edit',\n record: stored,\n });\n return;\n }\n\n // Not in stored-agents (or storage doesn't support it). Check the runtime\n // registry for a code-defined agent.\n const codeDefined = mastra.getAgentById(agentId);\n if (codeDefined) {\n // Code-defined agents have no owner/ACL — route's requiresAuth /\n // requiresPermission is the gate. Pass-through.\n return;\n }\n\n if (action === 'connect') {\n throw new HTTPException(404, { message: `Agent \"${agentId}\" not found` });\n }\n\n // Disconnect against an unknown agentId = orphan cleanup (stored agent was\n // deleted but the channel installation row is still around). Allow it, but\n // gate on channels:write so this isn't an \"any authenticated user\" backdoor.\n // Follow the same no-auth-configured pass-through as assertWriteAccess.\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n if (hasAdminBypass(requestContext, 'channels')) return;\n if (hasScopedPermission({ requestContext, resource: 'channels', action: 'write' })) return;\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n// ============================================================================\n// Route Definitions\n// ============================================================================\n\n/**\n * GET /channels/platforms - List available channel platforms\n */\nexport const LIST_CHANNEL_PLATFORMS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/platforms',\n responseType: 'json',\n responseSchema: listChannelPlatformsResponseSchema,\n summary: 'List channel platforms',\n description: 'Returns available channel platforms and their configuration status',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra }) => {\n assertChannelsAvailable();\n try {\n const channels = await resolveChannelProviders(mastra);\n return channels.map(channel => {\n if (channel.getInfo) {\n return channel.getInfo();\n }\n return {\n id: channel.id,\n name: channel.id.charAt(0).toUpperCase() + channel.id.slice(1),\n isConfigured: true,\n };\n });\n } catch (error) {\n return handleError(error, 'Error listing channel platforms');\n }\n },\n});\n\n/**\n * GET /channels/:platform/installations - List installations for a platform\n */\nexport const LIST_CHANNEL_INSTALLATIONS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/:platform/installations',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n responseSchema: listChannelInstallationsResponseSchema,\n summary: 'List channel installations',\n description: 'Returns all active and pending installations for a channel platform',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, platform }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n if (!channel.listInstallations) {\n return [];\n }\n\n return await channel.listInstallations();\n } catch (error) {\n return handleError(error, 'Error listing channel installations');\n }\n },\n});\n\n/**\n * POST /channels/:platform/connect - Connect an agent to a platform\n */\nexport const CONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/connect',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n bodySchema: connectChannelBodySchema,\n responseSchema: connectChannelResponseSchema,\n summary: 'Connect agent to channel',\n description: 'Creates a platform app for the agent and returns an OAuth authorization URL',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId, options }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n if (!channel.connect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic connection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'connect');\n\n return await channel.connect(agentId, options);\n } catch (error) {\n return handleError(error, 'Error connecting agent to channel');\n }\n },\n});\n\n/**\n * POST /channels/:platform/:agentId/reconcile - Reconcile an agent's installation\n *\n * The explicit write path for connect flows that complete out-of-band (e.g.\n * Discord's bot invite has no redirect back to the server). Listing stays a\n * pure read; Studio calls this on window focus while a connect is in flight.\n * Gated on the same write access as connect — reconciliation can activate the\n * agent's installation.\n */\nexport const RECONCILE_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/:agentId/reconcile',\n responseType: 'json',\n pathParamSchema: channelAgentPathParams,\n responseSchema: reconcileChannelResponseSchema,\n summary: 'Reconcile channel installation',\n description:\n 'Checks a pending installation against platform state and activates it if its connect flow has completed. Returns the installation, or null when the agent has none or the platform does not support reconciliation.',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n // Resolve the agent (404 on unknown) and authorize the write before the\n // capability check so unknown agents never read as a successful no-op.\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'connect');\n\n if (!channel.reconcileInstallation) {\n return null;\n }\n\n return await channel.reconcileInstallation(agentId);\n } catch (error) {\n return handleError(error, 'Error reconciling channel installation');\n }\n },\n});\n\n/**\n * POST /channels/:platform/:agentId/disconnect - Disconnect an agent from a platform\n */\nexport const DISCONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/:agentId/disconnect',\n responseType: 'json',\n pathParamSchema: channelAgentPathParams,\n responseSchema: disconnectChannelResponseSchema,\n summary: 'Disconnect agent from channel',\n description: 'Deletes the platform app and cleans up the installation',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n if (!channel.disconnect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic disconnection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'disconnect');\n\n await channel.disconnect(agentId);\n return { success: true };\n } catch (error) {\n return handleError(error, 'Error disconnecting agent from channel');\n }\n },\n});\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as HTTPException } from "./http-exception-CyfxZB6W.js";
|
|
2
2
|
import { n as createRoute } from "./route-builder-lBil8Cvo.js";
|
|
3
|
-
import "./constants-
|
|
3
|
+
import "./constants-DazK_RZj.js";
|
|
4
4
|
import { handleError } from "./server/handlers/error.js";
|
|
5
5
|
import { assertWriteAccess, getCallerAuthorId, hasAdminBypass, hasScopedPermission } from "./server/handlers/authorship.js";
|
|
6
6
|
import { z } from "zod/v4";
|
|
@@ -247,4 +247,4 @@ const DISCONNECT_CHANNEL_ROUTE = createRoute({
|
|
|
247
247
|
//#endregion
|
|
248
248
|
export { RECONCILE_CHANNEL_ROUTE as a, LIST_CHANNEL_PLATFORMS_ROUTE as i, DISCONNECT_CHANNEL_ROUTE as n, LIST_CHANNEL_INSTALLATIONS_ROUTE as r, CONNECT_CHANNEL_ROUTE as t };
|
|
249
249
|
|
|
250
|
-
//# sourceMappingURL=channels-
|
|
250
|
+
//# sourceMappingURL=channels-B3aoI-f1.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channels-DjOa1rPQ.js","names":[],"sources":["../src/server/schemas/channels.ts","../src/server/handlers/channels.ts"],"sourcesContent":["import { z } from 'zod/v4';\n\n// ============================================================================\n// Path Parameter Schemas\n// ============================================================================\n\nexport const channelPlatformPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n});\n\nexport const channelAgentPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n agentId: z.string().describe('Agent identifier'),\n});\n\n// ============================================================================\n// Body Parameter Schemas\n// ============================================================================\n\nexport const connectChannelBodySchema = z.object({\n agentId: z.string().describe('Agent identifier to connect'),\n options: z.record(z.string(), z.unknown()).optional().describe('Platform-specific connection options'),\n});\n\n// ============================================================================\n// Response Schemas\n// ============================================================================\n\nconst channelPlatformInfoSchema = z.object({\n id: z.string().describe('Platform identifier'),\n name: z.string().describe('Human-readable platform name'),\n isConfigured: z.boolean().describe('Whether the platform is ready to connect agents'),\n connectOptionsSchema: z.record(z.string(), z.unknown()).optional().describe('JSON Schema for connect options'),\n});\n\nconst channelInstallationInfoSchema = z.object({\n id: z.string().describe('Installation identifier'),\n platform: z.string().describe('Platform identifier'),\n agentId: z.string().describe('Connected agent identifier'),\n status: z.enum(['active', 'pending']).describe('Installation status'),\n displayName: z.string().optional().describe('Platform-specific display name'),\n installedAt: z.coerce.date().optional().describe('Installation timestamp'),\n});\n\nconst channelConnectOAuthSchema = z.object({\n type: z.literal('oauth').describe('OAuth-based connection requiring browser redirect'),\n authorizationUrl: z.string().describe('OAuth authorization URL for user redirect'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectDeepLinkSchema = z.object({\n type: z.literal('deep_link').describe('Deep-link connection requiring native app interaction'),\n url: z.string().describe('Deep link URL to open in platform app'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectImmediateSchema = z.object({\n type: z.literal('immediate').describe('Immediate connection with no user interaction needed'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectResultSchema = z.discriminatedUnion('type', [\n channelConnectOAuthSchema,\n channelConnectDeepLinkSchema,\n channelConnectImmediateSchema,\n]);\n\nexport const listChannelPlatformsResponseSchema = z.array(channelPlatformInfoSchema);\n\nexport const listChannelInstallationsResponseSchema = z.array(channelInstallationInfoSchema);\n\nexport const connectChannelResponseSchema = channelConnectResultSchema;\n\nexport const disconnectChannelResponseSchema = z.object({\n success: z.boolean(),\n});\n\nexport const reconcileChannelResponseSchema = channelInstallationInfoSchema\n .nullable()\n .describe('The reconciled installation, or null when the agent has none (or the platform does not reconcile)');\n","import type { Mastra } from '@mastra/core';\nimport type { ChannelProvider } from '@mastra/core/channels';\nimport type { RequestContext } from '@mastra/core/di';\nimport { coreFeatures } from '@mastra/core/features';\n\nimport { MASTRA_USER_KEY } from '../constants';\nimport { HTTPException } from '../http-exception';\nimport {\n channelPlatformPathParams,\n channelAgentPathParams,\n connectChannelBodySchema,\n listChannelPlatformsResponseSchema,\n listChannelInstallationsResponseSchema,\n connectChannelResponseSchema,\n disconnectChannelResponseSchema,\n reconcileChannelResponseSchema,\n} from '../schemas/channels';\nimport { createRoute } from '../server-adapter/routes/route-builder';\n\nimport { assertWriteAccess, getCallerAuthorId, hasAdminBypass, hasScopedPermission } from './authorship';\nimport { handleError } from './error';\n\n// ============================================================================\n// Feature gate + helpers\n// ============================================================================\n\nfunction assertChannelsAvailable(): void {\n if (!coreFeatures.has('channels')) {\n throw new HTTPException(501, { message: 'Channels require a newer version of @mastra/core' });\n }\n}\n\n/**\n * Resolves the current channel providers. Prefers `resolveChannels()` so a\n * live resolver (e.g. `channels()` from @mastra/connect) is consulted —\n * connections added after boot are picked up without a restart. Falls back to\n * the static snapshot on older @mastra/core versions without the method.\n */\nasync function resolveChannelProviders(mastra: Mastra): Promise<ChannelProvider[]> {\n const resolveChannels = (mastra as Mastra & { resolveChannels?: () => Promise<Record<string, ChannelProvider>> })\n .resolveChannels;\n const record = typeof resolveChannels === 'function' ? await resolveChannels.call(mastra) : (mastra.channels ?? {});\n return Object.values(record);\n}\n\nasync function getChannelOrThrow(mastra: Mastra, platform: string): Promise<ChannelProvider> {\n const channels = await resolveChannelProviders(mastra);\n const channel = channels.find(c => c.id === platform);\n if (!channel) {\n const available = channels.map(c => c.id).join(', ');\n throw new HTTPException(404, {\n message: `Channel \"${platform}\" is not registered. Available: ${available || 'none'}`,\n });\n }\n return channel;\n}\n\n/**\n * Unified connect/disconnect authorization.\n *\n * - Stored agent exists → same write access as editing the agent record.\n * - Code-defined agent (no stored record) → route's `requiresAuth` is the gate.\n * - Agent doesn't exist anywhere:\n * - connect → 404 (can't connect a channel to a non-existent agent)\n * - disconnect → orphan cleanup, gated on `channels:write`\n */\nasync function assertChannelAgentWriteAccess(\n mastra: Mastra,\n requestContext: RequestContext,\n agentId: string,\n action: 'connect' | 'disconnect',\n): Promise<void> {\n const storage = mastra.getStorage();\n const agentsStore = storage ? await storage.getStore('agents') : null;\n const stored = agentsStore ? await agentsStore.getById(agentId) : null;\n\n if (stored) {\n assertWriteAccess({\n requestContext,\n resource: 'agents',\n resourceId: agentId,\n action: 'edit',\n record: stored,\n });\n return;\n }\n\n // Not in stored-agents (or storage doesn't support it). Check the runtime\n // registry for a code-defined agent.\n const codeDefined = mastra.getAgentById(agentId);\n if (codeDefined) {\n // Code-defined agents have no owner/ACL — route's requiresAuth /\n // requiresPermission is the gate. Pass-through.\n return;\n }\n\n if (action === 'connect') {\n throw new HTTPException(404, { message: `Agent \"${agentId}\" not found` });\n }\n\n // Disconnect against an unknown agentId = orphan cleanup (stored agent was\n // deleted but the channel installation row is still around). Allow it, but\n // gate on channels:write so this isn't an \"any authenticated user\" backdoor.\n // Follow the same no-auth-configured pass-through as assertWriteAccess.\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n if (hasAdminBypass(requestContext, 'channels')) return;\n if (hasScopedPermission({ requestContext, resource: 'channels', action: 'write' })) return;\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n// ============================================================================\n// Route Definitions\n// ============================================================================\n\n/**\n * GET /channels/platforms - List available channel platforms\n */\nexport const LIST_CHANNEL_PLATFORMS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/platforms',\n responseType: 'json',\n responseSchema: listChannelPlatformsResponseSchema,\n summary: 'List channel platforms',\n description: 'Returns available channel platforms and their configuration status',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra }) => {\n assertChannelsAvailable();\n try {\n const channels = await resolveChannelProviders(mastra);\n return channels.map(channel => {\n if (channel.getInfo) {\n return channel.getInfo();\n }\n return {\n id: channel.id,\n name: channel.id.charAt(0).toUpperCase() + channel.id.slice(1),\n isConfigured: true,\n };\n });\n } catch (error) {\n return handleError(error, 'Error listing channel platforms');\n }\n },\n});\n\n/**\n * GET /channels/:platform/installations - List installations for a platform\n */\nexport const LIST_CHANNEL_INSTALLATIONS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/:platform/installations',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n responseSchema: listChannelInstallationsResponseSchema,\n summary: 'List channel installations',\n description: 'Returns all active and pending installations for a channel platform',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, platform }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n if (!channel.listInstallations) {\n return [];\n }\n\n return await channel.listInstallations();\n } catch (error) {\n return handleError(error, 'Error listing channel installations');\n }\n },\n});\n\n/**\n * POST /channels/:platform/connect - Connect an agent to a platform\n */\nexport const CONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/connect',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n bodySchema: connectChannelBodySchema,\n responseSchema: connectChannelResponseSchema,\n summary: 'Connect agent to channel',\n description: 'Creates a platform app for the agent and returns an OAuth authorization URL',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId, options }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n if (!channel.connect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic connection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'connect');\n\n return await channel.connect(agentId, options);\n } catch (error) {\n return handleError(error, 'Error connecting agent to channel');\n }\n },\n});\n\n/**\n * POST /channels/:platform/:agentId/reconcile - Reconcile an agent's installation\n *\n * The explicit write path for connect flows that complete out-of-band (e.g.\n * Discord's bot invite has no redirect back to the server). Listing stays a\n * pure read; Studio calls this on window focus while a connect is in flight.\n * Gated on the same write access as connect — reconciliation can activate the\n * agent's installation.\n */\nexport const RECONCILE_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/:agentId/reconcile',\n responseType: 'json',\n pathParamSchema: channelAgentPathParams,\n responseSchema: reconcileChannelResponseSchema,\n summary: 'Reconcile channel installation',\n description:\n 'Checks a pending installation against platform state and activates it if its connect flow has completed. Returns the installation, or null when the agent has none or the platform does not support reconciliation.',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n // Resolve the agent (404 on unknown) and authorize the write before the\n // capability check so unknown agents never read as a successful no-op.\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'connect');\n\n if (!channel.reconcileInstallation) {\n return null;\n }\n\n return await channel.reconcileInstallation(agentId);\n } catch (error) {\n return handleError(error, 'Error reconciling channel installation');\n }\n },\n});\n\n/**\n * POST /channels/:platform/:agentId/disconnect - Disconnect an agent from a platform\n */\nexport const DISCONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/:agentId/disconnect',\n responseType: 'json',\n pathParamSchema: channelAgentPathParams,\n responseSchema: disconnectChannelResponseSchema,\n summary: 'Disconnect agent from channel',\n description: 'Deletes the platform app and cleans up the installation',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n if (!channel.disconnect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic disconnection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'disconnect');\n\n await channel.disconnect(agentId);\n return { success: true };\n } catch (error) {\n return handleError(error, 'Error disconnecting agent from channel');\n }\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"channels-B3aoI-f1.js","names":[],"sources":["../src/server/schemas/channels.ts","../src/server/handlers/channels.ts"],"sourcesContent":["import { z } from 'zod/v4';\n\n// ============================================================================\n// Path Parameter Schemas\n// ============================================================================\n\nexport const channelPlatformPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n});\n\nexport const channelAgentPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n agentId: z.string().describe('Agent identifier'),\n});\n\n// ============================================================================\n// Body Parameter Schemas\n// ============================================================================\n\nexport const connectChannelBodySchema = z.object({\n agentId: z.string().describe('Agent identifier to connect'),\n options: z.record(z.string(), z.unknown()).optional().describe('Platform-specific connection options'),\n});\n\n// ============================================================================\n// Response Schemas\n// ============================================================================\n\nconst channelPlatformInfoSchema = z.object({\n id: z.string().describe('Platform identifier'),\n name: z.string().describe('Human-readable platform name'),\n isConfigured: z.boolean().describe('Whether the platform is ready to connect agents'),\n connectOptionsSchema: z.record(z.string(), z.unknown()).optional().describe('JSON Schema for connect options'),\n});\n\nconst channelInstallationInfoSchema = z.object({\n id: z.string().describe('Installation identifier'),\n platform: z.string().describe('Platform identifier'),\n agentId: z.string().describe('Connected agent identifier'),\n status: z.enum(['active', 'pending']).describe('Installation status'),\n displayName: z.string().optional().describe('Platform-specific display name'),\n installedAt: z.coerce.date().optional().describe('Installation timestamp'),\n});\n\nconst channelConnectOAuthSchema = z.object({\n type: z.literal('oauth').describe('OAuth-based connection requiring browser redirect'),\n authorizationUrl: z.string().describe('OAuth authorization URL for user redirect'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectDeepLinkSchema = z.object({\n type: z.literal('deep_link').describe('Deep-link connection requiring native app interaction'),\n url: z.string().describe('Deep link URL to open in platform app'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectImmediateSchema = z.object({\n type: z.literal('immediate').describe('Immediate connection with no user interaction needed'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectResultSchema = z.discriminatedUnion('type', [\n channelConnectOAuthSchema,\n channelConnectDeepLinkSchema,\n channelConnectImmediateSchema,\n]);\n\nexport const listChannelPlatformsResponseSchema = z.array(channelPlatformInfoSchema);\n\nexport const listChannelInstallationsResponseSchema = z.array(channelInstallationInfoSchema);\n\nexport const connectChannelResponseSchema = channelConnectResultSchema;\n\nexport const disconnectChannelResponseSchema = z.object({\n success: z.boolean(),\n});\n\nexport const reconcileChannelResponseSchema = channelInstallationInfoSchema\n .nullable()\n .describe('The reconciled installation, or null when the agent has none (or the platform does not reconcile)');\n","import type { Mastra } from '@mastra/core';\nimport type { ChannelProvider } from '@mastra/core/channels';\nimport type { RequestContext } from '@mastra/core/di';\nimport { coreFeatures } from '@mastra/core/features';\n\nimport { MASTRA_USER_KEY } from '../constants';\nimport { HTTPException } from '../http-exception';\nimport {\n channelPlatformPathParams,\n channelAgentPathParams,\n connectChannelBodySchema,\n listChannelPlatformsResponseSchema,\n listChannelInstallationsResponseSchema,\n connectChannelResponseSchema,\n disconnectChannelResponseSchema,\n reconcileChannelResponseSchema,\n} from '../schemas/channels';\nimport { createRoute } from '../server-adapter/routes/route-builder';\n\nimport { assertWriteAccess, getCallerAuthorId, hasAdminBypass, hasScopedPermission } from './authorship';\nimport { handleError } from './error';\n\n// ============================================================================\n// Feature gate + helpers\n// ============================================================================\n\nfunction assertChannelsAvailable(): void {\n if (!coreFeatures.has('channels')) {\n throw new HTTPException(501, { message: 'Channels require a newer version of @mastra/core' });\n }\n}\n\n/**\n * Resolves the current channel providers. Prefers `resolveChannels()` so a\n * live resolver (e.g. `channels()` from @mastra/connect) is consulted —\n * connections added after boot are picked up without a restart. Falls back to\n * the static snapshot on older @mastra/core versions without the method.\n */\nasync function resolveChannelProviders(mastra: Mastra): Promise<ChannelProvider[]> {\n const resolveChannels = (mastra as Mastra & { resolveChannels?: () => Promise<Record<string, ChannelProvider>> })\n .resolveChannels;\n const record = typeof resolveChannels === 'function' ? await resolveChannels.call(mastra) : (mastra.channels ?? {});\n return Object.values(record);\n}\n\nasync function getChannelOrThrow(mastra: Mastra, platform: string): Promise<ChannelProvider> {\n const channels = await resolveChannelProviders(mastra);\n const channel = channels.find(c => c.id === platform);\n if (!channel) {\n const available = channels.map(c => c.id).join(', ');\n throw new HTTPException(404, {\n message: `Channel \"${platform}\" is not registered. Available: ${available || 'none'}`,\n });\n }\n return channel;\n}\n\n/**\n * Unified connect/disconnect authorization.\n *\n * - Stored agent exists → same write access as editing the agent record.\n * - Code-defined agent (no stored record) → route's `requiresAuth` is the gate.\n * - Agent doesn't exist anywhere:\n * - connect → 404 (can't connect a channel to a non-existent agent)\n * - disconnect → orphan cleanup, gated on `channels:write`\n */\nasync function assertChannelAgentWriteAccess(\n mastra: Mastra,\n requestContext: RequestContext,\n agentId: string,\n action: 'connect' | 'disconnect',\n): Promise<void> {\n const storage = mastra.getStorage();\n const agentsStore = storage ? await storage.getStore('agents') : null;\n const stored = agentsStore ? await agentsStore.getById(agentId) : null;\n\n if (stored) {\n assertWriteAccess({\n requestContext,\n resource: 'agents',\n resourceId: agentId,\n action: 'edit',\n record: stored,\n });\n return;\n }\n\n // Not in stored-agents (or storage doesn't support it). Check the runtime\n // registry for a code-defined agent.\n const codeDefined = mastra.getAgentById(agentId);\n if (codeDefined) {\n // Code-defined agents have no owner/ACL — route's requiresAuth /\n // requiresPermission is the gate. Pass-through.\n return;\n }\n\n if (action === 'connect') {\n throw new HTTPException(404, { message: `Agent \"${agentId}\" not found` });\n }\n\n // Disconnect against an unknown agentId = orphan cleanup (stored agent was\n // deleted but the channel installation row is still around). Allow it, but\n // gate on channels:write so this isn't an \"any authenticated user\" backdoor.\n // Follow the same no-auth-configured pass-through as assertWriteAccess.\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n if (hasAdminBypass(requestContext, 'channels')) return;\n if (hasScopedPermission({ requestContext, resource: 'channels', action: 'write' })) return;\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n// ============================================================================\n// Route Definitions\n// ============================================================================\n\n/**\n * GET /channels/platforms - List available channel platforms\n */\nexport const LIST_CHANNEL_PLATFORMS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/platforms',\n responseType: 'json',\n responseSchema: listChannelPlatformsResponseSchema,\n summary: 'List channel platforms',\n description: 'Returns available channel platforms and their configuration status',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra }) => {\n assertChannelsAvailable();\n try {\n const channels = await resolveChannelProviders(mastra);\n return channels.map(channel => {\n if (channel.getInfo) {\n return channel.getInfo();\n }\n return {\n id: channel.id,\n name: channel.id.charAt(0).toUpperCase() + channel.id.slice(1),\n isConfigured: true,\n };\n });\n } catch (error) {\n return handleError(error, 'Error listing channel platforms');\n }\n },\n});\n\n/**\n * GET /channels/:platform/installations - List installations for a platform\n */\nexport const LIST_CHANNEL_INSTALLATIONS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/:platform/installations',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n responseSchema: listChannelInstallationsResponseSchema,\n summary: 'List channel installations',\n description: 'Returns all active and pending installations for a channel platform',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, platform }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n if (!channel.listInstallations) {\n return [];\n }\n\n return await channel.listInstallations();\n } catch (error) {\n return handleError(error, 'Error listing channel installations');\n }\n },\n});\n\n/**\n * POST /channels/:platform/connect - Connect an agent to a platform\n */\nexport const CONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/connect',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n bodySchema: connectChannelBodySchema,\n responseSchema: connectChannelResponseSchema,\n summary: 'Connect agent to channel',\n description: 'Creates a platform app for the agent and returns an OAuth authorization URL',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId, options }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n if (!channel.connect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic connection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'connect');\n\n return await channel.connect(agentId, options);\n } catch (error) {\n return handleError(error, 'Error connecting agent to channel');\n }\n },\n});\n\n/**\n * POST /channels/:platform/:agentId/reconcile - Reconcile an agent's installation\n *\n * The explicit write path for connect flows that complete out-of-band (e.g.\n * Discord's bot invite has no redirect back to the server). Listing stays a\n * pure read; Studio calls this on window focus while a connect is in flight.\n * Gated on the same write access as connect — reconciliation can activate the\n * agent's installation.\n */\nexport const RECONCILE_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/:agentId/reconcile',\n responseType: 'json',\n pathParamSchema: channelAgentPathParams,\n responseSchema: reconcileChannelResponseSchema,\n summary: 'Reconcile channel installation',\n description:\n 'Checks a pending installation against platform state and activates it if its connect flow has completed. Returns the installation, or null when the agent has none or the platform does not support reconciliation.',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n // Resolve the agent (404 on unknown) and authorize the write before the\n // capability check so unknown agents never read as a successful no-op.\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'connect');\n\n if (!channel.reconcileInstallation) {\n return null;\n }\n\n return await channel.reconcileInstallation(agentId);\n } catch (error) {\n return handleError(error, 'Error reconciling channel installation');\n }\n },\n});\n\n/**\n * POST /channels/:platform/:agentId/disconnect - Disconnect an agent from a platform\n */\nexport const DISCONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/:agentId/disconnect',\n responseType: 'json',\n pathParamSchema: channelAgentPathParams,\n responseSchema: disconnectChannelResponseSchema,\n summary: 'Disconnect agent from channel',\n description: 'Deletes the platform app and cleans up the installation',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId }) => {\n assertChannelsAvailable();\n try {\n const channel = await getChannelOrThrow(mastra, platform);\n\n if (!channel.disconnect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic disconnection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'disconnect');\n\n await channel.disconnect(agentId);\n return { success: true };\n } catch (error) {\n return handleError(error, 'Error disconnecting agent from channel');\n }\n },\n});\n"],"mappings":"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"}
|
|
@@ -41,7 +41,11 @@ const MASTRA_CLIENT_TYPE_HEADER = "x-mastra-client-type";
|
|
|
41
41
|
*/
|
|
42
42
|
const MASTRA_PUBLIC_HOST_HEADER = "x-mastra-public-host";
|
|
43
43
|
const MASTRA_STUDIO_CLIENT_TYPE = "studio";
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* RequestContext keys only trusted server code may set. Request bodies and query
|
|
46
|
+
* params can never supply them.
|
|
47
|
+
*/
|
|
48
|
+
const RESERVED_REQUEST_CONTEXT_KEYS = [
|
|
45
49
|
MASTRA_RESOURCE_ID_KEY,
|
|
46
50
|
MASTRA_THREAD_ID_KEY,
|
|
47
51
|
MASTRA_SCOPES_KEY,
|
|
@@ -54,7 +58,8 @@ const RESERVED_CONTEXT_KEYS = /* @__PURE__ */ new Set([
|
|
|
54
58
|
MASTRA_INHERITED_MEMORY_KEY,
|
|
55
59
|
"mastra__factoryMemorySettings",
|
|
56
60
|
"organizationId"
|
|
57
|
-
]
|
|
61
|
+
];
|
|
62
|
+
const RESERVED_CONTEXT_KEYS = new Set(RESERVED_REQUEST_CONTEXT_KEYS);
|
|
58
63
|
function isReservedRequestContextKey(key) {
|
|
59
64
|
return RESERVED_CONTEXT_KEYS.has(key);
|
|
60
65
|
}
|
|
@@ -123,6 +128,6 @@ async function resolveToolConfig(toolsConfig, toolName, context) {
|
|
|
123
128
|
};
|
|
124
129
|
}
|
|
125
130
|
//#endregion
|
|
126
|
-
export { MASTRA_PUBLIC_HOST_HEADER as a, MASTRA_THREAD_ID_KEY as c, MASTRA_USER_ROLES_KEY as d,
|
|
131
|
+
export { MASTRA_PUBLIC_HOST_HEADER as a, MASTRA_THREAD_ID_KEY as c, MASTRA_USER_ROLES_KEY as d, RESERVED_REQUEST_CONTEXT_KEYS as f, resolveToolConfig as g, isStudioClientTypeHeader as h, MASTRA_IS_STUDIO_KEY as i, MASTRA_USER_KEY as l, isReservedRequestContextKey as m, MASTRA_AUTH_TOKEN_KEY as n, MASTRA_RESOURCE_ID_KEY as o, WORKSPACE_TOOLS as p, MASTRA_CLIENT_TYPE_HEADER as r, MASTRA_STUDIO_CLIENT_TYPE as s, MASTRA_AUTH_MODE_KEY as t, MASTRA_USER_PERMISSIONS_KEY as u };
|
|
127
132
|
|
|
128
|
-
//# sourceMappingURL=constants-
|
|
133
|
+
//# sourceMappingURL=constants-DazK_RZj.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants-DazK_RZj.js","names":[],"sources":["../src/server/constants.ts"],"sourcesContent":["/**\n * Constants inlined from @mastra/core to avoid import compatibility\n * issues with older core versions that don't export them yet.\n *\n * - Reserved RequestContext keys are inlined from @mastra/core/request-context.\n * - Workspace tool constants are inlined from @mastra/core/workspace.\n */\n\nexport const MASTRA_RESOURCE_ID_KEY = 'mastra__resourceId';\n\nexport const MASTRA_THREAD_ID_KEY = 'mastra__threadId';\n\n/**\n * Agent scopes set by trusted middleware. Never accepted from a request body.\n */\nexport const MASTRA_SCOPES_KEY = 'mastra__scopes';\n\nexport const MASTRA_USER_KEY = 'mastra__user';\n\nexport const MASTRA_USER_PERMISSIONS_KEY = 'mastra__userPermissions';\n\nexport const MASTRA_USER_ROLES_KEY = 'mastra__userRoles';\n\nexport const MASTRA_AUTH_TOKEN_KEY = 'mastra__authToken';\n\nexport const MASTRA_IS_STUDIO_KEY = 'mastra__isStudio';\n\n/**\n * Carries a delegating agent's memory into a delegated sub-agent run. Set only\n * by the delegation path inside a single process.\n */\nexport const MASTRA_INHERITED_MEMORY_KEY = 'mastra__inheritedMemory';\n\n/**\n * Tracks which auth mode was used for the current request.\n * Set to 'studio' when studio auth was used, 'server' when server auth was used.\n * Used to determine which RBAC/FGA provider to use for permission checks.\n */\nexport const MASTRA_AUTH_MODE_KEY = 'mastra__authMode';\n\nexport type MastraAuthMode = 'studio' | 'server';\n\nexport const MASTRA_CLIENT_TYPE_HEADER = 'x-mastra-client-type';\n\n/**\n * Browser-facing host, set by a trusted proxy whose own `X-Forwarded-Host` does\n * not survive the hop to the app. Railway's gateway, for example, overwrites\n * `X-Forwarded-Host` with its internal domain, so an edge in front of it has no\n * other way to tell the app which hostname the user actually typed.\n *\n * Read by `getPublicOrigin()` ahead of `X-Forwarded-Host`. Carries the same\n * trust assumption as the other forwarded headers: meaningful only behind a\n * proxy that sets it, and it must be stripped from untrusted client requests.\n */\nexport const MASTRA_PUBLIC_HOST_HEADER = 'x-mastra-public-host';\n\nexport const MASTRA_STUDIO_CLIENT_TYPE = 'studio';\n\n/**\n * RequestContext keys only trusted server code may set. Request bodies and query\n * params can never supply them.\n */\nexport const RESERVED_REQUEST_CONTEXT_KEYS = [\n MASTRA_RESOURCE_ID_KEY,\n MASTRA_THREAD_ID_KEY,\n // Agent scopes decide memory identity and what the agent acts as; only\n // server middleware may set them.\n MASTRA_SCOPES_KEY,\n MASTRA_USER_KEY,\n MASTRA_USER_PERMISSIONS_KEY,\n MASTRA_USER_ROLES_KEY,\n MASTRA_AUTH_TOKEN_KEY,\n MASTRA_IS_STUDIO_KEY,\n MASTRA_AUTH_MODE_KEY,\n // Delegation stores a live memory instance here. A body-supplied value would\n // be handed to the agent as its memory and throw on the first memory call.\n MASTRA_INHERITED_MEMORY_KEY,\n // Factory stores the authoritative per-caller OM settings result here before\n // model-driven memory processors run. Client input must not spoof that result.\n 'mastra__factoryMemorySettings',\n // Tenant scope must be established server-side, never self-asserted by a\n // client. The trusted-actor FGA gate keys off `organizationId`, so a\n // body-supplied value must not be merged into the request context.\n 'organizationId',\n] as const;\n\nconst RESERVED_CONTEXT_KEYS: ReadonlySet<string> = new Set(RESERVED_REQUEST_CONTEXT_KEYS);\n\nexport function isReservedRequestContextKey(key: string): boolean {\n return RESERVED_CONTEXT_KEYS.has(key);\n}\n\nexport function isStudioClientTypeHeader(value: string | undefined): boolean {\n return value?.toLowerCase() === MASTRA_STUDIO_CLIENT_TYPE;\n}\n\nexport const WORKSPACE_TOOLS_PREFIX = 'mastra_workspace' as const;\n\nexport const WORKSPACE_TOOLS = {\n FILESYSTEM: {\n READ_FILE: `${WORKSPACE_TOOLS_PREFIX}_read_file` as const,\n WRITE_FILE: `${WORKSPACE_TOOLS_PREFIX}_write_file` as const,\n EDIT_FILE: `${WORKSPACE_TOOLS_PREFIX}_edit_file` as const,\n LIST_FILES: `${WORKSPACE_TOOLS_PREFIX}_list_files` as const,\n DELETE: `${WORKSPACE_TOOLS_PREFIX}_delete` as const,\n FILE_STAT: `${WORKSPACE_TOOLS_PREFIX}_file_stat` as const,\n MKDIR: `${WORKSPACE_TOOLS_PREFIX}_mkdir` as const,\n GREP: `${WORKSPACE_TOOLS_PREFIX}_grep` as const,\n },\n SANDBOX: {\n EXECUTE_COMMAND: `${WORKSPACE_TOOLS_PREFIX}_execute_command` as const,\n },\n SEARCH: {\n SEARCH: `${WORKSPACE_TOOLS_PREFIX}_search` as const,\n INDEX: `${WORKSPACE_TOOLS_PREFIX}_index` as const,\n },\n} as const;\n\nexport type WorkspaceToolName =\n | (typeof WORKSPACE_TOOLS.FILESYSTEM)[keyof typeof WORKSPACE_TOOLS.FILESYSTEM]\n | (typeof WORKSPACE_TOOLS.SEARCH)[keyof typeof WORKSPACE_TOOLS.SEARCH]\n | (typeof WORKSPACE_TOOLS.SANDBOX)[keyof typeof WORKSPACE_TOOLS.SANDBOX];\n\n/**\n * A tool config value that may be a static boolean or a dynamic function.\n * Inlined from @mastra/core/workspace for compatibility.\n *\n * Uses `(...args: any[]) => any` for the function branch so it stays\n * assignable from all core context variants (ToolConfigContext,\n * ToolConfigWithArgsContext) without importing them.\n */\n\ntype DynamicToolConfigValue = boolean | ((...args: any[]) => any);\n\n/**\n * Configuration for a single workspace tool.\n */\nexport interface WorkspaceToolConfig {\n enabled?: DynamicToolConfigValue;\n requireApproval?: DynamicToolConfigValue;\n requireReadBeforeWrite?: DynamicToolConfigValue;\n}\n\n/**\n * Configuration for workspace tools.\n */\nexport type WorkspaceToolsConfig = {\n enabled?: DynamicToolConfigValue;\n requireApproval?: DynamicToolConfigValue;\n} & Partial<Record<WorkspaceToolName, WorkspaceToolConfig>>;\n\n/**\n * Safely resolve a dynamic config value (boolean or async function) to a boolean.\n * Falls back to `safeDefault` when no context is available or the function throws.\n */\nasync function resolveDynamicValue(\n value: DynamicToolConfigValue | undefined,\n context: { workspace: object; requestContext: Record<string, unknown> } | undefined,\n safeDefault: boolean,\n): Promise<boolean> {\n if (value === undefined) return safeDefault;\n if (typeof value === 'boolean') return value;\n if (!context) return safeDefault;\n try {\n return await value(context);\n } catch (error) {\n console.warn('[Workspace Tools] Dynamic config function threw, using safe default:', error);\n return safeDefault;\n }\n}\n\n/**\n * Resolve the effective configuration for a workspace tool.\n * Inlined from @mastra/core/workspace for compatibility.\n *\n * Dynamic function values are resolved by calling them with the provided\n * workspace and requestContext. If a function throws, safe defaults are used\n * (enabled → false, requireApproval → true, requireReadBeforeWrite → true).\n */\nexport async function resolveToolConfig(\n toolsConfig: WorkspaceToolsConfig | undefined,\n toolName: WorkspaceToolName,\n context?: { workspace: object; requestContext: Record<string, unknown> },\n): Promise<{ enabled: boolean; requireApproval: boolean; requireReadBeforeWrite?: boolean }> {\n let enabled: DynamicToolConfigValue = true;\n let requireApproval: DynamicToolConfigValue = false;\n let requireReadBeforeWrite: DynamicToolConfigValue | undefined;\n\n if (toolsConfig) {\n if (toolsConfig.enabled !== undefined) {\n enabled = toolsConfig.enabled;\n }\n if (toolsConfig.requireApproval !== undefined) {\n requireApproval = toolsConfig.requireApproval;\n }\n\n const perToolConfig = toolsConfig[toolName];\n if (perToolConfig) {\n if (perToolConfig.enabled !== undefined) {\n enabled = perToolConfig.enabled;\n }\n if (perToolConfig.requireApproval !== undefined) {\n requireApproval = perToolConfig.requireApproval;\n }\n if (perToolConfig.requireReadBeforeWrite !== undefined) {\n requireReadBeforeWrite = perToolConfig.requireReadBeforeWrite;\n }\n }\n }\n\n return {\n enabled: await resolveDynamicValue(enabled, context, false),\n requireApproval: await resolveDynamicValue(requireApproval, context, true),\n requireReadBeforeWrite:\n requireReadBeforeWrite !== undefined\n ? await resolveDynamicValue(requireReadBeforeWrite, context, true)\n : undefined,\n };\n}\n"],"mappings":";;;;;;;;AAQA,MAAa,yBAAyB;AAEtC,MAAa,uBAAuB;;;;AAKpC,MAAa,oBAAoB;AAEjC,MAAa,kBAAkB;AAE/B,MAAa,8BAA8B;AAE3C,MAAa,wBAAwB;AAErC,MAAa,wBAAwB;AAErC,MAAa,uBAAuB;;;;;AAMpC,MAAa,8BAA8B;;;;;;AAO3C,MAAa,uBAAuB;AAIpC,MAAa,4BAA4B;;;;;;;;;;;AAYzC,MAAa,4BAA4B;AAEzC,MAAa,4BAA4B;;;;;AAMzC,MAAa,gCAAgC;CAC3C;CACA;CAGA;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CAGA;CAIA;AACF;AAEA,MAAM,wBAA6C,IAAI,IAAI,6BAA6B;AAExF,SAAgB,4BAA4B,KAAsB;CAChE,OAAO,sBAAsB,IAAI,GAAG;AACtC;AAEA,SAAgB,yBAAyB,OAAoC;CAC3E,OAAO,OAAO,YAAY,MAAM;AAClC;AAEA,MAAa,yBAAyB;AAEtC,MAAa,kBAAkB;CAC7B,YAAY;EACV,WAAW,GAAG,uBAAuB;EACrC,YAAY,GAAG,uBAAuB;EACtC,WAAW,GAAG,uBAAuB;EACrC,YAAY,GAAG,uBAAuB;EACtC,QAAQ,GAAG,uBAAuB;EAClC,WAAW,GAAG,uBAAuB;EACrC,OAAO,GAAG,uBAAuB;EACjC,MAAM,GAAG,uBAAuB;CAClC;CACA,SAAS,EACP,iBAAiB,GAAG,uBAAuB,kBAC7C;CACA,QAAQ;EACN,QAAQ,GAAG,uBAAuB;EAClC,OAAO,GAAG,uBAAuB;CACnC;AACF;;;;;AAuCA,eAAe,oBACb,OACA,SACA,aACkB;CAClB,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,IAAI,OAAO,UAAU,WAAW,OAAO;CACvC,IAAI,CAAC,SAAS,OAAO;CACrB,IAAI;EACF,OAAO,MAAM,MAAM,OAAO;CAC5B,SAAS,OAAO;EACd,QAAQ,KAAK,wEAAwE,KAAK;EAC1F,OAAO;CACT;AACF;;;;;;;;;AAUA,eAAsB,kBACpB,aACA,UACA,SAC2F;CAC3F,IAAI,UAAkC;CACtC,IAAI,kBAA0C;CAC9C,IAAI;CAEJ,IAAI,aAAa;EACf,IAAI,YAAY,YAAY,KAAA,GAC1B,UAAU,YAAY;EAExB,IAAI,YAAY,oBAAoB,KAAA,GAClC,kBAAkB,YAAY;EAGhC,MAAM,gBAAgB,YAAY;EAClC,IAAI,eAAe;GACjB,IAAI,cAAc,YAAY,KAAA,GAC5B,UAAU,cAAc;GAE1B,IAAI,cAAc,oBAAoB,KAAA,GACpC,kBAAkB,cAAc;GAElC,IAAI,cAAc,2BAA2B,KAAA,GAC3C,yBAAyB,cAAc;EAE3C;CACF;CAEA,OAAO;EACL,SAAS,MAAM,oBAAoB,SAAS,SAAS,KAAK;EAC1D,iBAAiB,MAAM,oBAAoB,iBAAiB,SAAS,IAAI;EACzE,wBACE,2BAA2B,KAAA,IACvB,MAAM,oBAAoB,wBAAwB,SAAS,IAAI,IAC/D,KAAA;CACR;AACF"}
|
|
@@ -41,7 +41,11 @@ const MASTRA_CLIENT_TYPE_HEADER = "x-mastra-client-type";
|
|
|
41
41
|
*/
|
|
42
42
|
const MASTRA_PUBLIC_HOST_HEADER = "x-mastra-public-host";
|
|
43
43
|
const MASTRA_STUDIO_CLIENT_TYPE = "studio";
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* RequestContext keys only trusted server code may set. Request bodies and query
|
|
46
|
+
* params can never supply them.
|
|
47
|
+
*/
|
|
48
|
+
const RESERVED_REQUEST_CONTEXT_KEYS = [
|
|
45
49
|
MASTRA_RESOURCE_ID_KEY,
|
|
46
50
|
MASTRA_THREAD_ID_KEY,
|
|
47
51
|
MASTRA_SCOPES_KEY,
|
|
@@ -54,7 +58,8 @@ const RESERVED_CONTEXT_KEYS = /* @__PURE__ */ new Set([
|
|
|
54
58
|
MASTRA_INHERITED_MEMORY_KEY,
|
|
55
59
|
"mastra__factoryMemorySettings",
|
|
56
60
|
"organizationId"
|
|
57
|
-
]
|
|
61
|
+
];
|
|
62
|
+
const RESERVED_CONTEXT_KEYS = new Set(RESERVED_REQUEST_CONTEXT_KEYS);
|
|
58
63
|
function isReservedRequestContextKey(key) {
|
|
59
64
|
return RESERVED_CONTEXT_KEYS.has(key);
|
|
60
65
|
}
|
|
@@ -189,6 +194,12 @@ Object.defineProperty(exports, "MASTRA_USER_ROLES_KEY", {
|
|
|
189
194
|
return MASTRA_USER_ROLES_KEY;
|
|
190
195
|
}
|
|
191
196
|
});
|
|
197
|
+
Object.defineProperty(exports, "RESERVED_REQUEST_CONTEXT_KEYS", {
|
|
198
|
+
enumerable: true,
|
|
199
|
+
get: function() {
|
|
200
|
+
return RESERVED_REQUEST_CONTEXT_KEYS;
|
|
201
|
+
}
|
|
202
|
+
});
|
|
192
203
|
Object.defineProperty(exports, "WORKSPACE_TOOLS", {
|
|
193
204
|
enumerable: true,
|
|
194
205
|
get: function() {
|
|
@@ -214,4 +225,4 @@ Object.defineProperty(exports, "resolveToolConfig", {
|
|
|
214
225
|
}
|
|
215
226
|
});
|
|
216
227
|
|
|
217
|
-
//# sourceMappingURL=constants-
|
|
228
|
+
//# sourceMappingURL=constants-e7aaPCLj.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants-e7aaPCLj.cjs","names":[],"sources":["../src/server/constants.ts"],"sourcesContent":["/**\n * Constants inlined from @mastra/core to avoid import compatibility\n * issues with older core versions that don't export them yet.\n *\n * - Reserved RequestContext keys are inlined from @mastra/core/request-context.\n * - Workspace tool constants are inlined from @mastra/core/workspace.\n */\n\nexport const MASTRA_RESOURCE_ID_KEY = 'mastra__resourceId';\n\nexport const MASTRA_THREAD_ID_KEY = 'mastra__threadId';\n\n/**\n * Agent scopes set by trusted middleware. Never accepted from a request body.\n */\nexport const MASTRA_SCOPES_KEY = 'mastra__scopes';\n\nexport const MASTRA_USER_KEY = 'mastra__user';\n\nexport const MASTRA_USER_PERMISSIONS_KEY = 'mastra__userPermissions';\n\nexport const MASTRA_USER_ROLES_KEY = 'mastra__userRoles';\n\nexport const MASTRA_AUTH_TOKEN_KEY = 'mastra__authToken';\n\nexport const MASTRA_IS_STUDIO_KEY = 'mastra__isStudio';\n\n/**\n * Carries a delegating agent's memory into a delegated sub-agent run. Set only\n * by the delegation path inside a single process.\n */\nexport const MASTRA_INHERITED_MEMORY_KEY = 'mastra__inheritedMemory';\n\n/**\n * Tracks which auth mode was used for the current request.\n * Set to 'studio' when studio auth was used, 'server' when server auth was used.\n * Used to determine which RBAC/FGA provider to use for permission checks.\n */\nexport const MASTRA_AUTH_MODE_KEY = 'mastra__authMode';\n\nexport type MastraAuthMode = 'studio' | 'server';\n\nexport const MASTRA_CLIENT_TYPE_HEADER = 'x-mastra-client-type';\n\n/**\n * Browser-facing host, set by a trusted proxy whose own `X-Forwarded-Host` does\n * not survive the hop to the app. Railway's gateway, for example, overwrites\n * `X-Forwarded-Host` with its internal domain, so an edge in front of it has no\n * other way to tell the app which hostname the user actually typed.\n *\n * Read by `getPublicOrigin()` ahead of `X-Forwarded-Host`. Carries the same\n * trust assumption as the other forwarded headers: meaningful only behind a\n * proxy that sets it, and it must be stripped from untrusted client requests.\n */\nexport const MASTRA_PUBLIC_HOST_HEADER = 'x-mastra-public-host';\n\nexport const MASTRA_STUDIO_CLIENT_TYPE = 'studio';\n\n/**\n * RequestContext keys only trusted server code may set. Request bodies and query\n * params can never supply them.\n */\nexport const RESERVED_REQUEST_CONTEXT_KEYS = [\n MASTRA_RESOURCE_ID_KEY,\n MASTRA_THREAD_ID_KEY,\n // Agent scopes decide memory identity and what the agent acts as; only\n // server middleware may set them.\n MASTRA_SCOPES_KEY,\n MASTRA_USER_KEY,\n MASTRA_USER_PERMISSIONS_KEY,\n MASTRA_USER_ROLES_KEY,\n MASTRA_AUTH_TOKEN_KEY,\n MASTRA_IS_STUDIO_KEY,\n MASTRA_AUTH_MODE_KEY,\n // Delegation stores a live memory instance here. A body-supplied value would\n // be handed to the agent as its memory and throw on the first memory call.\n MASTRA_INHERITED_MEMORY_KEY,\n // Factory stores the authoritative per-caller OM settings result here before\n // model-driven memory processors run. Client input must not spoof that result.\n 'mastra__factoryMemorySettings',\n // Tenant scope must be established server-side, never self-asserted by a\n // client. The trusted-actor FGA gate keys off `organizationId`, so a\n // body-supplied value must not be merged into the request context.\n 'organizationId',\n] as const;\n\nconst RESERVED_CONTEXT_KEYS: ReadonlySet<string> = new Set(RESERVED_REQUEST_CONTEXT_KEYS);\n\nexport function isReservedRequestContextKey(key: string): boolean {\n return RESERVED_CONTEXT_KEYS.has(key);\n}\n\nexport function isStudioClientTypeHeader(value: string | undefined): boolean {\n return value?.toLowerCase() === MASTRA_STUDIO_CLIENT_TYPE;\n}\n\nexport const WORKSPACE_TOOLS_PREFIX = 'mastra_workspace' as const;\n\nexport const WORKSPACE_TOOLS = {\n FILESYSTEM: {\n READ_FILE: `${WORKSPACE_TOOLS_PREFIX}_read_file` as const,\n WRITE_FILE: `${WORKSPACE_TOOLS_PREFIX}_write_file` as const,\n EDIT_FILE: `${WORKSPACE_TOOLS_PREFIX}_edit_file` as const,\n LIST_FILES: `${WORKSPACE_TOOLS_PREFIX}_list_files` as const,\n DELETE: `${WORKSPACE_TOOLS_PREFIX}_delete` as const,\n FILE_STAT: `${WORKSPACE_TOOLS_PREFIX}_file_stat` as const,\n MKDIR: `${WORKSPACE_TOOLS_PREFIX}_mkdir` as const,\n GREP: `${WORKSPACE_TOOLS_PREFIX}_grep` as const,\n },\n SANDBOX: {\n EXECUTE_COMMAND: `${WORKSPACE_TOOLS_PREFIX}_execute_command` as const,\n },\n SEARCH: {\n SEARCH: `${WORKSPACE_TOOLS_PREFIX}_search` as const,\n INDEX: `${WORKSPACE_TOOLS_PREFIX}_index` as const,\n },\n} as const;\n\nexport type WorkspaceToolName =\n | (typeof WORKSPACE_TOOLS.FILESYSTEM)[keyof typeof WORKSPACE_TOOLS.FILESYSTEM]\n | (typeof WORKSPACE_TOOLS.SEARCH)[keyof typeof WORKSPACE_TOOLS.SEARCH]\n | (typeof WORKSPACE_TOOLS.SANDBOX)[keyof typeof WORKSPACE_TOOLS.SANDBOX];\n\n/**\n * A tool config value that may be a static boolean or a dynamic function.\n * Inlined from @mastra/core/workspace for compatibility.\n *\n * Uses `(...args: any[]) => any` for the function branch so it stays\n * assignable from all core context variants (ToolConfigContext,\n * ToolConfigWithArgsContext) without importing them.\n */\n\ntype DynamicToolConfigValue = boolean | ((...args: any[]) => any);\n\n/**\n * Configuration for a single workspace tool.\n */\nexport interface WorkspaceToolConfig {\n enabled?: DynamicToolConfigValue;\n requireApproval?: DynamicToolConfigValue;\n requireReadBeforeWrite?: DynamicToolConfigValue;\n}\n\n/**\n * Configuration for workspace tools.\n */\nexport type WorkspaceToolsConfig = {\n enabled?: DynamicToolConfigValue;\n requireApproval?: DynamicToolConfigValue;\n} & Partial<Record<WorkspaceToolName, WorkspaceToolConfig>>;\n\n/**\n * Safely resolve a dynamic config value (boolean or async function) to a boolean.\n * Falls back to `safeDefault` when no context is available or the function throws.\n */\nasync function resolveDynamicValue(\n value: DynamicToolConfigValue | undefined,\n context: { workspace: object; requestContext: Record<string, unknown> } | undefined,\n safeDefault: boolean,\n): Promise<boolean> {\n if (value === undefined) return safeDefault;\n if (typeof value === 'boolean') return value;\n if (!context) return safeDefault;\n try {\n return await value(context);\n } catch (error) {\n console.warn('[Workspace Tools] Dynamic config function threw, using safe default:', error);\n return safeDefault;\n }\n}\n\n/**\n * Resolve the effective configuration for a workspace tool.\n * Inlined from @mastra/core/workspace for compatibility.\n *\n * Dynamic function values are resolved by calling them with the provided\n * workspace and requestContext. If a function throws, safe defaults are used\n * (enabled → false, requireApproval → true, requireReadBeforeWrite → true).\n */\nexport async function resolveToolConfig(\n toolsConfig: WorkspaceToolsConfig | undefined,\n toolName: WorkspaceToolName,\n context?: { workspace: object; requestContext: Record<string, unknown> },\n): Promise<{ enabled: boolean; requireApproval: boolean; requireReadBeforeWrite?: boolean }> {\n let enabled: DynamicToolConfigValue = true;\n let requireApproval: DynamicToolConfigValue = false;\n let requireReadBeforeWrite: DynamicToolConfigValue | undefined;\n\n if (toolsConfig) {\n if (toolsConfig.enabled !== undefined) {\n enabled = toolsConfig.enabled;\n }\n if (toolsConfig.requireApproval !== undefined) {\n requireApproval = toolsConfig.requireApproval;\n }\n\n const perToolConfig = toolsConfig[toolName];\n if (perToolConfig) {\n if (perToolConfig.enabled !== undefined) {\n enabled = perToolConfig.enabled;\n }\n if (perToolConfig.requireApproval !== undefined) {\n requireApproval = perToolConfig.requireApproval;\n }\n if (perToolConfig.requireReadBeforeWrite !== undefined) {\n requireReadBeforeWrite = perToolConfig.requireReadBeforeWrite;\n }\n }\n }\n\n return {\n enabled: await resolveDynamicValue(enabled, context, false),\n requireApproval: await resolveDynamicValue(requireApproval, context, true),\n requireReadBeforeWrite:\n requireReadBeforeWrite !== undefined\n ? await resolveDynamicValue(requireReadBeforeWrite, context, true)\n : undefined,\n };\n}\n"],"mappings":";;;;;;;;AAQA,MAAa,yBAAyB;AAEtC,MAAa,uBAAuB;;;;AAKpC,MAAa,oBAAoB;AAEjC,MAAa,kBAAkB;AAE/B,MAAa,8BAA8B;AAE3C,MAAa,wBAAwB;AAErC,MAAa,wBAAwB;AAErC,MAAa,uBAAuB;;;;;AAMpC,MAAa,8BAA8B;;;;;;AAO3C,MAAa,uBAAuB;AAIpC,MAAa,4BAA4B;;;;;;;;;;;AAYzC,MAAa,4BAA4B;AAEzC,MAAa,4BAA4B;;;;;AAMzC,MAAa,gCAAgC;CAC3C;CACA;CAGA;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CAGA;CAIA;AACF;AAEA,MAAM,wBAA6C,IAAI,IAAI,6BAA6B;AAExF,SAAgB,4BAA4B,KAAsB;CAChE,OAAO,sBAAsB,IAAI,GAAG;AACtC;AAEA,SAAgB,yBAAyB,OAAoC;CAC3E,OAAO,OAAO,YAAY,MAAM;AAClC;AAEA,MAAa,yBAAyB;AAEtC,MAAa,kBAAkB;CAC7B,YAAY;EACV,WAAW,GAAG,uBAAuB;EACrC,YAAY,GAAG,uBAAuB;EACtC,WAAW,GAAG,uBAAuB;EACrC,YAAY,GAAG,uBAAuB;EACtC,QAAQ,GAAG,uBAAuB;EAClC,WAAW,GAAG,uBAAuB;EACrC,OAAO,GAAG,uBAAuB;EACjC,MAAM,GAAG,uBAAuB;CAClC;CACA,SAAS,EACP,iBAAiB,GAAG,uBAAuB,kBAC7C;CACA,QAAQ;EACN,QAAQ,GAAG,uBAAuB;EAClC,OAAO,GAAG,uBAAuB;CACnC;AACF;;;;;AAuCA,eAAe,oBACb,OACA,SACA,aACkB;CAClB,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,IAAI,OAAO,UAAU,WAAW,OAAO;CACvC,IAAI,CAAC,SAAS,OAAO;CACrB,IAAI;EACF,OAAO,MAAM,MAAM,OAAO;CAC5B,SAAS,OAAO;EACd,QAAQ,KAAK,wEAAwE,KAAK;EAC1F,OAAO;CACT;AACF;;;;;;;;;AAUA,eAAsB,kBACpB,aACA,UACA,SAC2F;CAC3F,IAAI,UAAkC;CACtC,IAAI,kBAA0C;CAC9C,IAAI;CAEJ,IAAI,aAAa;EACf,IAAI,YAAY,YAAY,KAAA,GAC1B,UAAU,YAAY;EAExB,IAAI,YAAY,oBAAoB,KAAA,GAClC,kBAAkB,YAAY;EAGhC,MAAM,gBAAgB,YAAY;EAClC,IAAI,eAAe;GACjB,IAAI,cAAc,YAAY,KAAA,GAC5B,UAAU,cAAc;GAE1B,IAAI,cAAc,oBAAoB,KAAA,GACpC,kBAAkB,cAAc;GAElC,IAAI,cAAc,2BAA2B,KAAA,GAC3C,yBAAyB,cAAc;EAE3C;CACF;CAEA,OAAO;EACL,SAAS,MAAM,oBAAoB,SAAS,SAAS,KAAK;EAC1D,iBAAiB,MAAM,oBAAoB,iBAAiB,SAAS,IAAI;EACzE,wBACE,2BAA2B,KAAA,IACvB,MAAM,oBAAoB,wBAAwB,SAAS,IAAI,IAC/D,KAAA;CACR;AACF"}
|
|
@@ -20,8 +20,8 @@ let _mastra_core_storage = require("@mastra/core/storage");
|
|
|
20
20
|
let _mastra_core_features = require("@mastra/core/features");
|
|
21
21
|
let _mastra_core_observability = require("@mastra/core/observability");
|
|
22
22
|
let _mastra_core_processors = require("@mastra/core/processors");
|
|
23
|
-
let _mastra_core_workflows = require("@mastra/core/workflows");
|
|
24
23
|
let fs = require("fs");
|
|
24
|
+
let _mastra_core_workflows = require("@mastra/core/workflows");
|
|
25
25
|
let os = require("os");
|
|
26
26
|
let path = require("path");
|
|
27
27
|
let crypto$1 = require("crypto");
|
|
@@ -4637,7 +4637,7 @@ function splitLines(text) {
|
|
|
4637
4637
|
return result;
|
|
4638
4638
|
}
|
|
4639
4639
|
//#endregion
|
|
4640
|
-
//#region ../memory/dist/src-
|
|
4640
|
+
//#region ../memory/dist/src-D9Uu93Xu.js
|
|
4641
4641
|
var __defProp$3 = Object.defineProperty;
|
|
4642
4642
|
var __exportAll = (all, no_symbols) => {
|
|
4643
4643
|
let target = {};
|
|
@@ -30989,7 +30989,8 @@ function hasGoogleGenerativeAIKey() {
|
|
|
30989
30989
|
/**
|
|
30990
30990
|
* Resolve the concrete model ID `'auto'` selects for a main model ID.
|
|
30991
30991
|
*
|
|
30992
|
-
* Order: Gemini when
|
|
30992
|
+
* Order: Gemini when Google is usable (`canUseProvider('google')`, or `GOOGLE_GENERATIVE_AI_API_KEY`
|
|
30993
|
+
* when no check is given); else the main provider's low-cost
|
|
30993
30994
|
* model (keeping a `mastra/` gateway prefix); else the main model ID itself. Returns `undefined`
|
|
30994
30995
|
* only when there is no Google key and no main model ID.
|
|
30995
30996
|
*/
|
|
@@ -30998,7 +30999,7 @@ function resolveAutoModelId(mainModelId, options) {
|
|
|
30998
30999
|
...AUTO_MODEL_BY_PROVIDER,
|
|
30999
31000
|
...options?.autoModels
|
|
31000
31001
|
};
|
|
31001
|
-
if (hasGoogleGenerativeAIKey() && models.google) return models.google;
|
|
31002
|
+
if ((options?.canUseProvider ? options.canUseProvider("google") : hasGoogleGenerativeAIKey()) && models.google) return models.google;
|
|
31002
31003
|
if (!mainModelId) return;
|
|
31003
31004
|
const prefix = mainModelId.startsWith(ROUTE_PREFIX) ? ROUTE_PREFIX : "";
|
|
31004
31005
|
const provider = mainModelId.slice(prefix.length).split("/", 1)[0];
|
|
@@ -35635,6 +35636,7 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
35635
35636
|
mastra;
|
|
35636
35637
|
autoModels;
|
|
35637
35638
|
resolveAutoModelHook;
|
|
35639
|
+
canUseProvider;
|
|
35638
35640
|
memory;
|
|
35639
35641
|
/**
|
|
35640
35642
|
* Track message IDs observed during this instance's lifetime.
|
|
@@ -35733,6 +35735,7 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
35733
35735
|
this.hooks = config.hooks;
|
|
35734
35736
|
this.autoModels = config.autoModels;
|
|
35735
35737
|
this.resolveAutoModelHook = config.resolveModel;
|
|
35738
|
+
this.canUseProvider = config.canUseProvider;
|
|
35736
35739
|
this.hookExecution = config.hookExecution ?? "non-blocking";
|
|
35737
35740
|
this.mastra = config.mastra;
|
|
35738
35741
|
this.memory = config.memory;
|
|
@@ -35932,11 +35935,18 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
35932
35935
|
model: await this.resolveAutoModel(options)
|
|
35933
35936
|
};
|
|
35934
35937
|
}
|
|
35938
|
+
autoModelOptions(requestContext) {
|
|
35939
|
+
const canUseProvider = this.canUseProvider;
|
|
35940
|
+
return {
|
|
35941
|
+
autoModels: this.autoModels,
|
|
35942
|
+
canUseProvider: canUseProvider ? (providerId) => canUseProvider(providerId, { requestContext }) : void 0
|
|
35943
|
+
};
|
|
35944
|
+
}
|
|
35935
35945
|
async resolveAutoModel(options) {
|
|
35936
35946
|
let mainModel = options?.currentModel?.model;
|
|
35937
35947
|
if (!mainModel && options?.mainAgent) mainModel = await options.mainAgent.getModel({ requestContext: options.requestContext });
|
|
35938
35948
|
const mainModelId = getModelId(mainModel);
|
|
35939
|
-
const pick = resolveAutoModelId(mainModelId,
|
|
35949
|
+
const pick = resolveAutoModelId(mainModelId, this.autoModelOptions(options?.requestContext)) ?? (mainModel ? void 0 : OBSERVATIONAL_MEMORY_DEFAULTS.observation.model);
|
|
35940
35950
|
if (mainModel && (!pick || pick === mainModelId)) return mainModel;
|
|
35941
35951
|
const modelId = pick;
|
|
35942
35952
|
return this.resolveAutoModelHook ? await this.resolveAutoModelHook(modelId, { requestContext: options?.requestContext }) : modelId;
|
|
@@ -36003,7 +36013,7 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
36003
36013
|
async getCompressionStartLevel(requestContext) {
|
|
36004
36014
|
try {
|
|
36005
36015
|
const reflectionModel = await this.resolveModelFunction(this.reflectionConfig.model, requestContext);
|
|
36006
|
-
if ((reflectionModel === "auto" ? resolveAutoModelId(void 0,
|
|
36016
|
+
if ((reflectionModel === "auto" ? resolveAutoModelId(void 0, this.autoModelOptions(requestContext)) ?? "" : (await this.resolveModelContext(reflectionModel, requestContext))?.modelId ?? "").includes("gemini-2.5-flash")) return 2;
|
|
36007
36017
|
return 1;
|
|
36008
36018
|
} catch {
|
|
36009
36019
|
return 1;
|
|
@@ -39963,6 +39973,7 @@ ${workingMemory}`;
|
|
|
39963
39973
|
shareTokenBudget: omConfig.shareTokenBudget,
|
|
39964
39974
|
model: omConfig.model,
|
|
39965
39975
|
autoModels: omConfig.autoModels,
|
|
39976
|
+
canUseProvider: omConfig.canUseProvider,
|
|
39966
39977
|
resolveModel: omConfig.resolveModel,
|
|
39967
39978
|
mastra: this._mastraInstance,
|
|
39968
39979
|
onIndexObservations,
|
|
@@ -51899,4 +51910,4 @@ const agentBuilderWorkflows = {
|
|
|
51899
51910
|
//#endregion
|
|
51900
51911
|
exports.agentBuilderWorkflows = agentBuilderWorkflows;
|
|
51901
51912
|
|
|
51902
|
-
//# sourceMappingURL=dist-
|
|
51913
|
+
//# sourceMappingURL=dist-B8rA8_Wt.cjs.map
|