@mastra/factory 0.24.0 → 0.25.0-alpha.1

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 (181) hide show
  1. package/README.md +36 -9
  2. package/dist/auth.d.ts.map +1 -1
  3. package/dist/auth.js +18 -4
  4. package/dist/auth.js.map +1 -1
  5. package/dist/boards/review.d.ts.map +1 -1
  6. package/dist/boards/review.js +3 -2
  7. package/dist/boards/review.js.map +1 -1
  8. package/dist/factory.d.ts +3 -0
  9. package/dist/factory.d.ts.map +1 -1
  10. package/dist/factory.js +90 -97
  11. package/dist/factory.js.map +1 -1
  12. package/dist/integrations/base.d.ts +14 -1
  13. package/dist/integrations/base.d.ts.map +1 -1
  14. package/dist/integrations/github/integration.d.ts +3 -0
  15. package/dist/integrations/github/integration.d.ts.map +1 -1
  16. package/dist/integrations/github/integration.js +4 -0
  17. package/dist/integrations/github/integration.js.map +1 -1
  18. package/dist/integrations/github/sandbox.d.ts +4 -0
  19. package/dist/integrations/github/sandbox.d.ts.map +1 -1
  20. package/dist/integrations/github/sandbox.js +2 -0
  21. package/dist/integrations/github/sandbox.js.map +1 -1
  22. package/dist/integrations/platform/github/integration.d.ts +3 -0
  23. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  24. package/dist/integrations/platform/github/integration.js +5 -0
  25. package/dist/integrations/platform/github/integration.js.map +1 -1
  26. package/dist/{session → integrations/slack}/channel-reply-processor.d.ts +4 -3
  27. package/dist/integrations/slack/channel-reply-processor.d.ts.map +1 -0
  28. package/dist/integrations/slack/channel-reply-processor.js +61 -0
  29. package/dist/integrations/slack/channel-reply-processor.js.map +1 -0
  30. package/dist/integrations/slack/channel-session-link-processor.d.ts.map +1 -0
  31. package/dist/{session → integrations/slack}/channel-session-link-processor.js +13 -4
  32. package/dist/integrations/slack/channel-session-link-processor.js.map +1 -0
  33. package/dist/integrations/slack/integration.d.ts +25 -1
  34. package/dist/integrations/slack/integration.d.ts.map +1 -1
  35. package/dist/integrations/slack/integration.js +55 -5
  36. package/dist/integrations/slack/integration.js.map +1 -1
  37. package/dist/integrations/slack/reply-reminder-processor.d.ts +23 -0
  38. package/dist/integrations/slack/reply-reminder-processor.d.ts.map +1 -0
  39. package/dist/integrations/slack/reply-reminder-processor.js +58 -0
  40. package/dist/integrations/slack/reply-reminder-processor.js.map +1 -0
  41. package/dist/integrations/slack/reply-tool.d.ts +31 -0
  42. package/dist/integrations/slack/reply-tool.d.ts.map +1 -0
  43. package/dist/integrations/slack/reply-tool.js +203 -0
  44. package/dist/integrations/slack/reply-tool.js.map +1 -0
  45. package/dist/integrations/slack/share-file-tool.d.ts +45 -0
  46. package/dist/integrations/slack/share-file-tool.d.ts.map +1 -0
  47. package/dist/integrations/slack/share-file-tool.js +106 -0
  48. package/dist/integrations/slack/share-file-tool.js.map +1 -0
  49. package/dist/integrations/slack/slack.d.ts.map +1 -1
  50. package/dist/integrations/slack/slack.js +54 -6
  51. package/dist/integrations/slack/slack.js.map +1 -1
  52. package/dist/mcp/events.d.ts +73 -0
  53. package/dist/mcp/events.d.ts.map +1 -0
  54. package/dist/mcp/events.js +158 -0
  55. package/dist/mcp/events.js.map +1 -0
  56. package/dist/mcp/routes.d.ts +0 -1
  57. package/dist/mcp/routes.d.ts.map +1 -1
  58. package/dist/mcp/routes.js +30 -3
  59. package/dist/mcp/routes.js.map +1 -1
  60. package/dist/packages/_internals/workspace/dist/index.js.map +1 -1
  61. package/dist/platform-auth-host.d.ts.map +1 -1
  62. package/dist/platform-auth-host.js +1 -1
  63. package/dist/platform-auth-host.js.map +1 -1
  64. package/dist/routes/config.d.ts +2 -0
  65. package/dist/routes/config.d.ts.map +1 -1
  66. package/dist/routes/config.js +52 -11
  67. package/dist/routes/config.js.map +1 -1
  68. package/dist/routes/contracts.d.ts +2 -0
  69. package/dist/routes/contracts.d.ts.map +1 -1
  70. package/dist/routes/contracts.js +1 -1
  71. package/dist/routes/contracts.js.map +1 -1
  72. package/dist/routes/session-access.d.ts +7 -2
  73. package/dist/routes/session-access.d.ts.map +1 -1
  74. package/dist/routes/session-access.js +41 -4
  75. package/dist/routes/session-access.js.map +1 -1
  76. package/dist/routes/skills.d.ts.map +1 -1
  77. package/dist/routes/skills.js +4 -3
  78. package/dist/routes/skills.js.map +1 -1
  79. package/dist/routes/source-control-sessions.d.ts +2 -0
  80. package/dist/routes/source-control-sessions.d.ts.map +1 -1
  81. package/dist/routes/source-control-sessions.js +161 -24
  82. package/dist/routes/source-control-sessions.js.map +1 -1
  83. package/dist/routes/surface.d.ts +2 -0
  84. package/dist/routes/surface.d.ts.map +1 -1
  85. package/dist/routes/surface.js +10 -4
  86. package/dist/routes/surface.js.map +1 -1
  87. package/dist/rules/dispatcher.d.ts.map +1 -1
  88. package/dist/rules/dispatcher.js +11 -3
  89. package/dist/rules/dispatcher.js.map +1 -1
  90. package/dist/rules/processor.d.ts +2 -2
  91. package/dist/rules/processor.d.ts.map +1 -1
  92. package/dist/rules/processor.js +3 -3
  93. package/dist/rules/processor.js.map +1 -1
  94. package/dist/sandbox/session-retirement.d.ts +11 -0
  95. package/dist/sandbox/session-retirement.d.ts.map +1 -1
  96. package/dist/sandbox/session-retirement.js +38 -1
  97. package/dist/sandbox/session-retirement.js.map +1 -1
  98. package/dist/sandbox/session-sandbox.d.ts +2 -0
  99. package/dist/sandbox/session-sandbox.d.ts.map +1 -1
  100. package/dist/sandbox/session-sandbox.js +5 -1
  101. package/dist/sandbox/session-sandbox.js.map +1 -1
  102. package/dist/session/credential-policy.d.ts +4 -2
  103. package/dist/session/credential-policy.d.ts.map +1 -1
  104. package/dist/session/credential-policy.js +11 -1
  105. package/dist/session/credential-policy.js.map +1 -1
  106. package/dist/session/factory-session.d.ts.map +1 -1
  107. package/dist/session/factory-session.js +14 -1
  108. package/dist/session/factory-session.js.map +1 -1
  109. package/dist/session/memory-settings-hydration.d.ts +0 -8
  110. package/dist/session/memory-settings-hydration.d.ts.map +1 -1
  111. package/dist/session/memory-settings-hydration.js +1 -19
  112. package/dist/session/memory-settings-hydration.js.map +1 -1
  113. package/dist/session/run-audit.d.ts +1 -0
  114. package/dist/session/run-audit.d.ts.map +1 -1
  115. package/dist/session/run-audit.js +7 -2
  116. package/dist/session/run-audit.js.map +1 -1
  117. package/dist/session/session-threads.d.ts +5 -0
  118. package/dist/session/session-threads.d.ts.map +1 -1
  119. package/dist/session/session-threads.js +8 -1
  120. package/dist/session/session-threads.js.map +1 -1
  121. package/dist/session/thinking-default.d.ts +6 -13
  122. package/dist/session/thinking-default.d.ts.map +1 -1
  123. package/dist/session/thinking-default.js +18 -22
  124. package/dist/session/thinking-default.js.map +1 -1
  125. package/dist/session-owner-signal.d.ts +2 -0
  126. package/dist/session-owner-signal.d.ts.map +1 -0
  127. package/dist/session-owner-signal.js +6 -0
  128. package/dist/session-owner-signal.js.map +1 -0
  129. package/dist/skills/service.d.ts +6 -7
  130. package/dist/skills/service.d.ts.map +1 -1
  131. package/dist/skills/service.js +9 -19
  132. package/dist/skills/service.js.map +1 -1
  133. package/dist/storage/domains/audit/actions.d.ts +1 -0
  134. package/dist/storage/domains/audit/actions.d.ts.map +1 -1
  135. package/dist/storage/domains/audit/actions.js +2 -1
  136. package/dist/storage/domains/audit/actions.js.map +1 -1
  137. package/dist/storage/domains/audit/base.d.ts +18 -2
  138. package/dist/storage/domains/audit/base.d.ts.map +1 -1
  139. package/dist/storage/domains/audit/base.js +22 -4
  140. package/dist/storage/domains/audit/base.js.map +1 -1
  141. package/dist/storage/domains/model-defaults/base.d.ts +8 -0
  142. package/dist/storage/domains/model-defaults/base.d.ts.map +1 -1
  143. package/dist/storage/domains/model-defaults/base.js +18 -0
  144. package/dist/storage/domains/model-defaults/base.js.map +1 -1
  145. package/dist/storage/domains/source-control/base.d.ts +26 -1
  146. package/dist/storage/domains/source-control/base.d.ts.map +1 -1
  147. package/dist/storage/domains/source-control/base.js +69 -5
  148. package/dist/storage/domains/source-control/base.js.map +1 -1
  149. package/dist/storage/domains/source-control/inmemory.d.ts +19 -1
  150. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  151. package/dist/storage/domains/source-control/inmemory.js +30 -2
  152. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  153. package/dist/tools/permissions.d.ts.map +1 -1
  154. package/dist/tools/permissions.js +2 -1
  155. package/dist/tools/permissions.js.map +1 -1
  156. package/dist/tools/sandbox-tools.d.ts +12 -0
  157. package/dist/tools/sandbox-tools.d.ts.map +1 -0
  158. package/dist/tools/sandbox-tools.js +40 -0
  159. package/dist/tools/sandbox-tools.js.map +1 -0
  160. package/dist/tools/scope.d.ts.map +1 -1
  161. package/dist/tools/scope.js +2 -5
  162. package/dist/tools/scope.js.map +1 -1
  163. package/dist/tools/session-tools.d.ts.map +1 -1
  164. package/dist/tools/session-tools.js +6 -2
  165. package/dist/tools/session-tools.js.map +1 -1
  166. package/dist/work-item-branch.d.ts +11 -3
  167. package/dist/work-item-branch.d.ts.map +1 -1
  168. package/dist/work-item-branch.js +34 -9
  169. package/dist/work-item-branch.js.map +1 -1
  170. package/dist/workspace.d.ts +2 -1
  171. package/dist/workspace.d.ts.map +1 -1
  172. package/dist/workspace.js +10 -2
  173. package/dist/workspace.js.map +1 -1
  174. package/factory-skills/configure-factory-rules/SKILL.md +2 -2
  175. package/package.json +15 -14
  176. package/dist/session/channel-reply-processor.d.ts.map +0 -1
  177. package/dist/session/channel-reply-processor.js +0 -46
  178. package/dist/session/channel-reply-processor.js.map +0 -1
  179. package/dist/session/channel-session-link-processor.d.ts.map +0 -1
  180. package/dist/session/channel-session-link-processor.js.map +0 -1
  181. /package/dist/{session → integrations/slack}/channel-session-link-processor.d.ts +0 -0
