@mastra/factory 0.8.0-alpha.14 → 0.8.0-alpha.15

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 (73) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/factory.d.ts.map +1 -1
  3. package/dist/factory.js +30 -2
  4. package/dist/factory.js.map +1 -1
  5. package/dist/integrations/base.d.ts +8 -0
  6. package/dist/integrations/base.d.ts.map +1 -1
  7. package/dist/integrations/github/integration.d.ts.map +1 -1
  8. package/dist/integrations/github/integration.js +3 -1
  9. package/dist/integrations/github/integration.js.map +1 -1
  10. package/dist/integrations/github/reconcile-worker.d.ts +5 -0
  11. package/dist/integrations/github/reconcile-worker.d.ts.map +1 -1
  12. package/dist/integrations/github/reconcile-worker.js +7 -0
  13. package/dist/integrations/github/reconcile-worker.js.map +1 -1
  14. package/dist/integrations/github/routes.d.ts.map +1 -1
  15. package/dist/integrations/github/routes.js +7 -3
  16. package/dist/integrations/github/routes.js.map +1 -1
  17. package/dist/integrations/github/sandbox.d.ts +31 -1
  18. package/dist/integrations/github/sandbox.d.ts.map +1 -1
  19. package/dist/integrations/github/sandbox.js +12 -6
  20. package/dist/integrations/github/sandbox.js.map +1 -1
  21. package/dist/integrations/platform/github/integration.d.ts +7 -0
  22. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  23. package/dist/integrations/platform/github/integration.js +32 -3
  24. package/dist/integrations/platform/github/integration.js.map +1 -1
  25. package/dist/routes/config.d.ts +8 -6
  26. package/dist/routes/config.d.ts.map +1 -1
  27. package/dist/routes/config.js +91 -56
  28. package/dist/routes/config.js.map +1 -1
  29. package/dist/routes/projects.d.ts +9 -1
  30. package/dist/routes/projects.d.ts.map +1 -1
  31. package/dist/routes/projects.js +8 -0
  32. package/dist/routes/projects.js.map +1 -1
  33. package/dist/routes/surface.d.ts +5 -0
  34. package/dist/routes/surface.d.ts.map +1 -1
  35. package/dist/routes/surface.js +2 -0
  36. package/dist/routes/surface.js.map +1 -1
  37. package/dist/sandbox/base-checkpoint-triggers.d.ts +77 -0
  38. package/dist/sandbox/base-checkpoint-triggers.d.ts.map +1 -0
  39. package/dist/sandbox/base-checkpoint-triggers.js +137 -0
  40. package/dist/sandbox/base-checkpoint-triggers.js.map +1 -0
  41. package/dist/sandbox/base-checkpoint.d.ts +59 -0
  42. package/dist/sandbox/base-checkpoint.d.ts.map +1 -0
  43. package/dist/sandbox/base-checkpoint.js +145 -0
  44. package/dist/sandbox/base-checkpoint.js.map +1 -0
  45. package/dist/sandbox/fleet.d.ts +32 -0
  46. package/dist/sandbox/fleet.d.ts.map +1 -1
  47. package/dist/sandbox/fleet.js +39 -10
  48. package/dist/sandbox/fleet.js.map +1 -1
  49. package/dist/session/checkpoint-capture.d.ts +3 -2
  50. package/dist/session/checkpoint-capture.d.ts.map +1 -1
  51. package/dist/session/checkpoint-capture.js +3 -3
  52. package/dist/session/checkpoint-capture.js.map +1 -1
  53. package/dist/session/model-pack-hydration.d.ts +55 -0
  54. package/dist/session/model-pack-hydration.d.ts.map +1 -0
  55. package/dist/session/model-pack-hydration.js +56 -0
  56. package/dist/session/model-pack-hydration.js.map +1 -0
  57. package/dist/storage/domains/model-packs/base.d.ts +26 -0
  58. package/dist/storage/domains/model-packs/base.d.ts.map +1 -1
  59. package/dist/storage/domains/model-packs/base.js +102 -13
  60. package/dist/storage/domains/model-packs/base.js.map +1 -1
  61. package/dist/storage/domains/source-control/base.d.ts +28 -0
  62. package/dist/storage/domains/source-control/base.d.ts.map +1 -1
  63. package/dist/storage/domains/source-control/base.js +70 -14
  64. package/dist/storage/domains/source-control/base.js.map +1 -1
  65. package/dist/storage/domains/source-control/inmemory.d.ts +9 -1
  66. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  67. package/dist/storage/domains/source-control/inmemory.js +8 -0
  68. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  69. package/dist/workspace.d.ts +31 -2
  70. package/dist/workspace.d.ts.map +1 -1
  71. package/dist/workspace.js +224 -53
  72. package/dist/workspace.js.map +1 -1
  73. package/package.json +1 -1
@@ -1,10 +1,11 @@
1
1
  import { WEB_OAUTH_FLOW_KINDS, getAuthProviderId, listTenantCredentialsForRequest, resolveCredentialContext, tenantOrgId } from "./provider-credentials.js";
2
2
  import { Route } from "./route.js";
