@mastra/factory 0.24.0-alpha.7 → 0.24.0-alpha.9
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/boards/review.d.ts.map +1 -1
- package/dist/boards/review.js +21 -1
- package/dist/boards/review.js.map +1 -1
- package/dist/boards/work-transition-policy.d.ts.map +1 -1
- package/dist/boards/work-transition-policy.js +2 -1
- package/dist/boards/work-transition-policy.js.map +1 -1
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +91 -13
- package/dist/factory.js.map +1 -1
- package/dist/integrations/github/rules.d.ts.map +1 -1
- package/dist/integrations/github/rules.js +26 -22
- package/dist/integrations/github/rules.js.map +1 -1
- package/dist/integrations/github/sandbox.d.ts +2 -3
- package/dist/integrations/github/sandbox.d.ts.map +1 -1
- package/dist/integrations/github/sandbox.js +78 -7
- package/dist/integrations/github/sandbox.js.map +1 -1
- package/dist/integrations/gitlab/rules.d.ts.map +1 -1
- package/dist/integrations/gitlab/rules.js +28 -21
- package/dist/integrations/gitlab/rules.js.map +1 -1
- package/dist/integrations/slack/integration.d.ts.map +1 -1
- package/dist/integrations/slack/integration.js +33 -6
- package/dist/integrations/slack/integration.js.map +1 -1
- package/dist/integrations/slack/slack.d.ts.map +1 -1
- package/dist/integrations/slack/slack.js +25 -24
- package/dist/integrations/slack/slack.js.map +1 -1
- package/dist/routes/attention-activity.d.ts.map +1 -1
- package/dist/routes/attention-activity.js +5 -2
- package/dist/routes/attention-activity.js.map +1 -1
- package/dist/routes/attention-providers.d.ts +0 -1
- package/dist/routes/attention-providers.d.ts.map +1 -1
- package/dist/routes/attention-providers.js +5 -6
- package/dist/routes/attention-providers.js.map +1 -1
- package/dist/routes/config.d.ts +4 -0
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +20 -6
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/provider-credentials.d.ts +2 -1
- package/dist/routes/provider-credentials.d.ts.map +1 -1
- package/dist/routes/provider-credentials.js +6 -2
- package/dist/routes/provider-credentials.js.map +1 -1
- package/dist/rules/dispatch-errors.d.ts.map +1 -1
- package/dist/rules/dispatch-errors.js +12 -0
- package/dist/rules/dispatch-errors.js.map +1 -1
- package/dist/rules/dispatcher.d.ts.map +1 -1
- package/dist/rules/dispatcher.js +42 -3
- package/dist/rules/dispatcher.js.map +1 -1
- package/dist/session/channel-reply-processor.d.ts +35 -0
- package/dist/session/channel-reply-processor.d.ts.map +1 -0
- package/dist/session/channel-reply-processor.js +46 -0
- package/dist/session/channel-reply-processor.js.map +1 -0
- package/dist/session/channel-session-link-processor.d.ts +39 -0
- package/dist/session/channel-session-link-processor.d.ts.map +1 -0
- package/dist/session/channel-session-link-processor.js +99 -0
- package/dist/session/channel-session-link-processor.js.map +1 -0
- package/dist/session/factory-session.d.ts +4 -0
- package/dist/session/factory-session.d.ts.map +1 -1
- package/dist/session/factory-session.js +1 -0
- package/dist/session/factory-session.js.map +1 -1
- package/dist/session/reply-credential-processor.d.ts.map +1 -1
- package/dist/session/reply-credential-processor.js +4 -6
- package/dist/session/reply-credential-processor.js.map +1 -1
- package/dist/session/run-audit.d.ts +24 -0
- package/dist/session/run-audit.d.ts.map +1 -1
- package/dist/session/run-audit.js +93 -7
- package/dist/session/run-audit.js.map +1 -1
- package/dist/session/source-control-tools.d.ts.map +1 -1
- package/dist/session/source-control-tools.js.map +1 -1
- package/dist/storage/domains/source-control/base.d.ts +7 -0
- package/dist/storage/domains/source-control/base.d.ts.map +1 -1
- package/dist/storage/domains/source-control/base.js +12 -0
- package/dist/storage/domains/source-control/base.js.map +1 -1
- package/dist/storage/domains/source-control/inmemory.d.ts +4 -0
- package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
- package/dist/storage/domains/source-control/inmemory.js +8 -0
- package/dist/storage/domains/source-control/inmemory.js.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts +2 -2
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.js +5 -0
- package/dist/storage/domains/work-items/base.js.map +1 -1
- package/dist/tools/approval-tools.d.ts +1 -1
- package/dist/tools/approval-tools.d.ts.map +1 -1
- package/dist/tools/approval-tools.js +3 -1
- package/dist/tools/approval-tools.js.map +1 -1
- package/dist/tools/deliver.d.ts +16 -2
- package/dist/tools/deliver.d.ts.map +1 -1
- package/dist/tools/deliver.js +12 -2
- package/dist/tools/deliver.js.map +1 -1
- package/dist/tools/index.d.ts +6 -5
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +9 -12
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/messaging-tools.d.ts +1 -1
- package/dist/tools/messaging-tools.d.ts.map +1 -1
- package/dist/tools/messaging-tools.js +84 -3
- package/dist/tools/messaging-tools.js.map +1 -1
- package/dist/tools/permissions.d.ts.map +1 -1
- package/dist/tools/permissions.js +3 -0
- package/dist/tools/permissions.js.map +1 -1
- package/dist/tools/read-tools.d.ts +3 -0
- package/dist/tools/read-tools.d.ts.map +1 -1
- package/dist/tools/read-tools.js +16 -8
- package/dist/tools/read-tools.js.map +1 -1
- package/dist/tools/reports.d.ts.map +1 -1
- package/dist/tools/reports.js +3 -1
- package/dist/tools/reports.js.map +1 -1
- package/dist/tools/scope.d.ts +6 -0
- package/dist/tools/scope.d.ts.map +1 -1
- package/dist/tools/scope.js +10 -1
- package/dist/tools/scope.js.map +1 -1
- package/dist/tools/session-tools.d.ts +1 -1
- package/dist/tools/session-tools.d.ts.map +1 -1
- package/dist/tools/session-tools.js +11 -7
- package/dist/tools/session-tools.js.map +1 -1
- package/dist/tools/sessions-state-processor.d.ts +5 -1
- package/dist/tools/sessions-state-processor.d.ts.map +1 -1
- package/dist/tools/sessions-state-processor.js +32 -48
- package/dist/tools/sessions-state-processor.js.map +1 -1
- package/dist/tools/side-sessions.d.ts +53 -0
- package/dist/tools/side-sessions.d.ts.map +1 -0
- package/dist/tools/side-sessions.js +83 -0
- package/dist/tools/side-sessions.js.map +1 -0
- package/dist/tools/work-item-tools.d.ts.map +1 -1
- package/dist/tools/work-item-tools.js +45 -25
- package/dist/tools/work-item-tools.js.map +1 -1
- package/package.json +6 -6
package/dist/routes/config.d.ts
CHANGED
|
@@ -118,6 +118,7 @@ export declare function isDeploymentModelProvider(provider: string): boolean;
|
|
|
118
118
|
* ignored with a warning rather than failing boot.
|
|
119
119
|
*/
|
|
120
120
|
export declare function resolveDeploymentModelProviders(providers: readonly string[] | undefined): ReadonlySet<string>;
|
|
121
|
+
type ModelCredentialHolder = 'personal' | 'organization' | 'deployment';
|
|
121
122
|
/**
|
|
122
123
|
* Compute which providers the user can reach, mirroring the TUI's
|
|
123
124
|
* `/models-pack` access derivation: OAuth/api-key from the credential store for
|
|
@@ -136,6 +137,8 @@ export interface ModelCatalogEntry {
|
|
|
136
137
|
modelName?: string;
|
|
137
138
|
hasApiKey: true;
|
|
138
139
|
reasoningOptions: ReturnType<typeof getModelReasoningOptions> | undefined;
|
|
140
|
+
credentialLabel?: string;
|
|
141
|
+
credentialHolder?: ModelCredentialHolder;
|
|
139
142
|
}
|
|
140
143
|
/**
|
|
141
144
|
* Models usable with the given credentials: built-in models whose provider the
|
|
@@ -243,4 +246,5 @@ export interface ConfigRoutesDeps extends RouteDependencies {
|
|
|
243
246
|
export declare class ConfigRoutes extends Route<ConfigRoutesDeps> {
|
|
244
247
|
routes(): ApiRoute[];
|
|
245
248
|
}
|
|
249
|
+
export {};
|
|
246
250
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/routes/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,mCAAmC,CAAC;AAK7F,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAOpD,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACxB,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAEhH,OAAO,KAAK,EAGV,qBAAqB,EACtB,MAAM,4CAA4C,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEtF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AAC5F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/routes/config.ts"],"names":[],"mappings":"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"}
|
package/dist/routes/config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { WEB_OAUTH_PROVIDERS, getAuthProviderId, listTenantCredentialsForRequest, resolveCredentialContext, tenantOrgId } from "./provider-credentials.js";
|
|
1
|
+
import { WEB_OAUTH_PROVIDERS, credentialLabel, getAuthProviderId, listTenantCredentialsForRequest, resolveCredentialContext, tenantOrgId } from "./provider-credentials.js";
|
|
2
2
|
import { effectiveModelScope } from "../storage/domains/projects/base.js";
|
|
3
3
|
import { resolveFactoryModelPolicy } from "../session/credential-policy.js";
|
|
4
4
|
import "../session/memory-settings-hydration.js";
|
|
@@ -155,6 +155,19 @@ function resolveDeploymentModelProviders(providers) {
|
|
|
155
155
|
}
|
|
156
156
|
return resolved;
|
|
157
157
|
}
|
|
158
|
+
function grantingTenantRecord(records, authProviderId) {
|
|
159
|
+
return records.find((r) => r.scope === "user" && r.provider === authProviderId) ?? records.find((r) => r.scope === "org" && r.provider === authProviderId);
|
|
160
|
+
}
|
|
161
|
+
function tenantModelCredential(records, provider) {
|
|
162
|
+
if (!records) return {};
|
|
163
|
+
if (isDeploymentModelProvider(provider)) return { credentialHolder: "deployment" };
|
|
164
|
+
const record = grantingTenantRecord(records, getAuthProviderId(provider));
|
|
165
|
+
if (!record) return {};
|
|
166
|
+
return {
|
|
167
|
+
credentialLabel: credentialLabel(provider, record.credential.type),
|
|
168
|
+
credentialHolder: record.scope === "user" ? "personal" : "organization"
|
|
169
|
+
};
|
|
170
|
+
}
|
|
158
171
|
/**
|
|
159
172
|
* Compute which providers the user can reach, mirroring the TUI's
|
|
160
173
|
* `/models-pack` access derivation: OAuth/api-key from the credential store for
|
|
@@ -167,9 +180,7 @@ async function buildProviderAccess({ controller, authStorage, tenantCredentials,
|
|
|
167
180
|
const authProviderId = getAuthProviderId(provider);
|
|
168
181
|
if (tenantCredentials) {
|
|
169
182
|
if (isDeploymentModelProvider(provider)) return deploymentProviders?.has(provider) && hasModelKey(provider) ? "apikey" : false;
|
|
170
|
-
const
|
|
171
|
-
const orgRec = tenantCredentials.find((r) => r.scope === "org" && r.provider === authProviderId);
|
|
172
|
-
const credential = userRec?.credential ?? orgRec?.credential;
|
|
183
|
+
const credential = grantingTenantRecord(tenantCredentials, authProviderId)?.credential;
|
|
173
184
|
if (credential?.type === "oauth") return "oauth";
|
|
174
185
|
if (credential?.type === "api_key" && credential.key.trim().length > 0) return "apikey";
|
|
175
186
|
return false;
|
|
@@ -215,10 +226,12 @@ async function buildModelCatalog({ controller, authStorage, tenantCredentials, d
|
|
|
215
226
|
provider,
|
|
216
227
|
modelName,
|
|
217
228
|
hasApiKey: true,
|
|
218
|
-
reasoningOptions: getModelReasoningOptions(id)
|
|
229
|
+
reasoningOptions: getModelReasoningOptions(id),
|
|
230
|
+
...tenantModelCredential(tenantCredentials, provider)
|
|
219
231
|
}] : []);
|
|
220
232
|
if (listCustomProviders) try {
|
|
221
233
|
const known = new Set(catalog.map((m) => m.id));
|
|
234
|
+
const customProviderCredential = tenantCredentials ? { credentialHolder: "organization" } : {};
|
|
222
235
|
for (const record of await listCustomProviders()) for (const model of record.models) {
|
|
223
236
|
const id = `${record.providerId}/${model}`;
|
|
224
237
|
if (known.has(id)) continue;
|
|
@@ -228,7 +241,8 @@ async function buildModelCatalog({ controller, authStorage, tenantCredentials, d
|
|
|
228
241
|
provider: record.providerId,
|
|
229
242
|
modelName: model,
|
|
230
243
|
hasApiKey: true,
|
|
231
|
-
reasoningOptions: void 0
|
|
244
|
+
reasoningOptions: void 0,
|
|
245
|
+
...customProviderCredential
|
|
232
246
|
});
|
|
233
247
|
}
|
|
234
248
|
} catch {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","names":[],"sources":["../../src/routes/config.ts"],"sourcesContent":["import { MastraCodeGateway } from '@mastra/code-sdk/agents/mastracode-gateway';\nimport type { AuthStorage } from '@mastra/code-sdk/auth/storage';\nimport { resolveAutoOMModelId } from '@mastra/code-sdk/onboarding/packs';\nimport type { ProviderAccess, ProviderAccessLevel } from '@mastra/code-sdk/onboarding/packs';\nimport { getCustomProviderId, MASTRA_GATEWAY_PROVIDER } from '@mastra/code-sdk/onboarding/settings';\nimport type { CustomProviderSetting } from '@mastra/code-sdk/onboarding/settings';\nimport { AMAZON_BEDROCK_GATEWAY_ID } from '@mastra/code-sdk/providers/amazon-bedrock-gateway';\nimport { MASTRA_GATEWAY_PREFIX } from '@mastra/code-sdk/providers/model-ids';\nimport { getModelReasoningOptions } from '@mastra/core/llm';\nimport { RequestContext } from '@mastra/core/request-context';\nimport type { ApiRoute } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\n\nimport type { Context } from 'hono';\nimport { z } from 'zod';\nimport { resolveFactoryModelPolicy } from '../session/credential-policy.js';\nimport { DEFAULT_OBSERVATION_THRESHOLD, DEFAULT_REFLECTION_THRESHOLD } from '../session/memory-settings-hydration.js';\nimport type {\n CredentialRecord,\n LoginSessionKind,\n ModelCredentialsStorage,\n} from '../storage/domains/credentials/base.js';\nimport type { CustomProviderRecord, CustomProvidersStorage } from '../storage/domains/custom-providers/base.js';\nimport { factoryMemorySettingsUserId } from '../storage/domains/memory-settings/base.js';\nimport type {\n MemorySettingsPatch,\n MemorySettingsRecord,\n MemorySettingsStorage,\n} from '../storage/domains/memory-settings/base.js';\nimport type { ModelDefaultsStorage } from '../storage/domains/model-defaults/base.js';\nimport { effectiveModelScope } from '../storage/domains/projects/base.js';\nimport type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';\nimport type { SourceControlStorageHandle } from '../storage/domains/source-control/base.js';\nimport type { WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport {\n getAuthProviderId,\n listTenantCredentialsForRequest,\n resolveCredentialContext,\n tenantOrgId,\n WEB_OAUTH_PROVIDERS,\n} from './provider-credentials.js';\nimport { Route } from './route.js';\nimport type { RouteAuth, RouteDependencies } from './route.js';\n\n/** Widen a route-local Hono context to the plain `Context` the auth helpers take. */\nfunction loose(c: unknown): Context {\n return c as Context;\n}\n\n/**\n * Server-side configuration routes for the web app.\n *\n * The browser has no access to the credential store or the model catalog, so\n * the web settings panel asks the server — which owns both — to list providers\n * and manage API keys. This mirrors the TUI's `/api-keys` command, exposing the\n * same `AuthStorage`-backed key management over HTTP.\n *\n * Keys are never returned to the client; only their presence and source.\n */\n\n/**\n * Where a provider's active credential comes from, as seen by the caller.\n * Local mode reports `oauth`/`stored` (server-global `auth.json`); tenant mode\n * reports the scoped variants (`oauth-user`/`stored-user`/`stored-org`).\n * `deployment` (tenant mode) marks a provider the operator opted in to run on\n * the server process's own credentials (e.g. Amazon Bedrock's AWS chain).\n */\nexport type ProviderCredentialSource =\n | 'deployment'\n | 'oauth'\n | 'stored'\n | 'env'\n | 'none'\n | 'oauth-user'\n | 'oauth-org'\n | 'stored-user'\n | 'stored-org';\n\n/** A model provider with the current source of its credentials. */\nexport interface ProviderInfo {\n provider: string;\n /** Env var the provider's key is read from, if any. */\n envVar?: string;\n /** Where the active credential comes from. */\n source: ProviderCredentialSource;\n /**\n * Tenant mode: whether an org-wide API key exists for this provider, even\n * when the caller's personal credential shadows it. Lets the UI tell\n * \"shared with the org\" apart from \"only works for me\".\n */\n orgKey?: boolean;\n /**\n * Tenant mode: the caller's personal credential for this provider, if any.\n * Reported independently of `source` so the UI can manage each scope even\n * when one shadows the other.\n */\n userCredential?: 'oauth' | 'api_key';\n /** Tenant mode: the shared org credential for this provider, if any. */\n orgCredential?: 'oauth' | 'api_key';\n /** Web OAuth sign-in capability, when the provider supports it. */\n oauth?: { supported: true; modes: LoginSessionKind[] };\n}\n\n/** Minimal session surface the config routes touch. */\nexport interface OMSession {\n /** `get()` returns '' when no model is selected, so callers fall back on falsy. */\n model: { get: () => string; switch?: (modelId: string) => Promise<void> };\n thread?: { getId: () => string | null };\n}\n\n/** Minimal controller surface this module needs (model catalog + modes + sessions). */\nexport interface ModelCatalog {\n listAvailableModels: () => Promise<\n Array<{ id?: string; modelName?: string; provider: string; hasApiKey: boolean; apiKeyEnvVar?: string }>\n >;\n listModes?: () => Array<{ id: string; defaultModelId?: string }>;\n getSessionByResource?: (resourceId: string, scope?: string) => Promise<OMSession | undefined>;\n}\n\n/**\n * Build a deduplicated, sorted list of providers from the model catalog,\n * annotated with where each provider's credential currently comes from.\n * Mirrors the TUI's `/api-keys` provider list.\n *\n * When `tenantCredentials` is given (deployed mode), sources reflect the\n * *caller's* tenant rows with user > org precedence and the server-global\n * `authStorage` is ignored; otherwise the local `auth.json` view is reported.\n */\nexport async function listProviders({\n controller,\n authStorage,\n tenantCredentials,\n deploymentProviders,\n}: {\n controller: ModelCatalog;\n authStorage?: AuthStorage;\n tenantCredentials?: CredentialRecord[];\n deploymentProviders?: ReadonlySet<string>;\n}): Promise<ProviderInfo[]> {\n const models = await controller.listAvailableModels();\n const seen = new Map<string, ProviderInfo>();\n\n for (const model of models) {\n if (seen.has(model.provider)) continue;\n\n if (tenantCredentials && isDeploymentModelProvider(model.provider)) {\n // Credentials for these providers live on the server process, never in\n // tenant rows, so no account can connect them. List them only when the\n // operator opted the deployment in and the server has credentials.\n const usable =\n deploymentProviders?.has(model.provider) && models.some(m => m.provider === model.provider && m.hasApiKey);\n if (usable) seen.set(model.provider, { provider: model.provider, source: 'deployment' });\n continue;\n }\n\n const authProviderId = getAuthProviderId(model.provider);\n let source: ProviderInfo['source'] = 'none';\n let orgKey: boolean | undefined;\n let userCredential: ProviderInfo['userCredential'];\n let orgCredential: ProviderInfo['orgCredential'];\n if (tenantCredentials) {\n const userRec = tenantCredentials.find(r => r.scope === 'user' && r.provider === authProviderId);\n const orgRec = tenantCredentials.find(r => r.scope === 'org' && r.provider === authProviderId);\n // Any shared org credential (API key or org-wide OAuth) counts.\n orgKey = orgRec !== undefined;\n userCredential = userRec?.credential.type;\n orgCredential = orgRec?.credential.type;\n if (userRec?.credential.type === 'oauth') {\n source = 'oauth-user';\n } else if (userRec?.credential.type === 'api_key') {\n source = 'stored-user';\n } else if (orgRec?.credential.type === 'oauth') {\n source = 'oauth-org';\n } else if (orgRec?.credential.type === 'api_key') {\n source = 'stored-org';\n }\n } else if (authStorage?.isLoggedIn(authProviderId)) {\n source = 'oauth';\n } else if (authStorage?.hasStoredApiKey(model.provider)) {\n source = 'stored';\n } else if (model.apiKeyEnvVar && process.env[model.apiKeyEnvVar]) {\n source = 'env';\n } else if (model.hasApiKey) {\n source = 'env';\n }\n\n const flowKind = WEB_OAUTH_PROVIDERS[model.provider]?.flow;\n seen.set(model.provider, {\n provider: model.provider,\n envVar: model.apiKeyEnvVar,\n source,\n ...(orgKey !== undefined ? { orgKey } : {}),\n ...(userCredential ? { userCredential } : {}),\n ...(orgCredential ? { orgCredential } : {}),\n ...(flowKind ? { oauth: { supported: true as const, modes: [flowKind] } } : {}),\n });\n }\n\n return Array.from(seen.values()).sort((a, b) => a.provider.localeCompare(b.provider));\n}\n\n/** A user-defined OpenAI-compatible provider, with key presence (never the key). */\nexport interface CustomProviderInfo {\n id: string;\n name: string;\n url: string;\n hasApiKey: boolean;\n models: string[];\n}\n\n/** Redact a stored custom-provider row for the client (key presence only). */\nfunction toCustomProviderInfo(record: CustomProviderRecord): CustomProviderInfo {\n return {\n id: record.providerId,\n name: record.name,\n url: record.url,\n hasApiKey: Boolean(record.apiKey),\n models: record.models,\n };\n}\n\n/** The resolved custom-providers storage scope for a request. */\ninterface CustomProvidersContext {\n storage: CustomProvidersStorage;\n orgId: string;\n userId: string;\n}\n\n/**\n * Resolve the custom-providers context for a request, or a ready-to-return\n * error response. Same posture as memory settings: tenant rows in deployed\n * mode, a sentinel `local` org in no-auth mode — never settings.json.\n */\nasync function resolveCustomProvidersContext({\n c,\n auth,\n customProviders,\n}: {\n c: Context;\n auth: RouteAuth;\n customProviders?: CustomProvidersStorage;\n}): Promise<CustomProvidersContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant && auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n if (customProviders) {\n try {\n await customProviders.ensureReady();\n return tenant\n ? { storage: customProviders, orgId: tenantOrgId(tenant), userId: tenant.userId }\n : { storage: customProviders, orgId: 'local', userId: 'local' };\n } catch {\n // fall through to the unavailable response\n }\n }\n return {\n response: c.json(\n {\n error: 'custom_providers_unavailable',\n message: 'Custom provider storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n}\n\n/** Validate + coerce a request body into a CustomProviderSetting. */\nfunction parseCustomProviderBody(body: unknown): CustomProviderSetting | { error: string } {\n if (!body || typeof body !== 'object') return { error: 'Invalid JSON body' };\n const b = body as Record<string, unknown>;\n const name = typeof b.name === 'string' ? b.name.trim() : '';\n if (!name) return { error: 'Missing required field: name' };\n const url = typeof b.url === 'string' ? b.url.trim() : '';\n if (!url) return { error: 'Missing required field: url' };\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return { error: 'url must be an http(s) URL' };\n }\n } catch {\n return { error: 'url must be a valid URL' };\n }\n const apiKey = typeof b.apiKey === 'string' && b.apiKey.trim() ? b.apiKey.trim() : undefined;\n const models = Array.isArray(b.models)\n ? b.models.filter((m): m is string => typeof m === 'string' && m.trim().length > 0).map(m => m.trim())\n : [];\n return { name, url, apiKey, models };\n}\n\n/**\n * Providers whose credentials can only come from the server process (Amazon\n * Bedrock authenticates through the AWS credential chain). In tenant mode they\n * are usable only when the operator lists them in\n * `MastraFactoryConfig.deploymentModelProviders`.\n */\nexport const DEPLOYMENT_MODEL_PROVIDERS: readonly string[] = [AMAZON_BEDROCK_GATEWAY_ID];\n\nexport function isDeploymentModelProvider(provider: string): boolean {\n return DEPLOYMENT_MODEL_PROVIDERS.includes(provider);\n}\n\n/**\n * Normalize the operator's `deploymentModelProviders` list. Unsupported ids are\n * ignored with a warning rather than failing boot.\n */\nexport function resolveDeploymentModelProviders(providers: readonly string[] | undefined): ReadonlySet<string> {\n const resolved = new Set<string>();\n for (const raw of providers ?? []) {\n const provider = raw.trim();\n if (!provider) continue;\n if (isDeploymentModelProvider(provider)) {\n resolved.add(provider);\n } else {\n console.warn(\n `[factory] Ignoring deployment model provider \"${provider}\". Supported: ${DEPLOYMENT_MODEL_PROVIDERS.join(', ')}.`,\n );\n }\n }\n return resolved;\n}\n\n/**\n * Compute which providers the user can reach, mirroring the TUI's\n * `/models-pack` access derivation: OAuth/api-key from the credential store for\n * the named providers, plus any other provider that has a usable key.\n */\nexport async function buildProviderAccess({\n controller,\n authStorage,\n tenantCredentials,\n deploymentProviders,\n}: {\n controller: ModelCatalog;\n authStorage?: AuthStorage;\n tenantCredentials?: CredentialRecord[];\n deploymentProviders?: ReadonlySet<string>;\n}): Promise<ProviderAccess> {\n const models = await controller.listAvailableModels();\n const hasModelKey = (provider: string) => models.some(m => m.provider === provider && m.hasApiKey);\n const accessLevel = (provider: string): ProviderAccessLevel => {\n const authProviderId = getAuthProviderId(provider);\n if (tenantCredentials) {\n // Tenant rows never authenticate these providers; only an operator\n // opt-in plus credentials on the server process does.\n if (isDeploymentModelProvider(provider)) {\n return deploymentProviders?.has(provider) && hasModelKey(provider) ? 'apikey' : false;\n }\n const userRec = tenantCredentials.find(r => r.scope === 'user' && r.provider === authProviderId);\n const orgRec = tenantCredentials.find(r => r.scope === 'org' && r.provider === authProviderId);\n const credential = userRec?.credential ?? orgRec?.credential;\n if (credential?.type === 'oauth') return 'oauth';\n if (credential?.type === 'api_key' && credential.key.trim().length > 0) return 'apikey';\n return false;\n }\n\n const oauthCredential = authStorage?.get(authProviderId);\n if (oauthCredential?.type === 'oauth') return 'oauth';\n if (authStorage?.hasStoredApiKey(provider)) return 'apikey';\n const directCredential = authStorage?.get(provider);\n if (directCredential?.type === 'api_key' && directCredential.key.trim().length > 0) return 'apikey';\n return hasModelKey(provider) ? 'apikey' : false;\n };\n const access: ProviderAccess = {\n anthropic: accessLevel('anthropic'),\n openai: accessLevel('openai'),\n cerebras: accessLevel('cerebras'),\n google: accessLevel('google'),\n deepseek: accessLevel('deepseek'),\n 'github-copilot': accessLevel('github-copilot'),\n };\n const seen = new Set(Object.keys(access));\n for (const m of models) {\n if (!seen.has(m.provider)) {\n access[m.provider] = accessLevel(m.provider);\n seen.add(m.provider);\n }\n }\n return access;\n}\n\nfunction canUseModelProvider(access: ProviderAccess, provider: string): boolean {\n return Boolean(access[provider]);\n}\n\n/** A model the caller can pick or switch to. */\nexport interface ModelCatalogEntry {\n id: string;\n provider: string;\n modelName?: string;\n hasApiKey: true;\n reasoningOptions: ReturnType<typeof getModelReasoningOptions> | undefined;\n}\n\n/**\n * Models usable with the given credentials: built-in models whose provider the\n * credentials reach, then the org's custom provider models. The Settings model\n * picker and `factory_switch_session_model` both use this so they cannot drift.\n */\nexport async function buildModelCatalog({\n controller,\n authStorage,\n tenantCredentials,\n deploymentProviders,\n listCustomProviders,\n}: {\n controller: ModelCatalog;\n authStorage?: AuthStorage;\n /** Tenant rows in deployed mode; absent in local mode, where `authStorage` and server keys govern. */\n tenantCredentials?: CredentialRecord[];\n deploymentProviders?: ReadonlySet<string>;\n listCustomProviders?: () => Promise<CustomProviderRecord[]>;\n}): Promise<ModelCatalogEntry[]> {\n const [models, access] = await Promise.all([\n controller.listAvailableModels(),\n buildProviderAccess({\n controller,\n authStorage: tenantCredentials ? undefined : authStorage,\n tenantCredentials,\n deploymentProviders,\n }),\n ]);\n const catalog: ModelCatalogEntry[] = models.flatMap(({ id, provider, modelName }) =>\n typeof id === 'string' && canUseModelProvider(access, provider)\n ? [{ id, provider, modelName, hasApiKey: true as const, reasoningOptions: getModelReasoningOptions(id) }]\n : [],\n );\n // The boot-time gateway catalog only carries the local custom providers, so\n // tenant callers get their org's rows here. Dedupe against ids already present.\n if (listCustomProviders) {\n try {\n const known = new Set(catalog.map(m => m.id));\n for (const record of await listCustomProviders()) {\n for (const model of record.models) {\n const id = `${record.providerId}/${model}`;\n if (known.has(id)) continue;\n known.add(id);\n catalog.push({\n id,\n provider: record.providerId,\n modelName: model,\n hasApiKey: true,\n reasoningOptions: undefined,\n });\n }\n }\n } catch {\n // Fail soft: the catalog still serves the built-in models.\n }\n }\n return catalog.sort((a, b) =>\n a.provider === b.provider ? a.id.localeCompare(b.id) : a.provider.localeCompare(b.provider),\n );\n}\n\n/**\n * The tenant credentials a session's model policy allows: the Factory's (org\n * rows) for Factory-scoped sessions, the session owner's for user-scoped ones.\n */\nexport async function listSessionScopedCredentials({\n credentials,\n orgId,\n userId,\n modelScope,\n}: {\n credentials: Pick<ModelCredentialsStorage, 'listCredentials'>;\n orgId: string;\n userId: string;\n modelScope: 'factory' | 'user';\n}): Promise<CredentialRecord[]> {\n const storageScope = modelScope === 'factory' ? 'org' : 'user';\n return (await credentials.listCredentials(orgId, userId)).filter(record => record.scope === storageScope);\n}\n\n/** Per-user default model context for the current request. */\nexport interface ModelDefaultsContext {\n storage: ModelDefaultsStorage;\n orgId: string;\n userId: string;\n}\n\n/** Resolve the default-model context for a request, or a ready-to-return error response. */\nasync function resolveModelDefaultsContext({\n c,\n auth,\n modelDefaults,\n}: {\n c: Context;\n auth: RouteAuth;\n modelDefaults?: ModelDefaultsStorage;\n}): Promise<ModelDefaultsContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant && auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n if (modelDefaults) {\n try {\n await modelDefaults.ensureReady();\n return tenant\n ? { storage: modelDefaults, orgId: tenantOrgId(tenant), userId: tenant.userId }\n : { storage: modelDefaults, orgId: 'local', userId: 'local' };\n } catch {\n // fall through to the unavailable response\n }\n }\n return {\n response: c.json(\n {\n error: 'model_defaults_unavailable',\n message: 'Default model storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n}\n\n// Mirrors the TUI `/om` command. Settings are persisted per organization and\n// user in the Factory app database, then loaded into request context for each\n// invocation without copying them into mutable session state.\n\nexport interface OMRoleConfigInfo {\n model: 'auto' | string;\n effectiveModelId: string;\n effectiveModelSource: 'explicit' | 'live-session' | 'configured-default';\n providerStatus: 'available' | 'unavailable';\n}\n\n/** Persisted intent plus the concrete models the current Factory configuration resolves. */\nexport interface OMConfigInfo {\n observer: OMRoleConfigInfo;\n reflector: OMRoleConfigInfo;\n /** @deprecated Use `observer.effectiveModelId`. */\n observerModelId: string;\n /** @deprecated Use `reflector.effectiveModelId`. */\n reflectorModelId: string;\n observationThreshold: number;\n reflectionThreshold: number;\n observeAttachments: 'auto' | boolean;\n}\n\nexport interface ProviderOMDefaultsResponse {\n ok: true;\n config: OMConfigInfo;\n}\n\nfunction modelProvider(modelId: string): string {\n // Effective IDs keep their `mastra/` route; the provider segment after it is what\n // the SDK resolver falls back to when the gateway is not configured.\n const normalized = modelId.replace(/^mastracode\\//, '').replace(/^mastra\\//, '');\n return normalized.split('/', 1)[0] ?? '';\n}\n\nfunction roleConfig(\n model: OMRoleConfigInfo['model'],\n effectiveModelId: string,\n autoModelSource: 'live-session' | 'configured-default',\n availableProviders: ReadonlySet<string>,\n): OMRoleConfigInfo {\n return {\n model,\n effectiveModelId,\n effectiveModelSource: model === 'auto' ? autoModelSource : 'explicit',\n providerStatus:\n availableProviders.has(modelProvider(effectiveModelId)) ||\n (effectiveModelId.startsWith(MASTRA_GATEWAY_PREFIX) && availableProviders.has(MASTRA_GATEWAY_PROVIDER))\n ? 'available'\n : 'unavailable',\n };\n}\n\nfunction readStoredOMConfig(\n record: MemorySettingsRecord | null,\n currentModelId: string | undefined,\n autoModelSource: 'live-session' | 'configured-default',\n availableProviders: ReadonlySet<string>,\n): OMConfigInfo {\n const autoModelId = resolveAutoOMModelId(currentModelId, providerId => availableProviders.has(providerId));\n const observerModelId = record?.observerModelId ?? autoModelId;\n const reflectorModelId = record?.reflectorModelId ?? autoModelId;\n return {\n observer: roleConfig(record?.observerModelId ?? 'auto', observerModelId, autoModelSource, availableProviders),\n reflector: roleConfig(record?.reflectorModelId ?? 'auto', reflectorModelId, autoModelSource, availableProviders),\n observerModelId,\n reflectorModelId,\n observationThreshold: record?.observationThreshold ?? DEFAULT_OBSERVATION_THRESHOLD,\n reflectionThreshold: record?.reflectionThreshold ?? DEFAULT_REFLECTION_THRESHOLD,\n observeAttachments: record?.observeAttachments ?? 'auto',\n };\n}\n\n/**\n * Where a request's OM settings live: the `memory-settings` factory storage\n * domain, one row per (org, user). Without a tenant (auth disabled), settings\n * land on a sentinel `(local, local)` row in the same table — the web surface\n * never reads or writes `settings.json` for memory settings.\n */\ninterface MemorySettingsContext {\n storage: MemorySettingsStorage;\n orgId: string;\n userId: string;\n}\n\n/**\n * Resolve the memory-settings context for a request, or a ready-to-return\n * error response. When `factoryProjectId` is provided the row addressed is the\n * factory project's shared settings (a sentinel user id in the caller's org)\n * instead of the caller's personal row — this is what factory board runs and\n * channel sessions hydrate from.\n */\nasync function resolveMemorySettingsContext({\n c,\n auth,\n memorySettings,\n factoryProjectId,\n factoryProjects,\n}: {\n c: Context;\n auth: RouteAuth;\n memorySettings?: MemorySettingsStorage;\n factoryProjectId?: string;\n factoryProjects?: FactoryProjectsStorage;\n}): Promise<MemorySettingsContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant && auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n // Factory-scoped rows are shared org state: the target project must exist in\n // the caller's org before its settings row can be read or written.\n if (factoryProjectId && tenant) {\n if (!factoryProjects) return { response: c.json({ error: 'factory_unavailable' }, 503) };\n try {\n await factoryProjects.ensureReady();\n const project = await factoryProjects.get({ orgId: tenantOrgId(tenant), id: factoryProjectId });\n if (!project) return { response: c.json({ error: 'factory_project_not_found' }, 404) };\n } catch {\n return { response: c.json({ error: 'factory_unavailable' }, 503) };\n }\n }\n if (memorySettings) {\n try {\n await memorySettings.ensureReady();\n const factoryUserId = factoryProjectId ? factoryMemorySettingsUserId(factoryProjectId) : undefined;\n return tenant\n ? { storage: memorySettings, orgId: tenantOrgId(tenant), userId: factoryUserId ?? tenant.userId }\n : { storage: memorySettings, orgId: 'local', userId: factoryUserId ?? 'local' };\n } catch {\n // fall through to the unavailable response\n }\n }\n return {\n response: c.json(\n {\n error: 'memory_settings_unavailable',\n message: 'Memory settings storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n}\n\n/** Persist an OM knob change to the caller's memory-settings row. */\nasync function persistMemorySettings(context: MemorySettingsContext, patch: MemorySettingsPatch): Promise<void> {\n await context.storage.patch({ orgId: context.orgId, userId: context.userId, patch });\n}\n\n/** Dependencies injected into {@link ConfigRoutes}. */\nexport interface ConfigRoutesDeps extends RouteDependencies {\n controller: ModelCatalog;\n features?: { knowledge: boolean };\n authStorage?: AuthStorage;\n /** Tenant credential domain handle; absent in local (no-DB) mode. */\n modelCredentials?: ModelCredentialsStorage;\n /** Tenant model-defaults domain handle; absent in local (no-DB) mode. */\n modelDefaults?: ModelDefaultsStorage;\n /** Source-control sessions available to config route integrations. */\n sourceControlSessions?: Pick<SourceControlStorageHandle['sessions'], 'getBySessionId'>;\n sourceControls?: Array<Pick<SourceControlStorageHandle, 'sessions'>>;\n /** Thread membership used to resolve the same model policy as an invocation. */\n workItems?: WorkItemsStorage;\n /** Tenant memory-settings domain handle; absent in local (no-DB) mode. */\n memorySettings?: MemorySettingsStorage;\n /** Factory projects domain, used to derive OM fallbacks from a factory's default model. */\n factoryProjects?: FactoryProjectsStorage;\n /** Custom-providers domain handle; absent when the app database is missing. */\n customProviders?: CustomProvidersStorage;\n /** Notifies the host after tenant credentials change so caches can be dropped. */\n onCredentialsChanged?: (tenant: { orgId: string; userId?: string }) => void;\n /** Notifies the host after custom providers change so model-router caches can be dropped. */\n onCustomProvidersChanged?: (tenant: { orgId: string }) => void;\n /**\n * Tenant mode: providers the operator opted in to run on the server process's\n * own credentials (see `DEPLOYMENT_MODEL_PROVIDERS`).\n */\n deploymentProviders?: ReadonlySet<string>;\n}\n\n/**\n * The web config routes as Mastra `apiRoutes`:\n * - `GET /web/config/features` — list server-enabled product features\n * - `GET /web/config/providers` — list providers + key source\n * - `PUT /web/config/providers/:provider/key` — set/update a provider's API key\n * - `DELETE /web/config/providers/:provider/key` — remove a stored API key\n * - `GET /web/config/models` — list available models (credentialed providers)\n * - `GET /web/config/custom-providers` — list custom OpenAI-compatible providers\n * - `POST /web/config/custom-providers` — create/update a custom provider\n * - `DELETE /web/config/custom-providers/:id` — remove a custom provider\n * - `GET /web/config/om` — read OM models/thresholds/observe-attachments\n * - `PUT /web/config/om/:role/model` — switch observer/reflector model\n * - `PUT /web/config/om/thresholds` — set observation/reflection thresholds\n * - `PUT /web/config/om/observe-attachments` — set observe-attachments (auto/on/off)\n */\nexport class ConfigRoutes extends Route<ConfigRoutesDeps> {\n routes(): ApiRoute[] {\n const options = this.deps;\n const { controller, authStorage, auth, deploymentProviders } = options;\n const onCredentialsChanged = options.onCredentialsChanged ?? (() => {});\n const onCustomProvidersChanged = options.onCustomProvidersChanged ?? (() => {});\n\n const resolveOMResponseContext = async (c: Context) => {\n const tenantCredentials = await listTenantCredentialsForRequest({\n c: loose(c),\n auth,\n credentials: options.modelCredentials,\n });\n const access = await buildProviderAccess({\n controller,\n authStorage: tenantCredentials ? undefined : authStorage,\n tenantCredentials,\n deploymentProviders,\n });\n const availableProviders = new Set(\n Object.entries(access).flatMap(([providerId, configured]) => (configured ? [providerId] : [])),\n );\n // `mastra/` routes run through the Mastra gateway whenever its key is configured.\n if (MastraCodeGateway.getMastraGatewayApiKey()) availableProviders.add(MASTRA_GATEWAY_PROVIDER);\n if (options.customProviders) {\n const context = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if (!('response' in context)) {\n for (const provider of await context.storage.list({ orgId: context.orgId })) {\n availableProviders.add(provider.providerId);\n }\n }\n }\n return availableProviders;\n };\n\n // Without a live session, Auto previews against the factory default model\n // (resolved with this account's providers in readStoredOMConfig) — not the\n // global built-in default, whose provider may have no credential here.\n const factoryOmFallback = async (factoryProjectId: string | undefined): Promise<string | undefined> => {\n try {\n return factoryProjectId\n ? await options.factoryProjects\n ?.getById({ id: factoryProjectId })\n .then(project => project?.defaultModelId ?? undefined)\n : controller.listModes?.().find(mode => mode.defaultModelId)?.defaultModelId;\n } catch {\n return undefined;\n }\n };\n\n return [\n registerApiRoute('/web/config/features', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => c.json({ knowledge: options.features?.knowledge ?? false }),\n }),\n\n registerApiRoute('/web/config/providers', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n try {\n // Tenant mode lists the caller's rows and never exposes the\n // server-global auth.json; local mode is unchanged.\n const tenantCredentials = await listTenantCredentialsForRequest({\n c: loose(c),\n auth,\n credentials: options.modelCredentials,\n });\n // Tenant mode also reports whether the caller may write org-wide\n // keys, so the settings UI can gate the \"Everyone in org\" option.\n const tenant = auth.tenant(loose(c));\n const orgKeyAdmin = tenant ? await auth.isOrganizationAdmin(loose(c), tenantOrgId(tenant)) : undefined;\n return c.json({\n providers: await listProviders({\n controller,\n authStorage: tenantCredentials ? undefined : authStorage,\n tenantCredentials,\n deploymentProviders,\n }),\n ...(orgKeyAdmin !== undefined ? { orgKeyAdmin } : {}),\n });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/providers/:provider/key', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCredentialContext({ c: loose(c), auth, credentials: options.modelCredentials });\n if ('response' in ctx) return ctx.response;\n\n const provider = c.req.param('provider');\n let body: { key?: unknown; envVar?: unknown; scope?: unknown };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const key = typeof body.key === 'string' ? body.key.trim() : '';\n if (!key) return c.json({ error: 'Missing required field: key' }, 400);\n const envVar = typeof body.envVar === 'string' ? body.envVar : undefined;\n const scope = body.scope === 'org' ? 'org' : 'user';\n try {\n if (ctx.mode === 'tenant') {\n // A stored key would never be read: these providers authenticate\n // with the server process's credentials only.\n if (isDeploymentModelProvider(provider)) {\n return c.json(\n {\n error: 'provider_configured_by_deployment',\n message: `${provider} is configured by the Factory deployment (credentials on the server), not per account.`,\n },\n 400,\n );\n }\n if (scope === 'org' && !(await auth.isOrganizationAdmin(loose(c), ctx.orgId))) {\n return c.json({ error: 'organization_admin_required' }, 403);\n }\n const tenant = scope === 'org' ? { orgId: ctx.orgId } : { orgId: ctx.orgId, userId: ctx.userId };\n // envVar is intentionally ignored: tenant credentials are resolved\n // per-request, never written into process.env.\n await ctx.storage.setCredential(tenant, getAuthProviderId(provider), { type: 'api_key', key });\n onCredentialsChanged(tenant);\n const records = await ctx.storage.listCredentials(ctx.orgId, ctx.userId);\n const providers = await listProviders({ controller, tenantCredentials: records, deploymentProviders });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n }\n if (!authStorage) return c.json({ error: 'Credential storage is not available' }, 503);\n // Local mode is single-user: scope is meaningless and ignored.\n authStorage.setStoredApiKey(provider, key, envVar);\n const providers = await listProviders({ controller, authStorage });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/providers/:provider/key', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCredentialContext({ c: loose(c), auth, credentials: options.modelCredentials });\n if ('response' in ctx) return ctx.response;\n\n const provider = c.req.param('provider');\n const scope = c.req.query('scope') === 'org' ? 'org' : 'user';\n try {\n if (ctx.mode === 'tenant') {\n if (scope === 'org' && !(await auth.isOrganizationAdmin(loose(c), ctx.orgId))) {\n return c.json({ error: 'organization_admin_required' }, 403);\n }\n const tenant = scope === 'org' ? { orgId: ctx.orgId } : { orgId: ctx.orgId, userId: ctx.userId };\n await ctx.storage.removeCredential(tenant, getAuthProviderId(provider));\n onCredentialsChanged(tenant);\n const records = await ctx.storage.listCredentials(ctx.orgId, ctx.userId);\n const providers = await listProviders({ controller, tenantCredentials: records, deploymentProviders });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n }\n if (!authStorage) return c.json({ error: 'Credential storage is not available' }, 503);\n authStorage.remove(`apikey:${provider}`);\n const providers = await listProviders({ controller, authStorage });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n // Mirrors the TUI's /custom-providers command, but backed by the\n // `custom-providers` domain (org rows in tenant mode, a sentinel `local`\n // org in no-auth mode) — the server never reads settings.json for these.\n\n registerApiRoute('/web/config/custom-providers', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if ('response' in ctx) return ctx.response;\n try {\n const records = await ctx.storage.list({ orgId: ctx.orgId });\n return c.json({ providers: records.map(toCustomProviderInfo) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/custom-providers', {\n method: 'POST',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if ('response' in ctx) return ctx.response;\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const parsed = parseCustomProviderBody(body);\n if ('error' in parsed) return c.json({ error: parsed.error }, 400);\n // `previousId` lets a rename remove the old entry as well as any name clash.\n const previousId =\n body && typeof body === 'object' && typeof (body as Record<string, unknown>).previousId === 'string'\n ? ((body as Record<string, unknown>).previousId as string)\n : undefined;\n try {\n const record = await ctx.storage.upsert({\n orgId: ctx.orgId,\n userId: ctx.userId,\n input: {\n providerId: getCustomProviderId(parsed.name),\n name: parsed.name,\n url: parsed.url,\n apiKey: parsed.apiKey,\n models: parsed.models,\n },\n previousProviderId: previousId,\n });\n onCustomProvidersChanged({ orgId: ctx.orgId });\n return c.json({ ok: true, provider: toCustomProviderInfo(record) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/custom-providers/:id', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if ('response' in ctx) return ctx.response;\n const id = c.req.param('id');\n try {\n await ctx.storage.delete({ orgId: ctx.orgId, providerId: id });\n onCustomProvidersChanged({ orgId: ctx.orgId });\n return c.json({ ok: true });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n // Session-independent model catalog for settings pickers (Factory default\n // model, pack editors). Only models whose provider has a credential are\n // returned — the same filter the session-scoped hook applies client-side.\n\n registerApiRoute('/web/config/models', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n try {\n const allTenantCredentials = await listTenantCredentialsForRequest({\n c: loose(c),\n auth,\n credentials: options.modelCredentials,\n });\n const factoryProjectId = c.req.query('factoryId') || undefined;\n const tenant = auth.tenant(c);\n let tenantCredentials = allTenantCredentials;\n let sessionPolicy: { modelScope: 'factory' | 'user'; defaultModelId: string | null } | undefined;\n const resourceId = c.req.query('resourceId');\n const threadId = c.req.query('threadId');\n if (resourceId !== undefined || threadId !== undefined) {\n const address = z\n .object({ resourceId: z.string().trim().min(1), threadId: z.string().trim().min(1) })\n .safeParse({ resourceId, threadId });\n if (!address.success) return c.json({ error: 'invalid_session_context' }, 400);\n if (!tenant && auth.enabled()) return c.json({ error: 'unauthorized' }, 401);\n if (tenant) {\n if (\n !options.factoryProjects ||\n !options.sourceControlSessions ||\n !options.workItems ||\n !options.modelCredentials\n )\n return c.json({ error: 'session_model_policy_unavailable' }, 503);\n const requestContext = new RequestContext();\n requestContext.set('user', { id: tenant.userId, organizationId: tenantOrgId(tenant) });\n requestContext.set('controller', address.data);\n let policy;\n try {\n policy = await resolveFactoryModelPolicy(requestContext, {\n projects: options.factoryProjects,\n sourceControl: options.sourceControlSessions,\n workItems: options.workItems,\n });\n } catch {\n return c.json({ error: 'session_model_policy_unavailable' }, 403);\n }\n if (!policy) return c.json({ error: 'unauthorized' }, 401);\n const orgId = policy.tenant.orgId ?? tenantOrgId(tenant);\n const modelScope = policy.tenant.credentialScope ?? 'user';\n tenantCredentials = await listSessionScopedCredentials({\n credentials: options.modelCredentials,\n orgId,\n userId: policy.tenant.userId,\n modelScope,\n });\n let defaultModelId = policy.factoryDefaultModelId ?? null;\n if (modelScope === 'user') {\n if (!options.modelDefaults) return c.json({ error: 'model_defaults_unavailable' }, 503);\n await options.modelDefaults.ensureReady();\n defaultModelId =\n (await options.modelDefaults.get({ orgId, userId: policy.tenant.userId }))?.modelId ?? null;\n }\n sessionPolicy = { modelScope, defaultModelId };\n }\n } else if (c.req.query('scope') !== undefined) {\n // Explicit settings scopes never override a live thread's owner and policy above.\n const scope = z.enum(['org', 'user']).safeParse(c.req.query('scope'));\n if (!scope.success) return c.json({ error: 'invalid_model_scope' }, 400);\n tenantCredentials = allTenantCredentials?.filter(record => record.scope === scope.data);\n } else if (allTenantCredentials && factoryProjectId && tenant) {\n if (!options.factoryProjects) return c.json({ error: 'factory_unavailable' }, 503);\n await options.factoryProjects.ensureReady();\n const project = await options.factoryProjects.get({ orgId: tenantOrgId(tenant), id: factoryProjectId });\n if (!project) return c.json({ error: 'factory_project_not_found' }, 404);\n const credentialScope = project.modelScope === 'user' ? 'user' : 'org';\n tenantCredentials = allTenantCredentials.filter(record => record.scope === credentialScope);\n }\n const customProviders = options.customProviders;\n const listCustomProviders = customProviders\n ? async () => {\n const ctx = await resolveCustomProvidersContext({ c: loose(c), auth, customProviders });\n return 'response' in ctx ? [] : ctx.storage.list({ orgId: ctx.orgId });\n }\n : undefined;\n const models = await buildModelCatalog({\n controller,\n authStorage,\n tenantCredentials,\n deploymentProviders,\n listCustomProviders,\n });\n return c.json({ ...sessionPolicy, models });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/default-model', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n try {\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n return c.json({ modelId: record?.modelId ?? null });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/default-model/apply', {\n method: 'POST',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n if (\n !options.factoryProjects ||\n !options.sourceControls ||\n !options.workItems ||\n !options.controller.getSessionByResource\n ) {\n return c.json({ error: 'model_apply_unavailable' }, 503);\n }\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n if (!record?.modelId) return c.json({ error: 'default_model_not_set' }, 400);\n\n const applied: string[] = [];\n const skipped: Array<{\n sessionId: string;\n reason: 'not-running' | 'thread-missing' | 'factory-scope' | 'apply-failed';\n }> = [];\n const seen = new Set<string>();\n try {\n await options.factoryProjects.ensureReady();\n const projects = await options.factoryProjects.list({ orgId: context.orgId });\n for (const project of projects) {\n // Factory-scoped sessions bill the org and use the Factory's model, never a personal default.\n const personal = effectiveModelScope(project.modelScope, 'session') === 'user';\n const workerSessions = new Set(\n (await options.workItems.listRunBindings(context.orgId, project.id)).map(binding => binding.sessionId),\n );\n for (const sourceControl of options.sourceControls) {\n const sessions = await sourceControl.sessions.listByProject({\n orgId: context.orgId,\n factoryProjectId: project.id,\n viewerUserId: context.userId,\n });\n for (const row of sessions) {\n if (\n row.userId !== context.userId ||\n row.originSessionId ||\n workerSessions.has(row.sessionId) ||\n seen.has(row.sessionId)\n )\n continue;\n seen.add(row.sessionId);\n if (!personal) {\n skipped.push({ sessionId: row.sessionId, reason: 'factory-scope' });\n continue;\n }\n const session = await options.controller.getSessionByResource(row.sessionId);\n if (!session?.thread || !session.model.switch) {\n skipped.push({ sessionId: row.sessionId, reason: 'not-running' });\n continue;\n }\n if (!session.thread.getId()) {\n skipped.push({ sessionId: row.sessionId, reason: 'thread-missing' });\n continue;\n }\n try {\n await session.model.switch(record.modelId);\n applied.push(row.sessionId);\n } catch (error) {\n console.warn('[factory] apply user default model failed for session', row.sessionId, error);\n skipped.push({ sessionId: row.sessionId, reason: 'apply-failed' });\n }\n }\n }\n }\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n return c.json({ modelId: record.modelId, applied, skipped });\n },\n }),\n\n registerApiRoute('/web/config/default-model', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const parsed = z.object({ modelId: z.string().trim().min(1).max(256) }).safeParse(body);\n if (!parsed.success) return c.json({ error: 'Missing required field: modelId' }, 400);\n const { modelId } = parsed.data;\n try {\n await context.storage.set({ orgId: context.orgId, userId: context.userId, modelId });\n return c.json({ ok: true, modelId });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/default-model', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n try {\n await context.storage.clear({ orgId: context.orgId, userId: context.userId });\n return c.json({ ok: true, modelId: null });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n // Mirrors the TUI's /om command. All five knobs are durably stored in the\n // per-(org, user) `memory-settings` app table — never settings.json or\n // mutable session state.\n\n registerApiRoute('/web/config/om', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const resourceId = c.req.query('resourceId');\n const scope = c.req.query('scope') || undefined;\n const factoryProjectId = c.req.query('factoryId') || undefined;\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n try {\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const fallback = await factoryOmFallback(factoryProjectId);\n const availableProviders = await resolveOMResponseContext(loose(c));\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n return c.json({\n config: readStoredOMConfig(\n record,\n sessionModelId || fallback,\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n ),\n });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/om/:role/model', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const role = c.req.param('role');\n if (role !== 'observer' && role !== 'reflector') {\n return c.json({ error: `Unknown OM role \"${role}\"` }, 400);\n }\n let body: { resourceId?: unknown; modelId?: unknown; scope?: unknown; factoryId?: unknown };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const resourceId = typeof body.resourceId === 'string' ? body.resourceId : '';\n const scope = typeof body.scope === 'string' && body.scope ? body.scope : undefined;\n const factoryProjectId = typeof body.factoryId === 'string' && body.factoryId ? body.factoryId : undefined;\n const model = typeof body.modelId === 'string' ? body.modelId.trim() : '';\n if (!model) {\n return c.json({ error: 'Missing required field: modelId' }, 400);\n }\n // `'auto'` is selection intent, not a model ID: store null so the role\n // follows the active main model instead of pinning a model named \"auto\".\n const wantsAuto = model === 'auto';\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n // Resolve the response context before persisting: a provider-enumeration\n // failure must not report 500 for a write that already succeeded.\n const availableProviders = await resolveOMResponseContext(loose(c));\n try {\n await persistMemorySettings(context, {\n [role === 'observer' ? 'observerModelId' : 'reflectorModelId']: wantsAuto ? null : model,\n });\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n const config = readStoredOMConfig(\n record,\n sessionModelId || (await factoryOmFallback(factoryProjectId)),\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n );\n return c.json({ ok: true, config });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/om/thresholds', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n let body: {\n resourceId?: unknown;\n observationThreshold?: unknown;\n reflectionThreshold?: unknown;\n scope?: unknown;\n factoryId?: unknown;\n };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const resourceId = typeof body.resourceId === 'string' ? body.resourceId : '';\n const scope = typeof body.scope === 'string' && body.scope ? body.scope : undefined;\n const factoryProjectId = typeof body.factoryId === 'string' && body.factoryId ? body.factoryId : undefined;\n const observation =\n typeof body.observationThreshold === 'number' && body.observationThreshold > 0\n ? Math.round(body.observationThreshold)\n : undefined;\n const reflection =\n typeof body.reflectionThreshold === 'number' && body.reflectionThreshold > 0\n ? Math.round(body.reflectionThreshold)\n : undefined;\n if (observation === undefined && reflection === undefined) {\n return c.json({ error: 'Provide observationThreshold and/or reflectionThreshold (positive numbers)' }, 400);\n }\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n const availableProviders = await resolveOMResponseContext(loose(c));\n try {\n await persistMemorySettings(context, {\n ...(observation !== undefined ? { observationThreshold: observation } : {}),\n ...(reflection !== undefined ? { reflectionThreshold: reflection } : {}),\n });\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n const config = readStoredOMConfig(\n record,\n sessionModelId || (await factoryOmFallback(factoryProjectId)),\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n );\n return c.json({ ok: true, config });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/om/observe-attachments', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n let body: { resourceId?: unknown; value?: unknown; scope?: unknown; factoryId?: unknown };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const resourceId = typeof body.resourceId === 'string' ? body.resourceId : '';\n const scope = typeof body.scope === 'string' && body.scope ? body.scope : undefined;\n const factoryProjectId = typeof body.factoryId === 'string' && body.factoryId ? body.factoryId : undefined;\n const raw = body.value;\n const value: 'auto' | boolean = raw === 'auto' || raw === true || raw === false ? raw : 'auto';\n if (raw !== 'auto' && raw !== true && raw !== false) {\n return c.json({ error: \"value must be 'auto', true, or false\" }, 400);\n }\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n const availableProviders = await resolveOMResponseContext(loose(c));\n try {\n await persistMemorySettings(context, { observeAttachments: value });\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n const config = readStoredOMConfig(\n record,\n sessionModelId || (await factoryOmFallback(factoryProjectId)),\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n );\n return c.json({ ok: true, config });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n ];\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","names":[],"sources":["../../src/routes/config.ts"],"sourcesContent":["import { MastraCodeGateway } from '@mastra/code-sdk/agents/mastracode-gateway';\nimport type { AuthStorage } from '@mastra/code-sdk/auth/storage';\nimport { resolveAutoOMModelId } from '@mastra/code-sdk/onboarding/packs';\nimport type { ProviderAccess, ProviderAccessLevel } from '@mastra/code-sdk/onboarding/packs';\nimport { getCustomProviderId, MASTRA_GATEWAY_PROVIDER } from '@mastra/code-sdk/onboarding/settings';\nimport type { CustomProviderSetting } from '@mastra/code-sdk/onboarding/settings';\nimport { AMAZON_BEDROCK_GATEWAY_ID } from '@mastra/code-sdk/providers/amazon-bedrock-gateway';\nimport { MASTRA_GATEWAY_PREFIX } from '@mastra/code-sdk/providers/model-ids';\nimport { getModelReasoningOptions } from '@mastra/core/llm';\nimport { RequestContext } from '@mastra/core/request-context';\nimport type { ApiRoute } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\n\nimport type { Context } from 'hono';\nimport { z } from 'zod';\nimport { resolveFactoryModelPolicy } from '../session/credential-policy.js';\nimport { DEFAULT_OBSERVATION_THRESHOLD, DEFAULT_REFLECTION_THRESHOLD } from '../session/memory-settings-hydration.js';\nimport type {\n CredentialRecord,\n LoginSessionKind,\n ModelCredentialsStorage,\n} from '../storage/domains/credentials/base.js';\nimport type { CustomProviderRecord, CustomProvidersStorage } from '../storage/domains/custom-providers/base.js';\nimport { factoryMemorySettingsUserId } from '../storage/domains/memory-settings/base.js';\nimport type {\n MemorySettingsPatch,\n MemorySettingsRecord,\n MemorySettingsStorage,\n} from '../storage/domains/memory-settings/base.js';\nimport type { ModelDefaultsStorage } from '../storage/domains/model-defaults/base.js';\nimport { effectiveModelScope } from '../storage/domains/projects/base.js';\nimport type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';\nimport type { SourceControlStorageHandle } from '../storage/domains/source-control/base.js';\nimport type { WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport {\n credentialLabel,\n getAuthProviderId,\n listTenantCredentialsForRequest,\n resolveCredentialContext,\n tenantOrgId,\n WEB_OAUTH_PROVIDERS,\n} from './provider-credentials.js';\nimport { Route } from './route.js';\nimport type { RouteAuth, RouteDependencies } from './route.js';\n\n/** Widen a route-local Hono context to the plain `Context` the auth helpers take. */\nfunction loose(c: unknown): Context {\n return c as Context;\n}\n\n/**\n * Server-side configuration routes for the web app.\n *\n * The browser has no access to the credential store or the model catalog, so\n * the web settings panel asks the server — which owns both — to list providers\n * and manage API keys. This mirrors the TUI's `/api-keys` command, exposing the\n * same `AuthStorage`-backed key management over HTTP.\n *\n * Keys are never returned to the client; only their presence and source.\n */\n\n/**\n * Where a provider's active credential comes from, as seen by the caller.\n * Local mode reports `oauth`/`stored` (server-global `auth.json`); tenant mode\n * reports the scoped variants (`oauth-user`/`stored-user`/`stored-org`).\n * `deployment` (tenant mode) marks a provider the operator opted in to run on\n * the server process's own credentials (e.g. Amazon Bedrock's AWS chain).\n */\nexport type ProviderCredentialSource =\n | 'deployment'\n | 'oauth'\n | 'stored'\n | 'env'\n | 'none'\n | 'oauth-user'\n | 'oauth-org'\n | 'stored-user'\n | 'stored-org';\n\n/** A model provider with the current source of its credentials. */\nexport interface ProviderInfo {\n provider: string;\n /** Env var the provider's key is read from, if any. */\n envVar?: string;\n /** Where the active credential comes from. */\n source: ProviderCredentialSource;\n /**\n * Tenant mode: whether an org-wide API key exists for this provider, even\n * when the caller's personal credential shadows it. Lets the UI tell\n * \"shared with the org\" apart from \"only works for me\".\n */\n orgKey?: boolean;\n /**\n * Tenant mode: the caller's personal credential for this provider, if any.\n * Reported independently of `source` so the UI can manage each scope even\n * when one shadows the other.\n */\n userCredential?: 'oauth' | 'api_key';\n /** Tenant mode: the shared org credential for this provider, if any. */\n orgCredential?: 'oauth' | 'api_key';\n /** Web OAuth sign-in capability, when the provider supports it. */\n oauth?: { supported: true; modes: LoginSessionKind[] };\n}\n\n/** Minimal session surface the config routes touch. */\nexport interface OMSession {\n /** `get()` returns '' when no model is selected, so callers fall back on falsy. */\n model: { get: () => string; switch?: (modelId: string) => Promise<void> };\n thread?: { getId: () => string | null };\n}\n\n/** Minimal controller surface this module needs (model catalog + modes + sessions). */\nexport interface ModelCatalog {\n listAvailableModels: () => Promise<\n Array<{ id?: string; modelName?: string; provider: string; hasApiKey: boolean; apiKeyEnvVar?: string }>\n >;\n listModes?: () => Array<{ id: string; defaultModelId?: string }>;\n getSessionByResource?: (resourceId: string, scope?: string) => Promise<OMSession | undefined>;\n}\n\n/**\n * Build a deduplicated, sorted list of providers from the model catalog,\n * annotated with where each provider's credential currently comes from.\n * Mirrors the TUI's `/api-keys` provider list.\n *\n * When `tenantCredentials` is given (deployed mode), sources reflect the\n * *caller's* tenant rows with user > org precedence and the server-global\n * `authStorage` is ignored; otherwise the local `auth.json` view is reported.\n */\nexport async function listProviders({\n controller,\n authStorage,\n tenantCredentials,\n deploymentProviders,\n}: {\n controller: ModelCatalog;\n authStorage?: AuthStorage;\n tenantCredentials?: CredentialRecord[];\n deploymentProviders?: ReadonlySet<string>;\n}): Promise<ProviderInfo[]> {\n const models = await controller.listAvailableModels();\n const seen = new Map<string, ProviderInfo>();\n\n for (const model of models) {\n if (seen.has(model.provider)) continue;\n\n if (tenantCredentials && isDeploymentModelProvider(model.provider)) {\n // Credentials for these providers live on the server process, never in\n // tenant rows, so no account can connect them. List them only when the\n // operator opted the deployment in and the server has credentials.\n const usable =\n deploymentProviders?.has(model.provider) && models.some(m => m.provider === model.provider && m.hasApiKey);\n if (usable) seen.set(model.provider, { provider: model.provider, source: 'deployment' });\n continue;\n }\n\n const authProviderId = getAuthProviderId(model.provider);\n let source: ProviderInfo['source'] = 'none';\n let orgKey: boolean | undefined;\n let userCredential: ProviderInfo['userCredential'];\n let orgCredential: ProviderInfo['orgCredential'];\n if (tenantCredentials) {\n const userRec = tenantCredentials.find(r => r.scope === 'user' && r.provider === authProviderId);\n const orgRec = tenantCredentials.find(r => r.scope === 'org' && r.provider === authProviderId);\n // Any shared org credential (API key or org-wide OAuth) counts.\n orgKey = orgRec !== undefined;\n userCredential = userRec?.credential.type;\n orgCredential = orgRec?.credential.type;\n if (userRec?.credential.type === 'oauth') {\n source = 'oauth-user';\n } else if (userRec?.credential.type === 'api_key') {\n source = 'stored-user';\n } else if (orgRec?.credential.type === 'oauth') {\n source = 'oauth-org';\n } else if (orgRec?.credential.type === 'api_key') {\n source = 'stored-org';\n }\n } else if (authStorage?.isLoggedIn(authProviderId)) {\n source = 'oauth';\n } else if (authStorage?.hasStoredApiKey(model.provider)) {\n source = 'stored';\n } else if (model.apiKeyEnvVar && process.env[model.apiKeyEnvVar]) {\n source = 'env';\n } else if (model.hasApiKey) {\n source = 'env';\n }\n\n const flowKind = WEB_OAUTH_PROVIDERS[model.provider]?.flow;\n seen.set(model.provider, {\n provider: model.provider,\n envVar: model.apiKeyEnvVar,\n source,\n ...(orgKey !== undefined ? { orgKey } : {}),\n ...(userCredential ? { userCredential } : {}),\n ...(orgCredential ? { orgCredential } : {}),\n ...(flowKind ? { oauth: { supported: true as const, modes: [flowKind] } } : {}),\n });\n }\n\n return Array.from(seen.values()).sort((a, b) => a.provider.localeCompare(b.provider));\n}\n\n/** A user-defined OpenAI-compatible provider, with key presence (never the key). */\nexport interface CustomProviderInfo {\n id: string;\n name: string;\n url: string;\n hasApiKey: boolean;\n models: string[];\n}\n\n/** Redact a stored custom-provider row for the client (key presence only). */\nfunction toCustomProviderInfo(record: CustomProviderRecord): CustomProviderInfo {\n return {\n id: record.providerId,\n name: record.name,\n url: record.url,\n hasApiKey: Boolean(record.apiKey),\n models: record.models,\n };\n}\n\n/** The resolved custom-providers storage scope for a request. */\ninterface CustomProvidersContext {\n storage: CustomProvidersStorage;\n orgId: string;\n userId: string;\n}\n\n/**\n * Resolve the custom-providers context for a request, or a ready-to-return\n * error response. Same posture as memory settings: tenant rows in deployed\n * mode, a sentinel `local` org in no-auth mode — never settings.json.\n */\nasync function resolveCustomProvidersContext({\n c,\n auth,\n customProviders,\n}: {\n c: Context;\n auth: RouteAuth;\n customProviders?: CustomProvidersStorage;\n}): Promise<CustomProvidersContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant && auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n if (customProviders) {\n try {\n await customProviders.ensureReady();\n return tenant\n ? { storage: customProviders, orgId: tenantOrgId(tenant), userId: tenant.userId }\n : { storage: customProviders, orgId: 'local', userId: 'local' };\n } catch {\n // fall through to the unavailable response\n }\n }\n return {\n response: c.json(\n {\n error: 'custom_providers_unavailable',\n message: 'Custom provider storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n}\n\n/** Validate + coerce a request body into a CustomProviderSetting. */\nfunction parseCustomProviderBody(body: unknown): CustomProviderSetting | { error: string } {\n if (!body || typeof body !== 'object') return { error: 'Invalid JSON body' };\n const b = body as Record<string, unknown>;\n const name = typeof b.name === 'string' ? b.name.trim() : '';\n if (!name) return { error: 'Missing required field: name' };\n const url = typeof b.url === 'string' ? b.url.trim() : '';\n if (!url) return { error: 'Missing required field: url' };\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return { error: 'url must be an http(s) URL' };\n }\n } catch {\n return { error: 'url must be a valid URL' };\n }\n const apiKey = typeof b.apiKey === 'string' && b.apiKey.trim() ? b.apiKey.trim() : undefined;\n const models = Array.isArray(b.models)\n ? b.models.filter((m): m is string => typeof m === 'string' && m.trim().length > 0).map(m => m.trim())\n : [];\n return { name, url, apiKey, models };\n}\n\n/**\n * Providers whose credentials can only come from the server process (Amazon\n * Bedrock authenticates through the AWS credential chain). In tenant mode they\n * are usable only when the operator lists them in\n * `MastraFactoryConfig.deploymentModelProviders`.\n */\nexport const DEPLOYMENT_MODEL_PROVIDERS: readonly string[] = [AMAZON_BEDROCK_GATEWAY_ID];\n\nexport function isDeploymentModelProvider(provider: string): boolean {\n return DEPLOYMENT_MODEL_PROVIDERS.includes(provider);\n}\n\n/**\n * Normalize the operator's `deploymentModelProviders` list. Unsupported ids are\n * ignored with a warning rather than failing boot.\n */\nexport function resolveDeploymentModelProviders(providers: readonly string[] | undefined): ReadonlySet<string> {\n const resolved = new Set<string>();\n for (const raw of providers ?? []) {\n const provider = raw.trim();\n if (!provider) continue;\n if (isDeploymentModelProvider(provider)) {\n resolved.add(provider);\n } else {\n console.warn(\n `[factory] Ignoring deployment model provider \"${provider}\". Supported: ${DEPLOYMENT_MODEL_PROVIDERS.join(', ')}.`,\n );\n }\n }\n return resolved;\n}\n\nfunction grantingTenantRecord(records: CredentialRecord[], authProviderId: string) {\n return (\n records.find(r => r.scope === 'user' && r.provider === authProviderId) ??\n records.find(r => r.scope === 'org' && r.provider === authProviderId)\n );\n}\n\ntype ModelCredentialHolder = 'personal' | 'organization' | 'deployment';\n\nfunction tenantModelCredential(\n records: CredentialRecord[] | undefined,\n provider: string,\n): { credentialLabel?: string; credentialHolder?: ModelCredentialHolder } {\n if (!records) return {};\n if (isDeploymentModelProvider(provider)) return { credentialHolder: 'deployment' };\n const record = grantingTenantRecord(records, getAuthProviderId(provider));\n if (!record) return {};\n return {\n credentialLabel: credentialLabel(provider, record.credential.type),\n credentialHolder: record.scope === 'user' ? 'personal' : 'organization',\n };\n}\n\n/**\n * Compute which providers the user can reach, mirroring the TUI's\n * `/models-pack` access derivation: OAuth/api-key from the credential store for\n * the named providers, plus any other provider that has a usable key.\n */\nexport async function buildProviderAccess({\n controller,\n authStorage,\n tenantCredentials,\n deploymentProviders,\n}: {\n controller: ModelCatalog;\n authStorage?: AuthStorage;\n tenantCredentials?: CredentialRecord[];\n deploymentProviders?: ReadonlySet<string>;\n}): Promise<ProviderAccess> {\n const models = await controller.listAvailableModels();\n const hasModelKey = (provider: string) => models.some(m => m.provider === provider && m.hasApiKey);\n const accessLevel = (provider: string): ProviderAccessLevel => {\n const authProviderId = getAuthProviderId(provider);\n if (tenantCredentials) {\n // Tenant rows never authenticate these providers; only an operator\n // opt-in plus credentials on the server process does.\n if (isDeploymentModelProvider(provider)) {\n return deploymentProviders?.has(provider) && hasModelKey(provider) ? 'apikey' : false;\n }\n const credential = grantingTenantRecord(tenantCredentials, authProviderId)?.credential;\n if (credential?.type === 'oauth') return 'oauth';\n if (credential?.type === 'api_key' && credential.key.trim().length > 0) return 'apikey';\n return false;\n }\n\n const oauthCredential = authStorage?.get(authProviderId);\n if (oauthCredential?.type === 'oauth') return 'oauth';\n if (authStorage?.hasStoredApiKey(provider)) return 'apikey';\n const directCredential = authStorage?.get(provider);\n if (directCredential?.type === 'api_key' && directCredential.key.trim().length > 0) return 'apikey';\n return hasModelKey(provider) ? 'apikey' : false;\n };\n const access: ProviderAccess = {\n anthropic: accessLevel('anthropic'),\n openai: accessLevel('openai'),\n cerebras: accessLevel('cerebras'),\n google: accessLevel('google'),\n deepseek: accessLevel('deepseek'),\n 'github-copilot': accessLevel('github-copilot'),\n };\n const seen = new Set(Object.keys(access));\n for (const m of models) {\n if (!seen.has(m.provider)) {\n access[m.provider] = accessLevel(m.provider);\n seen.add(m.provider);\n }\n }\n return access;\n}\n\nfunction canUseModelProvider(access: ProviderAccess, provider: string): boolean {\n return Boolean(access[provider]);\n}\n\n/** A model the caller can pick or switch to. */\nexport interface ModelCatalogEntry {\n id: string;\n provider: string;\n modelName?: string;\n hasApiKey: true;\n reasoningOptions: ReturnType<typeof getModelReasoningOptions> | undefined;\n credentialLabel?: string;\n credentialHolder?: ModelCredentialHolder;\n}\n\n/**\n * Models usable with the given credentials: built-in models whose provider the\n * credentials reach, then the org's custom provider models. The Settings model\n * picker and `factory_switch_session_model` both use this so they cannot drift.\n */\nexport async function buildModelCatalog({\n controller,\n authStorage,\n tenantCredentials,\n deploymentProviders,\n listCustomProviders,\n}: {\n controller: ModelCatalog;\n authStorage?: AuthStorage;\n /** Tenant rows in deployed mode; absent in local mode, where `authStorage` and server keys govern. */\n tenantCredentials?: CredentialRecord[];\n deploymentProviders?: ReadonlySet<string>;\n listCustomProviders?: () => Promise<CustomProviderRecord[]>;\n}): Promise<ModelCatalogEntry[]> {\n const [models, access] = await Promise.all([\n controller.listAvailableModels(),\n buildProviderAccess({\n controller,\n authStorage: tenantCredentials ? undefined : authStorage,\n tenantCredentials,\n deploymentProviders,\n }),\n ]);\n const catalog: ModelCatalogEntry[] = models.flatMap(({ id, provider, modelName }) =>\n typeof id === 'string' && canUseModelProvider(access, provider)\n ? [\n {\n id,\n provider,\n modelName,\n hasApiKey: true as const,\n reasoningOptions: getModelReasoningOptions(id),\n ...tenantModelCredential(tenantCredentials, provider),\n },\n ]\n : [],\n );\n // The boot-time gateway catalog only carries the local custom providers, so\n // tenant callers get their org's rows here. Dedupe against ids already present.\n if (listCustomProviders) {\n try {\n const known = new Set(catalog.map(m => m.id));\n const customProviderCredential: { credentialHolder?: ModelCredentialHolder } = tenantCredentials\n ? { credentialHolder: 'organization' }\n : {};\n for (const record of await listCustomProviders()) {\n for (const model of record.models) {\n const id = `${record.providerId}/${model}`;\n if (known.has(id)) continue;\n known.add(id);\n catalog.push({\n id,\n provider: record.providerId,\n modelName: model,\n hasApiKey: true,\n reasoningOptions: undefined,\n ...customProviderCredential,\n });\n }\n }\n } catch {\n // Fail soft: the catalog still serves the built-in models.\n }\n }\n return catalog.sort((a, b) =>\n a.provider === b.provider ? a.id.localeCompare(b.id) : a.provider.localeCompare(b.provider),\n );\n}\n\n/**\n * The tenant credentials a session's model policy allows: the Factory's (org\n * rows) for Factory-scoped sessions, the session owner's for user-scoped ones.\n */\nexport async function listSessionScopedCredentials({\n credentials,\n orgId,\n userId,\n modelScope,\n}: {\n credentials: Pick<ModelCredentialsStorage, 'listCredentials'>;\n orgId: string;\n userId: string;\n modelScope: 'factory' | 'user';\n}): Promise<CredentialRecord[]> {\n const storageScope = modelScope === 'factory' ? 'org' : 'user';\n return (await credentials.listCredentials(orgId, userId)).filter(record => record.scope === storageScope);\n}\n\n/** Per-user default model context for the current request. */\nexport interface ModelDefaultsContext {\n storage: ModelDefaultsStorage;\n orgId: string;\n userId: string;\n}\n\n/** Resolve the default-model context for a request, or a ready-to-return error response. */\nasync function resolveModelDefaultsContext({\n c,\n auth,\n modelDefaults,\n}: {\n c: Context;\n auth: RouteAuth;\n modelDefaults?: ModelDefaultsStorage;\n}): Promise<ModelDefaultsContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant && auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n if (modelDefaults) {\n try {\n await modelDefaults.ensureReady();\n return tenant\n ? { storage: modelDefaults, orgId: tenantOrgId(tenant), userId: tenant.userId }\n : { storage: modelDefaults, orgId: 'local', userId: 'local' };\n } catch {\n // fall through to the unavailable response\n }\n }\n return {\n response: c.json(\n {\n error: 'model_defaults_unavailable',\n message: 'Default model storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n}\n\n// Mirrors the TUI `/om` command. Settings are persisted per organization and\n// user in the Factory app database, then loaded into request context for each\n// invocation without copying them into mutable session state.\n\nexport interface OMRoleConfigInfo {\n model: 'auto' | string;\n effectiveModelId: string;\n effectiveModelSource: 'explicit' | 'live-session' | 'configured-default';\n providerStatus: 'available' | 'unavailable';\n}\n\n/** Persisted intent plus the concrete models the current Factory configuration resolves. */\nexport interface OMConfigInfo {\n observer: OMRoleConfigInfo;\n reflector: OMRoleConfigInfo;\n /** @deprecated Use `observer.effectiveModelId`. */\n observerModelId: string;\n /** @deprecated Use `reflector.effectiveModelId`. */\n reflectorModelId: string;\n observationThreshold: number;\n reflectionThreshold: number;\n observeAttachments: 'auto' | boolean;\n}\n\nexport interface ProviderOMDefaultsResponse {\n ok: true;\n config: OMConfigInfo;\n}\n\nfunction modelProvider(modelId: string): string {\n // Effective IDs keep their `mastra/` route; the provider segment after it is what\n // the SDK resolver falls back to when the gateway is not configured.\n const normalized = modelId.replace(/^mastracode\\//, '').replace(/^mastra\\//, '');\n return normalized.split('/', 1)[0] ?? '';\n}\n\nfunction roleConfig(\n model: OMRoleConfigInfo['model'],\n effectiveModelId: string,\n autoModelSource: 'live-session' | 'configured-default',\n availableProviders: ReadonlySet<string>,\n): OMRoleConfigInfo {\n return {\n model,\n effectiveModelId,\n effectiveModelSource: model === 'auto' ? autoModelSource : 'explicit',\n providerStatus:\n availableProviders.has(modelProvider(effectiveModelId)) ||\n (effectiveModelId.startsWith(MASTRA_GATEWAY_PREFIX) && availableProviders.has(MASTRA_GATEWAY_PROVIDER))\n ? 'available'\n : 'unavailable',\n };\n}\n\nfunction readStoredOMConfig(\n record: MemorySettingsRecord | null,\n currentModelId: string | undefined,\n autoModelSource: 'live-session' | 'configured-default',\n availableProviders: ReadonlySet<string>,\n): OMConfigInfo {\n const autoModelId = resolveAutoOMModelId(currentModelId, providerId => availableProviders.has(providerId));\n const observerModelId = record?.observerModelId ?? autoModelId;\n const reflectorModelId = record?.reflectorModelId ?? autoModelId;\n return {\n observer: roleConfig(record?.observerModelId ?? 'auto', observerModelId, autoModelSource, availableProviders),\n reflector: roleConfig(record?.reflectorModelId ?? 'auto', reflectorModelId, autoModelSource, availableProviders),\n observerModelId,\n reflectorModelId,\n observationThreshold: record?.observationThreshold ?? DEFAULT_OBSERVATION_THRESHOLD,\n reflectionThreshold: record?.reflectionThreshold ?? DEFAULT_REFLECTION_THRESHOLD,\n observeAttachments: record?.observeAttachments ?? 'auto',\n };\n}\n\n/**\n * Where a request's OM settings live: the `memory-settings` factory storage\n * domain, one row per (org, user). Without a tenant (auth disabled), settings\n * land on a sentinel `(local, local)` row in the same table — the web surface\n * never reads or writes `settings.json` for memory settings.\n */\ninterface MemorySettingsContext {\n storage: MemorySettingsStorage;\n orgId: string;\n userId: string;\n}\n\n/**\n * Resolve the memory-settings context for a request, or a ready-to-return\n * error response. When `factoryProjectId` is provided the row addressed is the\n * factory project's shared settings (a sentinel user id in the caller's org)\n * instead of the caller's personal row — this is what factory board runs and\n * channel sessions hydrate from.\n */\nasync function resolveMemorySettingsContext({\n c,\n auth,\n memorySettings,\n factoryProjectId,\n factoryProjects,\n}: {\n c: Context;\n auth: RouteAuth;\n memorySettings?: MemorySettingsStorage;\n factoryProjectId?: string;\n factoryProjects?: FactoryProjectsStorage;\n}): Promise<MemorySettingsContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant && auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n // Factory-scoped rows are shared org state: the target project must exist in\n // the caller's org before its settings row can be read or written.\n if (factoryProjectId && tenant) {\n if (!factoryProjects) return { response: c.json({ error: 'factory_unavailable' }, 503) };\n try {\n await factoryProjects.ensureReady();\n const project = await factoryProjects.get({ orgId: tenantOrgId(tenant), id: factoryProjectId });\n if (!project) return { response: c.json({ error: 'factory_project_not_found' }, 404) };\n } catch {\n return { response: c.json({ error: 'factory_unavailable' }, 503) };\n }\n }\n if (memorySettings) {\n try {\n await memorySettings.ensureReady();\n const factoryUserId = factoryProjectId ? factoryMemorySettingsUserId(factoryProjectId) : undefined;\n return tenant\n ? { storage: memorySettings, orgId: tenantOrgId(tenant), userId: factoryUserId ?? tenant.userId }\n : { storage: memorySettings, orgId: 'local', userId: factoryUserId ?? 'local' };\n } catch {\n // fall through to the unavailable response\n }\n }\n return {\n response: c.json(\n {\n error: 'memory_settings_unavailable',\n message: 'Memory settings storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n}\n\n/** Persist an OM knob change to the caller's memory-settings row. */\nasync function persistMemorySettings(context: MemorySettingsContext, patch: MemorySettingsPatch): Promise<void> {\n await context.storage.patch({ orgId: context.orgId, userId: context.userId, patch });\n}\n\n/** Dependencies injected into {@link ConfigRoutes}. */\nexport interface ConfigRoutesDeps extends RouteDependencies {\n controller: ModelCatalog;\n features?: { knowledge: boolean };\n authStorage?: AuthStorage;\n /** Tenant credential domain handle; absent in local (no-DB) mode. */\n modelCredentials?: ModelCredentialsStorage;\n /** Tenant model-defaults domain handle; absent in local (no-DB) mode. */\n modelDefaults?: ModelDefaultsStorage;\n /** Source-control sessions available to config route integrations. */\n sourceControlSessions?: Pick<SourceControlStorageHandle['sessions'], 'getBySessionId'>;\n sourceControls?: Array<Pick<SourceControlStorageHandle, 'sessions'>>;\n /** Thread membership used to resolve the same model policy as an invocation. */\n workItems?: WorkItemsStorage;\n /** Tenant memory-settings domain handle; absent in local (no-DB) mode. */\n memorySettings?: MemorySettingsStorage;\n /** Factory projects domain, used to derive OM fallbacks from a factory's default model. */\n factoryProjects?: FactoryProjectsStorage;\n /** Custom-providers domain handle; absent when the app database is missing. */\n customProviders?: CustomProvidersStorage;\n /** Notifies the host after tenant credentials change so caches can be dropped. */\n onCredentialsChanged?: (tenant: { orgId: string; userId?: string }) => void;\n /** Notifies the host after custom providers change so model-router caches can be dropped. */\n onCustomProvidersChanged?: (tenant: { orgId: string }) => void;\n /**\n * Tenant mode: providers the operator opted in to run on the server process's\n * own credentials (see `DEPLOYMENT_MODEL_PROVIDERS`).\n */\n deploymentProviders?: ReadonlySet<string>;\n}\n\n/**\n * The web config routes as Mastra `apiRoutes`:\n * - `GET /web/config/features` — list server-enabled product features\n * - `GET /web/config/providers` — list providers + key source\n * - `PUT /web/config/providers/:provider/key` — set/update a provider's API key\n * - `DELETE /web/config/providers/:provider/key` — remove a stored API key\n * - `GET /web/config/models` — list available models (credentialed providers)\n * - `GET /web/config/custom-providers` — list custom OpenAI-compatible providers\n * - `POST /web/config/custom-providers` — create/update a custom provider\n * - `DELETE /web/config/custom-providers/:id` — remove a custom provider\n * - `GET /web/config/om` — read OM models/thresholds/observe-attachments\n * - `PUT /web/config/om/:role/model` — switch observer/reflector model\n * - `PUT /web/config/om/thresholds` — set observation/reflection thresholds\n * - `PUT /web/config/om/observe-attachments` — set observe-attachments (auto/on/off)\n */\nexport class ConfigRoutes extends Route<ConfigRoutesDeps> {\n routes(): ApiRoute[] {\n const options = this.deps;\n const { controller, authStorage, auth, deploymentProviders } = options;\n const onCredentialsChanged = options.onCredentialsChanged ?? (() => {});\n const onCustomProvidersChanged = options.onCustomProvidersChanged ?? (() => {});\n\n const resolveOMResponseContext = async (c: Context) => {\n const tenantCredentials = await listTenantCredentialsForRequest({\n c: loose(c),\n auth,\n credentials: options.modelCredentials,\n });\n const access = await buildProviderAccess({\n controller,\n authStorage: tenantCredentials ? undefined : authStorage,\n tenantCredentials,\n deploymentProviders,\n });\n const availableProviders = new Set(\n Object.entries(access).flatMap(([providerId, configured]) => (configured ? [providerId] : [])),\n );\n // `mastra/` routes run through the Mastra gateway whenever its key is configured.\n if (MastraCodeGateway.getMastraGatewayApiKey()) availableProviders.add(MASTRA_GATEWAY_PROVIDER);\n if (options.customProviders) {\n const context = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if (!('response' in context)) {\n for (const provider of await context.storage.list({ orgId: context.orgId })) {\n availableProviders.add(provider.providerId);\n }\n }\n }\n return availableProviders;\n };\n\n // Without a live session, Auto previews against the factory default model\n // (resolved with this account's providers in readStoredOMConfig) — not the\n // global built-in default, whose provider may have no credential here.\n const factoryOmFallback = async (factoryProjectId: string | undefined): Promise<string | undefined> => {\n try {\n return factoryProjectId\n ? await options.factoryProjects\n ?.getById({ id: factoryProjectId })\n .then(project => project?.defaultModelId ?? undefined)\n : controller.listModes?.().find(mode => mode.defaultModelId)?.defaultModelId;\n } catch {\n return undefined;\n }\n };\n\n return [\n registerApiRoute('/web/config/features', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => c.json({ knowledge: options.features?.knowledge ?? false }),\n }),\n\n registerApiRoute('/web/config/providers', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n try {\n // Tenant mode lists the caller's rows and never exposes the\n // server-global auth.json; local mode is unchanged.\n const tenantCredentials = await listTenantCredentialsForRequest({\n c: loose(c),\n auth,\n credentials: options.modelCredentials,\n });\n // Tenant mode also reports whether the caller may write org-wide\n // keys, so the settings UI can gate the \"Everyone in org\" option.\n const tenant = auth.tenant(loose(c));\n const orgKeyAdmin = tenant ? await auth.isOrganizationAdmin(loose(c), tenantOrgId(tenant)) : undefined;\n return c.json({\n providers: await listProviders({\n controller,\n authStorage: tenantCredentials ? undefined : authStorage,\n tenantCredentials,\n deploymentProviders,\n }),\n ...(orgKeyAdmin !== undefined ? { orgKeyAdmin } : {}),\n });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/providers/:provider/key', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCredentialContext({ c: loose(c), auth, credentials: options.modelCredentials });\n if ('response' in ctx) return ctx.response;\n\n const provider = c.req.param('provider');\n let body: { key?: unknown; envVar?: unknown; scope?: unknown };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const key = typeof body.key === 'string' ? body.key.trim() : '';\n if (!key) return c.json({ error: 'Missing required field: key' }, 400);\n const envVar = typeof body.envVar === 'string' ? body.envVar : undefined;\n const scope = body.scope === 'org' ? 'org' : 'user';\n try {\n if (ctx.mode === 'tenant') {\n // A stored key would never be read: these providers authenticate\n // with the server process's credentials only.\n if (isDeploymentModelProvider(provider)) {\n return c.json(\n {\n error: 'provider_configured_by_deployment',\n message: `${provider} is configured by the Factory deployment (credentials on the server), not per account.`,\n },\n 400,\n );\n }\n if (scope === 'org' && !(await auth.isOrganizationAdmin(loose(c), ctx.orgId))) {\n return c.json({ error: 'organization_admin_required' }, 403);\n }\n const tenant = scope === 'org' ? { orgId: ctx.orgId } : { orgId: ctx.orgId, userId: ctx.userId };\n // envVar is intentionally ignored: tenant credentials are resolved\n // per-request, never written into process.env.\n await ctx.storage.setCredential(tenant, getAuthProviderId(provider), { type: 'api_key', key });\n onCredentialsChanged(tenant);\n const records = await ctx.storage.listCredentials(ctx.orgId, ctx.userId);\n const providers = await listProviders({ controller, tenantCredentials: records, deploymentProviders });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n }\n if (!authStorage) return c.json({ error: 'Credential storage is not available' }, 503);\n // Local mode is single-user: scope is meaningless and ignored.\n authStorage.setStoredApiKey(provider, key, envVar);\n const providers = await listProviders({ controller, authStorage });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/providers/:provider/key', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCredentialContext({ c: loose(c), auth, credentials: options.modelCredentials });\n if ('response' in ctx) return ctx.response;\n\n const provider = c.req.param('provider');\n const scope = c.req.query('scope') === 'org' ? 'org' : 'user';\n try {\n if (ctx.mode === 'tenant') {\n if (scope === 'org' && !(await auth.isOrganizationAdmin(loose(c), ctx.orgId))) {\n return c.json({ error: 'organization_admin_required' }, 403);\n }\n const tenant = scope === 'org' ? { orgId: ctx.orgId } : { orgId: ctx.orgId, userId: ctx.userId };\n await ctx.storage.removeCredential(tenant, getAuthProviderId(provider));\n onCredentialsChanged(tenant);\n const records = await ctx.storage.listCredentials(ctx.orgId, ctx.userId);\n const providers = await listProviders({ controller, tenantCredentials: records, deploymentProviders });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n }\n if (!authStorage) return c.json({ error: 'Credential storage is not available' }, 503);\n authStorage.remove(`apikey:${provider}`);\n const providers = await listProviders({ controller, authStorage });\n return c.json({ ok: true, provider: providers.find(p => p.provider === provider) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n // Mirrors the TUI's /custom-providers command, but backed by the\n // `custom-providers` domain (org rows in tenant mode, a sentinel `local`\n // org in no-auth mode) — the server never reads settings.json for these.\n\n registerApiRoute('/web/config/custom-providers', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if ('response' in ctx) return ctx.response;\n try {\n const records = await ctx.storage.list({ orgId: ctx.orgId });\n return c.json({ providers: records.map(toCustomProviderInfo) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/custom-providers', {\n method: 'POST',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if ('response' in ctx) return ctx.response;\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const parsed = parseCustomProviderBody(body);\n if ('error' in parsed) return c.json({ error: parsed.error }, 400);\n // `previousId` lets a rename remove the old entry as well as any name clash.\n const previousId =\n body && typeof body === 'object' && typeof (body as Record<string, unknown>).previousId === 'string'\n ? ((body as Record<string, unknown>).previousId as string)\n : undefined;\n try {\n const record = await ctx.storage.upsert({\n orgId: ctx.orgId,\n userId: ctx.userId,\n input: {\n providerId: getCustomProviderId(parsed.name),\n name: parsed.name,\n url: parsed.url,\n apiKey: parsed.apiKey,\n models: parsed.models,\n },\n previousProviderId: previousId,\n });\n onCustomProvidersChanged({ orgId: ctx.orgId });\n return c.json({ ok: true, provider: toCustomProviderInfo(record) });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/custom-providers/:id', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const ctx = await resolveCustomProvidersContext({\n c: loose(c),\n auth,\n customProviders: options.customProviders,\n });\n if ('response' in ctx) return ctx.response;\n const id = c.req.param('id');\n try {\n await ctx.storage.delete({ orgId: ctx.orgId, providerId: id });\n onCustomProvidersChanged({ orgId: ctx.orgId });\n return c.json({ ok: true });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n // Session-independent model catalog for settings pickers (Factory default\n // model, pack editors). Only models whose provider has a credential are\n // returned — the same filter the session-scoped hook applies client-side.\n\n registerApiRoute('/web/config/models', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n try {\n const allTenantCredentials = await listTenantCredentialsForRequest({\n c: loose(c),\n auth,\n credentials: options.modelCredentials,\n });\n const factoryProjectId = c.req.query('factoryId') || undefined;\n const tenant = auth.tenant(c);\n let tenantCredentials = allTenantCredentials;\n let sessionPolicy: { modelScope: 'factory' | 'user'; defaultModelId: string | null } | undefined;\n const resourceId = c.req.query('resourceId');\n const threadId = c.req.query('threadId');\n if (resourceId !== undefined || threadId !== undefined) {\n const address = z\n .object({ resourceId: z.string().trim().min(1), threadId: z.string().trim().min(1) })\n .safeParse({ resourceId, threadId });\n if (!address.success) return c.json({ error: 'invalid_session_context' }, 400);\n if (!tenant && auth.enabled()) return c.json({ error: 'unauthorized' }, 401);\n if (tenant) {\n if (\n !options.factoryProjects ||\n !options.sourceControlSessions ||\n !options.workItems ||\n !options.modelCredentials\n )\n return c.json({ error: 'session_model_policy_unavailable' }, 503);\n const requestContext = new RequestContext();\n requestContext.set('user', { id: tenant.userId, organizationId: tenantOrgId(tenant) });\n requestContext.set('controller', address.data);\n let policy;\n try {\n policy = await resolveFactoryModelPolicy(requestContext, {\n projects: options.factoryProjects,\n sourceControl: options.sourceControlSessions,\n workItems: options.workItems,\n });\n } catch {\n return c.json({ error: 'session_model_policy_unavailable' }, 403);\n }\n if (!policy) return c.json({ error: 'unauthorized' }, 401);\n const orgId = policy.tenant.orgId ?? tenantOrgId(tenant);\n const modelScope = policy.tenant.credentialScope ?? 'user';\n tenantCredentials = await listSessionScopedCredentials({\n credentials: options.modelCredentials,\n orgId,\n userId: policy.tenant.userId,\n modelScope,\n });\n let defaultModelId = policy.factoryDefaultModelId ?? null;\n if (modelScope === 'user') {\n if (!options.modelDefaults) return c.json({ error: 'model_defaults_unavailable' }, 503);\n await options.modelDefaults.ensureReady();\n defaultModelId =\n (await options.modelDefaults.get({ orgId, userId: policy.tenant.userId }))?.modelId ?? null;\n }\n sessionPolicy = { modelScope, defaultModelId };\n }\n } else if (c.req.query('scope') !== undefined) {\n // Explicit settings scopes never override a live thread's owner and policy above.\n const scope = z.enum(['org', 'user']).safeParse(c.req.query('scope'));\n if (!scope.success) return c.json({ error: 'invalid_model_scope' }, 400);\n tenantCredentials = allTenantCredentials?.filter(record => record.scope === scope.data);\n } else if (allTenantCredentials && factoryProjectId && tenant) {\n if (!options.factoryProjects) return c.json({ error: 'factory_unavailable' }, 503);\n await options.factoryProjects.ensureReady();\n const project = await options.factoryProjects.get({ orgId: tenantOrgId(tenant), id: factoryProjectId });\n if (!project) return c.json({ error: 'factory_project_not_found' }, 404);\n const credentialScope = project.modelScope === 'user' ? 'user' : 'org';\n tenantCredentials = allTenantCredentials.filter(record => record.scope === credentialScope);\n }\n const customProviders = options.customProviders;\n const listCustomProviders = customProviders\n ? async () => {\n const ctx = await resolveCustomProvidersContext({ c: loose(c), auth, customProviders });\n return 'response' in ctx ? [] : ctx.storage.list({ orgId: ctx.orgId });\n }\n : undefined;\n const models = await buildModelCatalog({\n controller,\n authStorage,\n tenantCredentials,\n deploymentProviders,\n listCustomProviders,\n });\n return c.json({ ...sessionPolicy, models });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/default-model', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n try {\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n return c.json({ modelId: record?.modelId ?? null });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/default-model/apply', {\n method: 'POST',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n if (\n !options.factoryProjects ||\n !options.sourceControls ||\n !options.workItems ||\n !options.controller.getSessionByResource\n ) {\n return c.json({ error: 'model_apply_unavailable' }, 503);\n }\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n if (!record?.modelId) return c.json({ error: 'default_model_not_set' }, 400);\n\n const applied: string[] = [];\n const skipped: Array<{\n sessionId: string;\n reason: 'not-running' | 'thread-missing' | 'factory-scope' | 'apply-failed';\n }> = [];\n const seen = new Set<string>();\n try {\n await options.factoryProjects.ensureReady();\n const projects = await options.factoryProjects.list({ orgId: context.orgId });\n for (const project of projects) {\n // Factory-scoped sessions bill the org and use the Factory's model, never a personal default.\n const personal = effectiveModelScope(project.modelScope, 'session') === 'user';\n const workerSessions = new Set(\n (await options.workItems.listRunBindings(context.orgId, project.id)).map(binding => binding.sessionId),\n );\n for (const sourceControl of options.sourceControls) {\n const sessions = await sourceControl.sessions.listByProject({\n orgId: context.orgId,\n factoryProjectId: project.id,\n viewerUserId: context.userId,\n });\n for (const row of sessions) {\n if (\n row.userId !== context.userId ||\n row.originSessionId ||\n workerSessions.has(row.sessionId) ||\n seen.has(row.sessionId)\n )\n continue;\n seen.add(row.sessionId);\n if (!personal) {\n skipped.push({ sessionId: row.sessionId, reason: 'factory-scope' });\n continue;\n }\n const session = await options.controller.getSessionByResource(row.sessionId);\n if (!session?.thread || !session.model.switch) {\n skipped.push({ sessionId: row.sessionId, reason: 'not-running' });\n continue;\n }\n if (!session.thread.getId()) {\n skipped.push({ sessionId: row.sessionId, reason: 'thread-missing' });\n continue;\n }\n try {\n await session.model.switch(record.modelId);\n applied.push(row.sessionId);\n } catch (error) {\n console.warn('[factory] apply user default model failed for session', row.sessionId, error);\n skipped.push({ sessionId: row.sessionId, reason: 'apply-failed' });\n }\n }\n }\n }\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n return c.json({ modelId: record.modelId, applied, skipped });\n },\n }),\n\n registerApiRoute('/web/config/default-model', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const parsed = z.object({ modelId: z.string().trim().min(1).max(256) }).safeParse(body);\n if (!parsed.success) return c.json({ error: 'Missing required field: modelId' }, 400);\n const { modelId } = parsed.data;\n try {\n await context.storage.set({ orgId: context.orgId, userId: context.userId, modelId });\n return c.json({ ok: true, modelId });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/default-model', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const context = await resolveModelDefaultsContext({\n c: loose(c),\n auth,\n modelDefaults: options.modelDefaults,\n });\n if ('response' in context) return context.response;\n try {\n await context.storage.clear({ orgId: context.orgId, userId: context.userId });\n return c.json({ ok: true, modelId: null });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n // Mirrors the TUI's /om command. All five knobs are durably stored in the\n // per-(org, user) `memory-settings` app table — never settings.json or\n // mutable session state.\n\n registerApiRoute('/web/config/om', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const resourceId = c.req.query('resourceId');\n const scope = c.req.query('scope') || undefined;\n const factoryProjectId = c.req.query('factoryId') || undefined;\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n try {\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const fallback = await factoryOmFallback(factoryProjectId);\n const availableProviders = await resolveOMResponseContext(loose(c));\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n return c.json({\n config: readStoredOMConfig(\n record,\n sessionModelId || fallback,\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n ),\n });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/om/:role/model', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const role = c.req.param('role');\n if (role !== 'observer' && role !== 'reflector') {\n return c.json({ error: `Unknown OM role \"${role}\"` }, 400);\n }\n let body: { resourceId?: unknown; modelId?: unknown; scope?: unknown; factoryId?: unknown };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const resourceId = typeof body.resourceId === 'string' ? body.resourceId : '';\n const scope = typeof body.scope === 'string' && body.scope ? body.scope : undefined;\n const factoryProjectId = typeof body.factoryId === 'string' && body.factoryId ? body.factoryId : undefined;\n const model = typeof body.modelId === 'string' ? body.modelId.trim() : '';\n if (!model) {\n return c.json({ error: 'Missing required field: modelId' }, 400);\n }\n // `'auto'` is selection intent, not a model ID: store null so the role\n // follows the active main model instead of pinning a model named \"auto\".\n const wantsAuto = model === 'auto';\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n // Resolve the response context before persisting: a provider-enumeration\n // failure must not report 500 for a write that already succeeded.\n const availableProviders = await resolveOMResponseContext(loose(c));\n try {\n await persistMemorySettings(context, {\n [role === 'observer' ? 'observerModelId' : 'reflectorModelId']: wantsAuto ? null : model,\n });\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n const config = readStoredOMConfig(\n record,\n sessionModelId || (await factoryOmFallback(factoryProjectId)),\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n );\n return c.json({ ok: true, config });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/om/thresholds', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n let body: {\n resourceId?: unknown;\n observationThreshold?: unknown;\n reflectionThreshold?: unknown;\n scope?: unknown;\n factoryId?: unknown;\n };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const resourceId = typeof body.resourceId === 'string' ? body.resourceId : '';\n const scope = typeof body.scope === 'string' && body.scope ? body.scope : undefined;\n const factoryProjectId = typeof body.factoryId === 'string' && body.factoryId ? body.factoryId : undefined;\n const observation =\n typeof body.observationThreshold === 'number' && body.observationThreshold > 0\n ? Math.round(body.observationThreshold)\n : undefined;\n const reflection =\n typeof body.reflectionThreshold === 'number' && body.reflectionThreshold > 0\n ? Math.round(body.reflectionThreshold)\n : undefined;\n if (observation === undefined && reflection === undefined) {\n return c.json({ error: 'Provide observationThreshold and/or reflectionThreshold (positive numbers)' }, 400);\n }\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n const availableProviders = await resolveOMResponseContext(loose(c));\n try {\n await persistMemorySettings(context, {\n ...(observation !== undefined ? { observationThreshold: observation } : {}),\n ...(reflection !== undefined ? { reflectionThreshold: reflection } : {}),\n });\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n const config = readStoredOMConfig(\n record,\n sessionModelId || (await factoryOmFallback(factoryProjectId)),\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n );\n return c.json({ ok: true, config });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n\n registerApiRoute('/web/config/om/observe-attachments', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n let body: { resourceId?: unknown; value?: unknown; scope?: unknown; factoryId?: unknown };\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const resourceId = typeof body.resourceId === 'string' ? body.resourceId : '';\n const scope = typeof body.scope === 'string' && body.scope ? body.scope : undefined;\n const factoryProjectId = typeof body.factoryId === 'string' && body.factoryId ? body.factoryId : undefined;\n const raw = body.value;\n const value: 'auto' | boolean = raw === 'auto' || raw === true || raw === false ? raw : 'auto';\n if (raw !== 'auto' && raw !== true && raw !== false) {\n return c.json({ error: \"value must be 'auto', true, or false\" }, 400);\n }\n const context = await resolveMemorySettingsContext({\n c: loose(c),\n auth,\n memorySettings: options.memorySettings,\n factoryProjectId,\n factoryProjects: options.factoryProjects,\n });\n if ('response' in context) return context.response;\n const availableProviders = await resolveOMResponseContext(loose(c));\n try {\n await persistMemorySettings(context, { observeAttachments: value });\n const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });\n const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : undefined;\n const sessionModelId = session?.model.get();\n const config = readStoredOMConfig(\n record,\n sessionModelId || (await factoryOmFallback(factoryProjectId)),\n sessionModelId ? 'live-session' : 'configured-default',\n availableProviders,\n );\n return c.json({ ok: true, config });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n ];\n }\n}\n"],"mappings":"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"}
|
|
@@ -28,12 +28,13 @@ export { getCredentialProviderId as getAuthProviderId } from '@mastra/code-sdk/p
|
|
|
28
28
|
* *catalog* provider id (what the routes and settings UI use). All flows need
|
|
29
29
|
* no inbound connection to the server: Anthropic uses paste-code PKCE, the
|
|
30
30
|
* rest use RFC 8628-style device codes. `subscription` names the plan the
|
|
31
|
-
* sign-in bills, as shown under a reply.
|
|
31
|
+
* sign-in bills, as shown under a reply and in the composer.
|
|
32
32
|
*/
|
|
33
33
|
export declare const WEB_OAUTH_PROVIDERS: Readonly<Record<string, {
|
|
34
34
|
flow: LoginSessionKind;
|
|
35
35
|
subscription: string;
|
|
36
36
|
}>>;
|
|
37
|
+
export declare function credentialLabel(provider: string, credentialType: CredentialRecord['credential']['type']): string | undefined;
|
|
37
38
|
export type CredentialContext = {
|
|
38
39
|
mode: 'local';
|
|
39
40
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-credentials.d.ts","sourceRoot":"","sources":["../../src/routes/provider-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"provider-credentials.d.ts","sourceRoot":"","sources":["../../src/routes/provider-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAIpC,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACxB,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;GAKG;AACH,OAAO,EAAE,uBAAuB,IAAI,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEpG;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAK1G,CAAC;AAEF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,sBAIvG;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,uBAAuB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExF;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,uBAAuB,GAAG,SAAS,GAC/C,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC,CAQ9C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE9E;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,EAC7C,CAAC,EACD,IAAI,EACJ,WAAW,GACZ,EAAE;IACD,CAAC,EAAE,OAAO,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,qEAAqE;IACrE,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,GAAG,OAAO,CAAC,iBAAiB,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC,CAuBtD;AAED;;;;;;GAMG;AACH,wBAAsB,+BAA+B,CAAC,EACpD,CAAC,EACD,IAAI,EACJ,WAAW,GACZ,EAAE;IACD,CAAC,EAAE,OAAO,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,qEAAqE;IACrE,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,GAAG,OAAO,CAAC,gBAAgB,EAAE,GAAG,SAAS,CAAC,CAO1C"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { factoryUserOrgId } from "../auth.js";
|
|
2
|
+
import { providerDisplayName } from "../provider-display-name.js";
|
|
2
3
|
import { getCredentialProviderId as getAuthProviderId } from "@mastra/code-sdk/providers/model-ids";
|
|
3
4
|
//#region src/routes/provider-credentials.ts
|
|
4
5
|
/**
|
|
@@ -6,7 +7,7 @@ import { getCredentialProviderId as getAuthProviderId } from "@mastra/code-sdk/p
|
|
|
6
7
|
* *catalog* provider id (what the routes and settings UI use). All flows need
|
|
7
8
|
* no inbound connection to the server: Anthropic uses paste-code PKCE, the
|
|
8
9
|
* rest use RFC 8628-style device codes. `subscription` names the plan the
|
|
9
|
-
* sign-in bills, as shown under a reply.
|
|
10
|
+
* sign-in bills, as shown under a reply and in the composer.
|
|
10
11
|
*/
|
|
11
12
|
const WEB_OAUTH_PROVIDERS = {
|
|
12
13
|
anthropic: {
|
|
@@ -26,6 +27,9 @@ const WEB_OAUTH_PROVIDERS = {
|
|
|
26
27
|
subscription: "SuperGrok/X Premium+"
|
|
27
28
|
}
|
|
28
29
|
};
|
|
30
|
+
function credentialLabel(provider, credentialType) {
|
|
31
|
+
return credentialType === "api_key" ? `${providerDisplayName(provider)} API key` : WEB_OAUTH_PROVIDERS[provider]?.subscription;
|
|
32
|
+
}
|
|
29
33
|
/**
|
|
30
34
|
* The tenant credentials domain, when registered and ready. `undefined` means
|
|
31
35
|
* the factory never ran (no handle threaded in) or the domain's init failed
|
|
@@ -88,6 +92,6 @@ async function listTenantCredentialsForRequest({ c, auth, credentials }) {
|
|
|
88
92
|
return storage.listCredentials(tenantOrgId(tenant), tenant.userId);
|
|
89
93
|
}
|
|
90
94
|
//#endregion
|
|
91
|
-
export { WEB_OAUTH_PROVIDERS, getAuthProviderId, getTenantCredentialsStorage, listTenantCredentialsForRequest, resolveCredentialContext, tenantOrgId };
|
|
95
|
+
export { WEB_OAUTH_PROVIDERS, credentialLabel, getAuthProviderId, getTenantCredentialsStorage, listTenantCredentialsForRequest, resolveCredentialContext, tenantOrgId };
|
|
92
96
|
|
|
93
97
|
//# sourceMappingURL=provider-credentials.js.map
|