package/dist/factory.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createRequestTimingMiddleware, factoryTimingEnabled, instrumentAsyncMethods, timedPhase } from "./timing.js";
2
- import { buildAuthDisabledRoutes, buildAuthRoutes, createFactoryAuthGate, createFactoryInteractiveMarker, createFactoryRouteAuth, factoryUserOrgId, getFactoryAuthOrgId, getFactoryAuthUserFromContext, getFactoryAuthUserId } from "./auth.js";
2
+ import { buildAuthDisabledRoutes, buildAuthRoutes, createFactoryAuthGate, createFactoryInteractiveMarker, createFactoryRouteAuth, getFactoryAuthOrgId, getFactoryAuthUserFromContext, getFactoryAuthUserId } from "./auth.js";
3
3
  import { assertFactoryConfigVersion } from "./rules/validation.js";
4
4
  import { boardForWorkItem, isTerminalWorkItem } from "./boards/semantics.js";
5
5
  import { createBoardRegistry } from "./boards/registry.js";
@@ -25,6 +25,7 @@ import { observeSessionFilesystem } from "./session/filesystem-capture.js";
25
25
  import { sessionMemoryResourceId, sessionStampCounts } from "./session/session-threads.js";
26
26
  import { createPlaintextFactorySecretEncryption } from "./secret-encryption.js";
