@mastra/factory 0.24.0-alpha.1 → 0.24.0-alpha.2

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 (175) hide show
  1. package/README.md +80 -4
  2. package/dist/auth.d.ts +8 -0
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +15 -1
  5. package/dist/auth.js.map +1 -1
  6. package/dist/boards/work-transition-policy.d.ts.map +1 -1
  7. package/dist/boards/work-transition-policy.js +10 -0
  8. package/dist/boards/work-transition-policy.js.map +1 -1
  9. package/dist/boards/work.d.ts +14 -0
  10. package/dist/boards/work.d.ts.map +1 -1
  11. package/dist/boards/work.js +70 -7
  12. package/dist/boards/work.js.map +1 -1
  13. package/dist/capabilities/version-control.d.ts +26 -0
  14. package/dist/capabilities/version-control.d.ts.map +1 -1
  15. package/dist/factory.d.ts.map +1 -1
  16. package/dist/factory.js +173 -11
  17. package/dist/factory.js.map +1 -1
  18. package/dist/integrations/github/integration.d.ts.map +1 -1
  19. package/dist/integrations/github/integration.js +37 -1
  20. package/dist/integrations/github/integration.js.map +1 -1
  21. package/dist/integrations/gitlab/api.d.ts +15 -0
  22. package/dist/integrations/gitlab/api.d.ts.map +1 -1
  23. package/dist/integrations/gitlab/api.js +9 -0
  24. package/dist/integrations/gitlab/api.js.map +1 -1
  25. package/dist/integrations/gitlab/version-control.d.ts.map +1 -1
  26. package/dist/integrations/gitlab/version-control.js +37 -3
  27. package/dist/integrations/gitlab/version-control.js.map +1 -1
  28. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  29. package/dist/integrations/platform/github/integration.js +27 -1
  30. package/dist/integrations/platform/github/integration.js.map +1 -1
  31. package/dist/integrations/subscription-session.d.ts +15 -0
  32. package/dist/integrations/subscription-session.d.ts.map +1 -1
  33. package/dist/integrations/subscription-session.js +30 -13
  34. package/dist/integrations/subscription-session.js.map +1 -1
  35. package/dist/provider-display-name.d.ts +2 -0
  36. package/dist/provider-display-name.d.ts.map +1 -0
  37. package/dist/provider-display-name.js +16 -0
  38. package/dist/provider-display-name.js.map +1 -0
  39. package/dist/routes/config.js +2 -2
  40. package/dist/routes/config.js.map +1 -1
  41. package/dist/routes/contracts.d.ts +4 -0
  42. package/dist/routes/contracts.d.ts.map +1 -1
  43. package/dist/routes/contracts.js +3 -1
  44. package/dist/routes/contracts.js.map +1 -1
  45. package/dist/routes/oauth.js +1 -1
  46. package/dist/routes/oauth.js.map +1 -1
  47. package/dist/routes/provider-credentials.d.ts +6 -2
  48. package/dist/routes/provider-credentials.d.ts.map +1 -1
  49. package/dist/routes/provider-credentials.js +20 -7
  50. package/dist/routes/provider-credentials.js.map +1 -1
  51. package/dist/routes/source-control-sessions.d.ts +1 -0
  52. package/dist/routes/source-control-sessions.d.ts.map +1 -1
  53. package/dist/routes/source-control-sessions.js +1 -1
  54. package/dist/routes/source-control-sessions.js.map +1 -1
  55. package/dist/routes/surface.d.ts +1 -0
  56. package/dist/routes/surface.d.ts.map +1 -1
  57. package/dist/routes/surface.js +1 -0
  58. package/dist/routes/surface.js.map +1 -1
  59. package/dist/routes/work-items.d.ts.map +1 -1
  60. package/dist/routes/work-items.js +57 -117
  61. package/dist/routes/work-items.js.map +1 -1
  62. package/dist/rules/dispatcher.d.ts +7 -0
  63. package/dist/rules/dispatcher.d.ts.map +1 -1
  64. package/dist/rules/dispatcher.js +60 -3
  65. package/dist/rules/dispatcher.js.map +1 -1
  66. package/dist/rules/processor.d.ts.map +1 -1
  67. package/dist/rules/processor.js +2 -1
  68. package/dist/rules/processor.js.map +1 -1
  69. package/dist/rules/tools.d.ts.map +1 -1
  70. package/dist/rules/tools.js +82 -3
  71. package/dist/rules/tools.js.map +1 -1
  72. package/dist/rules/transition-service.d.ts +17 -0
  73. package/dist/rules/transition-service.d.ts.map +1 -1
  74. package/dist/rules/transition-service.js +25 -0
  75. package/dist/rules/transition-service.js.map +1 -1
  76. package/dist/rules/types.d.ts +2 -0
  77. package/dist/rules/types.d.ts.map +1 -1
  78. package/dist/rules/types.js.map +1 -1
  79. package/dist/sandbox/local-factory-sandbox.d.ts.map +1 -1
  80. package/dist/sandbox/local-factory-sandbox.js +1 -0
  81. package/dist/sandbox/local-factory-sandbox.js.map +1 -1
  82. package/dist/session/factory-session.d.ts +15 -1
  83. package/dist/session/factory-session.d.ts.map +1 -1
  84. package/dist/session/factory-session.js +4 -2
  85. package/dist/session/factory-session.js.map +1 -1
  86. package/dist/session/reply-credential-processor.d.ts +15 -0
  87. package/dist/session/reply-credential-processor.d.ts.map +1 -0
  88. package/dist/session/reply-credential-processor.js +40 -0
  89. package/dist/session/reply-credential-processor.js.map +1 -0
  90. package/dist/session/source-control-tools.d.ts +19 -1
  91. package/dist/session/source-control-tools.d.ts.map +1 -1
  92. package/dist/session/source-control-tools.js +70 -3
  93. package/dist/session/source-control-tools.js.map +1 -1
  94. package/dist/storage/domains/projects/base.d.ts +6 -0
  95. package/dist/storage/domains/projects/base.d.ts.map +1 -1
  96. package/dist/storage/domains/projects/base.js +12 -0
  97. package/dist/storage/domains/projects/base.js.map +1 -1
  98. package/dist/storage/domains/source-control/base.d.ts +17 -0
  99. package/dist/storage/domains/source-control/base.d.ts.map +1 -1
  100. package/dist/storage/domains/source-control/base.js +23 -0
  101. package/dist/storage/domains/source-control/base.js.map +1 -1
  102. package/dist/storage/domains/source-control/inmemory.d.ts +4 -0
  103. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  104. package/dist/storage/domains/source-control/inmemory.js +5 -1
  105. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  106. package/dist/storage/domains/work-items/base.d.ts +56 -0
  107. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  108. package/dist/storage/domains/work-items/base.js +139 -25
  109. package/dist/storage/domains/work-items/base.js.map +1 -1
  110. package/dist/tools/approval-tools.d.ts +15 -0
  111. package/dist/tools/approval-tools.d.ts.map +1 -0
  112. package/dist/tools/approval-tools.js +77 -0
  113. package/dist/tools/approval-tools.js.map +1 -0
  114. package/dist/tools/deliver.d.ts +54 -0
  115. package/dist/tools/deliver.d.ts.map +1 -0
  116. package/dist/tools/deliver.js +105 -0
  117. package/dist/tools/deliver.js.map +1 -0
  118. package/dist/tools/index.d.ts +29 -0
  119. package/dist/tools/index.d.ts.map +1 -0
  120. package/dist/tools/index.js +39 -0
  121. package/dist/tools/index.js.map +1 -0
  122. package/dist/tools/messaging-tools.d.ts +28 -0
  123. package/dist/tools/messaging-tools.d.ts.map +1 -0
  124. package/dist/tools/messaging-tools.js +312 -0
  125. package/dist/tools/messaging-tools.js.map +1 -0
  126. package/dist/tools/permissions.d.ts +31 -0
  127. package/dist/tools/permissions.d.ts.map +1 -0
  128. package/dist/tools/permissions.js +44 -0
  129. package/dist/tools/permissions.js.map +1 -0
  130. package/dist/tools/read-tools.d.ts +27 -0
  131. package/dist/tools/read-tools.d.ts.map +1 -0
  132. package/dist/tools/read-tools.js +285 -0
  133. package/dist/tools/read-tools.js.map +1 -0
  134. package/dist/tools/reports.d.ts +163 -0
  135. package/dist/tools/reports.d.ts.map +1 -0
  136. package/dist/tools/reports.js +352 -0
  137. package/dist/tools/reports.js.map +1 -0
  138. package/dist/tools/run-watch.d.ts +46 -0
  139. package/dist/tools/run-watch.d.ts.map +1 -0
  140. package/dist/tools/run-watch.js +102 -0
  141. package/dist/tools/run-watch.js.map +1 -0
  142. package/dist/tools/scope.d.ts +45 -0
  143. package/dist/tools/scope.d.ts.map +1 -0
  144. package/dist/tools/scope.js +73 -0
  145. package/dist/tools/scope.js.map +1 -0
  146. package/dist/tools/session-tools.d.ts +31 -0
  147. package/dist/tools/session-tools.d.ts.map +1 -0
  148. package/dist/tools/session-tools.js +312 -0
  149. package/dist/tools/session-tools.js.map +1 -0
  150. package/dist/tools/sessions-state-processor.d.ts +37 -0
  151. package/dist/tools/sessions-state-processor.d.ts.map +1 -0
  152. package/dist/tools/sessions-state-processor.js +206 -0
  153. package/dist/tools/sessions-state-processor.js.map +1 -0
  154. package/dist/tools/work-item-tools.d.ts +28 -0
  155. package/dist/tools/work-item-tools.d.ts.map +1 -0
  156. package/dist/tools/work-item-tools.js +322 -0
  157. package/dist/tools/work-item-tools.js.map +1 -0
  158. package/dist/work-items/create-work-item.d.ts +55 -0
  159. package/dist/work-items/create-work-item.d.ts.map +1 -0
  160. package/dist/work-items/create-work-item.js +101 -0
  161. package/dist/work-items/create-work-item.js.map +1 -0
  162. package/dist/work-items/decision-actions.d.ts +42 -0
  163. package/dist/work-items/decision-actions.d.ts.map +1 -0
  164. package/dist/work-items/decision-actions.js +70 -0
  165. package/dist/work-items/decision-actions.js.map +1 -0
  166. package/dist/workspace.d.ts.map +1 -1
  167. package/dist/workspace.js +3 -1
  168. package/dist/workspace.js.map +1 -1
  169. package/factory-skills/factory-gitlab-rereview/SKILL.md +1 -1
  170. package/factory-skills/factory-gitlab-review/SKILL.md +1 -1
  171. package/factory-skills/factory-plan/SKILL.md +4 -4
  172. package/factory-skills/factory-rereview/SKILL.md +3 -1
  173. package/factory-skills/factory-review/SKILL.md +3 -1
  174. package/factory-skills/factory-self-review/SKILL.md +46 -0
  175. package/package.json +9 -9
@@ -53,6 +53,30 @@ async function prepareSessionRunContext(requestContext, sessionId, sourceControl
53
53
  await primeTenantCredentialsForRequestContext(requestContext);
54
54
  return "prepared";
55
55
  }
