@mastra/factory 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/factory.js +142 -35
  3. package/dist/factory.js.map +1 -1
  4. package/dist/index.js +142 -35
  5. package/dist/index.js.map +1 -1
  6. package/dist/integrations/github/integration.js +1 -1
  7. package/dist/integrations/github/integration.js.map +1 -1
  8. package/dist/integrations/github/routes.js +1 -1
  9. package/dist/integrations/github/routes.js.map +1 -1
  10. package/dist/integrations/platform/api-client.js +1 -1
  11. package/dist/integrations/platform/api-client.js.map +1 -1
  12. package/dist/integrations/platform/github/event-worker.js.map +1 -1
  13. package/dist/integrations/platform/github/integration.js +2 -2
  14. package/dist/integrations/platform/github/integration.js.map +1 -1
  15. package/dist/integrations/platform/linear/integration.js +1 -1
  16. package/dist/integrations/platform/linear/integration.js.map +1 -1
  17. package/dist/routes/config.d.ts +4 -0
  18. package/dist/routes/config.d.ts.map +1 -1
  19. package/dist/routes/config.js +89 -26
  20. package/dist/routes/config.js.map +1 -1
  21. package/dist/routes/surface.d.ts.map +1 -1
  22. package/dist/routes/surface.js +136 -31
  23. package/dist/routes/surface.js.map +1 -1
  24. package/dist/routes/work-items.d.ts.map +1 -1
  25. package/dist/routes/work-items.js +2 -1
  26. package/dist/routes/work-items.js.map +1 -1
  27. package/dist/rules/defaults.d.ts.map +1 -1
  28. package/dist/rules/defaults.js +3 -1
  29. package/dist/rules/defaults.js.map +1 -1
  30. package/dist/rules/github-service.d.ts.map +1 -1
  31. package/dist/rules/github-service.js +10 -2
  32. package/dist/rules/github-service.js.map +1 -1
  33. package/dist/rules/index.js +3 -1
  34. package/dist/rules/index.js.map +1 -1
  35. package/dist/rules/start-coordinator.d.ts +3 -1
  36. package/dist/rules/start-coordinator.d.ts.map +1 -1
  37. package/dist/rules/start-coordinator.js +33 -1
  38. package/dist/rules/start-coordinator.js.map +1 -1
  39. package/dist/server-error.js +1 -1
  40. package/dist/server-error.js.map +1 -1
  41. package/package.json +6 -6
@@ -296,6 +296,16 @@ async function applyPackToSession({
296
296
  }
297
297
  var DEFAULT_OBSERVATION_THRESHOLD = 3e4;
298
298
  var DEFAULT_REFLECTION_THRESHOLD = 4e4;
299
+ function providerOMModelId(providerId, factoryModelId) {
300
+ switch (providerId) {
301
+ case "anthropic":
302
+ return "anthropic/claude-haiku-4-5";
303
+ case "openai":
304
+ return "openai/gpt-5.4-mini";
305
+ default:
306
+ return factoryModelId || DEFAULT_OM_MODEL_ID;
307
+ }
308
+ }
299
309
  function readOMConfig(session) {
300
310
  const state = session.state.get() ?? {};
301
311
  const observeAttachments = state.observeAttachments;
@@ -307,6 +317,15 @@ function readOMConfig(session) {
307
317
  observeAttachments: observeAttachments === true || observeAttachments === false ? observeAttachments : "auto"
308
318
  };
309
319
  }
320
+ function readStoredOMConfig(record) {
321
+ return {
322
+ observerModelId: record?.observerModelId ?? DEFAULT_OM_MODEL_ID,
323
+ reflectorModelId: record?.reflectorModelId ?? DEFAULT_OM_MODEL_ID,
324
+ observationThreshold: record?.observationThreshold ?? DEFAULT_OBSERVATION_THRESHOLD,
325
+ reflectionThreshold: record?.reflectionThreshold ?? DEFAULT_REFLECTION_THRESHOLD,
326
+ observeAttachments: record?.observeAttachments ?? "auto"
327
+ };
328
+ }
310
329
  async function resolveMemorySettingsContext({
311
330
  c,
312
331
  auth,
@@ -716,19 +735,60 @@ var ConfigRoutes = class extends Route {
716
735
  }
717
736
  }
718
737
  }),
