@mastra/factory 0.2.2-alpha.0 → 0.2.2-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 (174) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/auth.d.ts +2 -2
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +401 -314
  5. package/dist/auth.js.map +1 -1
  6. package/dist/capabilities/connection.js +1 -1
  7. package/dist/capabilities/intake.js +1 -1
  8. package/dist/capabilities/version-control.js +1 -1
  9. package/dist/factory.d.ts.map +1 -1
  10. package/dist/factory.js +441 -39455
  11. package/dist/factory.js.map +1 -1
  12. package/dist/index.js +2 -39466
  13. package/dist/integrations/base.js +1 -1
  14. package/dist/integrations/github/config.js +36 -22
  15. package/dist/integrations/github/config.js.map +1 -1
  16. package/dist/integrations/github/factory-session.js +33 -37
  17. package/dist/integrations/github/factory-session.js.map +1 -1
  18. package/dist/integrations/github/integration.js +1037 -3624
  19. package/dist/integrations/github/integration.js.map +1 -1
  20. package/dist/integrations/github/issue-triage.js +71 -71
  21. package/dist/integrations/github/issue-triage.js.map +1 -1
  22. package/dist/integrations/github/pat.js +47 -36
  23. package/dist/integrations/github/pat.js.map +1 -1
  24. package/dist/integrations/github/provenance.js +72 -101
  25. package/dist/integrations/github/provenance.js.map +1 -1
  26. package/dist/integrations/github/routes.d.ts.map +1 -1
  27. package/dist/integrations/github/routes.js +1272 -1833
  28. package/dist/integrations/github/routes.js.map +1 -1
  29. package/dist/integrations/github/rules.js +203 -471
  30. package/dist/integrations/github/rules.js.map +1 -1
  31. package/dist/integrations/github/sandbox.d.ts +2 -0
  32. package/dist/integrations/github/sandbox.d.ts.map +1 -1
  33. package/dist/integrations/github/sandbox.js +401 -326
  34. package/dist/integrations/github/sandbox.js.map +1 -1
  35. package/dist/integrations/github/session-subscriptions.js +165 -223
  36. package/dist/integrations/github/session-subscriptions.js.map +1 -1
  37. package/dist/integrations/github/subscriptions.js +43 -51
  38. package/dist/integrations/github/subscriptions.js.map +1 -1
  39. package/dist/integrations/github/token-refresh.js +15 -18
  40. package/dist/integrations/github/token-refresh.js.map +1 -1
  41. package/dist/integrations/github/webhook.js +359 -343
  42. package/dist/integrations/github/webhook.js.map +1 -1
  43. package/dist/integrations/linear/agent-tools.js +77 -100
  44. package/dist/integrations/linear/agent-tools.js.map +1 -1
  45. package/dist/integrations/linear/integration.js +611 -1309
  46. package/dist/integrations/linear/integration.js.map +1 -1
  47. package/dist/integrations/linear/routes.js +227 -230
  48. package/dist/integrations/linear/routes.js.map +1 -1
  49. package/dist/integrations/linear/rules.js +126 -346
  50. package/dist/integrations/linear/rules.js.map +1 -1
  51. package/dist/integrations/linear/storage.js +1 -1
  52. package/dist/integrations/platform/api-client.js +131 -135
  53. package/dist/integrations/platform/api-client.js.map +1 -1
  54. package/dist/integrations/platform/github/event-worker.js +275 -573
  55. package/dist/integrations/platform/github/event-worker.js.map +1 -1
  56. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  57. package/dist/integrations/platform/github/integration.js +845 -3942
  58. package/dist/integrations/platform/github/integration.js.map +1 -1
  59. package/dist/integrations/platform/linear/integration.js +457 -1309
  60. package/dist/integrations/platform/linear/integration.js.map +1 -1
  61. package/dist/integrations/workos/integration.js +80 -85
  62. package/dist/integrations/workos/integration.js.map +1 -1
  63. package/dist/routes/config.d.ts.map +1 -1
  64. package/dist/routes/config.js +933 -915
  65. package/dist/routes/config.js.map +1 -1
  66. package/dist/routes/custom-provider-source.js +110 -93
  67. package/dist/routes/custom-provider-source.js.map +1 -1
  68. package/dist/routes/fs.js +401 -349
  69. package/dist/routes/fs.js.map +1 -1
  70. package/dist/routes/intake.js +165 -165
  71. package/dist/routes/intake.js.map +1 -1
  72. package/dist/routes/oauth.js +447 -25166
  73. package/dist/routes/oauth.js.map +1 -1
  74. package/dist/routes/projects.js +437 -376
  75. package/dist/routes/projects.js.map +1 -1
  76. package/dist/routes/provider-credentials.js +76 -58
  77. package/dist/routes/provider-credentials.js.map +1 -1
  78. package/dist/routes/route.js +12 -8
  79. package/dist/routes/route.js.map +1 -1
  80. package/dist/routes/skills.js +160 -173
  81. package/dist/routes/skills.js.map +1 -1
  82. package/dist/routes/surface.js +250 -28618
  83. package/dist/routes/surface.js.map +1 -1
  84. package/dist/routes/tenant-credentials.js +141 -166
  85. package/dist/routes/tenant-credentials.js.map +1 -1
  86. package/dist/routes/work-items.js +654 -862
  87. package/dist/routes/work-items.js.map +1 -1
  88. package/dist/rules/binding-context.js +23 -35
  89. package/dist/rules/binding-context.js.map +1 -1
  90. package/dist/rules/defaults.js +200 -309
  91. package/dist/rules/defaults.js.map +1 -1
  92. package/dist/rules/dispatcher.d.ts.map +1 -1
  93. package/dist/rules/dispatcher.js +438 -677
  94. package/dist/rules/dispatcher.js.map +1 -1
  95. package/dist/rules/index.js +5 -599
  96. package/dist/rules/processor.js +344 -596
  97. package/dist/rules/processor.js.map +1 -1
  98. package/dist/rules/resolve.js +21 -18
  99. package/dist/rules/resolve.js.map +1 -1
  100. package/dist/rules/start-coordinator.js +168 -157
  101. package/dist/rules/start-coordinator.js.map +1 -1
  102. package/dist/rules/tools.js +50 -85
  103. package/dist/rules/tools.js.map +1 -1
  104. package/dist/rules/transition-service.js +183 -454
  105. package/dist/rules/transition-service.js.map +1 -1
  106. package/dist/rules/types.js +33 -29
  107. package/dist/rules/types.js.map +1 -1
  108. package/dist/rules/validation.js +266 -281
  109. package/dist/rules/validation.js.map +1 -1
  110. package/dist/sandbox/fleet.js +272 -250
  111. package/dist/sandbox/fleet.js.map +1 -1
  112. package/dist/sandbox/reattach.js +13 -6
  113. package/dist/sandbox/reattach.js.map +1 -1
  114. package/dist/server-error.js +12 -16
  115. package/dist/server-error.js.map +1 -1
  116. package/dist/skills/service.js +30 -35
  117. package/dist/skills/service.js.map +1 -1
  118. package/dist/spa-static.d.ts.map +1 -1
  119. package/dist/spa-static.js +91 -64
  120. package/dist/spa-static.js.map +1 -1
  121. package/dist/state-signing.js +73 -44
  122. package/dist/state-signing.js.map +1 -1
  123. package/dist/storage/domains/audit/agent-audit.js +60 -59
  124. package/dist/storage/domains/audit/agent-audit.js.map +1 -1
  125. package/dist/storage/domains/audit/base.js +169 -112
  126. package/dist/storage/domains/audit/base.js.map +1 -1
  127. package/dist/storage/domains/audit/domain.js +155 -153
  128. package/dist/storage/domains/audit/domain.js.map +1 -1
  129. package/dist/storage/domains/credentials/base.js +259 -243
  130. package/dist/storage/domains/credentials/base.js.map +1 -1
  131. package/dist/storage/domains/custom-providers/base.js +138 -143
  132. package/dist/storage/domains/custom-providers/base.js.map +1 -1
  133. package/dist/storage/domains/intake/base.js +75 -57
  134. package/dist/storage/domains/intake/base.js.map +1 -1
  135. package/dist/storage/domains/integrations/base.js +310 -245
  136. package/dist/storage/domains/integrations/base.js.map +1 -1
  137. package/dist/storage/domains/memory-settings/base.js +117 -102
  138. package/dist/storage/domains/memory-settings/base.js.map +1 -1
  139. package/dist/storage/domains/model-packs/base.js +89 -88
  140. package/dist/storage/domains/model-packs/base.js.map +1 -1
  141. package/dist/storage/domains/projects/base.js +97 -92
  142. package/dist/storage/domains/projects/base.js.map +1 -1
  143. package/dist/storage/domains/queue-health/base.js +111 -76
  144. package/dist/storage/domains/queue-health/base.js.map +1 -1
  145. package/dist/storage/domains/source-control/base.d.ts +9 -0
  146. package/dist/storage/domains/source-control/base.d.ts.map +1 -1
  147. package/dist/storage/domains/source-control/base.js +777 -702
  148. package/dist/storage/domains/source-control/base.js.map +1 -1
  149. package/dist/storage/domains/source-control/inmemory.d.ts +4 -0
  150. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  151. package/dist/storage/domains/source-control/inmemory.js +322 -344
  152. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  153. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  154. package/dist/storage/domains/work-items/base.js +1266 -1132
  155. package/dist/storage/domains/work-items/base.js.map +1 -1
  156. package/dist/storage/domains/work-items/metrics.js +202 -184
  157. package/dist/storage/domains/work-items/metrics.js.map +1 -1
  158. package/dist/timing.d.ts +15 -0
  159. package/dist/timing.d.ts.map +1 -0
  160. package/dist/timing.js +34 -0
  161. package/dist/timing.js.map +1 -0
  162. package/dist/workspace.d.ts +2 -3
  163. package/dist/workspace.d.ts.map +1 -1
  164. package/dist/workspace.js +236 -438
  165. package/dist/workspace.js.map +1 -1
  166. package/factory-skills/factory-review/SKILL.md +9 -2
  167. package/package.json +9 -9
  168. package/dist/capabilities/connection.js.map +0 -1
  169. package/dist/capabilities/intake.js.map +0 -1
  170. package/dist/capabilities/version-control.js.map +0 -1
  171. package/dist/index.js.map +0 -1
  172. package/dist/integrations/base.js.map +0 -1
  173. package/dist/integrations/linear/storage.js.map +0 -1
  174. package/dist/rules/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/storage/domains/integrations/base.ts"],"sourcesContent":["/**\n * Generic integration storage — the default persistence surface for\n * `FactoryIntegration`s.\n *\n * Most integrations persist the same three shapes: an org-owned OAuth\n * **connection**, **subscriptions** binding external objects to\n * sessions/threads, and per-`(org, user)` **settings**. This built-in domain\n * stores all three in shared collections keyed by `integration_id`, so an\n * integration author writes zero schema, zero DDL, and zero queries — and\n * org scoping is enforced by construction through the pre-scoped handle\n * returned by {@link IntegrationStorage.forIntegration}.\n *\n * Source-control integrations additionally use the shared, provider-scoped\n * source-control domain for installations, projects, worktrees, and sandboxes.\n *\n * Payloads (`data` / `config`) are JSON documents typed per-integration via\n * the handle's generics. JSON round-trips exactly what JSON can represent:\n * store timestamps inside payloads as epoch millis or ISO strings, not\n * `Date`s.\n */\n\nimport { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\nexport const INTEGRATION_CONNECTIONS_SCHEMA: CollectionSchema = {\n name: 'integration_connections',\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n /** Who connected it (audit only — never scopes reads). */\n user_id: { type: 'text', nullable: true },\n data: { type: 'json' },\n metadata: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'integration_connections_integration_org_unique', columns: ['integration_id', 'org_id'] }],\n};\n\nexport const INTEGRATION_SUBSCRIPTIONS_SCHEMA: CollectionSchema = {\n name: 'integration_subscriptions',\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n /** Canonical external-object key the integration derives (e.g. `pr:{installation}:{repo}:{number}`). */\n target_key: { type: 'text' },\n session_id: { type: 'text', nullable: true },\n resource_id: { type: 'text', nullable: true },\n thread_id: { type: 'text', nullable: true },\n session_scope: { type: 'text', nullable: true },\n status: { type: 'text' },\n data: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n indexes: [\n { name: 'integration_subscriptions_target_idx', columns: ['integration_id', 'target_key'] },\n { name: 'integration_subscriptions_org_idx', columns: ['integration_id', 'org_id'] },\n ],\n};\n\nexport const INTEGRATION_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'integration_settings',\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n config: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n { name: 'integration_settings_integration_org_user_unique', columns: ['integration_id', 'org_id', 'user_id'] },\n ],\n};\n\n/** An integration's org-owned connection (typically the OAuth grant). */\nexport interface IntegrationConnection<TData> {\n id: string;\n orgId: string;\n /** Who connected it (audit only). */\n userId: string | null;\n data: TData;\n metadata: Record<string, unknown>;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/** A subscription binding an external object to a session/thread. */\nexport interface IntegrationSubscription<TData> {\n id: string;\n orgId: string;\n targetKey: string;\n sessionId: string | null;\n resourceId: string | null;\n threadId: string | null;\n sessionScope: string | null;\n status: string;\n data: TData;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport type CreateIntegrationSubscriptionInput<TData> = {\n orgId: string;\n targetKey: string;\n sessionId?: string | null;\n resourceId?: string | null;\n threadId?: string | null;\n sessionScope?: string | null;\n /** Defaults to `'active'`. */\n status?: string;\n} & ({} extends TData ? { data?: TData } : { data: TData });\n\n/**\n * Typed query surface pre-scoped to one `integration_id`. Every read and\n * write is automatically filtered/stamped with the integration id, so an\n * integration cannot reach another integration's rows.\n */\nexport interface IntegrationStorageHandle<\n TConnection = Record<string, unknown>,\n TSettings = Record<string, unknown>,\n TSubscription = Record<string, unknown>,\n> {\n readonly integrationId: string;\n connections: {\n /** The org's connection, or `null` when not connected. */\n get(orgId: string): Promise<IntegrationConnection<TConnection> | null>;\n /** Insert or replace the org's connection (one per org; `created_at` preserved on update). */\n upsert(\n orgId: string,\n input: { userId?: string | null; data: TConnection; metadata?: Record<string, unknown> },\n ): Promise<void>;\n /**\n * Atomic read-modify-write of the connection's `data` payload (token\n * rotation etc.). Returns the updated connection, or `null` when the org\n * has no connection.\n */\n update(orgId: string, fn: (data: TConnection) => TConnection): Promise<IntegrationConnection<TConnection> | null>;\n /** Remove the org's connection. Returns whether a row was deleted. */\n delete(orgId: string): Promise<boolean>;\n };\n subscriptions: {\n create(input: CreateIntegrationSubscriptionInput<TSubscription>): Promise<IntegrationSubscription<TSubscription>>;\n /** All subscriptions for an external object (webhook fan-out), optionally filtered by status. */\n listByTarget(targetKey: string, opts?: { status?: string }): Promise<IntegrationSubscription<TSubscription>[]>;\n listBySession(sessionId: string): Promise<IntegrationSubscription<TSubscription>[]>;\n listByThread(resourceId: string, threadId: string): Promise<IntegrationSubscription<TSubscription>[]>;\n updateStatus(id: string, status: string): Promise<void>;\n delete(id: string): Promise<boolean>;\n /** Targeted cleanup, always org-scoped. Returns the number of rows deleted. */\n deleteWhere(where: { orgId: string; targetKey?: string; sessionId?: string }): Promise<number>;\n };\n settings: {\n /** The `(org, user)` config, or `null` when never saved. */\n get(orgId: string, userId: string): Promise<TSettings | null>;\n /** Upsert the `(org, user)` config (`created_at` preserved on update). */\n save(orgId: string, userId: string, config: TSettings): Promise<void>;\n };\n}\n\ninterface ConnectionRow extends Record<string, unknown> {\n id: string;\n integration_id: string;\n org_id: string;\n user_id: string | null;\n data: unknown;\n metadata: Record<string, unknown>;\n created_at: Date;\n updated_at: Date;\n}\n\ninterface SubscriptionRow extends Record<string, unknown> {\n id: string;\n integration_id: string;\n org_id: string;\n target_key: string;\n session_id: string | null;\n resource_id: string | null;\n thread_id: string | null;\n session_scope: string | null;\n status: string;\n data: unknown;\n created_at: Date;\n updated_at: Date;\n}\n\n/**\n * The built-in generic integration domain, written once against the\n * `FactoryStorageOps` surface — works on any `FactoryStorage` backend.\n */\nexport class IntegrationStorage extends FactoryStorageDomain {\n constructor() {\n super('integrations');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([\n INTEGRATION_CONNECTIONS_SCHEMA,\n INTEGRATION_SUBSCRIPTIONS_SCHEMA,\n INTEGRATION_SETTINGS_SCHEMA,\n ]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('integration_subscriptions', {});\n await this.ops.deleteMany('integration_settings', {});\n await this.ops.deleteMany('integration_connections', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n /** A typed handle pre-scoped to `integrationId`. */\n forIntegration<\n TConnection = Record<string, unknown>,\n TSettings = Record<string, unknown>,\n TSubscription = Record<string, unknown>,\n >(integrationId: string): IntegrationStorageHandle<TConnection, TSettings, TSubscription> {\n if (!integrationId) throw new Error('[IntegrationStorage] integrationId is required.');\n const db = () => this.#db;\n const scoped = { integration_id: integrationId };\n\n const mapConnection = (row: ConnectionRow): IntegrationConnection<TConnection> => ({\n id: row.id,\n orgId: row.org_id,\n userId: row.user_id,\n data: row.data as TConnection,\n metadata: row.metadata ?? {},\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n });\n\n const mapSubscription = (row: SubscriptionRow): IntegrationSubscription<TSubscription> => ({\n id: row.id,\n orgId: row.org_id,\n targetKey: row.target_key,\n sessionId: row.session_id,\n resourceId: row.resource_id,\n threadId: row.thread_id,\n sessionScope: row.session_scope,\n status: row.status,\n data: row.data as TSubscription,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n });\n\n return {\n integrationId,\n connections: {\n get: async orgId => {\n const row = await db().findOne<ConnectionRow>('integration_connections', { ...scoped, org_id: orgId });\n return row ? mapConnection(row) : null;\n },\n upsert: async (orgId, input) => {\n const where = { ...scoped, org_id: orgId };\n const update = async () =>\n db().updateMany('integration_connections', where, {\n user_id: input.userId ?? null,\n data: input.data,\n metadata: input.metadata ?? {},\n updated_at: new Date(),\n });\n\n let lastError: unknown;\n for (let attempt = 0; attempt < 2; attempt++) {\n if ((await update()) > 0) return;\n\n const now = new Date();\n try {\n await db().insertOne<ConnectionRow>('integration_connections', {\n ...where,\n user_id: input.userId ?? null,\n data: input.data,\n metadata: input.metadata ?? {},\n created_at: now,\n updated_at: now,\n });\n return;\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n lastError = error;\n }\n }\n throw lastError;\n },\n update: async (orgId, fn) => {\n const row = await db().updateAtomic<ConnectionRow>(\n 'integration_connections',\n { ...scoped, org_id: orgId },\n current => ({ data: fn(current.data as TConnection), updated_at: new Date() }),\n );\n return row ? mapConnection(row) : null;\n },\n delete: async orgId => {\n const deleted = await db().deleteMany('integration_connections', { ...scoped, org_id: orgId });\n return deleted > 0;\n },\n },\n subscriptions: {\n create: async input => {\n const now = new Date();\n const row = await db().insertOne<SubscriptionRow>('integration_subscriptions', {\n ...scoped,\n org_id: input.orgId,\n target_key: input.targetKey,\n session_id: input.sessionId ?? null,\n resource_id: input.resourceId ?? null,\n thread_id: input.threadId ?? null,\n session_scope: input.sessionScope ?? null,\n status: input.status ?? 'active',\n data: input.data ?? {},\n created_at: now,\n updated_at: now,\n });\n return mapSubscription(row);\n },\n listByTarget: async (targetKey, opts) => {\n const rows = await db().findMany<SubscriptionRow>(\n 'integration_subscriptions',\n { ...scoped, target_key: targetKey, ...(opts?.status !== undefined ? { status: opts.status } : {}) },\n { orderBy: [['created_at', 'asc']] },\n );\n return rows.map(mapSubscription);\n },\n listBySession: async sessionId => {\n const rows = await db().findMany<SubscriptionRow>(\n 'integration_subscriptions',\n { ...scoped, session_id: sessionId },\n { orderBy: [['created_at', 'asc']] },\n );\n return rows.map(mapSubscription);\n },\n listByThread: async (resourceId, threadId) => {\n const rows = await db().findMany<SubscriptionRow>(\n 'integration_subscriptions',\n { ...scoped, resource_id: resourceId, thread_id: threadId },\n { orderBy: [['created_at', 'asc']] },\n );\n return rows.map(mapSubscription);\n },\n updateStatus: async (id, status) => {\n await db().updateMany('integration_subscriptions', { ...scoped, id }, { status, updated_at: new Date() });\n },\n delete: async id => {\n const deleted = await db().deleteMany('integration_subscriptions', { ...scoped, id });\n return deleted > 0;\n },\n deleteWhere: async where => {\n return db().deleteMany('integration_subscriptions', {\n ...scoped,\n org_id: where.orgId,\n ...(where.targetKey !== undefined ? { target_key: where.targetKey } : {}),\n ...(where.sessionId !== undefined ? { session_id: where.sessionId } : {}),\n });\n },\n },\n settings: {\n get: async (orgId, userId) => {\n const row = await db().findOne<{ config: TSettings }>('integration_settings', {\n ...scoped,\n org_id: orgId,\n user_id: userId,\n });\n return row ? structuredClone(row.config) : null;\n },\n save: async (orgId, userId, config) => {\n const where = { ...scoped, org_id: orgId, user_id: userId };\n const update = async () =>\n db().updateMany('integration_settings', where, {\n config,\n updated_at: new Date(),\n });\n\n let lastError: unknown;\n for (let attempt = 0; attempt < 2; attempt++) {\n if ((await update()) > 0) return;\n\n const now = new Date();\n try {\n await db().insertOne('integration_settings', {\n ...where,\n config,\n created_at: now,\n updated_at: now,\n });\n return;\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n lastError = error;\n }\n }\n throw lastError;\n },\n },\n };\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"base.js","names":["#db"],"sources":["../../../../src/storage/domains/integrations/base.ts"],"sourcesContent":["/**\n * Generic integration storage — the default persistence surface for\n * `FactoryIntegration`s.\n *\n * Most integrations persist the same three shapes: an org-owned OAuth\n * **connection**, **subscriptions** binding external objects to\n * sessions/threads, and per-`(org, user)` **settings**. This built-in domain\n * stores all three in shared collections keyed by `integration_id`, so an\n * integration author writes zero schema, zero DDL, and zero queries — and\n * org scoping is enforced by construction through the pre-scoped handle\n * returned by {@link IntegrationStorage.forIntegration}.\n *\n * Source-control integrations additionally use the shared, provider-scoped\n * source-control domain for installations, projects, worktrees, and sandboxes.\n *\n * Payloads (`data` / `config`) are JSON documents typed per-integration via\n * the handle's generics. JSON round-trips exactly what JSON can represent:\n * store timestamps inside payloads as epoch millis or ISO strings, not\n * `Date`s.\n */\n\nimport { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\nexport const INTEGRATION_CONNECTIONS_SCHEMA: CollectionSchema = {\n name: 'integration_connections',\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n /** Who connected it (audit only — never scopes reads). */\n user_id: { type: 'text', nullable: true },\n data: { type: 'json' },\n metadata: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'integration_connections_integration_org_unique', columns: ['integration_id', 'org_id'] }],\n};\n\nexport const INTEGRATION_SUBSCRIPTIONS_SCHEMA: CollectionSchema = {\n name: 'integration_subscriptions',\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n /** Canonical external-object key the integration derives (e.g. `pr:{installation}:{repo}:{number}`). */\n target_key: { type: 'text' },\n session_id: { type: 'text', nullable: true },\n resource_id: { type: 'text', nullable: true },\n thread_id: { type: 'text', nullable: true },\n session_scope: { type: 'text', nullable: true },\n status: { type: 'text' },\n data: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n indexes: [\n { name: 'integration_subscriptions_target_idx', columns: ['integration_id', 'target_key'] },\n { name: 'integration_subscriptions_org_idx', columns: ['integration_id', 'org_id'] },\n ],\n};\n\nexport const INTEGRATION_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'integration_settings',\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n config: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n { name: 'integration_settings_integration_org_user_unique', columns: ['integration_id', 'org_id', 'user_id'] },\n ],\n};\n\n/** An integration's org-owned connection (typically the OAuth grant). */\nexport interface IntegrationConnection<TData> {\n id: string;\n orgId: string;\n /** Who connected it (audit only). */\n userId: string | null;\n data: TData;\n metadata: Record<string, unknown>;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/** A subscription binding an external object to a session/thread. */\nexport interface IntegrationSubscription<TData> {\n id: string;\n orgId: string;\n targetKey: string;\n sessionId: string | null;\n resourceId: string | null;\n threadId: string | null;\n sessionScope: string | null;\n status: string;\n data: TData;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport type CreateIntegrationSubscriptionInput<TData> = {\n orgId: string;\n targetKey: string;\n sessionId?: string | null;\n resourceId?: string | null;\n threadId?: string | null;\n sessionScope?: string | null;\n /** Defaults to `'active'`. */\n status?: string;\n} & ({} extends TData ? { data?: TData } : { data: TData });\n\n/**\n * Typed query surface pre-scoped to one `integration_id`. Every read and\n * write is automatically filtered/stamped with the integration id, so an\n * integration cannot reach another integration's rows.\n */\nexport interface IntegrationStorageHandle<\n TConnection = Record<string, unknown>,\n TSettings = Record<string, unknown>,\n TSubscription = Record<string, unknown>,\n> {\n readonly integrationId: string;\n connections: {\n /** The org's connection, or `null` when not connected. */\n get(orgId: string): Promise<IntegrationConnection<TConnection> | null>;\n /** Insert or replace the org's connection (one per org; `created_at` preserved on update). */\n upsert(\n orgId: string,\n input: { userId?: string | null; data: TConnection; metadata?: Record<string, unknown> },\n ): Promise<void>;\n /**\n * Atomic read-modify-write of the connection's `data` payload (token\n * rotation etc.). Returns the updated connection, or `null` when the org\n * has no connection.\n */\n update(orgId: string, fn: (data: TConnection) => TConnection): Promise<IntegrationConnection<TConnection> | null>;\n /** Remove the org's connection. Returns whether a row was deleted. */\n delete(orgId: string): Promise<boolean>;\n };\n subscriptions: {\n create(input: CreateIntegrationSubscriptionInput<TSubscription>): Promise<IntegrationSubscription<TSubscription>>;\n /** All subscriptions for an external object (webhook fan-out), optionally filtered by status. */\n listByTarget(targetKey: string, opts?: { status?: string }): Promise<IntegrationSubscription<TSubscription>[]>;\n listBySession(sessionId: string): Promise<IntegrationSubscription<TSubscription>[]>;\n listByThread(resourceId: string, threadId: string): Promise<IntegrationSubscription<TSubscription>[]>;\n updateStatus(id: string, status: string): Promise<void>;\n delete(id: string): Promise<boolean>;\n /** Targeted cleanup, always org-scoped. Returns the number of rows deleted. */\n deleteWhere(where: { orgId: string; targetKey?: string; sessionId?: string }): Promise<number>;\n };\n settings: {\n /** The `(org, user)` config, or `null` when never saved. */\n get(orgId: string, userId: string): Promise<TSettings | null>;\n /** Upsert the `(org, user)` config (`created_at` preserved on update). */\n save(orgId: string, userId: string, config: TSettings): Promise<void>;\n };\n}\n\ninterface ConnectionRow extends Record<string, unknown> {\n id: string;\n integration_id: string;\n org_id: string;\n user_id: string | null;\n data: unknown;\n metadata: Record<string, unknown>;\n created_at: Date;\n updated_at: Date;\n}\n\ninterface SubscriptionRow extends Record<string, unknown> {\n id: string;\n integration_id: string;\n org_id: string;\n target_key: string;\n session_id: string | null;\n resource_id: string | null;\n thread_id: string | null;\n session_scope: string | null;\n status: string;\n data: unknown;\n created_at: Date;\n updated_at: Date;\n}\n\n/**\n * The built-in generic integration domain, written once against the\n * `FactoryStorageOps` surface — works on any `FactoryStorage` backend.\n */\nexport class IntegrationStorage extends FactoryStorageDomain {\n constructor() {\n super('integrations');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([\n INTEGRATION_CONNECTIONS_SCHEMA,\n INTEGRATION_SUBSCRIPTIONS_SCHEMA,\n INTEGRATION_SETTINGS_SCHEMA,\n ]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('integration_subscriptions', {});\n await this.ops.deleteMany('integration_settings', {});\n await this.ops.deleteMany('integration_connections', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n /** A typed handle pre-scoped to `integrationId`. */\n forIntegration<\n TConnection = Record<string, unknown>,\n TSettings = Record<string, unknown>,\n TSubscription = Record<string, unknown>,\n >(integrationId: string): IntegrationStorageHandle<TConnection, TSettings, TSubscription> {\n if (!integrationId) throw new Error('[IntegrationStorage] integrationId is required.');\n const db = () => this.#db;\n const scoped = { integration_id: integrationId };\n\n const mapConnection = (row: ConnectionRow): IntegrationConnection<TConnection> => ({\n id: row.id,\n orgId: row.org_id,\n userId: row.user_id,\n data: row.data as TConnection,\n metadata: row.metadata ?? {},\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n });\n\n const mapSubscription = (row: SubscriptionRow): IntegrationSubscription<TSubscription> => ({\n id: row.id,\n orgId: row.org_id,\n targetKey: row.target_key,\n sessionId: row.session_id,\n resourceId: row.resource_id,\n threadId: row.thread_id,\n sessionScope: row.session_scope,\n status: row.status,\n data: row.data as TSubscription,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n });\n\n return {\n integrationId,\n connections: {\n get: async orgId => {\n const row = await db().findOne<ConnectionRow>('integration_connections', { ...scoped, org_id: orgId });\n return row ? mapConnection(row) : null;\n },\n upsert: async (orgId, input) => {\n const where = { ...scoped, org_id: orgId };\n const update = async () =>\n db().updateMany('integration_connections', where, {\n user_id: input.userId ?? null,\n data: input.data,\n metadata: input.metadata ?? {},\n updated_at: new Date(),\n });\n\n let lastError: unknown;\n for (let attempt = 0; attempt < 2; attempt++) {\n if ((await update()) > 0) return;\n\n const now = new Date();\n try {\n await db().insertOne<ConnectionRow>('integration_connections', {\n ...where,\n user_id: input.userId ?? null,\n data: input.data,\n metadata: input.metadata ?? {},\n created_at: now,\n updated_at: now,\n });\n return;\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n lastError = error;\n }\n }\n throw lastError;\n },\n update: async (orgId, fn) => {\n const row = await db().updateAtomic<ConnectionRow>(\n 'integration_connections',\n { ...scoped, org_id: orgId },\n current => ({ data: fn(current.data as TConnection), updated_at: new Date() }),\n );\n return row ? mapConnection(row) : null;\n },\n delete: async orgId => {\n const deleted = await db().deleteMany('integration_connections', { ...scoped, org_id: orgId });\n return deleted > 0;\n },\n },\n subscriptions: {\n create: async input => {\n const now = new Date();\n const row = await db().insertOne<SubscriptionRow>('integration_subscriptions', {\n ...scoped,\n org_id: input.orgId,\n target_key: input.targetKey,\n session_id: input.sessionId ?? null,\n resource_id: input.resourceId ?? null,\n thread_id: input.threadId ?? null,\n session_scope: input.sessionScope ?? null,\n status: input.status ?? 'active',\n data: input.data ?? {},\n created_at: now,\n updated_at: now,\n });\n return mapSubscription(row);\n },\n listByTarget: async (targetKey, opts) => {\n const rows = await db().findMany<SubscriptionRow>(\n 'integration_subscriptions',\n { ...scoped, target_key: targetKey, ...(opts?.status !== undefined ? { status: opts.status } : {}) },\n { orderBy: [['created_at', 'asc']] },\n );\n return rows.map(mapSubscription);\n },\n listBySession: async sessionId => {\n const rows = await db().findMany<SubscriptionRow>(\n 'integration_subscriptions',\n { ...scoped, session_id: sessionId },\n { orderBy: [['created_at', 'asc']] },\n );\n return rows.map(mapSubscription);\n },\n listByThread: async (resourceId, threadId) => {\n const rows = await db().findMany<SubscriptionRow>(\n 'integration_subscriptions',\n { ...scoped, resource_id: resourceId, thread_id: threadId },\n { orderBy: [['created_at', 'asc']] },\n );\n return rows.map(mapSubscription);\n },\n updateStatus: async (id, status) => {\n await db().updateMany('integration_subscriptions', { ...scoped, id }, { status, updated_at: new Date() });\n },\n delete: async id => {\n const deleted = await db().deleteMany('integration_subscriptions', { ...scoped, id });\n return deleted > 0;\n },\n deleteWhere: async where => {\n return db().deleteMany('integration_subscriptions', {\n ...scoped,\n org_id: where.orgId,\n ...(where.targetKey !== undefined ? { target_key: where.targetKey } : {}),\n ...(where.sessionId !== undefined ? { session_id: where.sessionId } : {}),\n });\n },\n },\n settings: {\n get: async (orgId, userId) => {\n const row = await db().findOne<{ config: TSettings }>('integration_settings', {\n ...scoped,\n org_id: orgId,\n user_id: userId,\n });\n return row ? structuredClone(row.config) : null;\n },\n save: async (orgId, userId, config) => {\n const where = { ...scoped, org_id: orgId, user_id: userId };\n const update = async () =>\n db().updateMany('integration_settings', where, {\n config,\n updated_at: new Date(),\n });\n\n let lastError: unknown;\n for (let attempt = 0; attempt < 2; attempt++) {\n if ((await update()) > 0) return;\n\n const now = new Date();\n try {\n await db().insertOne('integration_settings', {\n ...where,\n config,\n created_at: now,\n updated_at: now,\n });\n return;\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n lastError = error;\n }\n }\n throw lastError;\n },\n },\n };\n }\n}\n"],"mappings":"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"}
@@ -1,111 +1,126 @@
1
- // src/storage/domains/memory-settings/base.ts
2
1
  import { FactoryStorageDomain, UniqueViolationError } from "@mastra/core/storage";
3
- var MEMORY_SETTINGS_SCHEMA = {
4
- name: "memory_settings",
5
- columns: {
6
- id: { type: "uuid-pk" },
7
- org_id: { type: "text" },
8
- user_id: { type: "text" },
9
- observer_model_id: { type: "text", nullable: true },
10
- reflector_model_id: { type: "text", nullable: true },
11
- observation_threshold: { type: "integer", nullable: true },
12
- reflection_threshold: { type: "integer", nullable: true },
13
- // 'auto' | true | false — json keeps the tri-state without string encoding.
14
- observe_attachments: { type: "json", nullable: true },
15
- created_at: { type: "timestamp" },
16
- updated_at: { type: "timestamp" }
17
- },
18
- uniqueIndexes: [{ name: "memory_settings_org_user_key", columns: ["org_id", "user_id"] }]
2
+ //#region src/storage/domains/memory-settings/base.ts
3
+ const MEMORY_SETTINGS_SCHEMA = {
4
+ name: "memory_settings",
5
+ columns: {
6
+ id: { type: "uuid-pk" },
7
+ org_id: { type: "text" },
8
+ user_id: { type: "text" },
9
+ observer_model_id: {
10
+ type: "text",
11
+ nullable: true
12
+ },
13
+ reflector_model_id: {
14
+ type: "text",
15
+ nullable: true
16
+ },
17
+ observation_threshold: {
18
+ type: "integer",
19
+ nullable: true
20
+ },
21
+ reflection_threshold: {
22
+ type: "integer",
23
+ nullable: true
24
+ },
25
+ observe_attachments: {
26
+ type: "json",
27
+ nullable: true
28
+ },
29
+ created_at: { type: "timestamp" },
30
+ updated_at: { type: "timestamp" }
31
+ },
32
+ uniqueIndexes: [{
33
+ name: "memory_settings_org_user_key",
34
+ columns: ["org_id", "user_id"]
35
+ }]
19
36
  };
20
37
  function toRecord(row) {
21
- return {
22
- orgId: row.org_id,
23
- userId: row.user_id,
24
- observerModelId: row.observer_model_id,
25
- reflectorModelId: row.reflector_model_id,
26
- observationThreshold: row.observation_threshold,
27
- reflectionThreshold: row.reflection_threshold,
28
- observeAttachments: row.observe_attachments,
29
- createdAt: row.created_at,
30
- updatedAt: row.updated_at
31
- };
38
+ return {
39
+ orgId: row.org_id,
40
+ userId: row.user_id,
41
+ observerModelId: row.observer_model_id,
42
+ reflectorModelId: row.reflector_model_id,
43
+ observationThreshold: row.observation_threshold,
44
+ reflectionThreshold: row.reflection_threshold,
45
+ observeAttachments: row.observe_attachments,
46
+ createdAt: row.created_at,
47
+ updatedAt: row.updated_at
48
+ };
32
49
  }
33
50
  function patchToColumns(patch) {
34
- const columns = {};
35
- if (patch.observerModelId !== void 0) columns.observer_model_id = patch.observerModelId;
36
- if (patch.reflectorModelId !== void 0) columns.reflector_model_id = patch.reflectorModelId;
37
- if (patch.observationThreshold !== void 0) columns.observation_threshold = patch.observationThreshold;
38
- if (patch.reflectionThreshold !== void 0) columns.reflection_threshold = patch.reflectionThreshold;
39
- if (patch.observeAttachments !== void 0) columns.observe_attachments = patch.observeAttachments;
40
- return columns;
51
+ const columns = {};
52
+ if (patch.observerModelId !== void 0) columns.observer_model_id = patch.observerModelId;
53
+ if (patch.reflectorModelId !== void 0) columns.reflector_model_id = patch.reflectorModelId;
54
+ if (patch.observationThreshold !== void 0) columns.observation_threshold = patch.observationThreshold;
55
+ if (patch.reflectionThreshold !== void 0) columns.reflection_threshold = patch.reflectionThreshold;
56
+ if (patch.observeAttachments !== void 0) columns.observe_attachments = patch.observeAttachments;
57
+ return columns;
41
58
  }
42
59
  var MemorySettingsStorage = class extends FactoryStorageDomain {
43
- constructor() {
44
- super("memory-settings");
45
- }
46
- async init() {
47
- await this.ensureCollections([MEMORY_SETTINGS_SCHEMA]);
48
- }
49
- async dangerouslyClearAll() {
50
- await this.ops.deleteMany("memory_settings", {});
51
- }
52
- get #db() {
53
- return this.ops;
54
- }
55
- async get({ orgId, userId }) {
56
- const row = await this.#db.findOne("memory_settings", { org_id: orgId, user_id: userId });
57
- return row ? toRecord(row) : null;
58
- }
59
- /**
60
- * Upsert the user's row, writing only the knobs present in `patch`.
61
- * `fillIfUnset` knobs are written only where the stored value is still
62
- * `NULL`, decided inside the atomic update so concurrent explicit writes
63
- * win over fills. Concurrent first writes are resolved via the shared
64
- * insert-then-catch-unique-violation pattern (see `queue_health`).
65
- */
66
- async patch({
67
- orgId,
68
- userId,
69
- patch,
70
- fillIfUnset
71
- }) {
72
- const now = /* @__PURE__ */ new Date();
73
- const updateExisting = () => this.#db.updateAtomic("memory_settings", { org_id: orgId, user_id: userId }, (row) => {
74
- const columns = { ...patchToColumns(patch), updated_at: now };
75
- if (fillIfUnset?.observerModelId !== void 0 && row.observer_model_id == null) {
76
- columns.observer_model_id = patch.observerModelId ?? fillIfUnset.observerModelId;
77
- }
78
- if (fillIfUnset?.reflectorModelId !== void 0 && row.reflector_model_id == null) {
79
- columns.reflector_model_id = patch.reflectorModelId ?? fillIfUnset.reflectorModelId;
80
- }
81
- return columns;
82
- });
83
- const updated = await updateExisting();
84
- if (updated) return toRecord(updated);
85
- try {
86
- const row = await this.#db.insertOne("memory_settings", {
87
- org_id: orgId,
88
- user_id: userId,
89
- observer_model_id: fillIfUnset?.observerModelId ?? null,
90
- reflector_model_id: fillIfUnset?.reflectorModelId ?? null,
91
- observation_threshold: null,
92
- reflection_threshold: null,
93
- observe_attachments: null,
94
- ...patchToColumns(patch),
95
- created_at: now,
96
- updated_at: now
97
- });
98
- return toRecord(row);
99
- } catch (error) {
100
- if (!(error instanceof UniqueViolationError)) throw error;
101
- const row = await updateExisting();
102
- if (!row) throw error;
103
- return toRecord(row);
104
- }
105
- }
106
- };
107
- export {
108
- MEMORY_SETTINGS_SCHEMA,
109
- MemorySettingsStorage
60
+ constructor() {
61
+ super("memory-settings");
62
+ }
63
+ async init() {
64
+ await this.ensureCollections([MEMORY_SETTINGS_SCHEMA]);
65
+ }
66
+ async dangerouslyClearAll() {
67
+ await this.ops.deleteMany("memory_settings", {});
68
+ }
69
+ get #db() {
70
+ return this.ops;
71
+ }
72
+ async get({ orgId, userId }) {
73
+ const row = await this.#db.findOne("memory_settings", {
74
+ org_id: orgId,
75
+ user_id: userId
76
+ });
77
+ return row ? toRecord(row) : null;
78
+ }
79
+ /**
80
+ * Upsert the user's row, writing only the knobs present in `patch`.
81
+ * `fillIfUnset` knobs are written only where the stored value is still
82
+ * `NULL`, decided inside the atomic update so concurrent explicit writes
83
+ * win over fills. Concurrent first writes are resolved via the shared
84
+ * insert-then-catch-unique-violation pattern (see `queue_health`).
85
+ */
86
+ async patch({ orgId, userId, patch, fillIfUnset }) {
87
+ const now = /* @__PURE__ */ new Date();
88
+ const updateExisting = () => this.#db.updateAtomic("memory_settings", {
89
+ org_id: orgId,
90
+ user_id: userId
91
+ }, (row) => {
92
+ const columns = {
93
+ ...patchToColumns(patch),
94
+ updated_at: now
95
+ };
96
+ if (fillIfUnset?.observerModelId !== void 0 && row.observer_model_id == null) columns.observer_model_id = patch.observerModelId ?? fillIfUnset.observerModelId;
97
+ if (fillIfUnset?.reflectorModelId !== void 0 && row.reflector_model_id == null) columns.reflector_model_id = patch.reflectorModelId ?? fillIfUnset.reflectorModelId;
98
+ return columns;
99
+ });
100
+ const updated = await updateExisting();
101
+ if (updated) return toRecord(updated);
102
+ try {
103
+ return toRecord(await this.#db.insertOne("memory_settings", {
104
+ org_id: orgId,
105
+ user_id: userId,
106
+ observer_model_id: fillIfUnset?.observerModelId ?? null,
107
+ reflector_model_id: fillIfUnset?.reflectorModelId ?? null,
108
+ observation_threshold: null,
109
+ reflection_threshold: null,
110
+ observe_attachments: null,
111
+ ...patchToColumns(patch),
112
+ created_at: now,
113
+ updated_at: now
114
+ }));
115
+ } catch (error) {
116
+ if (!(error instanceof UniqueViolationError)) throw error;
117
+ const row = await updateExisting();
118
+ if (!row) throw error;
119
+ return toRecord(row);
120
+ }
121
+ }
110
122
  };
