@mastra/factory 0.25.0-alpha.7 → 0.25.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.
- package/dist/factory.d.ts +1 -1
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +27 -3
- package/dist/factory.js.map +1 -1
- package/dist/integrations/slack/integration.d.ts +7 -8
- package/dist/integrations/slack/integration.d.ts.map +1 -1
- package/dist/integrations/slack/integration.js +11 -3
- package/dist/integrations/slack/integration.js.map +1 -1
- package/dist/integrations/slack/slack.d.ts +3 -1
- package/dist/integrations/slack/slack.d.ts.map +1 -1
- package/dist/integrations/slack/slack.js.map +1 -1
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +131 -54
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/provider-credentials.d.ts +6 -1
- package/dist/routes/provider-credentials.d.ts.map +1 -1
- package/dist/routes/provider-credentials.js +2 -2
- package/dist/routes/provider-credentials.js.map +1 -1
- package/dist/storage/domains/audit/domain.d.ts.map +1 -1
- package/dist/storage/domains/audit/domain.js +10 -3
- package/dist/storage/domains/audit/domain.js.map +1 -1
- package/package.json +15 -15
package/dist/routes/config.js
CHANGED
|
@@ -8,6 +8,7 @@ import { factoryMemorySettingsUserId } from "../storage/domains/memory-settings/
|
|
|
8
8
|
import { Route } from "./route.js";
|
|
9
9
|
import { RequestContext } from "@mastra/core/request-context";
|
|
10
10
|
import { registerApiRoute } from "@mastra/core/server";
|
|
11
|
+
import { MIN_OBSERVATION_THRESHOLD } from "@mastra/code-sdk/constants";
|
|
11
12
|
import { z } from "zod";
|
|
12
13
|
import { MASTRA_GATEWAY_PREFIX } from "@mastra/code-sdk/providers/model-ids";
|
|
13
14
|
import { MastraCodeGateway } from "@mastra/code-sdk/agents/mastracode-gateway";
|
|
@@ -306,7 +307,7 @@ function readStoredOMConfig(record, currentModelId, autoModelSource, availablePr
|
|
|
306
307
|
reflector: roleConfig(record?.reflectorModelId ?? "auto", reflectorModelId, autoModelSource, availableProviders),
|
|
307
308
|
observerModelId,
|
|
308
309
|
reflectorModelId,
|
|
309
|
-
observationThreshold: record?.observationThreshold ?? 3e4,
|
|
310
|
+
observationThreshold: Math.max(record?.observationThreshold ?? 3e4, MIN_OBSERVATION_THRESHOLD),
|
|
310
311
|
reflectionThreshold: record?.reflectionThreshold ?? 4e4,
|
|
311
312
|
observeAttachments: record?.observeAttachments ?? "auto"
|
|
312
313
|
};
|
|
@@ -381,12 +382,87 @@ var ConfigRoutes = class extends Route {
|
|
|
381
382
|
const { controller, authStorage, auth, deploymentProviders } = options;
|
|
382
383
|
const onCredentialsChanged = options.onCredentialsChanged ?? (() => {});
|
|
383
384
|
const onCustomProvidersChanged = options.onCustomProvidersChanged ?? (() => {});
|
|
384
|
-
const
|
|
385
|
-
const
|
|
385
|
+
const resolveSessionModelContext = async (c, address, includeDefaultModel = true) => {
|
|
386
|
+
const tenant = auth.tenant(c);
|
|
387
|
+
if (!tenant && auth.enabled()) return { response: c.json({ error: "unauthorized" }, 401) };
|
|
388
|
+
if (!tenant) return void 0;
|
|
389
|
+
if (!options.factoryProjects || !options.sourceControlSessions || !options.workItems || !options.modelCredentials) return { response: c.json({ error: "session_model_policy_unavailable" }, 503) };
|
|
390
|
+
const requestContext = new RequestContext();
|
|
391
|
+
requestContext.set("user", {
|
|
392
|
+
id: tenant.userId,
|
|
393
|
+
organizationId: tenantOrgId(tenant)
|
|
394
|
+
});
|
|
395
|
+
requestContext.set("controller", address);
|
|
396
|
+
let policy;
|
|
397
|
+
try {
|
|
398
|
+
policy = await resolveFactoryModelPolicy(requestContext, {
|
|
399
|
+
projects: options.factoryProjects,
|
|
400
|
+
sourceControl: options.sourceControlSessions,
|
|
401
|
+
workItems: options.workItems
|
|
402
|
+
});
|
|
403
|
+
} catch {
|
|
404
|
+
return { response: c.json({ error: "session_model_policy_unavailable" }, 403) };
|
|
405
|
+
}
|
|
406
|
+
if (!policy) return { response: c.json({ error: "unauthorized" }, 401) };
|
|
407
|
+
const orgId = policy.tenant.orgId ?? tenantOrgId(tenant);
|
|
408
|
+
const modelScope = policy.tenant.credentialScope ?? "user";
|
|
409
|
+
const tenantCredentials = await listSessionScopedCredentials({
|
|
410
|
+
credentials: options.modelCredentials,
|
|
411
|
+
orgId,
|
|
412
|
+
userId: policy.tenant.userId,
|
|
413
|
+
modelScope
|
|
414
|
+
});
|
|
415
|
+
let defaultModelId = policy.factoryDefaultModelId ?? null;
|
|
416
|
+
let personalThinkingLevel = null;
|
|
417
|
+
if (modelScope === "user" && includeDefaultModel) {
|
|
418
|
+
if (!options.modelDefaults) return { response: c.json({ error: "model_defaults_unavailable" }, 503) };
|
|
419
|
+
const ownerDefaults = await routedPersonalDefaults(policy.tenant, options.modelDefaults);
|
|
420
|
+
defaultModelId = ownerDefaults?.modelId ?? null;
|
|
421
|
+
personalThinkingLevel = ownerDefaults?.thinkingLevel ?? null;
|
|
422
|
+
}
|
|
423
|
+
return {
|
|
424
|
+
tenantCredentials,
|
|
425
|
+
modelScope,
|
|
426
|
+
defaultModelId,
|
|
427
|
+
personalThinkingLevel
|
|
428
|
+
};
|
|
429
|
+
};
|
|
430
|
+
const resolveOMResponseContext = async (c, { sessionId, threadId, resourceId, factoryProjectId }) => {
|
|
431
|
+
let tenantCredentials = await listTenantCredentialsForRequest({
|
|
386
432
|
c: loose(c),
|
|
387
433
|
auth,
|
|
388
434
|
credentials: options.modelCredentials
|
|
389
435
|
});
|
|
436
|
+
const tenant = auth.tenant(c);
|
|
437
|
+
if (sessionId !== void 0 && threadId !== void 0) {
|
|
438
|
+
const address = z.object({
|
|
439
|
+
sessionId: z.string().trim().min(1),
|
|
440
|
+
threadId: z.string().trim().min(1),
|
|
441
|
+
resourceId: z.string().trim().min(1).optional()
|
|
442
|
+
}).transform((data) => ({
|
|
443
|
+
...data,
|
|
444
|
+
resourceId: data.resourceId ?? data.sessionId
|
|
445
|
+
})).safeParse({
|
|
446
|
+
sessionId,
|
|
447
|
+
threadId,
|
|
448
|
+
resourceId
|
|
449
|
+
});
|
|
450
|
+
if (!address.success) return { response: c.json({ error: "invalid_session_context" }, 400) };
|
|
451
|
+
const sessionContext = await resolveSessionModelContext(c, address.data, false);
|
|
452
|
+
if (sessionContext && "response" in sessionContext) return { response: sessionContext.response };
|
|
453
|
+
tenantCredentials = sessionContext?.tenantCredentials;
|
|
454
|
+
} else if (threadId !== void 0) return { response: c.json({ error: "invalid_session_context" }, 400) };
|
|
455
|
+
else if (tenantCredentials && factoryProjectId && tenant) {
|
|
456
|
+
if (!options.factoryProjects) return { response: c.json({ error: "factory_unavailable" }, 503) };
|
|
457
|
+
await options.factoryProjects.ensureReady();
|
|
458
|
+
const project = await options.factoryProjects.get({
|
|
459
|
+
orgId: tenantOrgId(tenant),
|
|
460
|
+
id: factoryProjectId
|
|
461
|
+
});
|
|
462
|
+
if (!project) return { response: c.json({ error: "factory_project_not_found" }, 404) };
|
|
463
|
+
const scope = effectiveModelScope(project.modelScope, "run") === "factory" ? "org" : "user";
|
|
464
|
+
tenantCredentials = tenantCredentials.filter((record) => record.scope === scope);
|
|
465
|
+
} else if (tenantCredentials) tenantCredentials = tenantCredentials.filter((record) => record.scope === "user");
|
|
390
466
|
const access = await buildProviderAccess({
|
|
391
467
|
controller,
|
|
392
468
|
authStorage: tenantCredentials ? void 0 : authStorage,
|
|
@@ -403,7 +479,7 @@ var ConfigRoutes = class extends Route {
|
|
|
403
479
|
});
|
|
404
480
|
if (!("response" in context)) for (const provider of await context.storage.list({ orgId: context.orgId })) availableProviders.add(provider.providerId);
|
|
405
481
|
}
|
|
406
|
-
return availableProviders;
|
|
482
|
+
return { availableProviders };
|
|
407
483
|
};
|
|
408
484
|
const factoryOmFallback = async (factoryProjectId) => {
|
|
409
485
|
try {
|
|
@@ -672,46 +748,14 @@ var ConfigRoutes = class extends Route {
|
|
|
672
748
|
sessionId
|
|
673
749
|
});
|
|
674
750
|
if (!address.success) return c.json({ error: "invalid_session_context" }, 400);
|
|
675
|
-
|
|
676
|
-
if (
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
requestContext.set("user", {
|
|
680
|
-
id: tenant.userId,
|
|
681
|
-
organizationId: tenantOrgId(tenant)
|
|
682
|
-
});
|
|
683
|
-
requestContext.set("controller", address.data);
|
|
684
|
-
let policy;
|
|
685
|
-
try {
|
|
686
|
-
policy = await resolveFactoryModelPolicy(requestContext, {
|
|
687
|
-
projects: options.factoryProjects,
|
|
688
|
-
sourceControl: options.sourceControlSessions,
|
|
689
|
-
workItems: options.workItems
|
|
690
|
-
});
|
|
691
|
-
} catch {
|
|
692
|
-
return c.json({ error: "session_model_policy_unavailable" }, 403);
|
|
693
|
-
}
|
|
694
|
-
if (!policy) return c.json({ error: "unauthorized" }, 401);
|
|
695
|
-
const orgId = policy.tenant.orgId ?? tenantOrgId(tenant);
|
|
696
|
-
const modelScope = policy.tenant.credentialScope ?? "user";
|
|
697
|
-
tenantCredentials = await listSessionScopedCredentials({
|
|
698
|
-
credentials: options.modelCredentials,
|
|
699
|
-
orgId,
|
|
700
|
-
userId: policy.tenant.userId,
|
|
701
|
-
modelScope
|
|
702
|
-
});
|
|
703
|
-
let defaultModelId = policy.factoryDefaultModelId ?? null;
|
|
704
|
-
let personalThinkingLevel = null;
|
|
705
|
-
if (modelScope === "user") {
|
|
706
|
-
if (!options.modelDefaults) return c.json({ error: "model_defaults_unavailable" }, 503);
|
|
707
|
-
const ownerDefaults = await routedPersonalDefaults(policy.tenant, options.modelDefaults);
|
|
708
|
-
defaultModelId = ownerDefaults?.modelId ?? null;
|
|
709
|
-
personalThinkingLevel = ownerDefaults?.thinkingLevel ?? null;
|
|
710
|
-
}
|
|
751
|
+
const context = await resolveSessionModelContext(c, address.data);
|
|
752
|
+
if (context && "response" in context) return context.response;
|
|
753
|
+
if (context) {
|
|
754
|
+
tenantCredentials = context.tenantCredentials;
|
|
711
755
|
sessionPolicy = {
|
|
712
|
-
modelScope,
|
|
713
|
-
defaultModelId,
|
|
714
|
-
personalThinkingLevel
|
|
756
|
+
modelScope: context.modelScope,
|
|
757
|
+
defaultModelId: context.defaultModelId,
|
|
758
|
+
personalThinkingLevel: context.personalThinkingLevel
|
|
715
759
|
};
|
|
716
760
|
}
|
|
717
761
|
} else if (c.req.query("scope") !== void 0) {
|
|
@@ -972,6 +1016,8 @@ var ConfigRoutes = class extends Route {
|
|
|
972
1016
|
requiresAuth: false,
|
|
973
1017
|
handler: async (c) => {
|
|
974
1018
|
const sessionId = c.req.query("sessionId");
|
|
1019
|
+
const threadId = c.req.query("threadId");
|
|
1020
|
+
const resourceId = c.req.query("resourceId");
|
|
975
1021
|
const factoryProjectId = c.req.query("factoryId") || void 0;
|
|
976
1022
|
const context = await resolveMemorySettingsContext({
|
|
977
1023
|
c: loose(c),
|
|
@@ -987,9 +1033,15 @@ var ConfigRoutes = class extends Route {
|
|
|
987
1033
|
userId: context.userId
|
|
988
1034
|
});
|
|
989
1035
|
const fallback = await factoryOmFallback(factoryProjectId);
|
|
990
|
-
const
|
|
1036
|
+
const responseContext = await resolveOMResponseContext(loose(c), {
|
|
1037
|
+
sessionId,
|
|
1038
|
+
threadId,
|
|
1039
|
+
resourceId,
|
|
1040
|
+
factoryProjectId
|
|
1041
|
+
});
|
|
1042
|
+
if ("response" in responseContext) return responseContext.response;
|
|
991
1043
|
const sessionModelId = (sessionId ? await controller.getSession?.(sessionId) : void 0)?.model.get();
|
|
992
|
-
return c.json({ config: readStoredOMConfig(record, sessionModelId || fallback, sessionModelId ? "live-session" : "configured-default", availableProviders) });
|
|
1044
|
+
return c.json({ config: readStoredOMConfig(record, sessionModelId || fallback, sessionModelId ? "live-session" : "configured-default", responseContext.availableProviders) });
|
|
993
1045
|
} catch (error) {
|
|
994
1046
|
return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
|
|
995
1047
|
}
|
|
@@ -1007,7 +1059,9 @@ var ConfigRoutes = class extends Route {
|
|
|
1007
1059
|
} catch {
|
|
1008
1060
|
return c.json({ error: "Invalid JSON body" }, 400);
|
|
1009
1061
|
}
|
|
1010
|
-
const sessionId = typeof body.sessionId === "string" ? body.sessionId :
|
|
1062
|
+
const sessionId = typeof body.sessionId === "string" ? body.sessionId : void 0;
|
|
1063
|
+
const threadId = typeof body.threadId === "string" ? body.threadId : void 0;
|
|
1064
|
+
const resourceId = typeof body.resourceId === "string" ? body.resourceId : void 0;
|
|
1011
1065
|
const factoryProjectId = typeof body.factoryId === "string" && body.factoryId ? body.factoryId : void 0;
|
|
1012
1066
|
const model = typeof body.modelId === "string" ? body.modelId.trim() : "";
|
|
1013
1067
|
if (!model) return c.json({ error: "Missing required field: modelId" }, 400);
|
|
@@ -1020,7 +1074,13 @@ var ConfigRoutes = class extends Route {
|
|
|
1020
1074
|
factoryProjects: options.factoryProjects
|
|
1021
1075
|
});
|
|
1022
1076
|
if ("response" in context) return context.response;
|
|
1023
|
-
const
|
|
1077
|
+
const responseContext = await resolveOMResponseContext(loose(c), {
|
|
1078
|
+
sessionId,
|
|
1079
|
+
threadId,
|
|
1080
|
+
resourceId,
|
|
1081
|
+
factoryProjectId
|
|
1082
|
+
});
|
|
1083
|
+
if ("response" in responseContext) return responseContext.response;
|
|
1024
1084
|
try {
|
|
1025
1085
|
await persistMemorySettings(context, { [role === "observer" ? "observerModelId" : "reflectorModelId"]: wantsAuto ? null : model });
|
|
1026
1086
|
const record = await context.storage.get({
|
|
@@ -1028,7 +1088,7 @@ var ConfigRoutes = class extends Route {
|
|
|
1028
1088
|
userId: context.userId
|
|
1029
1089
|
});
|
|
1030
1090
|
const sessionModelId = (sessionId ? await controller.getSession?.(sessionId) : void 0)?.model.get();
|
|
1031
|
-
const config = readStoredOMConfig(record, sessionModelId || await factoryOmFallback(factoryProjectId), sessionModelId ? "live-session" : "configured-default", availableProviders);
|
|
1091
|
+
const config = readStoredOMConfig(record, sessionModelId || await factoryOmFallback(factoryProjectId), sessionModelId ? "live-session" : "configured-default", responseContext.availableProviders);
|
|
1032
1092
|
return c.json({
|
|
1033
1093
|
ok: true,
|
|
1034
1094
|
config
|
|
@@ -1048,11 +1108,14 @@ var ConfigRoutes = class extends Route {
|
|
|
1048
1108
|
} catch {
|
|
1049
1109
|
return c.json({ error: "Invalid JSON body" }, 400);
|
|
1050
1110
|
}
|
|
1051
|
-
const sessionId = typeof body.sessionId === "string" ? body.sessionId :
|
|
1111
|
+
const sessionId = typeof body.sessionId === "string" ? body.sessionId : void 0;
|
|
1112
|
+
const threadId = typeof body.threadId === "string" ? body.threadId : void 0;
|
|
1113
|
+
const resourceId = typeof body.resourceId === "string" ? body.resourceId : void 0;
|
|
1052
1114
|
const factoryProjectId = typeof body.factoryId === "string" && body.factoryId ? body.factoryId : void 0;
|
|
1053
1115
|
const observation = typeof body.observationThreshold === "number" && body.observationThreshold > 0 ? Math.round(body.observationThreshold) : void 0;
|
|
1054
1116
|
const reflection = typeof body.reflectionThreshold === "number" && body.reflectionThreshold > 0 ? Math.round(body.reflectionThreshold) : void 0;
|
|
1055
1117
|
if (observation === void 0 && reflection === void 0) return c.json({ error: "Provide observationThreshold and/or reflectionThreshold (positive numbers)" }, 400);
|
|
1118
|
+
if (observation !== void 0 && observation < MIN_OBSERVATION_THRESHOLD) return c.json({ error: `observationThreshold must be greater than ${MIN_OBSERVATION_THRESHOLD - 1} tokens` }, 400);
|
|
1056
1119
|
const context = await resolveMemorySettingsContext({
|
|
1057
1120
|
c: loose(c),
|
|
1058
1121
|
auth,
|
|
@@ -1061,7 +1124,13 @@ var ConfigRoutes = class extends Route {
|
|
|
1061
1124
|
factoryProjects: options.factoryProjects
|
|
1062
1125
|
});
|
|
1063
1126
|
if ("response" in context) return context.response;
|
|
1064
|
-
const
|
|
1127
|
+
const responseContext = await resolveOMResponseContext(loose(c), {
|
|
1128
|
+
sessionId,
|
|
1129
|
+
threadId,
|
|
1130
|
+
resourceId,
|
|
1131
|
+
factoryProjectId
|
|
1132
|
+
});
|
|
1133
|
+
if ("response" in responseContext) return responseContext.response;
|
|
1065
1134
|
try {
|
|
1066
1135
|
await persistMemorySettings(context, {
|
|
1067
1136
|
...observation !== void 0 ? { observationThreshold: observation } : {},
|
|
@@ -1072,7 +1141,7 @@ var ConfigRoutes = class extends Route {
|
|
|
1072
1141
|
userId: context.userId
|
|
1073
1142
|
});
|
|
1074
1143
|
const sessionModelId = (sessionId ? await controller.getSession?.(sessionId) : void 0)?.model.get();
|
|
1075
|
-
const config = readStoredOMConfig(record, sessionModelId || await factoryOmFallback(factoryProjectId), sessionModelId ? "live-session" : "configured-default", availableProviders);
|
|
1144
|
+
const config = readStoredOMConfig(record, sessionModelId || await factoryOmFallback(factoryProjectId), sessionModelId ? "live-session" : "configured-default", responseContext.availableProviders);
|
|
1076
1145
|
return c.json({
|
|
1077
1146
|
ok: true,
|
|
1078
1147
|
config
|
|
@@ -1092,7 +1161,9 @@ var ConfigRoutes = class extends Route {
|
|
|
1092
1161
|
} catch {
|
|
1093
1162
|
return c.json({ error: "Invalid JSON body" }, 400);
|
|
1094
1163
|
}
|
|
1095
|
-
const sessionId = typeof body.sessionId === "string" ? body.sessionId :
|
|
1164
|
+
const sessionId = typeof body.sessionId === "string" ? body.sessionId : void 0;
|
|
1165
|
+
const threadId = typeof body.threadId === "string" ? body.threadId : void 0;
|
|
1166
|
+
const resourceId = typeof body.resourceId === "string" ? body.resourceId : void 0;
|
|
1096
1167
|
const factoryProjectId = typeof body.factoryId === "string" && body.factoryId ? body.factoryId : void 0;
|
|
1097
1168
|
const raw = body.value;
|
|
1098
1169
|
const value = raw === "auto" || raw === true || raw === false ? raw : "auto";
|
|
@@ -1105,7 +1176,13 @@ var ConfigRoutes = class extends Route {
|
|
|
1105
1176
|
factoryProjects: options.factoryProjects
|
|
1106
1177
|
});
|
|
1107
1178
|
if ("response" in context) return context.response;
|
|
1108
|
-
const
|
|
1179
|
+
const responseContext = await resolveOMResponseContext(loose(c), {
|
|
1180
|
+
sessionId,
|
|
1181
|
+
threadId,
|
|
1182
|
+
resourceId,
|
|
1183
|
+
factoryProjectId
|
|
1184
|
+
});
|
|
1185
|
+
if ("response" in responseContext) return responseContext.response;
|
|
1109
1186
|
try {
|
|
1110
1187
|
await persistMemorySettings(context, { observeAttachments: value });
|
|
1111
1188
|
const record = await context.storage.get({
|
|
@@ -1113,7 +1190,7 @@ var ConfigRoutes = class extends Route {
|
|
|
1113
1190
|
userId: context.userId
|
|
1114
1191
|
});
|
|
1115
1192
|
const sessionModelId = (sessionId ? await controller.getSession?.(sessionId) : void 0)?.model.get();
|
|
1116
|
-
const config = readStoredOMConfig(record, sessionModelId || await factoryOmFallback(factoryProjectId), sessionModelId ? "live-session" : "configured-default", availableProviders);
|
|
1193
|
+
const config = readStoredOMConfig(record, sessionModelId || await factoryOmFallback(factoryProjectId), sessionModelId ? "live-session" : "configured-default", responseContext.availableProviders);
|
|
1117
1194
|
return c.json({
|
|
1118
1195
|
ok: true,
|
|
1119
1196
|
config
|