738
+ registerApiRoute("/web/config/om/provider-defaults", {
739
+ method: "POST",
740
+ requiresAuth: false,
741
+ handler: async (c) => {
742
+ let body;
743
+ try {
744
+ body = await c.req.json();
745
+ } catch {
746
+ return c.json({ error: "Invalid JSON body" }, 400);
747
+ }
748
+ const providerId = typeof body.providerId === "string" ? body.providerId.trim() : "";
749
+ const factoryModelId = typeof body.factoryModelId === "string" ? body.factoryModelId.trim() : "";
750
+ if (!providerId) return c.json({ error: "Missing required field: providerId" }, 400);
751
+ const context = await resolveMemorySettingsContext({
752
+ c: loose(c),
753
+ auth,
754
+ memorySettings: options.memorySettings
755
+ });
756
+ if ("response" in context) return context.response;
757
+ try {
758
+ const tenantCredentials = await listTenantCredentialsForRequest({
759
+ c: loose(c),
760
+ auth,
761
+ credentials: options.modelCredentials
762
+ });
763
+ const access = await buildProviderAccess({
764
+ controller,
765
+ authStorage: tenantCredentials ? void 0 : authStorage,
766
+ tenantCredentials
767
+ });
768
+ if (!access[providerId]) return c.json({ error: `Provider "${providerId}" is not configured` }, 400);
769
+ const modelId = providerOMModelId(providerId, factoryModelId);
770
+ const record = await context.storage.patch({
771
+ orgId: context.orgId,
772
+ userId: context.userId,
773
+ patch: {},
774
+ fillIfUnset: { observerModelId: modelId, reflectorModelId: modelId }
775
+ });
776
+ return c.json({ ok: true, config: readStoredOMConfig(record) });
777
+ } catch (error) {
778
+ return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
779
+ }
780
+ }
781
+ }),
719
782
  // ── Observational memory ──────────────────────────────────────────────────