27
27
  import { ModelCredentialsStorage } from "./storage/domains/credentials/base.js";
28
+ import { tenantOrgId } from "./routes/provider-credentials.js";
28
29
  import { createTenantCredentialPrimer, primeTenantCredentials, registerTenantCredentialResolver } from "./routes/tenant-credentials.js";
29
30
  import { hasResolvedOrg } from "./session/org-seed.js";
30
31
  import { createSessionAsRowOwner, prepareSessionRunContext } from "./integrations/subscription-session.js";
@@ -40,8 +41,8 @@ import { AuditStorage } from "./storage/domains/audit/base.js";
40
41
  import { resolveFactoryToolScope } from "./tools/scope.js";
41
42
  import { deliverFactorySessionNotification } from "./tools/deliver.js";
42
43
  import { createSessionApprovalNotifier, createSessionRunEndReporter, createStageChangeNotifier, createWorkItemRunEndReporter } from "./tools/reports.js";
43
- import { resolveFactoryCredentialTenant } from "./session/credential-policy.js";
44
- import { hydrateSessionMemorySettings, layerPersonalMemorySettings } from "./session/memory-settings-hydration.js";
44
+ import { resolveFactoryCredentialTenant, resolveFactoryModelPolicy } from "./session/credential-policy.js";
45
+ import { hydrateSessionMemorySettings } from "./session/memory-settings-hydration.js";
45
46
  import { MemorySettingsStorage, factoryMemorySettingsUserId } from "./storage/domains/memory-settings/base.js";