3
3
  import { applyStoredMemorySettings } from "../session/memory-settings-hydration.js";
4
+ import { applyActiveModelPack } from "../session/model-pack-hydration.js";
4
5
  import { registerApiRoute } from "@mastra/core/server";
5
6
  import { DEFAULT_OM_MODEL_ID } from "@mastra/code-sdk/constants";
6
7
  import { getAvailableModePacks, resolveProviderOMDefault } from "@mastra/code-sdk/onboarding/packs";
7
- import { THINKING_LEVEL_VALUES, THREAD_ACTIVE_MODEL_PACK_ID_KEY, getCustomProviderId, isThinkingLevelSetting, loadSettings, saveSettings } from "@mastra/code-sdk/onboarding/settings";
8
+ import { THINKING_LEVEL_VALUES, getCustomProviderId, isThinkingLevelSetting, loadSettings, saveSettings } from "@mastra/code-sdk/onboarding/settings";
8
9
  //#region src/routes/config.ts
9
10
  /** Widen a route-local Hono context to the plain `Context` the auth helpers take. */
10
11
  function loose(c) {
@@ -173,6 +174,13 @@ async function resolvePackContext({ c, auth, modelPacks }) {
173
174
  message: "Model pack storage is unavailable — the app database is not configured or failed to start."
174
175
  }, 503) };
175
176
  }
177
+ async function authorizePackSession({ c, auth, sessions, packContext, resourceId, scope }) {
178
+ if (!auth.enabled()) return null;
179
+ if (!sessions) return c.json({ error: "session_authorization_unavailable" }, 503);
180
+ const sourceSession = await sessions.getBySessionId(resourceId);
181
+ if (!sourceSession || sourceSession.orgId !== packContext.orgId || sourceSession.userId !== packContext.userId || !scope || sourceSession.sandboxWorkdir !== scope) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
182
+ return null;
183
+ }
176
184
  /** DB row → the `ModePack` shape the packs list and activation flow consume. */
