@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.
Files changed (151) hide show
  1. package/dist/{a2a-BeW8w9CL.cjs → a2a-D5CGFO8W.cjs} +2 -2
  2. package/dist/{a2a-BeW8w9CL.cjs.map → a2a-D5CGFO8W.cjs.map} +1 -1
  3. package/dist/{a2a-BWKuwXQY.js → a2a-Dg3ylOKc.js} +2 -2
  4. package/dist/{a2a-BWKuwXQY.js.map → a2a-Dg3ylOKc.js.map} +1 -1
  5. package/dist/{api-schema-manifest-C1XMN6QZ.cjs → api-schema-manifest-Dr8PM4Qj.cjs} +2 -2
  6. package/dist/{api-schema-manifest-C1XMN6QZ.cjs.map → api-schema-manifest-Dr8PM4Qj.cjs.map} +1 -1
  7. package/dist/{api-schema-manifest-BWXv2l4E.js → api-schema-manifest-aur2BK6a.js} +2 -2
  8. package/dist/{api-schema-manifest-BWXv2l4E.js.map → api-schema-manifest-aur2BK6a.js.map} +1 -1
  9. package/dist/{background-tasks-CP6TSFhc.cjs → background-tasks-BbYzMhlD.cjs} +2 -2
  10. package/dist/{background-tasks-CP6TSFhc.cjs.map → background-tasks-BbYzMhlD.cjs.map} +1 -1
  11. package/dist/{background-tasks-Clbud7G4.js → background-tasks-zvlIcbhg.js} +2 -2
  12. package/dist/{background-tasks-Clbud7G4.js.map → background-tasks-zvlIcbhg.js.map} +1 -1
  13. package/dist/{builder-registry-6A0b4EwP.js → builder-registry-1GwmVVwr.js} +2 -2
  14. package/dist/{builder-registry-6A0b4EwP.js.map → builder-registry-1GwmVVwr.js.map} +1 -1
  15. package/dist/{builder-registry-DbSG3HJ8.cjs → builder-registry-DagCZI4A.cjs} +2 -2
  16. package/dist/{builder-registry-DbSG3HJ8.cjs.map → builder-registry-DagCZI4A.cjs.map} +1 -1
  17. package/dist/{channels-DNWITrYK.cjs → channels-5J7CTFyY.cjs} +2 -2
  18. package/dist/{channels-DNWITrYK.cjs.map → channels-5J7CTFyY.cjs.map} +1 -1
  19. package/dist/{channels-DjOa1rPQ.js → channels-B3aoI-f1.js} +2 -2
  20. package/dist/{channels-DjOa1rPQ.js.map → channels-B3aoI-f1.js.map} +1 -1
  21. package/dist/{constants-C631oS02.js → constants-DazK_RZj.js} +9 -4
  22. package/dist/constants-DazK_RZj.js.map +1 -0
  23. package/dist/{constants-epIL4td4.cjs → constants-e7aaPCLj.cjs} +14 -3
  24. package/dist/constants-e7aaPCLj.cjs.map +1 -0
  25. package/dist/{dist-BRej8vIF.cjs → dist-B8rA8_Wt.cjs} +18 -7
  26. package/dist/{dist-BRej8vIF.cjs.map → dist-B8rA8_Wt.cjs.map} +1 -1
  27. package/dist/{dist-CPHBJa2G.js → dist-CdMzvOLk.js} +18 -7
  28. package/dist/{dist-CPHBJa2G.js.map → dist-CdMzvOLk.js.map} +1 -1
  29. package/dist/docs/SKILL.md +1 -1
  30. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  31. package/dist/{helpers-C_FYiA-F.js → helpers-DLhX1fqc.js} +2 -2
  32. package/dist/{helpers-C_FYiA-F.js.map → helpers-DLhX1fqc.js.map} +1 -1
  33. package/dist/{helpers-59ZdrW8t.cjs → helpers-ElhPeCSK.cjs} +2 -2
  34. package/dist/{helpers-59ZdrW8t.cjs.map → helpers-ElhPeCSK.cjs.map} +1 -1
  35. package/dist/{observability-new-endpoints-CJMR84MD.cjs → observability-new-endpoints-BoALDMSi.cjs} +2 -2
  36. package/dist/{observability-new-endpoints-CJMR84MD.cjs.map → observability-new-endpoints-BoALDMSi.cjs.map} +1 -1
  37. package/dist/{observability-new-endpoints-D9MEJyaw.js → observability-new-endpoints-CB7T6Z7c.js} +2 -2
  38. package/dist/{observability-new-endpoints-D9MEJyaw.js.map → observability-new-endpoints-CB7T6Z7c.js.map} +1 -1
  39. package/dist/{routes-CH2PZ0PI.js → routes-BhI1lW_W.js} +12 -12
  40. package/dist/{routes-CH2PZ0PI.js.map → routes-BhI1lW_W.js.map} +1 -1
  41. package/dist/{routes-BpxhmR6Y.cjs → routes-CuJPLAh8.cjs} +12 -12
  42. package/dist/{routes-BpxhmR6Y.cjs.map → routes-CuJPLAh8.cjs.map} +1 -1
  43. package/dist/{schedules-DvLXX2nW.cjs → schedules-B0g72u5Y.cjs} +2 -2
  44. package/dist/{schedules-DvLXX2nW.cjs.map → schedules-B0g72u5Y.cjs.map} +1 -1
  45. package/dist/{schedules-BRdVmFYi.js → schedules-CrAmZ2gu.js} +2 -2
  46. package/dist/{schedules-BRdVmFYi.js.map → schedules-CrAmZ2gu.js.map} +1 -1
  47. package/dist/server/auth/index.cjs +2 -2
  48. package/dist/server/auth/index.js +2 -2
  49. package/dist/server/constants.d.ts +5 -0
  50. package/dist/server/constants.d.ts.map +1 -1
  51. package/dist/server/handlers/a2a.cjs +1 -1
  52. package/dist/server/handlers/a2a.js +1 -1
  53. package/dist/server/handlers/agent-builder.cjs +2 -2
  54. package/dist/server/handlers/agent-builder.js +2 -2
  55. package/dist/server/handlers/agent-controller.cjs +2 -2
  56. package/dist/server/handlers/agent-controller.js +2 -2
  57. package/dist/server/handlers/agent-versions.cjs +1 -1
  58. package/dist/server/handlers/agent-versions.js +1 -1
  59. package/dist/server/handlers/agents.cjs +3 -3
  60. package/dist/server/handlers/agents.js +3 -3
  61. package/dist/server/handlers/auth.cjs +2 -2
  62. package/dist/server/handlers/auth.js +2 -2
  63. package/dist/server/handlers/authorship.cjs +1 -1
  64. package/dist/server/handlers/authorship.js +1 -1
  65. package/dist/server/handlers/background-tasks.cjs +1 -1
  66. package/dist/server/handlers/background-tasks.js +1 -1
  67. package/dist/server/handlers/builder-registry.cjs +1 -1
  68. package/dist/server/handlers/builder-registry.js +1 -1
  69. package/dist/server/handlers/channels.cjs +1 -1
  70. package/dist/server/handlers/channels.js +1 -1
  71. package/dist/server/handlers/conversations.cjs +1 -1
  72. package/dist/server/handlers/conversations.js +1 -1
  73. package/dist/server/handlers/datasets.cjs +1 -1
  74. package/dist/server/handlers/datasets.js +1 -1
  75. package/dist/server/handlers/logs.cjs +1 -1
  76. package/dist/server/handlers/logs.js +1 -1
  77. package/dist/server/handlers/mcp-client-versions.cjs +2 -2
  78. package/dist/server/handlers/mcp-client-versions.js +2 -2
  79. package/dist/server/handlers/memory.cjs +1 -1
  80. package/dist/server/handlers/memory.js +1 -1
  81. package/dist/server/handlers/observability-new-endpoints.cjs +1 -1
  82. package/dist/server/handlers/observability-new-endpoints.js +1 -1
  83. package/dist/server/handlers/observability.cjs +1 -1
  84. package/dist/server/handlers/observability.js +1 -1
  85. package/dist/server/handlers/plans.cjs +1 -1
  86. package/dist/server/handlers/plans.js +1 -1
  87. package/dist/server/handlers/prompt-block-versions.cjs +2 -2
  88. package/dist/server/handlers/prompt-block-versions.js +2 -2
  89. package/dist/server/handlers/responses.cjs +1 -1
  90. package/dist/server/handlers/responses.js +1 -1
  91. package/dist/server/handlers/responses.storage.cjs +1 -1
  92. package/dist/server/handlers/responses.storage.js +1 -1
  93. package/dist/server/handlers/schedules.cjs +1 -1
  94. package/dist/server/handlers/schedules.js +1 -1
  95. package/dist/server/handlers/scorer-versions.cjs +2 -2
  96. package/dist/server/handlers/scorer-versions.js +2 -2
  97. package/dist/server/handlers/stored-agent-favorites.cjs +1 -1
  98. package/dist/server/handlers/stored-agent-favorites.js +1 -1
  99. package/dist/server/handlers/stored-agents.cjs +2 -2
  100. package/dist/server/handlers/stored-agents.js +2 -2
  101. package/dist/server/handlers/stored-mcp-clients.cjs +2 -2
  102. package/dist/server/handlers/stored-mcp-clients.js +2 -2
  103. package/dist/server/handlers/stored-prompt-blocks.cjs +2 -2
  104. package/dist/server/handlers/stored-prompt-blocks.js +2 -2
  105. package/dist/server/handlers/stored-scorers.cjs +2 -2
  106. package/dist/server/handlers/stored-scorers.js +2 -2
  107. package/dist/server/handlers/stored-skill-favorites.cjs +2 -2
  108. package/dist/server/handlers/stored-skill-favorites.js +2 -2
  109. package/dist/server/handlers/stored-skills.cjs +2 -2
  110. package/dist/server/handlers/stored-skills.js +2 -2
  111. package/dist/server/handlers/stored-workspaces.cjs +1 -1
  112. package/dist/server/handlers/stored-workspaces.js +1 -1
  113. package/dist/server/handlers/system.cjs +1 -1
  114. package/dist/server/handlers/system.js +1 -1
  115. package/dist/server/handlers/tool-providers.cjs +1 -1
  116. package/dist/server/handlers/tool-providers.js +1 -1
  117. package/dist/server/handlers/tools.cjs +2 -2
  118. package/dist/server/handlers/tools.js +2 -2
  119. package/dist/server/handlers/utils.cjs +1 -1
  120. package/dist/server/handlers/utils.js +1 -1
  121. package/dist/server/handlers/validate-agent-instructions.cjs +1 -1
  122. package/dist/server/handlers/validate-agent-instructions.js +1 -1
  123. package/dist/server/handlers/workflow-builder.cjs +1 -1
  124. package/dist/server/handlers/workflow-builder.js +1 -1
  125. package/dist/server/handlers/workflows.cjs +2 -2
  126. package/dist/server/handlers/workflows.js +2 -2
  127. package/dist/server/handlers.cjs +1 -1
  128. package/dist/server/handlers.js +1 -1
  129. package/dist/server/schemas/index.cjs +6 -6
  130. package/dist/server/schemas/index.js +6 -6
  131. package/dist/server/server-adapter/index.cjs +5 -4
  132. package/dist/server/server-adapter/index.cjs.map +1 -1
  133. package/dist/server/server-adapter/index.d.ts +1 -1
  134. package/dist/server/server-adapter/index.d.ts.map +1 -1
  135. package/dist/server/server-adapter/index.js +5 -5
  136. package/dist/server/server-adapter/index.js.map +1 -1
  137. package/dist/{utils-CJxnYdr3.cjs → utils-BZdnPmsW.cjs} +2 -2
  138. package/dist/{utils-CJxnYdr3.cjs.map → utils-BZdnPmsW.cjs.map} +1 -1
  139. package/dist/{utils-DdGLbkOl.cjs → utils-CczRcgHQ.cjs} +2 -2
  140. package/dist/{utils-DdGLbkOl.cjs.map → utils-CczRcgHQ.cjs.map} +1 -1
  141. package/dist/{utils-mIFmRM_j.js → utils-D5DHrO3K.js} +2 -2
  142. package/dist/{utils-mIFmRM_j.js.map → utils-D5DHrO3K.js.map} +1 -1
  143. package/dist/{utils-BpQY-tBr.js → utils-tmrFs-gf.js} +2 -2
  144. package/dist/{utils-BpQY-tBr.js.map → utils-tmrFs-gf.js.map} +1 -1
  145. package/dist/{workflow-builder-BnKKH8iT.js → workflow-builder-DJ0eeJuG.js} +2 -2
  146. package/dist/{workflow-builder-BnKKH8iT.js.map → workflow-builder-DJ0eeJuG.js.map} +1 -1
  147. package/dist/{workflow-builder-BM6Nen0q.cjs → workflow-builder-DdSutoga.cjs} +2 -2
  148. package/dist/{workflow-builder-BM6Nen0q.cjs.map → workflow-builder-DdSutoga.cjs.map} +1 -1
  149. package/package.json +8 -8
  150. package/dist/constants-C631oS02.js.map +0 -1
  151. 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-C631oS02.js";
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-DjOa1rPQ.js.map
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
- const RESERVED_CONTEXT_KEYS = /* @__PURE__ */ new Set([
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, WORKSPACE_TOOLS as f, resolveToolConfig as h, MASTRA_IS_STUDIO_KEY as i, MASTRA_USER_KEY as l, isStudioClientTypeHeader as m, MASTRA_AUTH_TOKEN_KEY as n, MASTRA_RESOURCE_ID_KEY as o, isReservedRequestContextKey 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 };
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-C631oS02.js.map
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
- const RESERVED_CONTEXT_KEYS = /* @__PURE__ */ new Set([
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-epIL4td4.cjs.map
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-CTyZJ6A-.js
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 `GOOGLE_GENERATIVE_AI_API_KEY` is set; else the main provider's low-cost
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, { autoModels: this.autoModels }) ?? (mainModel ? void 0 : OBSERVATIONAL_MEMORY_DEFAULTS.observation.model);
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, { autoModels: this.autoModels }) ?? "" : (await this.resolveModelContext(reflectionModel, requestContext))?.modelId ?? "").includes("gemini-2.5-flash")) return 2;
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-BRej8vIF.cjs.map
51913
+ //# sourceMappingURL=dist-B8rA8_Wt.cjs.map