46
47
  import { resolveDeploymentModelProviders } from "./routes/config.js";
47
48
  import { observeSessionRunEnd } from "./session/run-audit.js";
@@ -66,15 +67,13 @@ import { createFactoryTransitionTools } from "./rules/tools.js";
66
67
  import { CallbackFactorySandbox } from "./sandbox/callback-factory-sandbox.js";
67
68
  import { SessionRetirementCoordinator } from "./sandbox/session-retirement.js";
68
69
  import { handleServerError } from "./server-error.js";
69
- import { FactoryChannelReplyProcessor } from "./session/channel-reply-processor.js";
70
- import { FactoryChannelSessionLinkProcessor } from "./session/channel-session-link-processor.js";
71
70
  import { hydrateSessionDefaultModel } from "./session/default-model-hydration.js";
72
71
  import { observeSessionFirstMessage } from "./session/first-message-capture.js";
73
72
  import { LiveSessions } from "./session/live-sessions.js";
74
73
  import { FactoryReplyCredentialProcessor } from "./session/reply-credential-processor.js";
75
74
  import { migrateSessionResources, privatizeOwnerResourceSessions } from "./session/resource-migration.js";
76
75
  import { createSourceControlTools } from "./session/source-control-tools.js";
77
- import { readFactoryThinkingLevel, resolveFactoryThinkingLevel } from "./session/thinking-default.js";
76
+ import { resolveFactoryThinkingLevel } from "./session/thinking-default.js";
78
77
  import { observeSessionThreadStamp } from "./session/thread-session-stamp.js";
79
78
  import { observeSessionThreadTitle } from "./session/thread-title-mirror.js";
80
79
  import { createSpaStaticMiddleware, resolveUiDistDir } from "./spa-static.js";
@@ -87,6 +86,7 @@ import { CustomProvidersStorage } from "./storage/domains/custom-providers/base.
87
86
  import { FilesystemStorage } from "./storage/domains/filesystem/base.js";
88
87
  import { IntegrationStorage } from "./storage/domains/integrations/base.js";
89
88
  import { ModelDefaultsStorage } from "./storage/domains/model-defaults/base.js";
89
+ import { createFactorySandboxTools } from "./tools/sandbox-tools.js";
90
90
  import { FactorySessionsStateProcessor } from "./tools/sessions-state-processor.js";
91
91
  import { RequestContext } from "@mastra/core/request-context";
92
92
  import { hasAuthInit, isUserProvider } from "@mastra/core/server";
@@ -118,6 +118,12 @@ import { describeFactorySandbox, isFactorySandbox } from "@mastra/core/workspace
118
118
  * and the storage domains those capabilities require.
119
119
  */
120
120
  const CONTROLLER_ID = "code";
121
+ /**
122
+ * Providers whose sandbox a session's agent may recreate itself. Each needs
123
+ * its `destroy()` to leave the instance able to start a fresh VM, proven
124
+ * against the real provider.
125
+ */
126
+ const SELF_RECREATE_SANDBOX_PROVIDERS = /* @__PURE__ */ new Set(["platform"]);
121
127
  /** Why a wake couldn't be run as its Factory session's owner. */