123
+ //#endregion
124
+ export { MEMORY_SETTINGS_SCHEMA, MemorySettingsStorage };
125
+
111
126
  //# sourceMappingURL=base.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/storage/domains/memory-settings/base.ts"],"sourcesContent":["import { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\n/**\n * A user's persisted memory (observational-memory) configuration. The\n * DB-backed tenant counterpart of the local `settings.json` OM fields\n * (`observerModelOverride`, `reflectorModelOverride`, `omObservationThreshold`,\n * `omReflectionThreshold`, `omObserveAttachments`): one row per `(org, user)`,\n * every knob nullable so only explicitly-changed values are stored.\n */\nexport interface MemorySettingsRecord {\n orgId: string;\n userId: string;\n observerModelId: string | null;\n reflectorModelId: string | null;\n observationThreshold: number | null;\n reflectionThreshold: number | null;\n observeAttachments: 'auto' | boolean | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/** Partial update — only the provided knobs are written. */\nexport interface MemorySettingsPatch {\n observerModelId?: string;\n reflectorModelId?: string;\n observationThreshold?: number;\n reflectionThreshold?: number;\n observeAttachments?: 'auto' | boolean;\n}\n\n/**\n * Knobs written only when the stored value is still unset (`NULL`). The check\n * happens inside the backend's atomic-update primitive, so a concurrent\n * explicit write to the same knob is never clobbered by a fill.\n */\nexport interface MemorySettingsFillIfUnset {\n observerModelId?: string;\n reflectorModelId?: string;\n}\n\nexport const MEMORY_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'memory_settings',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n observer_model_id: { type: 'text', nullable: true },\n reflector_model_id: { type: 'text', nullable: true },\n observation_threshold: { type: 'integer', nullable: true },\n reflection_threshold: { type: 'integer', nullable: true },\n // 'auto' | true | false — json keeps the tri-state without string encoding.\n observe_attachments: { type: 'json', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'memory_settings_org_user_key', columns: ['org_id', 'user_id'] }],\n};\n\ninterface MemorySettingsDbRow extends Record<string, unknown> {\n id: string;\n org_id: string;\n user_id: string;\n observer_model_id: string | null;\n reflector_model_id: string | null;\n observation_threshold: number | null;\n reflection_threshold: number | null;\n observe_attachments: 'auto' | boolean | null;\n created_at: Date;\n updated_at: Date;\n}\n\nfunction toRecord(row: MemorySettingsDbRow): MemorySettingsRecord {\n return {\n orgId: row.org_id,\n userId: row.user_id,\n observerModelId: row.observer_model_id,\n reflectorModelId: row.reflector_model_id,\n observationThreshold: row.observation_threshold,\n reflectionThreshold: row.reflection_threshold,\n observeAttachments: row.observe_attachments,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction patchToColumns(patch: MemorySettingsPatch): Partial<MemorySettingsDbRow> {\n const columns: Partial<MemorySettingsDbRow> = {};\n if (patch.observerModelId !== undefined) columns.observer_model_id = patch.observerModelId;\n if (patch.reflectorModelId !== undefined) columns.reflector_model_id = patch.reflectorModelId;\n if (patch.observationThreshold !== undefined) columns.observation_threshold = patch.observationThreshold;\n if (patch.reflectionThreshold !== undefined) columns.reflection_threshold = patch.reflectionThreshold;\n if (patch.observeAttachments !== undefined) columns.observe_attachments = patch.observeAttachments;\n return columns;\n}\n\nexport class MemorySettingsStorage extends FactoryStorageDomain {\n constructor() {\n super('memory-settings');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([MEMORY_SETTINGS_SCHEMA]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('memory_settings', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async get({ orgId, userId }: { orgId: string; userId: string }): Promise<MemorySettingsRecord | null> {\n const row = await this.#db.findOne<MemorySettingsDbRow>('memory_settings', { org_id: orgId, user_id: userId });\n return row ? toRecord(row) : null;\n }\n\n /**\n * Upsert the user's row, writing only the knobs present in `patch`.\n * `fillIfUnset` knobs are written only where the stored value is still\n * `NULL`, decided inside the atomic update so concurrent explicit writes\n * win over fills. Concurrent first writes are resolved via the shared\n * insert-then-catch-unique-violation pattern (see `queue_health`).\n */\n async patch({\n orgId,\n userId,\n patch,\n fillIfUnset,\n }: {\n orgId: string;\n userId: string;\n patch: MemorySettingsPatch;\n fillIfUnset?: MemorySettingsFillIfUnset;\n }): Promise<MemorySettingsRecord> {\n const now = new Date();\n const updateExisting = () =>\n this.#db.updateAtomic<MemorySettingsDbRow>('memory_settings', { org_id: orgId, user_id: userId }, row => {\n const columns: Partial<MemorySettingsDbRow> = { ...patchToColumns(patch), updated_at: now };\n if (fillIfUnset?.observerModelId !== undefined && row.observer_model_id == null) {\n columns.observer_model_id = patch.observerModelId ?? fillIfUnset.observerModelId;\n }\n if (fillIfUnset?.reflectorModelId !== undefined && row.reflector_model_id == null) {\n columns.reflector_model_id = patch.reflectorModelId ?? fillIfUnset.reflectorModelId;\n }\n return columns;\n });\n\n const updated = await updateExisting();\n if (updated) return toRecord(updated);\n\n try {\n const row = await this.#db.insertOne<MemorySettingsDbRow>('memory_settings', {\n org_id: orgId,\n user_id: userId,\n observer_model_id: fillIfUnset?.observerModelId ?? null,\n reflector_model_id: fillIfUnset?.reflectorModelId ?? null,\n observation_threshold: null,\n reflection_threshold: null,\n observe_attachments: null,\n ...patchToColumns(patch),\n created_at: now,\n updated_at: now,\n });\n return toRecord(row);\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n // Lost the first-write race — apply the patch to the winning row.\n const row = await updateExisting();\n if (!row) throw error;\n return toRecord(row);\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"base.js","names":["#db"],"sources":["../../../../src/storage/domains/memory-settings/base.ts"],"sourcesContent":["import { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\n/**\n * A user's persisted memory (observational-memory) configuration. The\n * DB-backed tenant counterpart of the local `settings.json` OM fields\n * (`observerModelOverride`, `reflectorModelOverride`, `omObservationThreshold`,\n * `omReflectionThreshold`, `omObserveAttachments`): one row per `(org, user)`,\n * every knob nullable so only explicitly-changed values are stored.\n */\nexport interface MemorySettingsRecord {\n orgId: string;\n userId: string;\n observerModelId: string | null;\n reflectorModelId: string | null;\n observationThreshold: number | null;\n reflectionThreshold: number | null;\n observeAttachments: 'auto' | boolean | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/** Partial update — only the provided knobs are written. */\nexport interface MemorySettingsPatch {\n observerModelId?: string;\n reflectorModelId?: string;\n observationThreshold?: number;\n reflectionThreshold?: number;\n observeAttachments?: 'auto' | boolean;\n}\n\n/**\n * Knobs written only when the stored value is still unset (`NULL`). The check\n * happens inside the backend's atomic-update primitive, so a concurrent\n * explicit write to the same knob is never clobbered by a fill.\n */\nexport interface MemorySettingsFillIfUnset {\n observerModelId?: string;\n reflectorModelId?: string;\n}\n\nexport const MEMORY_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'memory_settings',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n observer_model_id: { type: 'text', nullable: true },\n reflector_model_id: { type: 'text', nullable: true },\n observation_threshold: { type: 'integer', nullable: true },\n reflection_threshold: { type: 'integer', nullable: true },\n // 'auto' | true | false — json keeps the tri-state without string encoding.\n observe_attachments: { type: 'json', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'memory_settings_org_user_key', columns: ['org_id', 'user_id'] }],\n};\n\ninterface MemorySettingsDbRow extends Record<string, unknown> {\n id: string;\n org_id: string;\n user_id: string;\n observer_model_id: string | null;\n reflector_model_id: string | null;\n observation_threshold: number | null;\n reflection_threshold: number | null;\n observe_attachments: 'auto' | boolean | null;\n created_at: Date;\n updated_at: Date;\n}\n\nfunction toRecord(row: MemorySettingsDbRow): MemorySettingsRecord {\n return {\n orgId: row.org_id,\n userId: row.user_id,\n observerModelId: row.observer_model_id,\n reflectorModelId: row.reflector_model_id,\n observationThreshold: row.observation_threshold,\n reflectionThreshold: row.reflection_threshold,\n observeAttachments: row.observe_attachments,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction patchToColumns(patch: MemorySettingsPatch): Partial<MemorySettingsDbRow> {\n const columns: Partial<MemorySettingsDbRow> = {};\n if (patch.observerModelId !== undefined) columns.observer_model_id = patch.observerModelId;\n if (patch.reflectorModelId !== undefined) columns.reflector_model_id = patch.reflectorModelId;\n if (patch.observationThreshold !== undefined) columns.observation_threshold = patch.observationThreshold;\n if (patch.reflectionThreshold !== undefined) columns.reflection_threshold = patch.reflectionThreshold;\n if (patch.observeAttachments !== undefined) columns.observe_attachments = patch.observeAttachments;\n return columns;\n}\n\nexport class MemorySettingsStorage extends FactoryStorageDomain {\n constructor() {\n super('memory-settings');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([MEMORY_SETTINGS_SCHEMA]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('memory_settings', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async get({ orgId, userId }: { orgId: string; userId: string }): Promise<MemorySettingsRecord | null> {\n const row = await this.#db.findOne<MemorySettingsDbRow>('memory_settings', { org_id: orgId, user_id: userId });\n return row ? toRecord(row) : null;\n }\n\n /**\n * Upsert the user's row, writing only the knobs present in `patch`.\n * `fillIfUnset` knobs are written only where the stored value is still\n * `NULL`, decided inside the atomic update so concurrent explicit writes\n * win over fills. Concurrent first writes are resolved via the shared\n * insert-then-catch-unique-violation pattern (see `queue_health`).\n */\n async patch({\n orgId,\n userId,\n patch,\n fillIfUnset,\n }: {\n orgId: string;\n userId: string;\n patch: MemorySettingsPatch;\n fillIfUnset?: MemorySettingsFillIfUnset;\n }): Promise<MemorySettingsRecord> {\n const now = new Date();\n const updateExisting = () =>\n this.#db.updateAtomic<MemorySettingsDbRow>('memory_settings', { org_id: orgId, user_id: userId }, row => {\n const columns: Partial<MemorySettingsDbRow> = { ...patchToColumns(patch), updated_at: now };\n if (fillIfUnset?.observerModelId !== undefined && row.observer_model_id == null) {\n columns.observer_model_id = patch.observerModelId ?? fillIfUnset.observerModelId;\n }\n if (fillIfUnset?.reflectorModelId !== undefined && row.reflector_model_id == null) {\n columns.reflector_model_id = patch.reflectorModelId ?? fillIfUnset.reflectorModelId;\n }\n return columns;\n });\n\n const updated = await updateExisting();\n if (updated) return toRecord(updated);\n\n try {\n const row = await this.#db.insertOne<MemorySettingsDbRow>('memory_settings', {\n org_id: orgId,\n user_id: userId,\n observer_model_id: fillIfUnset?.observerModelId ?? null,\n reflector_model_id: fillIfUnset?.reflectorModelId ?? null,\n observation_threshold: null,\n reflection_threshold: null,\n observe_attachments: null,\n ...patchToColumns(patch),\n created_at: now,\n updated_at: now,\n });\n return toRecord(row);\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n // Lost the first-write race — apply the patch to the winning row.\n const row = await updateExisting();\n if (!row) throw error;\n return toRecord(row);\n }\n }\n}\n"],"mappings":"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"}