56
+ /**
57
+ * Create the controller session for a Factory session that isn't live, as its
58
+ * row's owner in the row's organization. Used when an event or message has to
59
+ * reach a session nobody has open: there is no signed-in user, so the session
60
+ * runs as the person it belongs to.
61
+ */
62
+ async function createSessionAsRowOwner(controller, args) {
63
+ const requestContext = new RequestContext();
64
+ requestContext.set("user", {
65
+ workosId: args.row.userId,
66
+ organizationId: args.row.orgId
67
+ });
68
+ const session = await controller.createSession({
69
+ id: args.sessionId,
70
+ ownerId: args.row.userId,
71
+ resourceId: args.ownerResourceId,
72
+ scope: args.scope,
73
+ tags: args.tags,
74
+ ...args.threadId ? { threadId: args.threadId } : {},
75
+ requestContext
76
+ });
77
+ await seedSessionOrg(session, args.row.orgId);
78
+ return session;
79
+ }
56
80
  async function resolveSubscriptionSession(controller, subscription, options) {
57
81
  const { label } = options;
58
82
  const { sessionId, resourceId, threadId } = subscription;
@@ -69,20 +93,13 @@ async function resolveSubscriptionSession(controller, subscription, options) {
69
93
  };
70
94
  const sessionRow = await options.sourceControl?.sessions.getBySessionId(sessionId);
71
95
  if (!sessionRow) throw new Error(`${label} subscription ${subscription.id} has no Factory session ${sessionId} to run as.`);
72
- const requestContext = new RequestContext();
73
- requestContext.set("user", {
74
- workosId: sessionRow.userId,
75
- organizationId: sessionRow.orgId
76
- });
77
- session = await controller.createSession({
78
- id: sessionId,
79
- ownerId: sessionRow.userId,
80
- resourceId: ownerResourceId,
96
+ session = await createSessionAsRowOwner(controller, {
97
+ sessionId,
98
+ ownerResourceId,
99
+ row: sessionRow,
81
100
  scope,
82
- tags,
83
- requestContext
101
+ tags
84
102
  });
85
- await seedSessionOrg(session, sessionRow.orgId);
86
103
  } else if (!hasResolvedOrg(session.state?.get()?.factoryOrgId)) try {
87
104
  const sessionRow = await options.sourceControl?.sessions.getBySessionId(sessionId);
88
105
  await seedSessionOrg(session, sessionRow?.orgId);
@@ -99,6 +116,6 @@ async function resolveSubscriptionSession(controller, subscription, options) {
99
116
  return session;
100
117
  }
101
118
  //#endregion
102
- export { prepareSessionRunContext, resolveSubscriptionSession, subscriptionRunContext };
119
+ export { createSessionAsRowOwner, prepareSessionRunContext, resolveSubscriptionSession, subscriptionRunContext };
103
120
 
104
121
  //# sourceMappingURL=subscription-session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"subscription-session.js","names":[],"sources":["../../src/integrations/subscription-session.ts"],"sourcesContent":["import type { MountedMastraCode } from '@mastra/code-sdk';\nimport { RequestContext } from '@mastra/core/request-context';\n\nimport { primeTenantCredentialsForRequestContext } from '../routes/tenant-credentials.js';\nimport { hasResolvedOrg, seedSessionOrg } from '../session/org-seed.js';\nimport type { IntegrationSubscription } from '../storage/domains/integrations/base.js';\n\n/** The Factory session row fields a woken session has to run as. */\nexport type FactorySessionOwner = { userId: string; orgId: string };\n\nexport interface SubscriptionSessionLookup {\n sessions: { getBySessionId(sessionId: string): Promise<FactorySessionOwner | null> };\n}\n\n/**\n * Bring the session that owns a subscribed thread online so a provider event\n * can be delivered to it. Provider-neutral: GitHub and GitLab subscriptions\n * carry the same session binding and differ only in their target data.\n */\nexport type SubscriptionSessionRow = IntegrationSubscription<{\n projectRepositoryId: string;\n subscribedByUserId?: string | null;\n}>;\n\n/**\n * The request context a provider-triggered run executes under: the user who\n * subscribed the thread, in the subscription's organization. A webhook carries\n * no signed-in user and tenant credential resolution fails closed without one,\n * so a woken run would otherwise stop before it could persist or answer the\n * notification. The subscription row already names that user, so delivery\n * costs no extra read; an older row without one falls back to the Factory\n * session's owner, the identity used when a session is recreated for delivery.\n */\nexport async function subscriptionRunContext(\n subscription: SubscriptionSessionRow,\n sourceControl: SubscriptionSessionLookup | undefined,\n): Promise<RequestContext | undefined> {\n let userId = subscription.data.subscribedByUserId ?? undefined;\n let orgId: string | undefined = subscription.orgId;\n if (!userId && subscription.sessionId && sourceControl) {\n const sessionRow = await sourceControl.sessions.getBySessionId(subscription.sessionId);\n userId = sessionRow?.userId;\n orgId = sessionRow?.orgId ?? orgId;\n }\n if (!userId || !hasResolvedOrg(orgId)) return undefined;\n const requestContext = new RequestContext();\n requestContext.set('user', { workosId: userId, organizationId: orgId });\n // The web auth middleware primes credential snapshots per request; a\n // webhook-triggered run has no request, so prime here or the model resolves\n // against an empty snapshot and the run fails closed before persisting. A\n // priming failure propagates: handing back an unprimed context would let the\n // caller accept the delivery, and retire a terminal subscription, for a run\n // that then fails without its credentials and cannot be redelivered.\n try {\n await primeTenantCredentialsForRequestContext(requestContext);\n } catch (error) {\n throw new Error(`Unable to prime tenant credentials for subscription ${subscription.id}; not delivered.`, {\n cause: error,\n });\n }\n return requestContext;\n}\n\n/**\n * Attach the Factory session's owner, in its organization, to the request\n * context of a run that has no inbound request (a notification or peer-signal\n * wake), and prime that tenant's credentials. The live session's `ownerId`\n * isn't used: sessions opened from the browser or Slack are owned by the\n * controller id, not a user. Leaves the context alone when `sessionId` names no\n * Factory session or its org is unresolved, so credential resolution fails\n * closed.\n */\nexport async function prepareSessionRunContext(\n requestContext: RequestContext,\n sessionId: string,\n sourceControl: SubscriptionSessionLookup,\n options?: { expectedOrgId?: string },\n): Promise<'prepared' | 'session-not-found' | 'organization-unresolved' | 'organization-mismatch'> {\n const sessionRow = await sourceControl.sessions.getBySessionId(sessionId);\n if (!sessionRow) return 'session-not-found';\n if (!hasResolvedOrg(sessionRow.orgId)) return 'organization-unresolved';\n if (options?.expectedOrgId !== undefined && sessionRow.orgId !== options.expectedOrgId) {\n return 'organization-mismatch';\n }\n requestContext.set('user', { workosId: sessionRow.userId, organizationId: sessionRow.orgId });\n await primeTenantCredentialsForRequestContext(requestContext);\n return 'prepared';\n}\n\nexport async function resolveSubscriptionSession(\n controller: MountedMastraCode['controller'],\n subscription: SubscriptionSessionRow,\n options: { label: string; sourceControl?: SubscriptionSessionLookup },\n) {\n const { label } = options;\n const { sessionId, resourceId, threadId } = subscription;\n if (!sessionId || !resourceId || !threadId) {\n throw new Error(`${label} subscription ${subscription.id} is missing its session binding.`);\n }\n // Read the thread straight from storage before touching sessions. This answers\n // two questions at once, and `queryThreadById` does it without constructing a\n // session (so no workspace or sandbox is provisioned just to make the check).\n //\n // First: do we even have this thread? A change request's events can reach a\n // deployment that never owned the subscribed thread, and delivery must not\n // fabricate a session for a thread that lives somewhere else.\n //\n // Second: which resource owns it? The subscription records the Factory project\n // as its `resourceId`, but an unscoped session is registered under its own id,\n // so the stored value routinely names a resource that does not own the thread.\n // The thread row is the authoritative answer; the stored id is only a fallback.\n const thread = await controller.queryThreadById({ threadId });\n if (!thread) return undefined;\n const ownerResourceId = thread.resourceId || resourceId;\n const scope = subscription.sessionScope || undefined;\n let session = await controller.getSessionByResource(ownerResourceId, scope);\n if (!session) {\n const tags = {\n factoryProjectId: resourceId,\n projectRepositoryId: subscription.data.projectRepositoryId,\n };\n // Creating the session resolves its workspace, which authorizes the caller\n // against the Factory session row — no signed-in user, so run as its owner.\n // The session is created under the resource that owns the thread, so the\n // thread switch below resolves; the persisted Factory session is keyed by\n // the subscription's session ID.\n const sessionRow = await options.sourceControl?.sessions.getBySessionId(sessionId);\n if (!sessionRow) {\n throw new Error(`${label} subscription ${subscription.id} has no Factory session ${sessionId} to run as.`);\n }\n const requestContext = new RequestContext();\n requestContext.set('user', { workosId: sessionRow.userId, organizationId: sessionRow.orgId });\n session = await controller.createSession({\n id: sessionId,\n ownerId: sessionRow.userId,\n resourceId: ownerResourceId,\n scope,\n tags,\n requestContext,\n });\n await seedSessionOrg(session, sessionRow.orgId);\n } else if (!hasResolvedOrg(session.state?.get()?.factoryOrgId)) {\n // A session created before the org seed existed carries the project tag and\n // no org, so capture would refuse for the rest of its life even though the\n // org is recoverable. Heal it — but only here, and only when it is missing:\n // hoisting the row fetch above would make an existing-session delivery throw\n // on a missing row where it previously succeeded, and fetching it every time\n // would add a storage read to every delivery. A row that is missing or a\n // lookup that throws leaves the session marked unresolved, and delivery\n // continues either way.\n try {\n const sessionRow = await options.sourceControl?.sessions.getBySessionId(sessionId);\n await seedSessionOrg(session, sessionRow?.orgId);\n } catch (error) {\n console.warn(`[${label} webhook] Unable to resolve the session organization.`, error);\n await seedSessionOrg(session, undefined);\n }\n } else if (session.state?.get()?.factoryOrgUnresolved) {\n // The org is present, so an earlier failed resolution left a stale marker\n // behind. Clear it without a storage read — nothing else re-seeds a session\n // once the start hook has run, so the marker would otherwise outlive its\n // cause.\n await seedSessionOrg(session, session.state.get()?.factoryOrgId);\n }\n if (session.thread.getId() !== threadId) {\n await session.thread.switch({ threadId, emitEvent: false });\n }\n if (session.thread.getId() !== threadId) {\n throw new Error(`Session ${sessionId} did not bind thread ${threadId}.`);\n }\n return session;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"subscription-session.js","names":[],"sources":["../../src/integrations/subscription-session.ts"],"sourcesContent":["import type { MountedMastraCode } from '@mastra/code-sdk';\nimport { RequestContext } from '@mastra/core/request-context';\n\nimport { primeTenantCredentialsForRequestContext } from '../routes/tenant-credentials.js';\nimport { hasResolvedOrg, seedSessionOrg } from '../session/org-seed.js';\nimport type { IntegrationSubscription } from '../storage/domains/integrations/base.js';\n\n/** The Factory session row fields a woken session has to run as. */\nexport type FactorySessionOwner = { userId: string; orgId: string };\n\nexport interface SubscriptionSessionLookup {\n sessions: { getBySessionId(sessionId: string): Promise<FactorySessionOwner | null> };\n}\n\n/**\n * Bring the session that owns a subscribed thread online so a provider event\n * can be delivered to it. Provider-neutral: GitHub and GitLab subscriptions\n * carry the same session binding and differ only in their target data.\n */\nexport type SubscriptionSessionRow = IntegrationSubscription<{\n projectRepositoryId: string;\n subscribedByUserId?: string | null;\n}>;\n\n/**\n * The request context a provider-triggered run executes under: the user who\n * subscribed the thread, in the subscription's organization. A webhook carries\n * no signed-in user and tenant credential resolution fails closed without one,\n * so a woken run would otherwise stop before it could persist or answer the\n * notification. The subscription row already names that user, so delivery\n * costs no extra read; an older row without one falls back to the Factory\n * session's owner, the identity used when a session is recreated for delivery.\n */\nexport async function subscriptionRunContext(\n subscription: SubscriptionSessionRow,\n sourceControl: SubscriptionSessionLookup | undefined,\n): Promise<RequestContext | undefined> {\n let userId = subscription.data.subscribedByUserId ?? undefined;\n let orgId: string | undefined = subscription.orgId;\n if (!userId && subscription.sessionId && sourceControl) {\n const sessionRow = await sourceControl.sessions.getBySessionId(subscription.sessionId);\n userId = sessionRow?.userId;\n orgId = sessionRow?.orgId ?? orgId;\n }\n if (!userId || !hasResolvedOrg(orgId)) return undefined;\n const requestContext = new RequestContext();\n requestContext.set('user', { workosId: userId, organizationId: orgId });\n // The web auth middleware primes credential snapshots per request; a\n // webhook-triggered run has no request, so prime here or the model resolves\n // against an empty snapshot and the run fails closed before persisting. A\n // priming failure propagates: handing back an unprimed context would let the\n // caller accept the delivery, and retire a terminal subscription, for a run\n // that then fails without its credentials and cannot be redelivered.\n try {\n await primeTenantCredentialsForRequestContext(requestContext);\n } catch (error) {\n throw new Error(`Unable to prime tenant credentials for subscription ${subscription.id}; not delivered.`, {\n cause: error,\n });\n }\n return requestContext;\n}\n\n/**\n * Attach the Factory session's owner, in its organization, to the request\n * context of a run that has no inbound request (a notification or peer-signal\n * wake), and prime that tenant's credentials. The live session's `ownerId`\n * isn't used: sessions opened from the browser or Slack are owned by the\n * controller id, not a user. Leaves the context alone when `sessionId` names no\n * Factory session or its org is unresolved, so credential resolution fails\n * closed.\n */\nexport async function prepareSessionRunContext(\n requestContext: RequestContext,\n sessionId: string,\n sourceControl: SubscriptionSessionLookup,\n options?: { expectedOrgId?: string },\n): Promise<'prepared' | 'session-not-found' | 'organization-unresolved' | 'organization-mismatch'> {\n const sessionRow = await sourceControl.sessions.getBySessionId(sessionId);\n if (!sessionRow) return 'session-not-found';\n if (!hasResolvedOrg(sessionRow.orgId)) return 'organization-unresolved';\n if (options?.expectedOrgId !== undefined && sessionRow.orgId !== options.expectedOrgId) {\n return 'organization-mismatch';\n }\n requestContext.set('user', { workosId: sessionRow.userId, organizationId: sessionRow.orgId });\n await primeTenantCredentialsForRequestContext(requestContext);\n return 'prepared';\n}\n\n/**\n * Create the controller session for a Factory session that isn't live, as its\n * row's owner in the row's organization. Used when an event or message has to\n * reach a session nobody has open: there is no signed-in user, so the session\n * runs as the person it belongs to.\n */\nexport async function createSessionAsRowOwner(\n controller: Pick<MountedMastraCode['controller'], 'createSession'>,\n args: {\n sessionId: string;\n ownerResourceId: string;\n row: FactorySessionOwner;\n tags: Record<string, string>;\n scope?: string;\n /** Bind this exact thread at creation instead of resuming or creating another. */\n threadId?: string;\n },\n) {\n const requestContext = new RequestContext();\n requestContext.set('user', { workosId: args.row.userId, organizationId: args.row.orgId });\n const session = await controller.createSession({\n id: args.sessionId,\n ownerId: args.row.userId,\n resourceId: args.ownerResourceId,\n scope: args.scope,\n tags: args.tags,\n ...(args.threadId ? { threadId: args.threadId } : {}),\n requestContext,\n });\n await seedSessionOrg(session, args.row.orgId);\n return session;\n}\n\nexport async function resolveSubscriptionSession(\n controller: MountedMastraCode['controller'],\n subscription: SubscriptionSessionRow,\n options: { label: string; sourceControl?: SubscriptionSessionLookup },\n) {\n const { label } = options;\n const { sessionId, resourceId, threadId } = subscription;\n if (!sessionId || !resourceId || !threadId) {\n throw new Error(`${label} subscription ${subscription.id} is missing its session binding.`);\n }\n // Read the thread straight from storage before touching sessions. This answers\n // two questions at once, and `queryThreadById` does it without constructing a\n // session (so no workspace or sandbox is provisioned just to make the check).\n //\n // First: do we even have this thread? A change request's events can reach a\n // deployment that never owned the subscribed thread, and delivery must not\n // fabricate a session for a thread that lives somewhere else.\n //\n // Second: which resource owns it? The subscription records the Factory project\n // as its `resourceId`, but an unscoped session is registered under its own id,\n // so the stored value routinely names a resource that does not own the thread.\n // The thread row is the authoritative answer; the stored id is only a fallback.\n const thread = await controller.queryThreadById({ threadId });\n if (!thread) return undefined;\n const ownerResourceId = thread.resourceId || resourceId;\n const scope = subscription.sessionScope || undefined;\n let session = await controller.getSessionByResource(ownerResourceId, scope);\n if (!session) {\n const tags = {\n factoryProjectId: resourceId,\n projectRepositoryId: subscription.data.projectRepositoryId,\n };\n // Creating the session resolves its workspace, which authorizes the caller\n // against the Factory session row — no signed-in user, so run as its owner.\n // The session is created under the resource that owns the thread, so the\n // thread switch below resolves; the persisted Factory session is keyed by\n // the subscription's session ID.\n const sessionRow = await options.sourceControl?.sessions.getBySessionId(sessionId);\n if (!sessionRow) {\n throw new Error(`${label} subscription ${subscription.id} has no Factory session ${sessionId} to run as.`);\n }\n session = await createSessionAsRowOwner(controller, {\n sessionId,\n ownerResourceId,\n row: sessionRow,\n scope,\n tags,\n });\n } else if (!hasResolvedOrg(session.state?.get()?.factoryOrgId)) {\n // A session created before the org seed existed carries the project tag and\n // no org, so capture would refuse for the rest of its life even though the\n // org is recoverable. Heal it — but only here, and only when it is missing:\n // hoisting the row fetch above would make an existing-session delivery throw\n // on a missing row where it previously succeeded, and fetching it every time\n // would add a storage read to every delivery. A row that is missing or a\n // lookup that throws leaves the session marked unresolved, and delivery\n // continues either way.\n try {\n const sessionRow = await options.sourceControl?.sessions.getBySessionId(sessionId);\n await seedSessionOrg(session, sessionRow?.orgId);\n } catch (error) {\n console.warn(`[${label} webhook] Unable to resolve the session organization.`, error);\n await seedSessionOrg(session, undefined);\n }\n } else if (session.state?.get()?.factoryOrgUnresolved) {\n // The org is present, so an earlier failed resolution left a stale marker\n // behind. Clear it without a storage read — nothing else re-seeds a session\n // once the start hook has run, so the marker would otherwise outlive its\n // cause.\n await seedSessionOrg(session, session.state.get()?.factoryOrgId);\n }\n if (session.thread.getId() !== threadId) {\n await session.thread.switch({ threadId, emitEvent: false });\n }\n if (session.thread.getId() !== threadId) {\n throw new Error(`Session ${sessionId} did not bind thread ${threadId}.`);\n }\n return session;\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function providerDisplayName(provider: string): string;
2
+ //# sourceMappingURL=provider-display-name.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-display-name.d.ts","sourceRoot":"","sources":["../src/provider-display-name.ts"],"names":[],"mappings":"AASA,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ5D"}
@@ -0,0 +1,16 @@
1
+ //#region src/provider-display-name.ts
2
+ const PROVIDER_DISPLAY_NAMES = {
3
+ anthropic: "Anthropic",
4
+ "github-copilot": "GitHub Copilot",
5
+ "kimi-code-plan-cn": "Kimi",
6
+ openai: "OpenAI",
7
+ "openai-codex": "OpenAI",
8
+ xai: "xAI"
9
+ };
10
+ function providerDisplayName(provider) {
11
+ return PROVIDER_DISPLAY_NAMES[provider] ?? provider.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
12
+ }
13
+ //#endregion
14
+ export { providerDisplayName };
15
+
16
+ //# sourceMappingURL=provider-display-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-display-name.js","names":[],"sources":["../src/provider-display-name.ts"],"sourcesContent":["const PROVIDER_DISPLAY_NAMES: Record<string, string> = {\n anthropic: 'Anthropic',\n 'github-copilot': 'GitHub Copilot',\n 'kimi-code-plan-cn': 'Kimi',\n openai: 'OpenAI',\n 'openai-codex': 'OpenAI',\n xai: 'xAI',\n};\n\nexport function providerDisplayName(provider: string): string {\n return (\n PROVIDER_DISPLAY_NAMES[provider] ??\n provider\n .split('-')\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ')\n );\n}\n"],"mappings":";AAAA,MAAM,yBAAiD;CACrD,WAAW;CACX,kBAAkB;CAClB,qBAAqB;CACrB,QAAQ;CACR,gBAAgB;CAChB,KAAK;AACP;AAEA,SAAgB,oBAAoB,UAA0B;CAC5D,OACE,uBAAuB,aACvB,SACG,MAAM,GAAG,CAAC,CACV,KAAI,SAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CACzD,KAAK,GAAG;AAEf"}
@@ -1,4 +1,4 @@
1
- import { WEB_OAUTH_FLOW_KINDS, getAuthProviderId, listTenantCredentialsForRequest, resolveCredentialContext, tenantOrgId } from "./provider-credentials.js";
1
+ import { WEB_OAUTH_PROVIDERS, getAuthProviderId, listTenantCredentialsForRequest, resolveCredentialContext, tenantOrgId } from "./provider-credentials.js";
2
2
  import { resolveFactoryModelPolicy } from "../session/credential-policy.js";
3
3
  import "../session/memory-settings-hydration.js";
4
4
  import { factoryMemorySettingsUserId } from "../storage/domains/memory-settings/base.js";
@@ -57,7 +57,7 @@ async function listProviders({ controller, authStorage, tenantCredentials, deplo
57
57
  else if (authStorage?.hasStoredApiKey(model.provider)) source = "stored";
58
58
  else if (model.apiKeyEnvVar && process.env[model.apiKeyEnvVar]) source = "env";
59
59
  else if (model.hasApiKey) source = "env";
60
- const flowKind = WEB_OAUTH_FLOW_KINDS[model.provider];
60
+ const flowKind = WEB_OAUTH_PROVIDERS[model.provider]?.flow;
61
61
  seen.set(model.provider, {
62
62
  provider: model.provider,
63
63
  envVar: model.apiKeyEnvVar,
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":[],"sources":["../../src/routes/config.ts"],"sourcesContent":["import { MastraCodeGateway } from '@mastra/code-sdk/agents/mastracode-gateway';\nimport type { AuthStorage } from '@mastra/code-sdk/auth/storage';\nimport { resolveAutoOMModelId } from '@mastra/code-sdk/onboarding/packs';\nimport type { ProviderAccess, ProviderAccessLevel } from '@mastra/code-sdk/onboarding/packs';\nimport { getCustomProviderId, MASTRA_GATEWAY_PROVIDER } from '@mastra/code-sdk/onboarding/settings';\nimport type { CustomProviderSetting } from '@mastra/code-sdk/onboarding/settings';\nimport { AMAZON_BEDROCK_GATEWAY_ID } from '@mastra/code-sdk/providers/amazon-bedrock-gateway';\nimport { MASTRA_GATEWAY_PREFIX } from '@mastra/code-sdk/providers/model-ids';\nimport { getModelReasoningOptions } from '@mastra/core/llm';\nimport { RequestContext } from '@mastra/core/request-context';\nimport type { ApiRoute } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\n\nimport type { Context } from 'hono';\nimport { z } from 'zod';\nimport { resolveFactoryModelPolicy } from '../session/credential-policy.js';\nimport { DEFAULT_OBSERVATION_THRESHOLD, DEFAULT_REFLECTION_THRESHOLD } from '../session/memory-settings-hydration.js';\nimport type {\n CredentialRecord,\n LoginSessionKind,\n ModelCredentialsStorage,\n} from '../storage/domains/credentials/base.js';\nimport type { CustomProviderRecord, CustomProvidersStorage } from '../storage/domains/custom-providers/base.js';\nimport { factoryMemorySettingsUserId } from '../storage/domains/memory-settings/base.js';\nimport type {\n MemorySettingsPatch,\n MemorySettingsRecord,\n MemorySettingsStorage,\n} from '../storage/domains/memory-settings/base.js';\nimport type { ModelDefaultsStorage } from '../storage/domains/model-defaults/base.js';\nimport type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';\nimport type { SourceControlStorageHandle } from '../storage/domains/source-control/base.js';\nimport type { WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport {\n getAuthProviderId,\n listTenantCredentialsForRequest,\n resolveCredentialContext,\n tenantOrgId,\n WEB_OAUTH_FLOW_KINDS,\n} from './provider-credentials.js';\nimport { Route } from './route.js';\nimport type { RouteAuth, RouteDependencies } from './route.js';\n\n/** Widen a route-local Hono context to the plain `Context` the auth helpers take. */\nfunction loose(c: unknown): Context {\n return c as Context;\n}\n\n/**\n * Server-side configuration routes for the web app.\n *\n * The browser has no access to the credential store or the model catalog, so\n * the web settings panel asks the server — which owns both — to list providers\n * and manage API keys. This mirrors the TUI's `/api-keys` command, exposing the\n * same `AuthStorage`-backed key management over HTTP.\n *\n * Keys are never returned to the client; only their presence and source.\n */\n\n/**\n * Where a provider's active credential comes from, as seen by the caller.\n * Local mode reports `oauth`/`stored` (server-global `auth.json`); tenant mode\n * reports the scoped variants (`oauth-user`/`stored-user`/`stored-org`).\n * `deployment` (tenant mode) marks a provider the operator opted in to run on\n * the server process's own credentials (e.g. Amazon Bedrock's AWS chain).\n */\nexport type ProviderCredentialSource =\n | 'deployment'\n | 'oauth'\n | 'stored'\n | 'env'\n | 'none'\n | 'oauth-user'\n | 'oauth-org'\n | 'stored-user'\n | 'stored-org';\n\n/** A model provider with the current source of its credentials. */\nexport interface ProviderInfo {\n provider: string;\n /** Env var the provider's key is read from, if any. */\n envVar?: string;\n /** Where the active credential comes from. */\n source: ProviderCredentialSource;\n /**\n * Tenant mode: whether an org-wide API key exists for this provider, even\n * when the caller's personal credential shadows it. Lets the UI tell\n * \"shared with the org\" apart from \"only works for me\".\n */\n orgKey?: boolean;\n /**\n * Tenant mode: the caller's personal credential for this provider, if any.\n * Reported independently of `source` so the UI can manage each scope even\n * when one shadows the other.\n */\n userCredential?: 'oauth' | 'api_key';\n /** Tenant mode: the shared org credential for this provider, if any. */\n orgCredential?: 'oauth' | 'api_key';\n /** Web OAuth sign-in capability, when the provider supports it. */\n oauth?: { supported: true; modes: LoginSessionKind[] };\n}\n\n/** Minimal session surface the config routes touch. */\nexport interface OMSession {\n /** `get()` returns '' when no model is selected, so callers fall back on falsy. */\n model: { get: () => string };\n}\n\n/** Minimal controller surface this module needs (model catalog + modes + sessions). */\ninterface ModelCatalog {\n listAvailableModels: () => Promise<\n Array<{ id?: string; modelName?: string; provider: string; hasApiKey: boolean; apiKeyEnvVar?: string }>\n >;\n listModes?: () => Array<{ id: string; defaultModelId?: string }>;\n getSessionByResource?: (resourceId: string, scope?: string) => Promise<OMSession | undefined>;\n}\n\n/**\n * Build a deduplicated, sorted list of providers from the model catalog,\n * annotated with where each provider's credential currently comes from.\n * Mirrors the TUI's `/api-keys` provider list.\n *\n * When `tenantCredentials` is given (deployed mode), sources reflect the\n * *caller's* tenant rows with user > org precedence and the server-global\n * `authStorage` is ignored; otherwise the local `auth.json` view is reported.\n */\nexport async function listProviders({\n controller,\n authStorage,\n tenantCredentials,\n deploymentProviders,\n}: {\n controller: ModelCatalog;\n authStorage?: AuthStorage;\n tenantCredentials?: CredentialRecord[];\n deploymentProviders?: ReadonlySet<string>;\n}): Promise<ProviderInfo[]> {\n const models = await controller.listAvailableModels();\n const seen = new Map<string, ProviderInfo>();\n\n for (const model of models) {\n if (seen.has(model.provider)) continue;\n\n if (tenantCredentials && isDeploymentModelProvider(model.provider)) {\n // Credentials for these providers live on the server process, never in\n // tenant rows, so no account can connect them. List them only when the\n // operator opted the deployment in and the server has credentials.\n const usable =\n deploymentProviders?.has(model.provider) && models.some(m => m.provider === model.provider && m.hasApiKey);\n if (usable) seen.set(model.provider, { provider: model.provider, source: 'deployment' });\n continue;\n }\n\n const authProviderId = getAuthProviderId(model.provider);\n let source: ProviderInfo['source'] = 'none';\n let orgKey: boolean | undefined;\n let userCredential: ProviderInfo['userCredential'];\n let orgCredential: ProviderInfo['orgCredential'];\n if (tenantCredentials) {\n const userRec = tenantCredentials.find(r => r.scope === 'user' && r.provider === authProviderId);\n const orgRec = tenantCredentials.find(r => r.scope === 'org' && r.provider === authProviderId);\n // Any shared org credential (API key or org-wide OAuth) counts.\n orgKey = orgRec !== undefined;\n userCredential = userRec?.credential.type;\n orgCredential = orgRec?.credential.type;\n if (userRec?.credential.type === 'oauth') {\n source = 'oauth-user';\n } else if (userRec?.credential.type === 'api_key') {\n source = 'stored-user';\n } else if (orgRec?.credential.type === 'oauth') {\n source = 'oauth-org';\n } else if (orgRec?.credential.type === 'api_key') {\n source = 'stored-org';\n }\n } else if (authStorage?.isLoggedIn(authProviderId)) {\n source = 'oauth';\n } else if (authStorage?.hasStoredApiKey(model.provider)) {\n source = 'stored';\n } else if (model.apiKeyEnvVar && process.env[model.apiKeyEnvVar]) {\n source = 'env';\n } else if (model.hasApiKey) {\n source = 'env';\n }\n\n const flowKind = WEB_OAUTH_FLOW_KINDS[model.provider];\n seen.set(model.provider, {\n provider: model.provider,\n envVar: model.apiKeyEnvVar,\n source,\n ...(orgKey !== undefined ? { orgKey } : {}),\n ...(userCredential ? { userCredential } : {}),\n ...(orgCredential ? { orgCredential } : {}),\n ...(flowKind ? { oauth: { supported: true as const, modes: [flowKind] } } : {}),\n });\n }\n\n return Array.from(seen.values()).sort((a, b) => a.provider.localeCompare(b.provider));\n}\n\n/** A user-defined OpenAI-compatible provider, with key presence (never the key). */\nexport interface CustomProviderInfo {\n id: string;\n name: string;\n url: string;\n hasApiKey: boolean;\n models: string[];\n}\n\n/** Redact a stored custom-provider row for the client (key presence only). */\nfunction toCustomProviderInfo(record: CustomProviderRecord): CustomProviderInfo {\n return {\n id: record.providerId,\n name: record.name,\n url: record.url,\n hasApiKey: Boolean(record.apiKey),\n models: record.models,\n };\n}\n\n/** The resolved custom-providers storage scope for a request. */\ninterface CustomProvidersContext {\n storage: CustomProvidersStorage;\n orgId: string;\n userId: string;\n}\n\n/**\n * Resolve the custom-providers context for a request, or a ready-to-return\n * error response. Same posture as memory settings: tenant rows in deployed\n * mode, a sentinel `local` org in no-auth mode — never settings.json.\n */\nasync function resolveCustomProvidersContext({\n c,\n auth,\n customProviders,\n}: {\n c: Context;\n auth: RouteAuth;\n customProviders?: CustomProvidersStorage;\n}): Promise<CustomProvidersContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant && auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n if (customProviders) {\n try {\n await customProviders.ensureReady();\n return tenant\n ? { storage: customProviders, orgId: tenantOrgId(tenant), userId: tenant.userId }\n : { storage: customProviders, orgId: 'local', userId: 'local' };\n } catch {\n // fall through to the unavailable response\n }\n }\n return {\n response: c.json(\n {\n error: 'custom_providers_unavailable',\n message: 'Custom provider storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n}\n\n/** Validate + coerce a request body into a CustomProviderSetting. */\nfunction parseCustomProviderBody(body: unknown): CustomProviderSetting | { error: string } {\n if (!body || typeof body !== 'object') return { error: 'Invalid JSON body' };\n const b = body as Record<string, unknown>;\n const name = typeof b.name === 'string' ? b.name.trim() : '';\n if (!name) return { error: 'Missing required field: name' };\n const url = typeof b.url === 'string' ? b.url.trim() : '';\n if (!url) return { error: 'Missing required field: url' };\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return { error: 'url must be an http(s) URL' };\n }\n } catch {\n return { error: 'url must be a valid URL' };\n }\n const apiKey = typeof b.apiKey === 'string' && b.apiKey.trim() ? b.apiKey.trim() : undefined;\n const models = Array.isArray(b.models)\n ? b.models.filter((m): m is string => typeof m === 'string' && m.trim().length > 0).map(m => m.trim())\n : [];\n return { name, url, apiKey, models };\n}\n\n/**\n * Providers whose credentials can only come from the server process (Amazon\n * Bedrock authenticates through the AWS credential chain). In tenant mode they\n * are usable only when the operator lists them in\n * `MastraFactoryConfig.deploymentModelProviders`.\n */\nexport const DEPLOYMENT_MODEL_PROVIDERS: readonly string[] = [AMAZON_BEDROCK_GATEWAY_ID];\n\nexport function isDeploymentModelProvider(provider: string): boolean {\n return DEPLOYMENT_MODEL_PROVIDERS.includes(provider);\n}\n\n/**\n * Normalize the operator's `deploymentModelProviders` list. Unsupported ids are\n * ignored with a warning rather than failing boot.\n */\nexport function resolveDeploymentModelProviders(providers: readonly string[] | undefined): ReadonlySet<string> {\n const resolved = new Set<string>();\n for (const raw of providers ?? []) {\n const provider = raw.trim();\n if (!provider) continue;\n if (isDeploymentModelProvider(provider)) {\n resolved.add(provider);\n } else {\n console.warn(\n `[factory] Ignoring deployment model provider \"${provider}\". Supported: ${DEPLOYMENT_MODEL_PROVIDERS.join(', ')}.`,\n );\n }\n }\n return resolved;\n}\n\n/**\n * Compute which providers the user can reach, mirroring the TUI's\n * `/models-pack` access derivation: OAuth/api-key from the credential store for\n * the named providers, plus any other provider that has a usable key.\n */\nexport async function buildProviderAccess({\n controller,\n authStorage,\n tenantCredentials,\n deploymentProviders,\n}: {\n controller: ModelCatalog;\n authStorage?: AuthStorage;\n tenantCredentials?: CredentialRecord[];\n deploymentProviders?: ReadonlySet<string>;\n}): Promise<ProviderAccess> {\n const models = await controller.listAvailableModels();\n const hasModelKey = (provider: string) => models.some(m => m.provider === provider && m.hasApiKey);\n const accessLevel = (provider: string): ProviderAccessLevel => {\n const authProviderId = getAuthProviderId(provider);\n if (tenantCredentials) {\n // Tenant rows never authenticate these providers; only an operator\n // opt-in plus credentials on the server process does.\n if (isDeploymentModelProvider(provider)) {\n return deploymentProviders?.has(provider) && hasModelKey(provider) ? 'apikey' : false;\n }\n const userRec = tenantCredentials.find(r => r.scope === 'user' && r.provider === authProviderId);\n const orgRec = tenantCredentials.find(r => r.scope === 'org' && r.provider === authProviderId);\n const credential = userRec?.credential ?? orgRec?.credential;\n if (credential?.type === 'oauth') return 'oauth';\n if (credential?.type === 'api_key' && credential.key.trim().length > 0) return 'apikey';\n return false;\n }\n\n const oauthCredential = authStorage?.get(authProviderId);\n if (oauthCredential?.type === 'oauth') return 'oauth';\n if (authStorage?.hasStoredApiKey(provider)) return 'apikey';\n const directCredential = authStorage?.get(provider);\n if (directCredential?.type === 'api_key' && directCredential.key.trim().length > 0) return 'apikey';\n return hasModelKey(provider) ? 'apikey' : false;\n };\n const access: ProviderAccess = {\n anthropic: accessLevel('anthropic'),\n openai: accessLevel('openai'),\n cerebras: accessLevel('cerebras'),\n google: accessLevel('google'),\n deepseek: accessLevel('deepseek'),\n 'github-copilot': accessLevel('github-copilot'),\n };\n const seen = new Set(Object.keys(access));\n for (const m of models) {\n if (!seen.has(m.provider)) {\n access[m.provider] = accessLevel(m.provider);\n seen.add(m.provider);\n }\n }\n return access;\n}\n\nfunction canUseModelProvider(access: ProviderAccess, provider: string): boolean {\n return Boolean(access[provider]);\n}\n\n/** Per-user default model context for the current request. */\nexport interface ModelDefaultsContext {\n storage: ModelDefaultsStorage;\n orgId: string;\n userId: string;\n}\n\n/** Resolve the default-model context for a request, or a ready-to-return error response. */\nasync function resolveModelDefaultsContext({\n c,\n auth,\n modelDefaults,\n}: {\n c: Context;\n auth: RouteAuth;\n modelDefaults?: ModelDefaultsStorage;\n}): Promise<ModelDefaultsContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant && auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n if (modelDefaults) {\n try {\n await modelDefaults.ensureReady();\n return tenant\n ? { storage: modelDefaults, orgId: tenantOrgId(tenant), userId: tenant.userId }\n : { storage: modelDefaults, orgId: 'local', userId: 'local' };\n } catch {\n // fall through to the unavailable response\n }\n }\n return {\n response: c.json(\n {\n error: 'model_defaults_unavailable',\n message: 'Default model storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n}\n\n// Mirrors the TUI `/om` command. Settings are persisted per organization and\n// user in the Factory app database, then loaded into request context for each\n// invocation without copying them into mutable session state.\n\nexport interface OMRoleConfigInfo {\n model: 'auto' | string;\n effectiveModelId: string;\n effectiveModelSource: 'explicit' | 'live-session' | 'configured-default';\n providerStatus: 'available' | 'unavailable';\n}\n\n/** Persisted intent plus the concrete models the current Factory configuration resolves. */\nexport interface OMConfigInfo {\n observer: OMRoleConfigInfo;\n reflector: OMRoleConfigInfo;\n /** @deprecated Use `observer.effectiveModelId`. */\n observerModelId: string;\n /** @deprecated Use `reflector.effectiveModelId`. */\n reflectorModelId: string;\n observationThreshold: number;\n reflectionThreshold: number;\n observeAttachments: 'auto' | boolean;\n}\n\nexport interface ProviderOMDefaultsResponse {\n ok: true;\n config: OMConfigInfo;\n}\n\nfunction modelProvider(modelId: string): string {\n // Effective IDs keep their `mastra/` route; the provider segment after it is what\n // the SDK resolver falls back to when the gateway is not configured.\n const normalized = modelId.replace(/^mastracode\\//, '').replace(/^mastra\\//, '');\n return normalized.split('/', 1)[0] ?? '';\n}\n\nfunction roleConfig(\n model: OMRoleConfigInfo['model'],\n effectiveModelId: string,\n autoModelSource: 'live-session' | 'configured-default',\n availableProviders: ReadonlySet<string>,\n): OMRoleConfigInfo {\n return {\n model,\n effectiveModelId,\n effectiveModelSource: model === 'auto' ? autoModelSource : 'explicit',\n providerStatus:\n availableProviders.has(modelProvider(effectiveModelId)) ||\n (effectiveModelId.startsWith(MASTRA_GATEWAY_PREFIX) && availableProviders.has(MASTRA_GATEWAY_PROVIDER))\n ? 'available'\n : 'unavailable',\n };\n}\n\nfunction readStoredOMConfig(\n record: MemorySettingsRecord | null,\n currentModelId: string | undefined,\n autoModelSource: 'live-session' | 'configured-default',\n availableProviders: ReadonlySet<string>,\n): OMConfigInfo {\n const autoModelId = resolveAutoOMModelId(currentModelId, providerId => availableProviders.has(providerId));\n const observerModelId = record?.observerModelId ?? autoModelId;\n const reflectorModelId = record?.reflectorModelId ?? autoModelId;\n return {\n observer: roleConfig(record?.observerModelId ?? 'auto', observerModelId, autoModelSource, availableProviders),\n reflector: roleConfig(record?.reflectorModelId ?? 'auto', reflectorModelId, autoModelSource, availableProviders),\n observerModelId,\n reflectorModelId,\n observationThreshold: record?.observationThreshold ?? DEFAULT_OBSERVATION_THRESHOLD,\n reflectionThreshold: record?.reflectionThreshold ?? DEFAULT_REFLECTION_THRESHOLD,\n observeAttachments: record?.observeAttachments ?? 'auto',\n };\n}\n\n/**\n * Where a request's OM settings live: the `memory-settings` factory storage\n * domain, one row per (org, user). Without a tenant (auth disabled), settings\n * land on a sentinel `(local, local)` row in the same table — the web surface\n * never reads or writes `settings.json` for memory settings.\n */\ninterface MemorySettingsContext {\n storage: MemorySettingsStorage;\n orgId: string;\n userId: string;\n}\n\n/**\n * Resolve the memory-settings context for a request, or a ready-to-return\n * error response. When `factoryProjectId` is provided the row addressed is the\n * factory project's shared settings (a sentinel user id in the caller's org)\n * instead of the caller's personal row — this is what factory board runs and\n * channel sessions hydrate from.\n */\nasync function resolveMemorySettingsContext({\n c,\n auth,\n memorySettings,\n factoryProjectId,\n factoryProjects,\n}: {\n c: Context;\n auth: RouteAuth;\n memorySettings?: MemorySettingsStorage;\n factoryProjectId?: string;\n factoryProjects?: FactoryProjectsStorage;\n}): Promise<MemorySettingsContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant && auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n // Factory-scoped rows are shared org state: the target project must exist in\n // the caller's org before its settings row can be read or written.\n if (factoryProjectId && tenant) {\n if (!factoryProjects) return { response: c.json({ error: 'factory_unavailable' }, 503) };\n try {\n await factoryProjects.ensureReady();\n const project = await factoryProjects.get({ orgId: tenantOrgId(tenant), id: factoryProjectId });\n if (!project) return { response: c.json({ error: 'factory_project_not_found' }, 404) };\n } catch {\n return { response: c.json({ error: 'factory_unavailable' }, 503) };\n }\n }\n if (memorySettings) {\n try {\n await memorySettings.ensureReady();\n const factoryUserId = factoryProjectId ? factoryMemorySettingsUserId(factoryProjectId) : undefined;\n return tenant\n ? { storage: memorySettings, orgId: tenantOrgId(tenant), userId: factoryUserId ?? tenant.userId }\n : { storage: memorySettings, orgId: 'local', userId: factoryUserId ?? 'local' };\n } catch {\n // fall through to the unavailable response\n }\n }\n return {\n response: c.json(\n {\n error: 'memory_settings_unavailable',\n message: 'Memory settings storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n}\n\n/** Persist an OM knob change to the caller's memory-settings row. */\nasync function persistMemorySettings(context: MemorySettingsContext, patch: MemorySettingsPatch): Promise<void> {\n await context.storage.patch({ orgId: context.orgId, userId: context.userId, patch });\n}\n\n/** Dependencies injected into {@link ConfigRoutes}. */\nexport interface ConfigRoutesDeps extends RouteDependencies {\n controller: ModelCatalog;\n features?: { knowledge: boolean };\n authStorage?: AuthStorage;\n /** Tenant credential domain handle; absent in local (no-DB) mode. */\n modelCredentials?: ModelCredentialsStorage;\n /** Tenant model-defaults domain handle; absent in local (no-DB) mode. */\n modelDefaults?: ModelDefaultsStorage;\n /** Source-control sessions available to config route integrations. */\n sourceControlSessions?: Pick<SourceControlStorageHandle['sessions'], 'getBySessionId'>;\n /** Thread membership used to resolve the same model policy as an invocation. */\n workItems?: WorkItemsStorage;\n /** Tenant memory-settings domain handle; absent in local (no-DB) mode. */\n memorySettings?: MemorySettingsStorage;\n /** Factory projects domain, used to derive OM fallbacks from a factory's default model. */\n factoryProjects?: FactoryProjectsStorage;\n /** Custom-providers domain handle; absent when the app database is missing. */\n customProviders?: CustomProvidersStorage;\n /** Notifies the host after tenant credentials change so caches can be dropped. */\n onCredentialsChanged?: (tenant: { orgId: string; userId?: string }) => void;\n /** Notifies the host after custom providers change so model-router caches can be dropped. */\n onCustomProvidersChanged?: (tenant: { orgId: string }) => void;\n /**\n * Tenant mode: providers the operator opted in to run on the server process's\n * own credentials (see `DEPLOYMENT_MODEL_PROVIDERS`).\n */\n deploymentProviders?: ReadonlySet<string>;\n}\n\n/**\n * The web config routes as Mastra `apiRoutes`:\n * - `GET /web/config/features` — list server-enabled product features\n * - `GET /web/config/providers` — list providers + key source\n * - `PUT /web/config/providers/:provider/key` — set/update a provider's API key\n * - `DELETE /web/config/providers/:provider/key` — remove a stored API key\n * - `GET /web/config/models` — list available models (credentialed providers)\n * - `GET /web/config/custom-providers` — list custom OpenAI-compatible providers\n * - `POST /web/config/custom-providers` — create/update a custom provider\n * - `DELETE /web/config/custom-providers/:id` — remove a custom provider\n * - `GET /web/config/om` — read OM models/thresholds/observe-attachments\n * - `PUT /web/config/om/:role/model` — switch observer/reflector model\n * - `PUT /web/config/om/thresholds` — set observation/reflection thresholds\n * - `PUT /web/config/om/observe-attachments` — set observe-attachments (auto/on/off)\n */\nexport class ConfigRoutes extends Route<ConfigRoutesDeps> {\n routes(): ApiRoute[] {\n const options = this.deps;\n const { controller, authStorage, auth, deploymentProviders } = options;\n const onCredentialsChanged = options.onCredentialsChanged ?? (() => {});\n const onCustomProvidersChanged = options.onCustomProvidersChanged ?? (() => {});\n\n const resolveOMResponseContext = async (c: Context) => {\n const tenantCredentials = await listTenantCredentialsForRequest({\n c: loose(c),\n auth,\n credentials: options.modelCredentials,\n });\n const access = await buildProviderAccess({\n controller,\n authStorage: tenantCredentials ? undefined : authStorage,\n tenantCredentials,\n deploymentProviders,\n });\n const availableProviders = new Set(\n Object.entries(access).flatMap(([providerId, configured]) => (configured ? [providerId] : [])),\n );\n // `mastra/` routes run through the Mastra gateway whenever its key is configured.\n if (MastraCodeGateway.getMastraGatewayApiKey()) availableProviders.add(MASTRA_GATEWAY_PROVIDER);\n if (options.customProviders) {\n const context = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if (!('response' in context)) {\n for (const provider of await context.storage.list({ orgId: context.orgId })) {\n availableProviders.add(provider.providerId);\n }\n }\n }\n return availableProviders;\n };\n\n // Without a live session, Auto previews against the factory default model\n // (resolved with this account's providers in readStoredOMConfig) — not the\n // global built-in default, whose provider may have no credential here.\n const factoryOmFallback = async (factoryProjectId: string | undefined): Promise<string | undefined> => {\n try {\n return factoryProjectId\n ? await options.factoryProjects\n ?.getById({ id: factoryProjectId })\n .then(project => project?.defaultModelId ?? undefined)\n : controller.listModes?.().find(mode => mode.defaultModelId)?.defaultModelId;\n } catch {\n return undefined;\n }\n };\n\n return [\n registerApiRoute('/web/config/features', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => c.json({ knowledge: options.features?.knowledge ?? false }),\n }),\n\n registerApiRoute('/web/config/providers', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n try {\n // Tenant mode lists the caller's rows and never exposes the\n // server-global auth.json; local mode is unchanged.\n const tenantCredentials = await listTenantCredentialsForRequest({\n c: loose(c),\n auth,\n credentials: options.modelCredentials,\n });\n // Tenant mode also reports whether the caller may write org-wide\n // keys, so the settings UI can gate the \"Everyone in org\" option.\n const tenant = auth.tenant(loose(c));\n const orgKeyAdmin = tenant ? await auth.isOrganizationAdmin(loose(c), tenantOrgId(tenant)) : undefined;\n return c.json({\n providers: await listProviders({\n controller,\n authStorage: tenantCredentials ? undefined : authStorage,\n tenantCredentials,\n deploymentProviders,\n }),\n ...(orgKeyAdmin !== undefined ? { orgKeyAdmin } : {}),\n });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/providers/:provider/key', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCredentialContext({ c: loose(c), auth, credentials: options.modelCredentials });\n if ('response' in ctx) return ctx.response;\n\n const provider = c.req.param('provider');\n let body: { key?: unknown; envVar?: unknown; scope?: unknown };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const key = typeof body.key === 'string' ? body.key.trim() : '';\n if (!key) return c.json({ error: 'Missing required field: key' }, 400);\n const envVar = typeof body.envVar === 'string' ? body.envVar : undefined;\n const scope = body.scope === 'org' ? 'org' : 'user';\n try {\n if (ctx.mode === 'tenant') {\n // A stored key would never be read: these providers authenticate\n // with the server process's credentials only.\n if (isDeploymentModelProvider(provider)) {\n return c.json(\n {\n error: 'provider_configured_by_deployment',\n message: `${provider} is configured by the Factory deployment (credentials on the server), not per account.`,\n },\n 400,\n );\n }\n if (scope === 'org' && !(await auth.isOrganizationAdmin(loose(c), ctx.orgId))) {\n return c.json({ error: 'organization_admin_required' }, 403);\n }\n const tenant = scope === 'org' ? { orgId: ctx.orgId } : { orgId: ctx.orgId, userId: ctx.userId };\n // envVar is intentionally ignored: tenant credentials are resolved\n // per-request, never written into process.env.\n await ctx.storage.setCredential(tenant, getAuthProviderId(provider), { type: 'api_key', key });\n onCredentialsChanged(tenant);\n const records = await ctx.storage.listCredentials(ctx.orgId, ctx.userId);\n const providers = await listProviders({ controller, tenantCredentials: records, deploymentProviders });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n }\n if (!authStorage) return c.json({ error: 'Credential storage is not available' }, 503);\n // Local mode is single-user: scope is meaningless and ignored.\n authStorage.setStoredApiKey(provider, key, envVar);\n const providers = await listProviders({ controller, authStorage });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/providers/:provider/key', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCredentialContext({ c: loose(c), auth, credentials: options.modelCredentials });\n if ('response' in ctx) return ctx.response;\n\n const provider = c.req.param('provider');\n const scope = c.req.query('scope') === 'org' ? 'org' : 'user';\n try {\n if (ctx.mode === 'tenant') {\n if (scope === 'org' && !(await auth.isOrganizationAdmin(loose(c), ctx.orgId))) {\n return c.json({ error: 'organization_admin_required' }, 403);\n }\n const tenant = scope === 'org' ? { orgId: ctx.orgId } : { orgId: ctx.orgId, userId: ctx.userId };\n await ctx.storage.removeCredential(tenant, getAuthProviderId(provider));\n onCredentialsChanged(tenant);\n const records = await ctx.storage.listCredentials(ctx.orgId, ctx.userId);\n const providers = await listProviders({ controller, tenantCredentials: records, deploymentProviders });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n }\n if (!authStorage) return c.json({ error: 'Credential storage is not available' }, 503);\n authStorage.remove(`apikey:${provider}`);\n const providers = await listProviders({ controller, authStorage });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n // Mirrors the TUI's /custom-providers command, but backed by the\n // `custom-providers` domain (org rows in tenant mode, a sentinel `local`\n // org in no-auth mode) — the server never reads settings.json for these.\n\n registerApiRoute('/web/config/custom-providers', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if ('response' in ctx) return ctx.response;\n try {\n const records = await ctx.storage.list({ orgId: ctx.orgId });\n return c.json({ providers: records.map(toCustomProviderInfo) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/custom-providers', {\n method: 'POST',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if ('response' in ctx) return ctx.response;\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const parsed = parseCustomProviderBody(body);\n if ('error' in parsed) return c.json({ error: parsed.error }, 400);\n // `previousId` lets a rename remove the old entry as well as any name clash.\n const previousId =\n body && typeof body === 'object' && typeof (body as Record<string, unknown>).previousId === 'string'\n ? ((body as Record<string, unknown>).previousId as string)\n : undefined;\n try {\n const record = await ctx.storage.upsert({\n orgId: ctx.orgId,\n userId: ctx.userId,\n input: {\n providerId: getCustomProviderId(parsed.name),\n name: parsed.name,\n url: parsed.url,\n apiKey: parsed.apiKey,\n models: parsed.models,\n },\n previousProviderId: previousId,\n });\n onCustomProvidersChanged({ orgId: ctx.orgId });\n return c.json({ ok: true, provider: toCustomProviderInfo(record) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/custom-providers/:id', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if ('response' in ctx) return ctx.response;\n const id = c.req.param('id');\n try {\n await ctx.storage.delete({ orgId: ctx.orgId, providerId: id });\n onCustomProvidersChanged({ orgId: ctx.orgId });\n return c.json({ ok: true });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n // Session-independent model catalog for settings pickers (Factory default\n // model, pack editors). Only models whose provider has a credential are\n // returned — the same filter the session-scoped hook applies client-side.\n\n registerApiRoute('/web/config/models', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n try {\n const allTenantCredentials = await listTenantCredentialsForRequest({\n c: loose(c),\n auth,\n credentials: options.modelCredentials,\n });\n const factoryProjectId = c.req.query('factoryId') || undefined;\n const tenant = auth.tenant(c);\n let tenantCredentials = allTenantCredentials;\n let sessionPolicy: { modelScope: 'factory' | 'user'; defaultModelId: string | null } | undefined;\n const resourceId = c.req.query('resourceId');\n const threadId = c.req.query('threadId');\n if (resourceId !== undefined || threadId !== undefined) {\n const address = z\n .object({ resourceId: z.string().trim().min(1), threadId: z.string().trim().min(1) })\n .safeParse({ resourceId, threadId });\n if (!address.success) return c.json({ error: 'invalid_session_context' }, 400);\n if (!tenant && auth.enabled()) return c.json({ error: 'unauthorized' }, 401);\n if (tenant) {\n if (\n !options.factoryProjects ||\n !options.sourceControlSessions ||\n !options.workItems ||\n !options.modelCredentials\n )\n return c.json({ error: 'session_model_policy_unavailable' }, 503);\n const requestContext = new RequestContext();\n requestContext.set('user', { id: tenant.userId, organizationId: tenantOrgId(tenant) });\n requestContext.set('controller', address.data);\n let policy;\n try {\n policy = await resolveFactoryModelPolicy(requestContext, {\n projects: options.factoryProjects,\n sourceControl: options.sourceControlSessions,\n workItems: options.workItems,\n });\n } catch {\n return c.json({ error: 'session_model_policy_unavailable' }, 403);\n }\n if (!policy) return c.json({ error: 'unauthorized' }, 401);\n const orgId = policy.tenant.orgId ?? tenantOrgId(tenant);\n const modelScope = policy.tenant.credentialScope ?? 'user';\n const storageScope = modelScope === 'factory' ? 'org' : 'user';\n tenantCredentials = (\n await options.modelCredentials.listCredentials(orgId, policy.tenant.userId)\n ).filter(record => record.scope === storageScope);\n let defaultModelId = policy.factoryDefaultModelId ?? null;\n if (modelScope === 'user') {\n if (!options.modelDefaults) return c.json({ error: 'model_defaults_unavailable' }, 503);\n await options.modelDefaults.ensureReady();\n defaultModelId =\n (await options.modelDefaults.get({ orgId, userId: policy.tenant.userId }))?.modelId ?? null;\n }\n sessionPolicy = { modelScope, defaultModelId };\n }\n } else if (c.req.query('scope') !== undefined) {\n // Explicit settings scopes never override a live thread's owner and policy above.\n const scope = z.enum(['org', 'user']).safeParse(c.req.query('scope'));\n if (!scope.success) return c.json({ error: 'invalid_model_scope' }, 400);\n tenantCredentials = allTenantCredentials?.filter(record => record.scope === scope.data);\n } else if (allTenantCredentials && factoryProjectId && tenant) {\n if (!options.factoryProjects) return c.json({ error: 'factory_unavailable' }, 503);\n await options.factoryProjects.ensureReady();\n const project = await options.factoryProjects.get({ orgId: tenantOrgId(tenant), id: factoryProjectId });\n if (!project) return c.json({ error: 'factory_project_not_found' }, 404);\n const credentialScope = project.modelScope === 'user' ? 'user' : 'org';\n tenantCredentials = allTenantCredentials.filter(record => record.scope === credentialScope);\n }\n const [models, access] = await Promise.all([\n controller.listAvailableModels(),\n buildProviderAccess({\n controller,\n authStorage: tenantCredentials ? undefined : authStorage,\n tenantCredentials,\n deploymentProviders,\n }),\n ]);\n const catalog = models.flatMap(({ id, provider, modelName }) =>\n typeof id === 'string' && canUseModelProvider(access, provider)\n ? [{ id, provider, modelName, hasApiKey: true, reasoningOptions: getModelReasoningOptions(id) }]\n : [],\n );\n // Append the caller's custom provider models (DB-backed, org rows in\n // tenant mode / sentinel `local` org in no-auth mode). The boot-time\n // gateway catalog only carries the local list, so tenant callers get\n // theirs here. Dedupe against ids already present.\n if (options.customProviders) {\n try {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if (!('response' in ctx)) {\n const known = new Set(catalog.map(m => m.id));\n for (const record of await ctx.storage.list({ orgId: ctx.orgId })) {\n for (const model of record.models) {\n const id = `${record.providerId}/${model}`;\n if (known.has(id)) continue;\n known.add(id);\n catalog.push({\n id,\n provider: record.providerId,\n modelName: model,\n hasApiKey: true,\n reasoningOptions: undefined,\n });\n }\n }\n }\n } catch {\n // Fail soft: the catalog still serves the built-in models.\n }\n }\n return c.json({\n ...sessionPolicy,\n models: catalog.sort((a, b) =>\n a.provider === b.provider ? a.id.localeCompare(b.id) : a.provider.localeCompare(b.provider),\n ),\n });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/default-model', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n try {\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n return c.json({ modelId: record?.modelId ?? null });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/default-model', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const parsed = z.object({ modelId: z.string().trim().min(1).max(256) }).safeParse(body);\n if (!parsed.success) return c.json({ error: 'Missing required field: modelId' }, 400);\n const { modelId } = parsed.data;\n try {\n await context.storage.set({ orgId: context.orgId, userId: context.userId, modelId });\n return c.json({ ok: true, modelId });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/default-model', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n try {\n await context.storage.clear({ orgId: context.orgId, userId: context.userId });\n return c.json({ ok: true, modelId: null });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n // Mirrors the TUI's /om command. All five knobs are durably stored in the\n // per-(org, user) `memory-settings` app table — never settings.json or\n // mutable session state.\n\n registerApiRoute('/web/config/om', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const resourceId = c.req.query('resourceId');\n const scope = c.req.query('scope') || undefined;\n const factoryProjectId = c.req.query('factoryId') || undefined;\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n try {\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const fallback = await factoryOmFallback(factoryProjectId);\n const availableProviders = await resolveOMResponseContext(loose(c));\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n return c.json({\n config: readStoredOMConfig(\n record,\n sessionModelId || fallback,\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n ),\n });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/om/:role/model', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const role = c.req.param('role');\n if (role !== 'observer' && role !== 'reflector') {\n return c.json({ error: `Unknown OM role \"${role}\"` }, 400);\n }\n let body: { resourceId?: unknown; modelId?: unknown; scope?: unknown; factoryId?: unknown };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const resourceId = typeof body.resourceId === 'string' ? body.resourceId : '';\n const scope = typeof body.scope === 'string' && body.scope ? body.scope : undefined;\n const factoryProjectId = typeof body.factoryId === 'string' && body.factoryId ? body.factoryId : undefined;\n const model = typeof body.modelId === 'string' ? body.modelId.trim() : '';\n if (!model) {\n return c.json({ error: 'Missing required field: modelId' }, 400);\n }\n // `'auto'` is selection intent, not a model ID: store null so the role\n // follows the active main model instead of pinning a model named \"auto\".\n const wantsAuto = model === 'auto';\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n // Resolve the response context before persisting: a provider-enumeration\n // failure must not report 500 for a write that already succeeded.\n const availableProviders = await resolveOMResponseContext(loose(c));\n try {\n await persistMemorySettings(context, {\n [role === 'observer' ? 'observerModelId' : 'reflectorModelId']: wantsAuto ? null : model,\n });\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n const config = readStoredOMConfig(\n record,\n sessionModelId || (await factoryOmFallback(factoryProjectId)),\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n );\n return c.json({ ok: true, config });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/om/thresholds', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n let body: {\n resourceId?: unknown;\n observationThreshold?: unknown;\n reflectionThreshold?: unknown;\n scope?: unknown;\n factoryId?: unknown;\n };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const resourceId = typeof body.resourceId === 'string' ? body.resourceId : '';\n const scope = typeof body.scope === 'string' && body.scope ? body.scope : undefined;\n const factoryProjectId = typeof body.factoryId === 'string' && body.factoryId ? body.factoryId : undefined;\n const observation =\n typeof body.observationThreshold === 'number' && body.observationThreshold > 0\n ? Math.round(body.observationThreshold)\n : undefined;\n const reflection =\n typeof body.reflectionThreshold === 'number' && body.reflectionThreshold > 0\n ? Math.round(body.reflectionThreshold)\n : undefined;\n if (observation === undefined && reflection === undefined) {\n return c.json({ error: 'Provide observationThreshold and/or reflectionThreshold (positive numbers)' }, 400);\n }\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n const availableProviders = await resolveOMResponseContext(loose(c));\n try {\n await persistMemorySettings(context, {\n ...(observation !== undefined ? { observationThreshold: observation } : {}),\n ...(reflection !== undefined ? { reflectionThreshold: reflection } : {}),\n });\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n const config = readStoredOMConfig(\n record,\n sessionModelId || (await factoryOmFallback(factoryProjectId)),\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n );\n return c.json({ ok: true, config });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/om/observe-attachments', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n let body: { resourceId?: unknown; value?: unknown; scope?: unknown; factoryId?: unknown };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const resourceId = typeof body.resourceId === 'string' ? body.resourceId : '';\n const scope = typeof body.scope === 'string' && body.scope ? body.scope : undefined;\n const factoryProjectId = typeof body.factoryId === 'string' && body.factoryId ? body.factoryId : undefined;\n const raw = body.value;\n const value: 'auto' | boolean = raw === 'auto' || raw === true || raw === false ? raw : 'auto';\n if (raw !== 'auto' && raw !== true && raw !== false) {\n return c.json({ error: \"value must be 'auto', true, or false\" }, 400);\n }\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n const availableProviders = await resolveOMResponseContext(loose(c));\n try {\n await persistMemorySettings(context, { observeAttachments: value });\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n const config = readStoredOMConfig(\n record,\n sessionModelId || (await factoryOmFallback(factoryProjectId)),\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n );\n return c.json({ ok: true, config });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n ];\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config.js","names":[],"sources":["../../src/routes/config.ts"],"sourcesContent":["import { MastraCodeGateway } from '@mastra/code-sdk/agents/mastracode-gateway';\nimport type { AuthStorage } from '@mastra/code-sdk/auth/storage';\nimport { resolveAutoOMModelId } from '@mastra/code-sdk/onboarding/packs';\nimport type { ProviderAccess, ProviderAccessLevel } from '@mastra/code-sdk/onboarding/packs';\nimport { getCustomProviderId, MASTRA_GATEWAY_PROVIDER } from '@mastra/code-sdk/onboarding/settings';\nimport type { CustomProviderSetting } from '@mastra/code-sdk/onboarding/settings';\nimport { AMAZON_BEDROCK_GATEWAY_ID } from '@mastra/code-sdk/providers/amazon-bedrock-gateway';\nimport { MASTRA_GATEWAY_PREFIX } from '@mastra/code-sdk/providers/model-ids';\nimport { getModelReasoningOptions } from '@mastra/core/llm';\nimport { RequestContext } from '@mastra/core/request-context';\nimport type { ApiRoute } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\n\nimport type { Context } from 'hono';\nimport { z } from 'zod';\nimport { resolveFactoryModelPolicy } from '../session/credential-policy.js';\nimport { DEFAULT_OBSERVATION_THRESHOLD, DEFAULT_REFLECTION_THRESHOLD } from '../session/memory-settings-hydration.js';\nimport type {\n CredentialRecord,\n LoginSessionKind,\n ModelCredentialsStorage,\n} from '../storage/domains/credentials/base.js';\nimport type { CustomProviderRecord, CustomProvidersStorage } from '../storage/domains/custom-providers/base.js';\nimport { factoryMemorySettingsUserId } from '../storage/domains/memory-settings/base.js';\nimport type {\n MemorySettingsPatch,\n MemorySettingsRecord,\n MemorySettingsStorage,\n} from '../storage/domains/memory-settings/base.js';\nimport type { ModelDefaultsStorage } from '../storage/domains/model-defaults/base.js';\nimport type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';\nimport type { SourceControlStorageHandle } from '../storage/domains/source-control/base.js';\nimport type { WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport {\n getAuthProviderId,\n listTenantCredentialsForRequest,\n resolveCredentialContext,\n tenantOrgId,\n WEB_OAUTH_PROVIDERS,\n} from './provider-credentials.js';\nimport { Route } from './route.js';\nimport type { RouteAuth, RouteDependencies } from './route.js';\n\n/** Widen a route-local Hono context to the plain `Context` the auth helpers take. */\nfunction loose(c: unknown): Context {\n return c as Context;\n}\n\n/**\n * Server-side configuration routes for the web app.\n *\n * The browser has no access to the credential store or the model catalog, so\n * the web settings panel asks the server — which owns both — to list providers\n * and manage API keys. This mirrors the TUI's `/api-keys` command, exposing the\n * same `AuthStorage`-backed key management over HTTP.\n *\n * Keys are never returned to the client; only their presence and source.\n */\n\n/**\n * Where a provider's active credential comes from, as seen by the caller.\n * Local mode reports `oauth`/`stored` (server-global `auth.json`); tenant mode\n * reports the scoped variants (`oauth-user`/`stored-user`/`stored-org`).\n * `deployment` (tenant mode) marks a provider the operator opted in to run on\n * the server process's own credentials (e.g. Amazon Bedrock's AWS chain).\n */\nexport type ProviderCredentialSource =\n | 'deployment'\n | 'oauth'\n | 'stored'\n | 'env'\n | 'none'\n | 'oauth-user'\n | 'oauth-org'\n | 'stored-user'\n | 'stored-org';\n\n/** A model provider with the current source of its credentials. */\nexport interface ProviderInfo {\n provider: string;\n /** Env var the provider's key is read from, if any. */\n envVar?: string;\n /** Where the active credential comes from. */\n source: ProviderCredentialSource;\n /**\n * Tenant mode: whether an org-wide API key exists for this provider, even\n * when the caller's personal credential shadows it. Lets the UI tell\n * \"shared with the org\" apart from \"only works for me\".\n */\n orgKey?: boolean;\n /**\n * Tenant mode: the caller's personal credential for this provider, if any.\n * Reported independently of `source` so the UI can manage each scope even\n * when one shadows the other.\n */\n userCredential?: 'oauth' | 'api_key';\n /** Tenant mode: the shared org credential for this provider, if any. */\n orgCredential?: 'oauth' | 'api_key';\n /** Web OAuth sign-in capability, when the provider supports it. */\n oauth?: { supported: true; modes: LoginSessionKind[] };\n}\n\n/** Minimal session surface the config routes touch. */\nexport interface OMSession {\n /** `get()` returns '' when no model is selected, so callers fall back on falsy. */\n model: { get: () => string };\n}\n\n/** Minimal controller surface this module needs (model catalog + modes + sessions). */\ninterface ModelCatalog {\n listAvailableModels: () => Promise<\n Array<{ id?: string; modelName?: string; provider: string; hasApiKey: boolean; apiKeyEnvVar?: string }>\n >;\n listModes?: () => Array<{ id: string; defaultModelId?: string }>;\n getSessionByResource?: (resourceId: string, scope?: string) => Promise<OMSession | undefined>;\n}\n\n/**\n * Build a deduplicated, sorted list of providers from the model catalog,\n * annotated with where each provider's credential currently comes from.\n * Mirrors the TUI's `/api-keys` provider list.\n *\n * When `tenantCredentials` is given (deployed mode), sources reflect the\n * *caller's* tenant rows with user > org precedence and the server-global\n * `authStorage` is ignored; otherwise the local `auth.json` view is reported.\n */\nexport async function listProviders({\n controller,\n authStorage,\n tenantCredentials,\n deploymentProviders,\n}: {\n controller: ModelCatalog;\n authStorage?: AuthStorage;\n tenantCredentials?: CredentialRecord[];\n deploymentProviders?: ReadonlySet<string>;\n}): Promise<ProviderInfo[]> {\n const models = await controller.listAvailableModels();\n const seen = new Map<string, ProviderInfo>();\n\n for (const model of models) {\n if (seen.has(model.provider)) continue;\n\n if (tenantCredentials && isDeploymentModelProvider(model.provider)) {\n // Credentials for these providers live on the server process, never in\n // tenant rows, so no account can connect them. List them only when the\n // operator opted the deployment in and the server has credentials.\n const usable =\n deploymentProviders?.has(model.provider) && models.some(m => m.provider === model.provider && m.hasApiKey);\n if (usable) seen.set(model.provider, { provider: model.provider, source: 'deployment' });\n continue;\n }\n\n const authProviderId = getAuthProviderId(model.provider);\n let source: ProviderInfo['source'] = 'none';\n let orgKey: boolean | undefined;\n let userCredential: ProviderInfo['userCredential'];\n let orgCredential: ProviderInfo['orgCredential'];\n if (tenantCredentials) {\n const userRec = tenantCredentials.find(r => r.scope === 'user' && r.provider === authProviderId);\n const orgRec = tenantCredentials.find(r => r.scope === 'org' && r.provider === authProviderId);\n // Any shared org credential (API key or org-wide OAuth) counts.\n orgKey = orgRec !== undefined;\n userCredential = userRec?.credential.type;\n orgCredential = orgRec?.credential.type;\n if (userRec?.credential.type === 'oauth') {\n source = 'oauth-user';\n } else if (userRec?.credential.type === 'api_key') {\n source = 'stored-user';\n } else if (orgRec?.credential.type === 'oauth') {\n source = 'oauth-org';\n } else if (orgRec?.credential.type === 'api_key') {\n source = 'stored-org';\n }\n } else if (authStorage?.isLoggedIn(authProviderId)) {\n source = 'oauth';\n } else if (authStorage?.hasStoredApiKey(model.provider)) {\n source = 'stored';\n } else if (model.apiKeyEnvVar && process.env[model.apiKeyEnvVar]) {\n source = 'env';\n } else if (model.hasApiKey) {\n source = 'env';\n }\n\n const flowKind = WEB_OAUTH_PROVIDERS[model.provider]?.flow;\n seen.set(model.provider, {\n provider: model.provider,\n envVar: model.apiKeyEnvVar,\n source,\n ...(orgKey !== undefined ? { orgKey } : {}),\n ...(userCredential ? { userCredential } : {}),\n ...(orgCredential ? { orgCredential } : {}),\n ...(flowKind ? { oauth: { supported: true as const, modes: [flowKind] } } : {}),\n });\n }\n\n return Array.from(seen.values()).sort((a, b) => a.provider.localeCompare(b.provider));\n}\n\n/** A user-defined OpenAI-compatible provider, with key presence (never the key). */\nexport interface CustomProviderInfo {\n id: string;\n name: string;\n url: string;\n hasApiKey: boolean;\n models: string[];\n}\n\n/** Redact a stored custom-provider row for the client (key presence only). */\nfunction toCustomProviderInfo(record: CustomProviderRecord): CustomProviderInfo {\n return {\n id: record.providerId,\n name: record.name,\n url: record.url,\n hasApiKey: Boolean(record.apiKey),\n models: record.models,\n };\n}\n\n/** The resolved custom-providers storage scope for a request. */\ninterface CustomProvidersContext {\n storage: CustomProvidersStorage;\n orgId: string;\n userId: string;\n}\n\n/**\n * Resolve the custom-providers context for a request, or a ready-to-return\n * error response. Same posture as memory settings: tenant rows in deployed\n * mode, a sentinel `local` org in no-auth mode — never settings.json.\n */\nasync function resolveCustomProvidersContext({\n c,\n auth,\n customProviders,\n}: {\n c: Context;\n auth: RouteAuth;\n customProviders?: CustomProvidersStorage;\n}): Promise<CustomProvidersContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant && auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n if (customProviders) {\n try {\n await customProviders.ensureReady();\n return tenant\n ? { storage: customProviders, orgId: tenantOrgId(tenant), userId: tenant.userId }\n : { storage: customProviders, orgId: 'local', userId: 'local' };\n } catch {\n // fall through to the unavailable response\n }\n }\n return {\n response: c.json(\n {\n error: 'custom_providers_unavailable',\n message: 'Custom provider storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n}\n\n/** Validate + coerce a request body into a CustomProviderSetting. */\nfunction parseCustomProviderBody(body: unknown): CustomProviderSetting | { error: string } {\n if (!body || typeof body !== 'object') return { error: 'Invalid JSON body' };\n const b = body as Record<string, unknown>;\n const name = typeof b.name === 'string' ? b.name.trim() : '';\n if (!name) return { error: 'Missing required field: name' };\n const url = typeof b.url === 'string' ? b.url.trim() : '';\n if (!url) return { error: 'Missing required field: url' };\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return { error: 'url must be an http(s) URL' };\n }\n } catch {\n return { error: 'url must be a valid URL' };\n }\n const apiKey = typeof b.apiKey === 'string' && b.apiKey.trim() ? b.apiKey.trim() : undefined;\n const models = Array.isArray(b.models)\n ? b.models.filter((m): m is string => typeof m === 'string' && m.trim().length > 0).map(m => m.trim())\n : [];\n return { name, url, apiKey, models };\n}\n\n/**\n * Providers whose credentials can only come from the server process (Amazon\n * Bedrock authenticates through the AWS credential chain). In tenant mode they\n * are usable only when the operator lists them in\n * `MastraFactoryConfig.deploymentModelProviders`.\n */\nexport const DEPLOYMENT_MODEL_PROVIDERS: readonly string[] = [AMAZON_BEDROCK_GATEWAY_ID];\n\nexport function isDeploymentModelProvider(provider: string): boolean {\n return DEPLOYMENT_MODEL_PROVIDERS.includes(provider);\n}\n\n/**\n * Normalize the operator's `deploymentModelProviders` list. Unsupported ids are\n * ignored with a warning rather than failing boot.\n */\nexport function resolveDeploymentModelProviders(providers: readonly string[] | undefined): ReadonlySet<string> {\n const resolved = new Set<string>();\n for (const raw of providers ?? []) {\n const provider = raw.trim();\n if (!provider) continue;\n if (isDeploymentModelProvider(provider)) {\n resolved.add(provider);\n } else {\n console.warn(\n `[factory] Ignoring deployment model provider \"${provider}\". Supported: ${DEPLOYMENT_MODEL_PROVIDERS.join(', ')}.`,\n );\n }\n }\n return resolved;\n}\n\n/**\n * Compute which providers the user can reach, mirroring the TUI's\n * `/models-pack` access derivation: OAuth/api-key from the credential store for\n * the named providers, plus any other provider that has a usable key.\n */\nexport async function buildProviderAccess({\n controller,\n authStorage,\n tenantCredentials,\n deploymentProviders,\n}: {\n controller: ModelCatalog;\n authStorage?: AuthStorage;\n tenantCredentials?: CredentialRecord[];\n deploymentProviders?: ReadonlySet<string>;\n}): Promise<ProviderAccess> {\n const models = await controller.listAvailableModels();\n const hasModelKey = (provider: string) => models.some(m => m.provider === provider && m.hasApiKey);\n const accessLevel = (provider: string): ProviderAccessLevel => {\n const authProviderId = getAuthProviderId(provider);\n if (tenantCredentials) {\n // Tenant rows never authenticate these providers; only an operator\n // opt-in plus credentials on the server process does.\n if (isDeploymentModelProvider(provider)) {\n return deploymentProviders?.has(provider) && hasModelKey(provider) ? 'apikey' : false;\n }\n const userRec = tenantCredentials.find(r => r.scope === 'user' && r.provider === authProviderId);\n const orgRec = tenantCredentials.find(r => r.scope === 'org' && r.provider === authProviderId);\n const credential = userRec?.credential ?? orgRec?.credential;\n if (credential?.type === 'oauth') return 'oauth';\n if (credential?.type === 'api_key' && credential.key.trim().length > 0) return 'apikey';\n return false;\n }\n\n const oauthCredential = authStorage?.get(authProviderId);\n if (oauthCredential?.type === 'oauth') return 'oauth';\n if (authStorage?.hasStoredApiKey(provider)) return 'apikey';\n const directCredential = authStorage?.get(provider);\n if (directCredential?.type === 'api_key' && directCredential.key.trim().length > 0) return 'apikey';\n return hasModelKey(provider) ? 'apikey' : false;\n };\n const access: ProviderAccess = {\n anthropic: accessLevel('anthropic'),\n openai: accessLevel('openai'),\n cerebras: accessLevel('cerebras'),\n google: accessLevel('google'),\n deepseek: accessLevel('deepseek'),\n 'github-copilot': accessLevel('github-copilot'),\n };\n const seen = new Set(Object.keys(access));\n for (const m of models) {\n if (!seen.has(m.provider)) {\n access[m.provider] = accessLevel(m.provider);\n seen.add(m.provider);\n }\n }\n return access;\n}\n\nfunction canUseModelProvider(access: ProviderAccess, provider: string): boolean {\n return Boolean(access[provider]);\n}\n\n/** Per-user default model context for the current request. */\nexport interface ModelDefaultsContext {\n storage: ModelDefaultsStorage;\n orgId: string;\n userId: string;\n}\n\n/** Resolve the default-model context for a request, or a ready-to-return error response. */\nasync function resolveModelDefaultsContext({\n c,\n auth,\n modelDefaults,\n}: {\n c: Context;\n auth: RouteAuth;\n modelDefaults?: ModelDefaultsStorage;\n}): Promise<ModelDefaultsContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant && auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n if (modelDefaults) {\n try {\n await modelDefaults.ensureReady();\n return tenant\n ? { storage: modelDefaults, orgId: tenantOrgId(tenant), userId: tenant.userId }\n : { storage: modelDefaults, orgId: 'local', userId: 'local' };\n } catch {\n // fall through to the unavailable response\n }\n }\n return {\n response: c.json(\n {\n error: 'model_defaults_unavailable',\n message: 'Default model storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n}\n\n// Mirrors the TUI `/om` command. Settings are persisted per organization and\n// user in the Factory app database, then loaded into request context for each\n// invocation without copying them into mutable session state.\n\nexport interface OMRoleConfigInfo {\n model: 'auto' | string;\n effectiveModelId: string;\n effectiveModelSource: 'explicit' | 'live-session' | 'configured-default';\n providerStatus: 'available' | 'unavailable';\n}\n\n/** Persisted intent plus the concrete models the current Factory configuration resolves. */\nexport interface OMConfigInfo {\n observer: OMRoleConfigInfo;\n reflector: OMRoleConfigInfo;\n /** @deprecated Use `observer.effectiveModelId`. */\n observerModelId: string;\n /** @deprecated Use `reflector.effectiveModelId`. */\n reflectorModelId: string;\n observationThreshold: number;\n reflectionThreshold: number;\n observeAttachments: 'auto' | boolean;\n}\n\nexport interface ProviderOMDefaultsResponse {\n ok: true;\n config: OMConfigInfo;\n}\n\nfunction modelProvider(modelId: string): string {\n // Effective IDs keep their `mastra/` route; the provider segment after it is what\n // the SDK resolver falls back to when the gateway is not configured.\n const normalized = modelId.replace(/^mastracode\\//, '').replace(/^mastra\\//, '');\n return normalized.split('/', 1)[0] ?? '';\n}\n\nfunction roleConfig(\n model: OMRoleConfigInfo['model'],\n effectiveModelId: string,\n autoModelSource: 'live-session' | 'configured-default',\n availableProviders: ReadonlySet<string>,\n): OMRoleConfigInfo {\n return {\n model,\n effectiveModelId,\n effectiveModelSource: model === 'auto' ? autoModelSource : 'explicit',\n providerStatus:\n availableProviders.has(modelProvider(effectiveModelId)) ||\n (effectiveModelId.startsWith(MASTRA_GATEWAY_PREFIX) && availableProviders.has(MASTRA_GATEWAY_PROVIDER))\n ? 'available'\n : 'unavailable',\n };\n}\n\nfunction readStoredOMConfig(\n record: MemorySettingsRecord | null,\n currentModelId: string | undefined,\n autoModelSource: 'live-session' | 'configured-default',\n availableProviders: ReadonlySet<string>,\n): OMConfigInfo {\n const autoModelId = resolveAutoOMModelId(currentModelId, providerId => availableProviders.has(providerId));\n const observerModelId = record?.observerModelId ?? autoModelId;\n const reflectorModelId = record?.reflectorModelId ?? autoModelId;\n return {\n observer: roleConfig(record?.observerModelId ?? 'auto', observerModelId, autoModelSource, availableProviders),\n reflector: roleConfig(record?.reflectorModelId ?? 'auto', reflectorModelId, autoModelSource, availableProviders),\n observerModelId,\n reflectorModelId,\n observationThreshold: record?.observationThreshold ?? DEFAULT_OBSERVATION_THRESHOLD,\n reflectionThreshold: record?.reflectionThreshold ?? DEFAULT_REFLECTION_THRESHOLD,\n observeAttachments: record?.observeAttachments ?? 'auto',\n };\n}\n\n/**\n * Where a request's OM settings live: the `memory-settings` factory storage\n * domain, one row per (org, user). Without a tenant (auth disabled), settings\n * land on a sentinel `(local, local)` row in the same table — the web surface\n * never reads or writes `settings.json` for memory settings.\n */\ninterface MemorySettingsContext {\n storage: MemorySettingsStorage;\n orgId: string;\n userId: string;\n}\n\n/**\n * Resolve the memory-settings context for a request, or a ready-to-return\n * error response. When `factoryProjectId` is provided the row addressed is the\n * factory project's shared settings (a sentinel user id in the caller's org)\n * instead of the caller's personal row — this is what factory board runs and\n * channel sessions hydrate from.\n */\nasync function resolveMemorySettingsContext({\n c,\n auth,\n memorySettings,\n factoryProjectId,\n factoryProjects,\n}: {\n c: Context;\n auth: RouteAuth;\n memorySettings?: MemorySettingsStorage;\n factoryProjectId?: string;\n factoryProjects?: FactoryProjectsStorage;\n}): Promise<MemorySettingsContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant && auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n // Factory-scoped rows are shared org state: the target project must exist in\n // the caller's org before its settings row can be read or written.\n if (factoryProjectId && tenant) {\n if (!factoryProjects) return { response: c.json({ error: 'factory_unavailable' }, 503) };\n try {\n await factoryProjects.ensureReady();\n const project = await factoryProjects.get({ orgId: tenantOrgId(tenant), id: factoryProjectId });\n if (!project) return { response: c.json({ error: 'factory_project_not_found' }, 404) };\n } catch {\n return { response: c.json({ error: 'factory_unavailable' }, 503) };\n }\n }\n if (memorySettings) {\n try {\n await memorySettings.ensureReady();\n const factoryUserId = factoryProjectId ? factoryMemorySettingsUserId(factoryProjectId) : undefined;\n return tenant\n ? { storage: memorySettings, orgId: tenantOrgId(tenant), userId: factoryUserId ?? tenant.userId }\n : { storage: memorySettings, orgId: 'local', userId: factoryUserId ?? 'local' };\n } catch {\n // fall through to the unavailable response\n }\n }\n return {\n response: c.json(\n {\n error: 'memory_settings_unavailable',\n message: 'Memory settings storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n}\n\n/** Persist an OM knob change to the caller's memory-settings row. */\nasync function persistMemorySettings(context: MemorySettingsContext, patch: MemorySettingsPatch): Promise<void> {\n await context.storage.patch({ orgId: context.orgId, userId: context.userId, patch });\n}\n\n/** Dependencies injected into {@link ConfigRoutes}. */\nexport interface ConfigRoutesDeps extends RouteDependencies {\n controller: ModelCatalog;\n features?: { knowledge: boolean };\n authStorage?: AuthStorage;\n /** Tenant credential domain handle; absent in local (no-DB) mode. */\n modelCredentials?: ModelCredentialsStorage;\n /** Tenant model-defaults domain handle; absent in local (no-DB) mode. */\n modelDefaults?: ModelDefaultsStorage;\n /** Source-control sessions available to config route integrations. */\n sourceControlSessions?: Pick<SourceControlStorageHandle['sessions'], 'getBySessionId'>;\n /** Thread membership used to resolve the same model policy as an invocation. */\n workItems?: WorkItemsStorage;\n /** Tenant memory-settings domain handle; absent in local (no-DB) mode. */\n memorySettings?: MemorySettingsStorage;\n /** Factory projects domain, used to derive OM fallbacks from a factory's default model. */\n factoryProjects?: FactoryProjectsStorage;\n /** Custom-providers domain handle; absent when the app database is missing. */\n customProviders?: CustomProvidersStorage;\n /** Notifies the host after tenant credentials change so caches can be dropped. */\n onCredentialsChanged?: (tenant: { orgId: string; userId?: string }) => void;\n /** Notifies the host after custom providers change so model-router caches can be dropped. */\n onCustomProvidersChanged?: (tenant: { orgId: string }) => void;\n /**\n * Tenant mode: providers the operator opted in to run on the server process's\n * own credentials (see `DEPLOYMENT_MODEL_PROVIDERS`).\n */\n deploymentProviders?: ReadonlySet<string>;\n}\n\n/**\n * The web config routes as Mastra `apiRoutes`:\n * - `GET /web/config/features` — list server-enabled product features\n * - `GET /web/config/providers` — list providers + key source\n * - `PUT /web/config/providers/:provider/key` — set/update a provider's API key\n * - `DELETE /web/config/providers/:provider/key` — remove a stored API key\n * - `GET /web/config/models` — list available models (credentialed providers)\n * - `GET /web/config/custom-providers` — list custom OpenAI-compatible providers\n * - `POST /web/config/custom-providers` — create/update a custom provider\n * - `DELETE /web/config/custom-providers/:id` — remove a custom provider\n * - `GET /web/config/om` — read OM models/thresholds/observe-attachments\n * - `PUT /web/config/om/:role/model` — switch observer/reflector model\n * - `PUT /web/config/om/thresholds` — set observation/reflection thresholds\n * - `PUT /web/config/om/observe-attachments` — set observe-attachments (auto/on/off)\n */\nexport class ConfigRoutes extends Route<ConfigRoutesDeps> {\n routes(): ApiRoute[] {\n const options = this.deps;\n const { controller, authStorage, auth, deploymentProviders } = options;\n const onCredentialsChanged = options.onCredentialsChanged ?? (() => {});\n const onCustomProvidersChanged = options.onCustomProvidersChanged ?? (() => {});\n\n const resolveOMResponseContext = async (c: Context) => {\n const tenantCredentials = await listTenantCredentialsForRequest({\n c: loose(c),\n auth,\n credentials: options.modelCredentials,\n });\n const access = await buildProviderAccess({\n controller,\n authStorage: tenantCredentials ? undefined : authStorage,\n tenantCredentials,\n deploymentProviders,\n });\n const availableProviders = new Set(\n Object.entries(access).flatMap(([providerId, configured]) => (configured ? [providerId] : [])),\n );\n // `mastra/` routes run through the Mastra gateway whenever its key is configured.\n if (MastraCodeGateway.getMastraGatewayApiKey()) availableProviders.add(MASTRA_GATEWAY_PROVIDER);\n if (options.customProviders) {\n const context = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if (!('response' in context)) {\n for (const provider of await context.storage.list({ orgId: context.orgId })) {\n availableProviders.add(provider.providerId);\n }\n }\n }\n return availableProviders;\n };\n\n // Without a live session, Auto previews against the factory default model\n // (resolved with this account's providers in readStoredOMConfig) — not the\n // global built-in default, whose provider may have no credential here.\n const factoryOmFallback = async (factoryProjectId: string | undefined): Promise<string | undefined> => {\n try {\n return factoryProjectId\n ? await options.factoryProjects\n ?.getById({ id: factoryProjectId })\n .then(project => project?.defaultModelId ?? undefined)\n : controller.listModes?.().find(mode => mode.defaultModelId)?.defaultModelId;\n } catch {\n return undefined;\n }\n };\n\n return [\n registerApiRoute('/web/config/features', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => c.json({ knowledge: options.features?.knowledge ?? false }),\n }),\n\n registerApiRoute('/web/config/providers', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n try {\n // Tenant mode lists the caller's rows and never exposes the\n // server-global auth.json; local mode is unchanged.\n const tenantCredentials = await listTenantCredentialsForRequest({\n c: loose(c),\n auth,\n credentials: options.modelCredentials,\n });\n // Tenant mode also reports whether the caller may write org-wide\n // keys, so the settings UI can gate the \"Everyone in org\" option.\n const tenant = auth.tenant(loose(c));\n const orgKeyAdmin = tenant ? await auth.isOrganizationAdmin(loose(c), tenantOrgId(tenant)) : undefined;\n return c.json({\n providers: await listProviders({\n controller,\n authStorage: tenantCredentials ? undefined : authStorage,\n tenantCredentials,\n deploymentProviders,\n }),\n ...(orgKeyAdmin !== undefined ? { orgKeyAdmin } : {}),\n });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/providers/:provider/key', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCredentialContext({ c: loose(c), auth, credentials: options.modelCredentials });\n if ('response' in ctx) return ctx.response;\n\n const provider = c.req.param('provider');\n let body: { key?: unknown; envVar?: unknown; scope?: unknown };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const key = typeof body.key === 'string' ? body.key.trim() : '';\n if (!key) return c.json({ error: 'Missing required field: key' }, 400);\n const envVar = typeof body.envVar === 'string' ? body.envVar : undefined;\n const scope = body.scope === 'org' ? 'org' : 'user';\n try {\n if (ctx.mode === 'tenant') {\n // A stored key would never be read: these providers authenticate\n // with the server process's credentials only.\n if (isDeploymentModelProvider(provider)) {\n return c.json(\n {\n error: 'provider_configured_by_deployment',\n message: `${provider} is configured by the Factory deployment (credentials on the server), not per account.`,\n },\n 400,\n );\n }\n if (scope === 'org' && !(await auth.isOrganizationAdmin(loose(c), ctx.orgId))) {\n return c.json({ error: 'organization_admin_required' }, 403);\n }\n const tenant = scope === 'org' ? { orgId: ctx.orgId } : { orgId: ctx.orgId, userId: ctx.userId };\n // envVar is intentionally ignored: tenant credentials are resolved\n // per-request, never written into process.env.\n await ctx.storage.setCredential(tenant, getAuthProviderId(provider), { type: 'api_key', key });\n onCredentialsChanged(tenant);\n const records = await ctx.storage.listCredentials(ctx.orgId, ctx.userId);\n const providers = await listProviders({ controller, tenantCredentials: records, deploymentProviders });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n }\n if (!authStorage) return c.json({ error: 'Credential storage is not available' }, 503);\n // Local mode is single-user: scope is meaningless and ignored.\n authStorage.setStoredApiKey(provider, key, envVar);\n const providers = await listProviders({ controller, authStorage });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/providers/:provider/key', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCredentialContext({ c: loose(c), auth, credentials: options.modelCredentials });\n if ('response' in ctx) return ctx.response;\n\n const provider = c.req.param('provider');\n const scope = c.req.query('scope') === 'org' ? 'org' : 'user';\n try {\n if (ctx.mode === 'tenant') {\n if (scope === 'org' && !(await auth.isOrganizationAdmin(loose(c), ctx.orgId))) {\n return c.json({ error: 'organization_admin_required' }, 403);\n }\n const tenant = scope === 'org' ? { orgId: ctx.orgId } : { orgId: ctx.orgId, userId: ctx.userId };\n await ctx.storage.removeCredential(tenant, getAuthProviderId(provider));\n onCredentialsChanged(tenant);\n const records = await ctx.storage.listCredentials(ctx.orgId, ctx.userId);\n const providers = await listProviders({ controller, tenantCredentials: records, deploymentProviders });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n }\n if (!authStorage) return c.json({ error: 'Credential storage is not available' }, 503);\n authStorage.remove(`apikey:${provider}`);\n const providers = await listProviders({ controller, authStorage });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n // Mirrors the TUI's /custom-providers command, but backed by the\n // `custom-providers` domain (org rows in tenant mode, a sentinel `local`\n // org in no-auth mode) — the server never reads settings.json for these.\n\n registerApiRoute('/web/config/custom-providers', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if ('response' in ctx) return ctx.response;\n try {\n const records = await ctx.storage.list({ orgId: ctx.orgId });\n return c.json({ providers: records.map(toCustomProviderInfo) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/custom-providers', {\n method: 'POST',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if ('response' in ctx) return ctx.response;\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const parsed = parseCustomProviderBody(body);\n if ('error' in parsed) return c.json({ error: parsed.error }, 400);\n // `previousId` lets a rename remove the old entry as well as any name clash.\n const previousId =\n body && typeof body === 'object' && typeof (body as Record<string, unknown>).previousId === 'string'\n ? ((body as Record<string, unknown>).previousId as string)\n : undefined;\n try {\n const record = await ctx.storage.upsert({\n orgId: ctx.orgId,\n userId: ctx.userId,\n input: {\n providerId: getCustomProviderId(parsed.name),\n name: parsed.name,\n url: parsed.url,\n apiKey: parsed.apiKey,\n models: parsed.models,\n },\n previousProviderId: previousId,\n });\n onCustomProvidersChanged({ orgId: ctx.orgId });\n return c.json({ ok: true, provider: toCustomProviderInfo(record) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/custom-providers/:id', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if ('response' in ctx) return ctx.response;\n const id = c.req.param('id');\n try {\n await ctx.storage.delete({ orgId: ctx.orgId, providerId: id });\n onCustomProvidersChanged({ orgId: ctx.orgId });\n return c.json({ ok: true });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n // Session-independent model catalog for settings pickers (Factory default\n // model, pack editors). Only models whose provider has a credential are\n // returned — the same filter the session-scoped hook applies client-side.\n\n registerApiRoute('/web/config/models', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n try {\n const allTenantCredentials = await listTenantCredentialsForRequest({\n c: loose(c),\n auth,\n credentials: options.modelCredentials,\n });\n const factoryProjectId = c.req.query('factoryId') || undefined;\n const tenant = auth.tenant(c);\n let tenantCredentials = allTenantCredentials;\n let sessionPolicy: { modelScope: 'factory' | 'user'; defaultModelId: string | null } | undefined;\n const resourceId = c.req.query('resourceId');\n const threadId = c.req.query('threadId');\n if (resourceId !== undefined || threadId !== undefined) {\n const address = z\n .object({ resourceId: z.string().trim().min(1), threadId: z.string().trim().min(1) })\n .safeParse({ resourceId, threadId });\n if (!address.success) return c.json({ error: 'invalid_session_context' }, 400);\n if (!tenant && auth.enabled()) return c.json({ error: 'unauthorized' }, 401);\n if (tenant) {\n if (\n !options.factoryProjects ||\n !options.sourceControlSessions ||\n !options.workItems ||\n !options.modelCredentials\n )\n return c.json({ error: 'session_model_policy_unavailable' }, 503);\n const requestContext = new RequestContext();\n requestContext.set('user', { id: tenant.userId, organizationId: tenantOrgId(tenant) });\n requestContext.set('controller', address.data);\n let policy;\n try {\n policy = await resolveFactoryModelPolicy(requestContext, {\n projects: options.factoryProjects,\n sourceControl: options.sourceControlSessions,\n workItems: options.workItems,\n });\n } catch {\n return c.json({ error: 'session_model_policy_unavailable' }, 403);\n }\n if (!policy) return c.json({ error: 'unauthorized' }, 401);\n const orgId = policy.tenant.orgId ?? tenantOrgId(tenant);\n const modelScope = policy.tenant.credentialScope ?? 'user';\n const storageScope = modelScope === 'factory' ? 'org' : 'user';\n tenantCredentials = (\n await options.modelCredentials.listCredentials(orgId, policy.tenant.userId)\n ).filter(record => record.scope === storageScope);\n let defaultModelId = policy.factoryDefaultModelId ?? null;\n if (modelScope === 'user') {\n if (!options.modelDefaults) return c.json({ error: 'model_defaults_unavailable' }, 503);\n await options.modelDefaults.ensureReady();\n defaultModelId =\n (await options.modelDefaults.get({ orgId, userId: policy.tenant.userId }))?.modelId ?? null;\n }\n sessionPolicy = { modelScope, defaultModelId };\n }\n } else if (c.req.query('scope') !== undefined) {\n // Explicit settings scopes never override a live thread's owner and policy above.\n const scope = z.enum(['org', 'user']).safeParse(c.req.query('scope'));\n if (!scope.success) return c.json({ error: 'invalid_model_scope' }, 400);\n tenantCredentials = allTenantCredentials?.filter(record => record.scope === scope.data);\n } else if (allTenantCredentials && factoryProjectId && tenant) {\n if (!options.factoryProjects) return c.json({ error: 'factory_unavailable' }, 503);\n await options.factoryProjects.ensureReady();\n const project = await options.factoryProjects.get({ orgId: tenantOrgId(tenant), id: factoryProjectId });\n if (!project) return c.json({ error: 'factory_project_not_found' }, 404);\n const credentialScope = project.modelScope === 'user' ? 'user' : 'org';\n tenantCredentials = allTenantCredentials.filter(record => record.scope === credentialScope);\n }\n const [models, access] = await Promise.all([\n controller.listAvailableModels(),\n buildProviderAccess({\n controller,\n authStorage: tenantCredentials ? undefined : authStorage,\n tenantCredentials,\n deploymentProviders,\n }),\n ]);\n const catalog = models.flatMap(({ id, provider, modelName }) =>\n typeof id === 'string' && canUseModelProvider(access, provider)\n ? [{ id, provider, modelName, hasApiKey: true, reasoningOptions: getModelReasoningOptions(id) }]\n : [],\n );\n // Append the caller's custom provider models (DB-backed, org rows in\n // tenant mode / sentinel `local` org in no-auth mode). The boot-time\n // gateway catalog only carries the local list, so tenant callers get\n // theirs here. Dedupe against ids already present.\n if (options.customProviders) {\n try {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if (!('response' in ctx)) {\n const known = new Set(catalog.map(m => m.id));\n for (const record of await ctx.storage.list({ orgId: ctx.orgId })) {\n for (const model of record.models) {\n const id = `${record.providerId}/${model}`;\n if (known.has(id)) continue;\n known.add(id);\n catalog.push({\n id,\n provider: record.providerId,\n modelName: model,\n hasApiKey: true,\n reasoningOptions: undefined,\n });\n }\n }\n }\n } catch {\n // Fail soft: the catalog still serves the built-in models.\n }\n }\n return c.json({\n ...sessionPolicy,\n models: catalog.sort((a, b) =>\n a.provider === b.provider ? a.id.localeCompare(b.id) : a.provider.localeCompare(b.provider),\n ),\n });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/default-model', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n try {\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n return c.json({ modelId: record?.modelId ?? null });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/default-model', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const parsed = z.object({ modelId: z.string().trim().min(1).max(256) }).safeParse(body);\n if (!parsed.success) return c.json({ error: 'Missing required field: modelId' }, 400);\n const { modelId } = parsed.data;\n try {\n await context.storage.set({ orgId: context.orgId, userId: context.userId, modelId });\n return c.json({ ok: true, modelId });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/default-model', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n try {\n await context.storage.clear({ orgId: context.orgId, userId: context.userId });\n return c.json({ ok: true, modelId: null });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n // Mirrors the TUI's /om command. All five knobs are durably stored in the\n // per-(org, user) `memory-settings` app table — never settings.json or\n // mutable session state.\n\n registerApiRoute('/web/config/om', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const resourceId = c.req.query('resourceId');\n const scope = c.req.query('scope') || undefined;\n const factoryProjectId = c.req.query('factoryId') || undefined;\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n try {\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const fallback = await factoryOmFallback(factoryProjectId);\n const availableProviders = await resolveOMResponseContext(loose(c));\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n return c.json({\n config: readStoredOMConfig(\n record,\n sessionModelId || fallback,\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n ),\n });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/om/:role/model', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const role = c.req.param('role');\n if (role !== 'observer' && role !== 'reflector') {\n return c.json({ error: `Unknown OM role \"${role}\"` }, 400);\n }\n let body: { resourceId?: unknown; modelId?: unknown; scope?: unknown; factoryId?: unknown };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const resourceId = typeof body.resourceId === 'string' ? body.resourceId : '';\n const scope = typeof body.scope === 'string' && body.scope ? body.scope : undefined;\n const factoryProjectId = typeof body.factoryId === 'string' && body.factoryId ? body.factoryId : undefined;\n const model = typeof body.modelId === 'string' ? body.modelId.trim() : '';\n if (!model) {\n return c.json({ error: 'Missing required field: modelId' }, 400);\n }\n // `'auto'` is selection intent, not a model ID: store null so the role\n // follows the active main model instead of pinning a model named \"auto\".\n const wantsAuto = model === 'auto';\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n // Resolve the response context before persisting: a provider-enumeration\n // failure must not report 500 for a write that already succeeded.\n const availableProviders = await resolveOMResponseContext(loose(c));\n try {\n await persistMemorySettings(context, {\n [role === 'observer' ? 'observerModelId' : 'reflectorModelId']: wantsAuto ? null : model,\n });\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n const config = readStoredOMConfig(\n record,\n sessionModelId || (await factoryOmFallback(factoryProjectId)),\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n );\n return c.json({ ok: true, config });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/om/thresholds', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n let body: {\n resourceId?: unknown;\n observationThreshold?: unknown;\n reflectionThreshold?: unknown;\n scope?: unknown;\n factoryId?: unknown;\n };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const resourceId = typeof body.resourceId === 'string' ? body.resourceId : '';\n const scope = typeof body.scope === 'string' && body.scope ? body.scope : undefined;\n const factoryProjectId = typeof body.factoryId === 'string' && body.factoryId ? body.factoryId : undefined;\n const observation =\n typeof body.observationThreshold === 'number' && body.observationThreshold > 0\n ? Math.round(body.observationThreshold)\n : undefined;\n const reflection =\n typeof body.reflectionThreshold === 'number' && body.reflectionThreshold > 0\n ? Math.round(body.reflectionThreshold)\n : undefined;\n if (observation === undefined && reflection === undefined) {\n return c.json({ error: 'Provide observationThreshold and/or reflectionThreshold (positive numbers)' }, 400);\n }\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n const availableProviders = await resolveOMResponseContext(loose(c));\n try {\n await persistMemorySettings(context, {\n ...(observation !== undefined ? { observationThreshold: observation } : {}),\n ...(reflection !== undefined ? { reflectionThreshold: reflection } : {}),\n });\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n const config = readStoredOMConfig(\n record,\n sessionModelId || (await factoryOmFallback(factoryProjectId)),\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n );\n return c.json({ ok: true, config });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/om/observe-attachments', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n let body: { resourceId?: unknown; value?: unknown; scope?: unknown; factoryId?: unknown };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const resourceId = typeof body.resourceId === 'string' ? body.resourceId : '';\n const scope = typeof body.scope === 'string' && body.scope ? body.scope : undefined;\n const factoryProjectId = typeof body.factoryId === 'string' && body.factoryId ? body.factoryId : undefined;\n const raw = body.value;\n const value: 'auto' | boolean = raw === 'auto' || raw === true || raw === false ? raw : 'auto';\n if (raw !== 'auto' && raw !== true && raw !== false) {\n return c.json({ error: \"value must be 'auto', true, or false\" }, 400);\n }\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n const availableProviders = await resolveOMResponseContext(loose(c));\n try {\n await persistMemorySettings(context, { observeAttachments: value });\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n const config = readStoredOMConfig(\n record,\n sessionModelId || (await factoryOmFallback(factoryProjectId)),\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n );\n return c.json({ ok: true, config });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n ];\n }\n}\n"],"mappings":"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"}
@@ -37,6 +37,8 @@ export declare const updateProjectBodySchema: z.ZodObject<{
37
37
  }>>;
38
38
  autoRunEnabled: z.ZodOptional<z.ZodBoolean>;
39
39
  autoApprovePlans: z.ZodOptional<z.ZodBoolean>;
40
+ reviewTestChecksEnabled: z.ZodOptional<z.ZodBoolean>;
41
+ selfReviewEnabled: z.ZodOptional<z.ZodBoolean>;
40
42
  }, z.core.$strip>;
41
43
  /** The configured FactorySandbox as factory describes it: provider id, JSON Schema of its settings, capabilities. */
42
44
  export declare const environmentSandboxSchema: z.ZodObject<{
@@ -399,6 +401,8 @@ export declare const FACTORY_ROUTE_CONTRACTS: {
399
401
  }>>;
400
402
  autoRunEnabled: z.ZodOptional<z.ZodBoolean>;
401
403
  autoApprovePlans: z.ZodOptional<z.ZodBoolean>;
404
+ reviewTestChecksEnabled: z.ZodOptional<z.ZodBoolean>;
405
+ selfReviewEnabled: z.ZodOptional<z.ZodBoolean>;
402
406
  }, z.core.$strip>;
403
407
  readonly responseSchema: z.ZodObject<{
404
408
  project: z.ZodRecord<z.ZodString, z.ZodUnknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/routes/contracts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/routes/contracts.ts"],"names":[],"mappings":"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"}