122
128
  const WAKE_OWNER_UNRESOLVED = {
123
129
  "session-not-found": "no Factory session row names its owner",
@@ -129,53 +135,18 @@ function hasPlatformCredentials() {
129
135
  }
130
136
  /**
131
137
  * Default auth provider — `MastraAuthStudio`, which proxies identity to the
132
- * shared Mastra platform API. `MastraAuthStudio` resolves `MASTRA_SHARED_API_URL`,
133
- * `MASTRA_ORGANIZATION_ID`, and `MASTRA_COOKIE_DOMAIN` from env on its own —
134
- * this helper only derives a cookie-domain fallback from the factory's
135
- * `publicUrl`.
136
- *
137
- * Cookie-domain resolution (Studio picks the first that wins):
138
- * 1. explicit `MASTRA_COOKIE_DOMAIN` env, if set;
139
- * 2. `.mastra.ai` when `sharedApiUrl` is on `.mastra.ai`;
140
- * 3. this parent-domain fallback derived from `publicUrl` — so a deploy on
141
- * `https://foo.mastra.cloud` mints cookies with `Domain=.mastra.cloud`
142
- * without the caller wiring the env var by hand.
143
- * 4. otherwise host-only (no `Domain=`), which is correct for `localhost`.
144
- */
145
- function buildDefaultStudioAuth(publicUrl) {
146
- return new MastraAuthStudio({ cookieDomain: parentDomainFromPublicUrl(publicUrl) });
147
- }
148
- /**
149
- * Derive a parent cookie domain from `publicUrl` by stripping the leftmost
150
- * label — the same shape platform-API's env injection uses (see
151
- * `platform/servers/api/src/lib/studio-env-vars.ts`: `.${routingDomain.replace(/^[^.]+\./, '')}`).
138
+ * shared Mastra platform API and resolves its own env (`MASTRA_SHARED_API_URL`,
139
+ * `MASTRA_ORGANIZATION_ID`, ...).
152
140
  *
153
- * Rather than a generic `strip-left-label` heuristic — which either emits
154
- * cookies scoped to a public suffix (`sub.example.co.uk` → `.example.co.uk`
155
- * requires PSL data to be safe) or misclassifies numeric hostnames like
156
- * `3scale.example.com` as IPv4 — we only derive a parent domain when the
157
- * host sits under one of the platform's known registrable domains. Anything
158
- * else (custom domains, arbitrary tenant hostnames, IPs, `localhost`)
159
- * falls through to host-only cookies. Callers that need a different scope
160
- * pass `MASTRA_COOKIE_DOMAIN` explicitly (Studio honors that first).
141
+ * The session cookie is **host-only** (`__Host-wos-session` on secure
142
+ * deployments). No parent `Domain` (e.g. `.mastra.cloud`) is derived from
143
+ * `publicUrl`: a parent-scoped session cookie is sent by the browser to every
144
+ * host under that parent, including other tenants' deployments. Callers that
145
+ * really want a domain-scoped cookie pass their own `MastraAuthStudio` (with
146
+ * `cookieDomain`) via `auth:`.
161
147
  */
162
- const KNOWN_PLATFORM_COOKIE_PARENTS = ["mastra.cloud", "mastra.ai"];
163
- function isIpLiteral(hostname) {
164
- if (hostname.includes(":")) return true;
165
- return /^\d+(?:\.\d+){3}$/.test(hostname);
166
- }
167
- function parentDomainFromPublicUrl(publicUrl) {
168
- let hostname;
169
- try {
170
- hostname = new URL(publicUrl).hostname.toLowerCase();
171
- } catch {
172
- return;
173
- }
174
- if (hostname === "localhost" || isIpLiteral(hostname)) return void 0;
175
- for (const parent of KNOWN_PLATFORM_COOKIE_PARENTS) {
176
- if (hostname === parent) return void 0;
177
- if (hostname.endsWith(`.${parent}`)) return `.${parent}`;
178
- }
148
+ function buildDefaultStudioAuth() {
149
+ return new MastraAuthStudio();
179
150
  }
180
151
  /** A session parking or being answered is inbox news, so the registry bumps the project's feed. */
181
152
  function liveSessionsTouchingTheFeed(controller, eventBus) {
@@ -265,13 +236,14 @@ var MastraFactory = class {
265
236
  const pubsub = this.#config.pubsub;
266
237
  const eventBus = pubsub ?? new EventEmitterPubSub();
267
238
  const configuredAuth = this.#config.auth;
268
- const auth = configuredAuth === null ? void 0 : configuredAuth ?? buildDefaultStudioAuth(publicOrigin);
239
+ const auth = configuredAuth === null ? void 0 : configuredAuth ?? buildDefaultStudioAuth();
269
240
  if (auth && !this.#config.secretEncryption) console.warn("[factory] auth is enabled but 'secretEncryption' is not configured. Persisted model credentials, custom-provider API keys, and integration secrets will be stored as plaintext. Provide 'secretEncryption' (e.g. via FACTORY_CREDENTIAL_ENCRYPTION_KEY) to encrypt them at rest.");
270
241
  const secretEncryption = this.#config.secretEncryption ?? createPlaintextFactorySecretEncryption();
271
242
  const deploymentModelProviders = resolveDeploymentModelProviders(this.#config.deploymentModelProviders);
272
243
  const routeAuth = createFactoryRouteAuth(auth);
273
244
  const mcpConfig = this.#config.mcp;
274
245
  const mcpAuthorizationServers = mcpConfig === false || mcpConfig?.enabled === false ? [] : resolveMcpAuthorizationServers(auth?.name, mcpConfig);
246
+ const mcpEnabled = Boolean(auth) && mcpAuthorizationServers.length > 0;
275
247
  const integrations = [...this.#config.integrations ?? []];
276
248
  const explicitGithub = integrations.some((integration) => integration.id === "github");
277
249
  let installedPlatformGithub = false;
@@ -374,17 +346,19 @@ var MastraFactory = class {
374
346
  projects: factoryProjectsStorage,
375
347
  auth: routeAuth,
376
348
  intake: intakeStorage,
377
- ...integrationSourceControl ? { sourceControl: integrationSourceControl } : {}
349
+ ...integrationSourceControl ? { sourceControl: integrationSourceControl } : {},
350
+ channels: () => this.#prepared?.base.controller.getChannels()
378
351
  });
379
352
  if (integration.versionControl && integrationSourceControl) integration.versionControl.initialize({ storage: integrationSourceControl });
380
353
  }
381
354
  const sourceControlHandles = [.../* @__PURE__ */ new Set(["github", ...integrations.filter((integration) => integration.versionControl).map(({ id }) => id)])].map((id) => sourceControlStorage.forIntegration(id));
382
355
  const sourceControlSessions = createSourceControlSessionLookup(sourceControlHandles);
383
- if (auth) registerTenantCredentialResolver(modelCredentialsStorage, deploymentModelProviders, (requestContext) => resolveFactoryCredentialTenant(requestContext, {
356
+ const modelPolicyDependencies = {
384
357
  projects: factoryProjectsStorage,
385
358
  sourceControl: sourceControlSessions,
386
359
  workItems: workItemsStorage
387
- }));
360
+ };
361
+ if (auth) registerTenantCredentialResolver(modelCredentialsStorage, deploymentModelProviders, (requestContext) => resolveFactoryCredentialTenant(requestContext, modelPolicyDependencies));
388
362
  const integrationRegistrations = integrations.map((integration) => {
389
363
  const requiredDomains = [
390
364
  "integrations",
@@ -659,41 +633,46 @@ var MastraFactory = class {
659
633
  controller: { getSession: async (sessionId) => this.#prepared?.base.controller.getSession(sessionId) }
660
634
  } : {}
661
635
  });
662
- const loadMemorySettings = async ({ requestContext, binding }) => {
663
- if (!requestContext) return;
636
+ const memorySettingsRowKey = async (requestContext, binding) => {
637
+ const policy = auth ? await resolveFactoryModelPolicy(requestContext, modelPolicyDependencies) : void 0;
638
+ if (policy) {
639
+ const orgId = tenantOrgId(policy.tenant);
640
+ return policy.tenant.credentialScope === "factory" && policy.factoryProjectId ? {
641
+ orgId,
642
+ userId: factoryMemorySettingsUserId(policy.factoryProjectId)
643
+ } : {
644
+ orgId,
645
+ userId: policy.tenant.userId
646
+ };
647
+ }
664
648
  const scope = readFactorySessionScope(requestContext);
665
- const user = getFactoryAuthUserFromContext(requestContext);
666
- const callerUserId = getFactoryAuthUserId(user);
667
- const callerOrgId = factoryUserOrgId(user);
668
649
  const factoryProjectId = binding?.factoryProjectId ?? scope?.factoryProjectId;
669
- const target = factoryProjectId ? {
670
- orgId: binding?.orgId ?? scope?.factoryOrgId ?? callerOrgId ?? "local",
671
- userId: factoryMemorySettingsUserId(factoryProjectId)
672
- } : callerUserId && callerOrgId ? {
673
- orgId: callerOrgId,
674
- userId: callerUserId
675
- } : {
650
+ if (!factoryProjectId) return {
676
651
  orgId: "local",
677
652
  userId: "local"
678
653
  };
679
- const record = await memorySettingsStorage.get(target);
680
- let personal = null;
681
- if (factoryProjectId && requestContext.get("channel") && callerUserId && callerOrgId) try {
682
- personal = await memorySettingsStorage.get({
683
- orgId: callerOrgId,
684
- userId: callerUserId
685
- });
686
- } catch (error) {
687
- console.warn("[Factory Memory Settings] Unable to read the sender's memory settings", { error: error instanceof Error ? error.message : String(error) });
688
- }
689
- requestContext.set("mastra__factoryMemorySettings", layerPersonalMemorySettings(record, personal));
654
+ return {
655
+ orgId: binding?.orgId ?? scope?.factoryOrgId ?? "local",
656
+ userId: factoryMemorySettingsUserId(factoryProjectId)
657
+ };
658
+ };
659
+ const loadMemorySettings = async ({ requestContext, binding }) => {
660
+ if (!requestContext) return;
661
+ const record = await memorySettingsStorage.get(await memorySettingsRowKey(requestContext, binding));
662
+ requestContext.set("mastra__factoryMemorySettings", record);
690
663
  };
664
+ const resolveDefaultThinkingLevel = (requestContext) => resolveFactoryThinkingLevel(requestContext, {
665
+ projects: factoryProjectsStorage,
666
+ sourceControl: sourceControlSessions,
667
+ workItems: workItemsStorage,
668
+ modelDefaults: modelDefaultsStorage
669
+ });
691
670
  const factoryProcessor = workItemsReady ? new FactoryPhaseStateProcessor({
692
671
  configVersion,
693
672
  storage: workItemsStorage,
694
673
  boards: this.#boards,
695
674
  loadMemorySettings,
696
- factoryThinkingLevel: (factoryProjectId) => readFactoryThinkingLevel(factoryProjectsStorage, factoryProjectId),
675
+ defaultThinkingLevel: resolveDefaultThinkingLevel,
697
676
  ...transitionService ? { transitionService } : {},
698
677
  ...githubIntegration ? { recordPullRequestProvenance: (input) => recordFactoryPullRequestProvenance(githubIntegration, sourceControlStorage.forIntegration("github"), integrationStorage.forIntegration("github"), workItemsStorage, input) } : {},
699
678
  messageReader: { listMessages: async (input) => {
@@ -711,6 +690,7 @@ var MastraFactory = class {
711
690
  if (proto.constructor?.name === "LibSQLFactoryStorage") return "libsql";
712
691
  }
713
692
  })();
693
+ const integrationInputProcessors = integrations.flatMap((integration) => integration.processors?.input ?? []);
714
694
  const toolIntegrations = integrationRegistrations.filter(({ integration }) => integration.agentTools || integration.sessionTools);
715
695
  const sourceControlToolProviders = integrations.flatMap((integration) => integration.versionControl ? [{
716
696
  id: integration.id,
@@ -719,14 +699,12 @@ var MastraFactory = class {
719
699
  }] : []);
720
700
  const prepared = await timedPhase("prepare.controllerMount", () => prepareAgentControllerMount({
721
701
  controllerId: CONTROLLER_ID,
702
+ browser: this.#config.browser,
722
703
  coAuthor: { name: "mastra-platform[bot]" },
723
704
  ...this.#config.disableBuiltinTools?.length ? { disableBuiltinTools: this.#config.disableBuiltinTools } : {},
724
705
  modes: false,
725
706
  subagents: [],
726
- resolveDefaultThinkingLevel: ({ requestContext }) => resolveFactoryThinkingLevel(requestContext, {
727
- projects: factoryProjectsStorage,
728
- sourceControl: sourceControlSessions
729
- }),
707
+ resolveDefaultThinkingLevel: ({ requestContext }) => resolveDefaultThinkingLevel(requestContext),
730
708
  workspace: createWorkspaceFactory({
731
709
  ...sandboxConfig ? { sandbox: sandboxConfig } : {},
732
710
  ...this.#config.sandboxStart ? { sandboxStart: this.#config.sandboxStart } : {},
@@ -839,7 +817,6 @@ var MastraFactory = class {
839
817
  ...mastraStorageBackend ? { storageBackend: mastraStorageBackend } : {},
840
818
  ...this.#config.knowledge ? { knowledge: this.#config.knowledge } : {},
841
819
  inputProcessors: async ({ requestContext }) => {
842
- const channelReplyProcessor = new FactoryChannelReplyProcessor();
843
820
  const environmentProcessor = new FactoryEnvironmentStateProcessor();
844
821
  const sessionsProcessor = workItemsStorage && storage.isDomainReady("source-control") ? [new FactorySessionsStateProcessor({
845
822
  authEnabled: routeAuth.enabled(),
@@ -859,7 +836,7 @@ var MastraFactory = class {
859
836
  if (factoryProcessor) {
860
837
  await factoryProcessor.prepareMemorySettings(requestContext);
861
838
  return [
862
- channelReplyProcessor,
839
+ ...integrationInputProcessors,
863
840
  environmentProcessor,
864
841
  ...sessionsProcessor,
865
842
  factoryProcessor
@@ -874,14 +851,14 @@ var MastraFactory = class {
874
851
  reportMemorySettingsUnavailable(requestContext, error instanceof Error ? error.message : String(error));
875
852
  }
876
853
  return [
877
- channelReplyProcessor,
854
+ ...integrationInputProcessors,
878
855
  environmentProcessor,
879
856
  ...sessionsProcessor
880
857
  ];
881
858
  },
882
- outputProcessors: [new FactoryChannelSessionLinkProcessor(), new FactoryReplyCredentialProcessor()],
859
+ outputProcessors: [...integrations.flatMap((integration) => integration.processors?.output ?? []), new FactoryReplyCredentialProcessor()],
883
860
  ...vector ? { vector } : {},
884
- ...toolIntegrations.length > 0 || sourceControlToolProviders.length > 0 || workItemsStorage && transitionService ? { extraTools: async ({ requestContext }) => {
861
+ extraTools: async ({ requestContext }) => {
885
862
  const tools = {};
886
863
  const toolOwners = /* @__PURE__ */ new Map();
887
864
  const mergeTools = (ownerId, contributed) => {
@@ -968,10 +945,16 @@ var MastraFactory = class {
968
945
  projects: factoryProjectsStorage,
969
946
  workItems: workItemsStorage
970
947
  });
971
- if (scope) mergeTools("factory-tools", createFactoryTools({
972
- scope,
973
- deps: factoryToolDeps
974
- }));
948
+ if (scope) {
949
+ mergeTools("factory-tools", createFactoryTools({
950
+ scope,
951
+ deps: factoryToolDeps
952
+ }));
953
+ if (sessionRetirement && sandboxConfig && SELF_RECREATE_SANDBOX_PROVIDERS.has(sandboxConfig.provider)) mergeTools("factory-sandbox-tools", createFactorySandboxTools(scope, {
954
+ sessions: sourceControlSessions,
955
+ resetSandbox: (input) => sessionRetirement.resetSessionSandbox(input)
956
+ }));
957
+ }
975
958
  }
976
959
  }
977
960
  for (const { integration, ready, ensureReady } of toolIntegrations) {
@@ -984,7 +967,7 @@ var MastraFactory = class {
984
967
  if (integration.sessionTools) mergeTools(integration.id, integration.sessionTools({ requestContext }));
985
968
  }
986
969
  return tools;
987
- } } : {},
970
+ },
988
971
  postToolObserver: async (toolContext) => {
989
972
  const requestContext = toolContext.context?.requestContext;
990
973
  if (requestContext) await observeAgentGitAction({
@@ -1023,7 +1006,7 @@ var MastraFactory = class {
1023
1006
  } : {},
1024
1007
  buildApiRoutes: ({ controller, authStorage }) => [
1025
1008
  ...auth ? buildAuthRoutes(auth, { publicUrl: publicOrigin }) : buildAuthDisabledRoutes(),
1026
- ...auth && mcpAuthorizationServers.length > 0 ? buildFactoryMcpRoutes({
1009
+ ...mcpEnabled ? buildFactoryMcpRoutes({
1027
1010
  auth: routeAuth,
1028
1011
  publicOrigin,
1029
1012
  authorizationServers: mcpAuthorizationServers,
@@ -1067,6 +1050,7 @@ var MastraFactory = class {
1067
1050
  intakeReady,
1068
1051
  factoryReady,
1069
1052
  knowledgeEnabled,
1053
+ mcpEnabled,
1070
1054
  deploymentModelProviders,
1071
1055
  knowledgeKey: this.#config.knowledge?.key,
1072
1056
  configVersion,
@@ -1137,10 +1121,19 @@ var MastraFactory = class {
1137
1121
  }) : []
1138
1122
  ],
1139
1123
  buildServerConfig: () => {
1140
- const cors = allowedOrigins.length ? { cors: {
1124
+ const mcpCors = {
1125
+ allowHeaders: [
1126
+ "Mcp-Protocol-Version",
1127
+ "Mcp-Method",
1128
+ "Mcp-Name"
1129
+ ],
1130
+ exposeHeaders: ["WWW-Authenticate"]
1131
+ };
1132
+ const cors = { cors: allowedOrigins.length ? {
1141
1133
  origin: allowedOrigins,
1142
- credentials: true
1143
- } } : {};
1134
+ credentials: true,
1135
+ ...mcpCors
1136
+ } : mcpCors };
1144
1137
  const onError = { onError: handleServerError };
1145
1138
  const uiDist = resolveUiDistDir();
1146
1139
  const spa = uiDist ? [createSpaStaticMiddleware(uiDist)] : [];