@@ -1,95 +1,96 @@
1
- // src/storage/domains/model-packs/base.ts
2
1
  import { FactoryStorageDomain } from "@mastra/core/storage";
3
- var MODEL_PACKS_SCHEMA = {
4
- name: "model_packs",
5
- columns: {
6
- id: { type: "uuid-pk" },
7
- org_id: { type: "text" },
8
- created_by: { type: "text" },
9
- name: { type: "text" },
10
- build_model_id: { type: "text" },
11
- plan_model_id: { type: "text" },
12
- fast_model_id: { type: "text" },
13
- created_at: { type: "timestamp" },
14
- updated_at: { type: "timestamp" }
15
- },
16
- indexes: [{ name: "model_packs_org_name_idx", columns: ["org_id", "name"] }]
2
+ //#region src/storage/domains/model-packs/base.ts
3
+ const MODEL_PACKS_SCHEMA = {
4
+ name: "model_packs",
5
+ columns: {
6
+ id: { type: "uuid-pk" },
7
+ org_id: { type: "text" },
8
+ created_by: { type: "text" },
9
+ name: { type: "text" },
10
+ build_model_id: { type: "text" },
11
+ plan_model_id: { type: "text" },
12
+ fast_model_id: { type: "text" },
13
+ created_at: { type: "timestamp" },
14
+ updated_at: { type: "timestamp" }
15
+ },
16
+ indexes: [{
17
+ name: "model_packs_org_name_idx",
18
+ columns: ["org_id", "name"]
19
+ }]
17
20
  };
18
21
  function toModelPack(row) {
19
- return {
20
- id: row.id,
21
- orgId: row.org_id,
22
- createdBy: row.created_by,
23
- name: row.name,
24
- models: { build: row.build_model_id, plan: row.plan_model_id, fast: row.fast_model_id },
25
- createdAt: row.created_at,
26
- updatedAt: row.updated_at
27
- };
22
+ return {
23
+ id: row.id,
24
+ orgId: row.org_id,
25
+ createdBy: row.created_by,
26
+ name: row.name,
27
+ models: {
28
+ build: row.build_model_id,
29
+ plan: row.plan_model_id,
30
+ fast: row.fast_model_id
31
+ },
32
+ createdAt: row.created_at,
33
+ updatedAt: row.updated_at
34
+ };
28
35
  }
29
36
  var ModelPacksStorage = class extends FactoryStorageDomain {
30
- constructor() {
31
- super("model-packs");
32
- }
33
- async init() {
34
- await this.ensureCollections([MODEL_PACKS_SCHEMA]);
35
- }
36
- async dangerouslyClearAll() {
37
- await this.ops.deleteMany("model_packs", {});
38
- }
39
- get #db() {
40
- return this.ops;
41
- }
42
- /** Create or replace a pack by `(orgId, name)` — mirrors the settings.json upsert semantics. */
43
- async upsert({
44
- orgId,
45
- userId,
46
- input
47
- }) {
48
- const now = /* @__PURE__ */ new Date();
49
- const existing = await this.#db.findOne("model_packs", { org_id: orgId, name: input.name });
50
- if (existing) {
51
- const row2 = await this.#db.updateAtomic(
52
- "model_packs",
53
- { org_id: orgId, id: existing.id },
54
- () => ({
55
- build_model_id: input.models.build,
56
- plan_model_id: input.models.plan,
57
- fast_model_id: input.models.fast,
58
- updated_at: now
59
- })
60
- );
61
- return toModelPack(row2 ?? existing);
62
- }
63
- const row = await this.#db.insertOne("model_packs", {
64
- org_id: orgId,
65
- created_by: userId,
66
- name: input.name,
67
- build_model_id: input.models.build,
68
- plan_model_id: input.models.plan,
69
- fast_model_id: input.models.fast,
70
- created_at: now,
71
- updated_at: now
72
- });
73
- return toModelPack(row);
74
- }
75
- async list({ orgId }) {
76
- const rows = await this.#db.findMany(
77
- "model_packs",
78
- { org_id: orgId },
79
- { orderBy: [["name", "asc"]] }
80
- );
81
- return rows.map(toModelPack);
82
- }
83
- async get({ orgId, id }) {
84
- const row = await this.#db.findOne("model_packs", { org_id: orgId, id });
85
- return row ? toModelPack(row) : null;
86
- }
87
- async delete({ orgId, id }) {
88
- return await this.#db.deleteMany("model_packs", { org_id: orgId, id }) > 0;
89
- }
90
- };
91
- export {
92
- MODEL_PACKS_SCHEMA,
93
- ModelPacksStorage
37
+ constructor() {
38
+ super("model-packs");
39
+ }
40
+ async init() {
41
+ await this.ensureCollections([MODEL_PACKS_SCHEMA]);
42
+ }
43
+ async dangerouslyClearAll() {
44
+ await this.ops.deleteMany("model_packs", {});
45
+ }
46
+ get #db() {
47
+ return this.ops;
48
+ }
49
+ /** Create or replace a pack by `(orgId, name)` — mirrors the settings.json upsert semantics. */
50
+ async upsert({ orgId, userId, input }) {
51
+ const now = /* @__PURE__ */ new Date();
52
+ const existing = await this.#db.findOne("model_packs", {
53
+ org_id: orgId,
54
+ name: input.name
55
+ });
56
+ if (existing) return toModelPack(await this.#db.updateAtomic("model_packs", {
57
+ org_id: orgId,
58
+ id: existing.id
59
+ }, () => ({
60
+ build_model_id: input.models.build,
61
+ plan_model_id: input.models.plan,
62
+ fast_model_id: input.models.fast,
63
+ updated_at: now
64
+ })) ?? existing);
65
+ return toModelPack(await this.#db.insertOne("model_packs", {
66
+ org_id: orgId,
67
+ created_by: userId,
68
+ name: input.name,
69
+ build_model_id: input.models.build,
70
+ plan_model_id: input.models.plan,
71
+ fast_model_id: input.models.fast,
72
+ created_at: now,
73
+ updated_at: now
74
+ }));
75
+ }
76
+ async list({ orgId }) {
77
+ return (await this.#db.findMany("model_packs", { org_id: orgId }, { orderBy: [["name", "asc"]] })).map(toModelPack);
78
+ }
79
+ async get({ orgId, id }) {
80
+ const row = await this.#db.findOne("model_packs", {
81
+ org_id: orgId,
82
+ id
83
+ });
84
+ return row ? toModelPack(row) : null;
85
+ }
86
+ async delete({ orgId, id }) {
87
+ return await this.#db.deleteMany("model_packs", {
88
+ org_id: orgId,
89
+ id
90
+ }) > 0;
91
+ }
94
92
  };