720
- // Mirrors the TUI's /om command. All five knobs are session-scoped (resolved
721
- // from the session, persisted to its state + thread setting) and durably
722
- // stored in the per-(org, user) `memory-settings` app table never
723
- // settings.json. GET hydrates the session from the stored row first so the
724
- // DB, not the SDK's boot-time seed, is the source of truth.
783
+ // Mirrors the TUI's /om command. All five knobs are durably stored in the
784
+ // per-(org, user) `memory-settings` app table never settings.json. When a
785
+ // session is supplied, changes are also applied to its state and thread.
725
786
  registerApiRoute("/web/config/om", {
726
787
  method: "GET",
727
788
  requiresAuth: false,
728
789
  handler: async (c) => {
729
790
  const resourceId = c.req.query("resourceId");
730
791
  const scope = c.req.query("scope") || void 0;
731
- if (!resourceId) return c.json({ error: "Missing required query param: resourceId" }, 400);
732
792
  const context = await resolveMemorySettingsContext({
733
793
  c: loose(c),
734
794
  auth,
@@ -736,9 +796,10 @@ var ConfigRoutes = class extends Route {
736
796
  });
737
797
  if ("response" in context) return context.response;
738
798
  try {
799
+ const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });
800
+ if (!resourceId) return c.json({ config: readStoredOMConfig(record) });
739
801
  const session = await controller.getSessionByResource?.(resourceId, scope);
740
802
  if (!session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
741
- const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });
742
803
  await hydrateSessionMemorySettings(session, record);
743
804
  return c.json({ config: readOMConfig(session) });
744
805
  } catch (error) {
@@ -763,7 +824,6 @@ var ConfigRoutes = class extends Route {
763
824
  const resourceId = typeof body.resourceId === "string" ? body.resourceId : "";
764
825
  const scope = typeof body.scope === "string" && body.scope ? body.scope : void 0;
765
826
  const modelId = typeof body.modelId === "string" ? body.modelId.trim() : "";
766
- if (!resourceId) return c.json({ error: "Missing required field: resourceId" }, 400);
767
827
  if (!modelId) return c.json({ error: "Missing required field: modelId" }, 400);
768
828
  const context = await resolveMemorySettingsContext({
769
829
  c: loose(c),
@@ -772,18 +832,19 @@ var ConfigRoutes = class extends Route {
772
832
  });
773
833
  if ("response" in context) return context.response;
774
834
  try {
775
- const session = await controller.getSessionByResource?.(resourceId, scope);
776
- if (!session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
777
- const otherRole = role === "observer" ? session.om.reflector : session.om.observer;
778
- const otherRoleCurrentModelId = otherRole.modelId() ?? null;
779
- await session.om[role].switchModel({ modelId });
835
+ const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : void 0;
836
+ if (resourceId && !session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
837
+ const otherRole = session ? role === "observer" ? session.om.reflector : session.om.observer : void 0;
838
+ const otherRoleCurrentModelId = otherRole?.modelId() ?? null;
839
+ await session?.om[role].switchModel({ modelId });
780
840
  const otherKey = role === "observer" ? "reflectorModelId" : "observerModelId";
781
841
  await persistMemorySettings(
782
842
  context,
783
843
  { [role === "observer" ? "observerModelId" : "reflectorModelId"]: modelId },
784
844
  otherRoleCurrentModelId ? { [otherKey]: otherRoleCurrentModelId } : void 0
785
845
  );
786
- return c.json({ ok: true, config: readOMConfig(session) });
846
+ const config = session ? readOMConfig(session) : readStoredOMConfig(await context.storage.get({ orgId: context.orgId, userId: context.userId }));
847
+ return c.json({ ok: true, config });
787
848
  } catch (error) {
788
849
  return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
789
850
  }
@@ -801,7 +862,6 @@ var ConfigRoutes = class extends Route {
801
862
  }
802
863
  const resourceId = typeof body.resourceId === "string" ? body.resourceId : "";
803
864
  const scope = typeof body.scope === "string" && body.scope ? body.scope : void 0;
804
- if (!resourceId) return c.json({ error: "Missing required field: resourceId" }, 400);
805
865
  const observation = typeof body.observationThreshold === "number" && body.observationThreshold > 0 ? Math.round(body.observationThreshold) : void 0;
806
866
  const reflection = typeof body.reflectionThreshold === "number" && body.reflectionThreshold > 0 ? Math.round(body.reflectionThreshold) : void 0;
807
867
  if (observation === void 0 && reflection === void 0) {
@@ -814,13 +874,13 @@ var ConfigRoutes = class extends Route {
814
874
  });
815
875
  if ("response" in context) return context.response;
816
876
  try {
817
- const session = await controller.getSessionByResource?.(resourceId, scope);
818
- if (!session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
819
- if (observation !== void 0) {
877
+ const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : void 0;
878
+ if (resourceId && !session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
879
+ if (observation !== void 0 && session) {
820
880
  await session.state.set({ observationThreshold: observation });
821
881
  await session.thread.setSetting({ key: "observationThreshold", value: observation });
822
882
  }
823
- if (reflection !== void 0) {
883
+ if (reflection !== void 0 && session) {
824
884
  await session.state.set({ reflectionThreshold: reflection });
825
885
  await session.thread.setSetting({ key: "reflectionThreshold", value: reflection });
826
886
  }
@@ -828,7 +888,8 @@ var ConfigRoutes = class extends Route {
828
888
  ...observation !== void 0 ? { observationThreshold: observation } : {},
829
889
  ...reflection !== void 0 ? { reflectionThreshold: reflection } : {}
830
890
  });
831
- return c.json({ ok: true, config: readOMConfig(session) });
891
+ const config = session ? readOMConfig(session) : readStoredOMConfig(await context.storage.get({ orgId: context.orgId, userId: context.userId }));
892
+ return c.json({ ok: true, config });
832
893
  } catch (error) {
833
894
  return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
834
895
  }
@@ -846,7 +907,6 @@ var ConfigRoutes = class extends Route {
846
907
  }
847
908
  const resourceId = typeof body.resourceId === "string" ? body.resourceId : "";
848
909
  const scope = typeof body.scope === "string" && body.scope ? body.scope : void 0;
849
- if (!resourceId) return c.json({ error: "Missing required field: resourceId" }, 400);
850
910
  const raw = body.value;
851
911
  const value = raw === "auto" || raw === true || raw === false ? raw : "auto";
852
912
  if (raw !== "auto" && raw !== true && raw !== false) {
@@ -859,12 +919,15 @@ var ConfigRoutes = class extends Route {
859
919
  });
860
920
  if ("response" in context) return context.response;
861
921
  try {
862
- const session = await controller.getSessionByResource?.(resourceId, scope);
863
- if (!session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
864
- await session.state.set({ observeAttachments: value });
865
- await session.thread.setSetting({ key: "observeAttachments", value });
922
+ const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : void 0;
923
+ if (resourceId && !session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
924
+ if (session) {
925
+ await session.state.set({ observeAttachments: value });
926
+ await session.thread.setSetting({ key: "observeAttachments", value });
927
+ }
866
928
  await persistMemorySettings(context, { observeAttachments: value });
867
- return c.json({ ok: true, config: readOMConfig(session) });
929
+ const config = session ? readOMConfig(session) : readStoredOMConfig(await context.storage.get({ orgId: context.orgId, userId: context.userId }));
930
+ return c.json({ ok: true, config });
868
931
  } catch (error) {
869
932
  return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
870
933
  }