177
185
  function recordToModePack(record) {
178
186
  return {
@@ -185,8 +193,8 @@ function recordToModePack(record) {
185
193
  /**
186
194
  * List available model packs (built-in, gated by provider access, plus saved
187
195
  * custom packs from the request's pack context). Drops the synthetic
188
- * "New Custom" placeholder — the web client has its own create flow. `active`
189
- * is set from the given session's thread when a resourceId is supplied.
196
+ * "New Custom" placeholder because the web client has its own create flow.
197
+ * `active` marks the user's default pack for new interactive chats.
190
198
  */
191
199
  async function listModelPacks({ controller, authStorage, tenantCredentials, packContext, activePackId }) {
192
200
  return [...getAvailableModePacks(await buildProviderAccess({
@@ -199,50 +207,11 @@ async function listModelPacks({ controller, authStorage, tenantCredentials, pack
199
207
  active: activePackId != null && p.id === activePackId
200
208
  }));
201
209
  }
202
- /** Resolve the active pack id for a session by reading its current thread. */
203
- async function resolveActivePackId(session) {
204
- if (!session) return null;
205
- const threadId = session.thread.getId();
206
- if (!threadId) return null;
207
- const value = (await session.thread.list()).find((t) => t.id === threadId)?.metadata?.[THREAD_ACTIVE_MODEL_PACK_ID_KEY];
210
+ async function resolveSessionModelPackId(session) {
211
+ if (!session?.thread.getId()) return null;
212
+ const value = await session.thread.getSetting({ key: "activeModelPackId" });
208
213
  return typeof value === "string" ? value : null;
209
214
  }
210
- /**
211
- * Apply a pack to a session: seed each mode's default model, switch the current
212
- * mode's model, set per-subagent models, and tag the thread with the active
213
- * pack id. Mirrors the TUI `applyPack` orchestration.
214
- */
215
- async function applyPackToSession({ controller, session, pack }) {
216
- const modes = controller.listModes?.() ?? [];
217
- const packModels = pack.models;
218
- for (const mode of modes) {
219
- const modelId = packModels[mode.id];
220
- if (modelId) {
221
- mode.defaultModelId = modelId;
222
- await session.thread.setSetting({
223
- key: `modeModelId_${mode.id}`,
224
- value: modelId
225
- });
226
- }
227
- }
228
- const currentModeModel = packModels[session.mode.get()];
229
- if (currentModeModel) await session.model.switch({ modelId: currentModeModel });
230
- for (const [agentType, modeId] of Object.entries({
231
- explore: "fast",
232
- plan: "plan",
233
- execute: "build"
234
- })) {
235
- const saModelId = packModels[modeId];
236
- if (saModelId) await session.subagents.model.set({
237
- modelId: saModelId,
238
- agentType
239
- });
240
- }
241
- await session.thread.setSetting({
242
- key: THREAD_ACTIVE_MODEL_PACK_ID_KEY,
243
- value: pack.id
244
- });
245
- }
246
215
  function readOMConfig(session) {
247
216
  const observeAttachments = (session.state.get() ?? {}).observeAttachments;
248
217
  return {
@@ -595,7 +564,22 @@ var ConfigRoutes = class extends Route {
595
564
  const resourceId = c.req.query("resourceId");
596
565
  const scope = c.req.query("scope") || void 0;
597
566
  try {
598
- const activePackId = await resolveActivePackId(resourceId ? await controller.getSessionByResource?.(resourceId, scope) : void 0);
567
+ const activePackId = (await packContext.storage.getActive({
568
+ orgId: packContext.orgId,
569
+ userId: packContext.userId
570
+ }))?.packId ?? null;
571
+ if (resourceId) {
572
+ const unauthorized = await authorizePackSession({
573
+ c: loose(c),
574
+ auth,
575
+ sessions: options.sourceControlSessions,
576
+ packContext,
577
+ resourceId,
578
+ scope
579
+ });
580
+ if (unauthorized) return unauthorized;
581
+ }
582
+ const sessionPackId = await resolveSessionModelPackId(resourceId ? await controller.getSessionByResource?.(resourceId, scope) : void 0);
599
583
  const tenantCredentials = await listTenantCredentialsForRequest({
600
584
  c: loose(c),
601
585
  auth,
@@ -609,7 +593,8 @@ var ConfigRoutes = class extends Route {
609
593
  packContext,
610
594
  activePackId
611
595
  }),
612
- activePackId
596
+ activePackId,
597
+ sessionPackId
613
598
  });
614
599
  } catch (error) {
615
600
  return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
@@ -661,6 +646,30 @@ var ConfigRoutes = class extends Route {
661
646
  }
662
647
  }
663
648
  }),
649
+ registerApiRoute("/web/config/model-packs/active", {
650
+ method: "DELETE",
651
+ requiresAuth: false,
652
+ handler: async (c) => {
653
+ const packContext = await resolvePackContext({
654
+ c: loose(c),
655
+ auth,
656
+ modelPacks: options.modelPacks
657
+ });
658
+ if ("response" in packContext) return packContext.response;
659
+ try {
660
+ await packContext.storage.clearActive({
661
+ orgId: packContext.orgId,
662
+ userId: packContext.userId
663
+ });
664
+ return c.json({
665
+ ok: true,
666
+ activePackId: null
667
+ });
668
+ } catch (error) {
669
+ return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
670
+ }
671
+ }
672
+ }),
664
673
  registerApiRoute("/web/config/model-packs/:id", {
665
674
  method: "DELETE",
666
675
  requiresAuth: false,
@@ -700,12 +709,25 @@ var ConfigRoutes = class extends Route {
700
709
  } catch {
701
710
  return c.json({ error: "Invalid JSON body" }, 400);
702
711
  }
703
- const resourceId = typeof body.resourceId === "string" ? body.resourceId : "";
712
+ const target = body.target ?? "default";
713
+ if (target !== "default" && target !== "session") return c.json({ error: "target must be \"default\" or \"session\"" }, 400);
714
+ const resourceId = typeof body.resourceId === "string" && body.resourceId ? body.resourceId : void 0;
704
715
  const scope = typeof body.scope === "string" && body.scope ? body.scope : void 0;
705
- if (!resourceId) return c.json({ error: "Missing required field: resourceId" }, 400);
716
+ if (target === "session" && !resourceId) return c.json({ error: "Missing required field for session activation: resourceId" }, 400);
706
717
  try {
707
- const session = await controller.getSessionByResource?.(resourceId, scope);
708
- if (!session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
718
+ if (target === "session" && resourceId) {
719
+ const unauthorized = await authorizePackSession({
720
+ c: loose(c),
721
+ auth,
722
+ sessions: options.sourceControlSessions,
723
+ packContext,
724
+ resourceId,
725
+ scope
726
+ });
727
+ if (unauthorized) return unauthorized;
728
+ }
729
+ const session = target === "session" && resourceId ? await controller.getSessionByResource?.(resourceId, scope) : void 0;
730
+ if (target === "session" && !session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
709
731
  const tenantCredentials = await listTenantCredentialsForRequest({
710
732
  c: loose(c),
711
733
  auth,
@@ -718,14 +740,27 @@ var ConfigRoutes = class extends Route {
718
740
  packContext
719
741
  })).find((p) => p.id === id);
720
742
  if (!pack) return c.json({ error: `Unknown pack "${id}"` }, 404);
721
- await applyPackToSession({
722
- controller,
723
- session,
724
- pack
743
+ if (target === "default") {
744
+ await packContext.storage.setActive({
745
+ orgId: packContext.orgId,
746
+ userId: packContext.userId,
747
+ packId: pack.id,
748
+ models: pack.models
749
+ });
750
+ return c.json({
751
+ ok: true,
752
+ target,
753
+ activePackId: pack.id
754
+ });
755
+ }
756
+ if (session) await applyActiveModelPack(session, {
757
+ packId: pack.id,
758
+ models: pack.models
725
759
  });
726
760
  return c.json({
727
761
  ok: true,
728
- activePackId: pack.id
762
+ target,
763
+ sessionPackId: pack.id
729
764
  });
730
765
  } catch (error) {
731
766
  return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);