93
+ //#endregion
94
+ export { MODEL_PACKS_SCHEMA, ModelPacksStorage };
95
+
95
96
  //# sourceMappingURL=base.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/storage/domains/model-packs/base.ts"],"sourcesContent":["import { FactoryStorageDomain } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\n/** A saved custom model pack: one model per mode (build / plan / fast). */\nexport interface ModelPackRecord {\n id: string;\n orgId: string;\n createdBy: string;\n name: string;\n models: { build: string; plan: string; fast: string };\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface UpsertModelPackInput {\n name: string;\n models: { build: string; plan: string; fast: string };\n}\n\nexport const MODEL_PACKS_SCHEMA: CollectionSchema = {\n name: 'model_packs',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n created_by: { type: 'text' },\n name: { type: 'text' },\n build_model_id: { type: 'text' },\n plan_model_id: { type: 'text' },\n fast_model_id: { type: 'text' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n indexes: [{ name: 'model_packs_org_name_idx', columns: ['org_id', 'name'] }],\n};\n\ninterface ModelPackDbRow extends Record<string, unknown> {\n id: string;\n org_id: string;\n created_by: string;\n name: string;\n build_model_id: string;\n plan_model_id: string;\n fast_model_id: string;\n created_at: Date;\n updated_at: Date;\n}\n\nfunction toModelPack(row: ModelPackDbRow): ModelPackRecord {\n return {\n id: row.id,\n orgId: row.org_id,\n createdBy: row.created_by,\n name: row.name,\n models: { build: row.build_model_id, plan: row.plan_model_id, fast: row.fast_model_id },\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nexport class ModelPacksStorage extends FactoryStorageDomain {\n constructor() {\n super('model-packs');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([MODEL_PACKS_SCHEMA]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('model_packs', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n /** Create or replace a pack by `(orgId, name)` — mirrors the settings.json upsert semantics. */\n async upsert({\n orgId,\n userId,\n input,\n }: {\n orgId: string;\n userId: string;\n input: UpsertModelPackInput;\n }): Promise<ModelPackRecord> {\n const now = new Date();\n const existing = await this.#db.findOne<ModelPackDbRow>('model_packs', { org_id: orgId, name: input.name });\n if (existing) {\n const row = await this.#db.updateAtomic<ModelPackDbRow>(\n 'model_packs',\n { org_id: orgId, id: existing.id },\n () => ({\n build_model_id: input.models.build,\n plan_model_id: input.models.plan,\n fast_model_id: input.models.fast,\n updated_at: now,\n }),\n );\n return toModelPack(row ?? existing);\n }\n const row = await this.#db.insertOne<ModelPackDbRow>('model_packs', {\n org_id: orgId,\n created_by: userId,\n name: input.name,\n build_model_id: input.models.build,\n plan_model_id: input.models.plan,\n fast_model_id: input.models.fast,\n created_at: now,\n updated_at: now,\n });\n return toModelPack(row);\n }\n\n async list({ orgId }: { orgId: string }): Promise<ModelPackRecord[]> {\n const rows = await this.#db.findMany<ModelPackDbRow>(\n 'model_packs',\n { org_id: orgId },\n { orderBy: [['name', 'asc']] },\n );\n return rows.map(toModelPack);\n }\n\n async get({ orgId, id }: { orgId: string; id: string }): Promise<ModelPackRecord | null> {\n const row = await this.#db.findOne<ModelPackDbRow>('model_packs', { org_id: orgId, id });\n return row ? toModelPack(row) : null;\n }\n\n async delete({ orgId, id }: { orgId: string; id: string }): Promise<boolean> {\n return (await this.#db.deleteMany('model_packs', { org_id: orgId, id })) > 0;\n }\n}\n"],"mappings":"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","names":["row"]}
1
+ {"version":3,"file":"base.js","names":["#db"],"sources":["../../../../src/storage/domains/model-packs/base.ts"],"sourcesContent":["import { FactoryStorageDomain } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\n/** A saved custom model pack: one model per mode (build / plan / fast). */\nexport interface ModelPackRecord {\n id: string;\n orgId: string;\n createdBy: string;\n name: string;\n models: { build: string; plan: string; fast: string };\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface UpsertModelPackInput {\n name: string;\n models: { build: string; plan: string; fast: string };\n}\n\nexport const MODEL_PACKS_SCHEMA: CollectionSchema = {\n name: 'model_packs',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n created_by: { type: 'text' },\n name: { type: 'text' },\n build_model_id: { type: 'text' },\n plan_model_id: { type: 'text' },\n fast_model_id: { type: 'text' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n indexes: [{ name: 'model_packs_org_name_idx', columns: ['org_id', 'name'] }],\n};\n\ninterface ModelPackDbRow extends Record<string, unknown> {\n id: string;\n org_id: string;\n created_by: string;\n name: string;\n build_model_id: string;\n plan_model_id: string;\n fast_model_id: string;\n created_at: Date;\n updated_at: Date;\n}\n\nfunction toModelPack(row: ModelPackDbRow): ModelPackRecord {\n return {\n id: row.id,\n orgId: row.org_id,\n createdBy: row.created_by,\n name: row.name,\n models: { build: row.build_model_id, plan: row.plan_model_id, fast: row.fast_model_id },\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nexport class ModelPacksStorage extends FactoryStorageDomain {\n constructor() {\n super('model-packs');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([MODEL_PACKS_SCHEMA]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('model_packs', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n /** Create or replace a pack by `(orgId, name)` — mirrors the settings.json upsert semantics. */\n async upsert({\n orgId,\n userId,\n input,\n }: {\n orgId: string;\n userId: string;\n input: UpsertModelPackInput;\n }): Promise<ModelPackRecord> {\n const now = new Date();\n const existing = await this.#db.findOne<ModelPackDbRow>('model_packs', { org_id: orgId, name: input.name });\n if (existing) {\n const row = await this.#db.updateAtomic<ModelPackDbRow>(\n 'model_packs',\n { org_id: orgId, id: existing.id },\n () => ({\n build_model_id: input.models.build,\n plan_model_id: input.models.plan,\n fast_model_id: input.models.fast,\n updated_at: now,\n }),\n );\n return toModelPack(row ?? existing);\n }\n const row = await this.#db.insertOne<ModelPackDbRow>('model_packs', {\n org_id: orgId,\n created_by: userId,\n name: input.name,\n build_model_id: input.models.build,\n plan_model_id: input.models.plan,\n fast_model_id: input.models.fast,\n created_at: now,\n updated_at: now,\n });\n return toModelPack(row);\n }\n\n async list({ orgId }: { orgId: string }): Promise<ModelPackRecord[]> {\n const rows = await this.#db.findMany<ModelPackDbRow>(\n 'model_packs',\n { org_id: orgId },\n { orderBy: [['name', 'asc']] },\n );\n return rows.map(toModelPack);\n }\n\n async get({ orgId, id }: { orgId: string; id: string }): Promise<ModelPackRecord | null> {\n const row = await this.#db.findOne<ModelPackDbRow>('model_packs', { org_id: orgId, id });\n return row ? toModelPack(row) : null;\n }\n\n async delete({ orgId, id }: { orgId: string; id: string }): Promise<boolean> {\n return (await this.#db.deleteMany('model_packs', { org_id: orgId, id })) > 0;\n }\n}\n"],"mappings":";;AAmBA,MAAa,qBAAuC;CAClD,MAAM;CACN,SAAS;EACP,IAAI,EAAE,MAAM,UAAU;EACtB,QAAQ,EAAE,MAAM,OAAO;EACvB,YAAY,EAAE,MAAM,OAAO;EAC3B,MAAM,EAAE,MAAM,OAAO;EACrB,gBAAgB,EAAE,MAAM,OAAO;EAC/B,eAAe,EAAE,MAAM,OAAO;EAC9B,eAAe,EAAE,MAAM,OAAO;EAC9B,YAAY,EAAE,MAAM,YAAY;EAChC,YAAY,EAAE,MAAM,YAAY;CAClC;CACA,SAAS,CAAC;EAAE,MAAM;EAA4B,SAAS,CAAC,UAAU,MAAM;CAAE,CAAC;AAC7E;AAcA,SAAS,YAAY,KAAsC;CACzD,OAAO;EACL,IAAI,IAAI;EACR,OAAO,IAAI;EACX,WAAW,IAAI;EACf,MAAM,IAAI;EACV,QAAQ;GAAE,OAAO,IAAI;GAAgB,MAAM,IAAI;GAAe,MAAM,IAAI;EAAc;EACtF,WAAW,IAAI;EACf,WAAW,IAAI;CACjB;AACF;AAEA,IAAa,oBAAb,cAAuC,qBAAqB;CAC1D,cAAc;EACZ,MAAM,aAAa;CACrB;CAEA,MAAM,OAAsB;EAC1B,MAAM,KAAK,kBAAkB,CAAC,kBAAkB,CAAC;CACnD;CAEA,MAAM,sBAAqC;EACzC,MAAM,KAAK,IAAI,WAAW,eAAe,CAAC,CAAC;CAC7C;CAEA,IAAIA,MAAyB;EAC3B,OAAO,KAAK;CACd;;CAGA,MAAM,OAAO,EACX,OACA,QACA,SAK2B;EAC3B,MAAM,sBAAM,IAAI,KAAK;EACrB,MAAM,WAAW,MAAM,KAAKA,IAAI,QAAwB,eAAe;GAAE,QAAQ;GAAO,MAAM,MAAM;EAAK,CAAC;EAC1G,IAAI,UAWF,OAAO,YAAY,MAVD,KAAKA,IAAI,aACzB,eACA;GAAE,QAAQ;GAAO,IAAI,SAAS;EAAG,UAC1B;GACL,gBAAgB,MAAM,OAAO;GAC7B,eAAe,MAAM,OAAO;GAC5B,eAAe,MAAM,OAAO;GAC5B,YAAY;EACd,EACF,KAC0B,QAAQ;EAYpC,OAAO,YAAY,MAVD,KAAKA,IAAI,UAA0B,eAAe;GAClE,QAAQ;GACR,YAAY;GACZ,MAAM,MAAM;GACZ,gBAAgB,MAAM,OAAO;GAC7B,eAAe,MAAM,OAAO;GAC5B,eAAe,MAAM,OAAO;GAC5B,YAAY;GACZ,YAAY;EACd,CAAC,CACqB;CACxB;CAEA,MAAM,KAAK,EAAE,SAAwD;EAMnE,QAAO,MALY,KAAKA,IAAI,SAC1B,eACA,EAAE,QAAQ,MAAM,GAChB,EAAE,SAAS,CAAC,CAAC,QAAQ,KAAK,CAAC,EAAE,CAC/B,EAAA,CACY,IAAI,WAAW;CAC7B;CAEA,MAAM,IAAI,EAAE,OAAO,MAAsE;EACvF,MAAM,MAAM,MAAM,KAAKA,IAAI,QAAwB,eAAe;GAAE,QAAQ;GAAO;EAAG,CAAC;EACvF,OAAO,MAAM,YAAY,GAAG,IAAI;CAClC;CAEA,MAAM,OAAO,EAAE,OAAO,MAAuD;EAC3E,OAAQ,MAAM,KAAKA,IAAI,WAAW,eAAe;GAAE,QAAQ;GAAO;EAAG,CAAC,IAAK;CAC7E;AACF"}