@mastra/code-sdk 0.1.0-alpha.6 → 0.1.0-alpha.7

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/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @mastra/code-sdk
2
2
 
3
+ ## 0.1.0-alpha.7
4
+
5
+ ### Minor Changes
6
+
7
+ - Renamed the Gateway constants exported from `@mastra/code-sdk/onboarding/settings` and added `MastraCodeGateway.getMastraGatewayApiKey()` so they match the Gateway product name. The old constant and method names keep working as deprecated aliases, and the stored values are unchanged. ([#18691](https://github.com/mastra-ai/mastra/pull/18691))
8
+
9
+ ```ts
10
+ // Before
11
+ import { MEMORY_GATEWAY_PROVIDER, MEMORY_GATEWAY_DEFAULT_URL } from '@mastra/code-sdk/onboarding/settings';
12
+
13
+ // After
14
+ import { MASTRA_GATEWAY_PROVIDER, MASTRA_GATEWAY_DEFAULT_URL } from '@mastra/code-sdk/onboarding/settings';
15
+ ```
16
+
17
+ - Improved GitHub plugin dependency installs by requiring exact pnpm versions and running them through Corepack, with an actionable setup error when Corepack is unavailable. ([#19288](https://github.com/mastra-ai/mastra/pull/19288))
18
+
19
+ ### Patch Changes
20
+
21
+ - Fixed secure discovery of symlinked custom commands and skills. ([#19279](https://github.com/mastra-ai/mastra/pull/19279))
22
+
23
+ - Updated dependencies [[`25e7c12`](https://github.com/mastra-ai/mastra/commit/25e7c126a770069ae7fb7ecf1d2adb40e017b009), [`1ce5121`](https://github.com/mastra-ai/mastra/commit/1ce512155d122bb21f47d98383e82ffbf84b39e8), [`3cfc47a`](https://github.com/mastra-ai/mastra/commit/3cfc47a6b89940aadd0f46fb01ae9624a73a865d), [`2bb7817`](https://github.com/mastra-ai/mastra/commit/2bb78176112fde628483de2830528f7eee911e56), [`51d9870`](https://github.com/mastra-ai/mastra/commit/51d987032c689c2855374d0f244f5d654da809d1), [`5cab274`](https://github.com/mastra-ai/mastra/commit/5cab2744250e22d12fefa7b32637dce224233cee), [`7fa27d3`](https://github.com/mastra-ai/mastra/commit/7fa27d3b6f5ed68cd34e454a4d3ad9c482a0cfbc), [`a58dcbb`](https://github.com/mastra-ai/mastra/commit/a58dcbb546d7e1d65ebdc1f39e55f0908fcd9391), [`153bd3b`](https://github.com/mastra-ai/mastra/commit/153bd3b396bdfed6b74cf43de12db8fd2d83c04a), [`07bb863`](https://github.com/mastra-ai/mastra/commit/07bb8631919c6f7cf377dccd45b096e0f17fbed0), [`8a586ec`](https://github.com/mastra-ai/mastra/commit/8a586eca9a4914f31dff6140d0d45ac375b00669), [`3927473`](https://github.com/mastra-ai/mastra/commit/392747323ddb10c643d12be7b9ae913159dfaeed), [`dce50dc`](https://github.com/mastra-ai/mastra/commit/dce50dc9a1c1fcd0f427bb5f6250ec74910cb04b), [`634caff`](https://github.com/mastra-ai/mastra/commit/634caff29a9200ad058b67d53f96d9e5832fb8a2), [`2eb656e`](https://github.com/mastra-ai/mastra/commit/2eb656ecb64671d4a95e3c94bf507ce6a0ef9e3b), [`8a586ec`](https://github.com/mastra-ai/mastra/commit/8a586eca9a4914f31dff6140d0d45ac375b00669)]:
24
+ - @mastra/core@1.51.0-alpha.7
25
+ - @mastra/observability@1.16.1-alpha.1
26
+ - @mastra/mcp@1.14.0-alpha.0
27
+
3
28
  ## 0.1.0-alpha.6
4
29
 
5
30
  ### Patch Changes
@@ -32,12 +32,14 @@ export declare function getAnthropicApiKey(): string | undefined;
32
32
  * Main slot → dedicated apikey: slot → env var.
33
33
  */
34
34
  export declare function getOpenAIApiKey(): string | undefined;
35
- export declare function resolveAuth(request: GatewayAuthRequest, memoryGatewayApiKey?: string): GatewayAuthResult | undefined;
35
+ export declare function resolveAuth(request: GatewayAuthRequest, mastraGatewayApiKey?: string): GatewayAuthResult | undefined;
36
36
  export declare class MastraCodeGateway extends MastraModelGateway {
37
37
  #private;
38
38
  readonly id = "mastracode";
39
39
  readonly name = "MastraCode Gateway";
40
40
  constructor({ mastraGatewayBaseUrl, mastraGatewayApiKey, routeThroughMastraGateway, thinkingLevel, customProviders, settingsPath, }: MastraCodeGatewayOptions);
41
+ static getMastraGatewayApiKey(): string | undefined;
42
+ /** @deprecated Renamed to {@link MastraCodeGateway.getMastraGatewayApiKey}. */
41
43
  static getMemoryGatewayApiKey(): string | undefined;
42
44
  /**
43
45
  * Claim an unprefixed model id (e.g. a bare `anthropic/...`) when this gateway
@@ -46,7 +48,7 @@ export declare class MastraCodeGateway extends MastraModelGateway {
46
48
  * bar and `/api-keys` reflect OAuth logins instead of only checking env vars.
47
49
  */
48
50
  handlesModel(modelId: string): boolean;
49
- static resolveProviderAuth(request: GatewayAuthRequest, memoryGatewayApiKey?: string): GatewayAuthResult | undefined;
51
+ static resolveProviderAuth(request: GatewayAuthRequest, mastraGatewayApiKey?: string): GatewayAuthResult | undefined;
50
52
  static createModelCatalogProvider(gateway: MastraModelGatewayInterface): CustomModelCatalogProvider;
51
53
  createModelCatalogProvider(): CustomModelCatalogProvider;
52
54
  fetchProviders(): Promise<Record<string, ProviderConfig>>;
@@ -1 +1 @@
1
- {"version":3,"file":"mastracode-gateway.d.ts","sourceRoot":"","sources":["../../src/agents/mastracode-gateway.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mastracode-gateway.d.ts","sourceRoot":"","sources":["../../src/agents/mastracode-gateway.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAwB,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AACtG,OAAO,EAGL,kBAAkB,EAGnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,2BAA2B,EAC3B,cAAc,EACf,MAAM,kBAAkB,CAAC;AAkB1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,qBAAqB,YAAY,CAAC;AAC/C,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAYlD,MAAM,MAAM,wBAAwB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEzG,MAAM,MAAM,wBAAwB,GAAG;IACrC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yBAAyB,EAAE,OAAO,CAAC;IACnC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,eAAe,CAAC,EAAE,wBAAwB,EAAE,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAIF,wBAAgB,iBAAiB,SAEhC;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEhE;AAMD,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoBrE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAQvD;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAQpD;AA+BD,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAEpH;AAgFD,qBAAa,iBAAkB,SAAQ,kBAAkB;;IACvD,QAAQ,CAAC,EAAE,gBAAyB;IACpC,QAAQ,CAAC,IAAI,wBAAwB;gBAUzB,EACV,oBAAoB,EACpB,mBAAmB,EACnB,yBAAyB,EACzB,aAAa,EACb,eAAe,EACf,YAAY,GACb,EAAE,wBAAwB;IAW3B,MAAM,CAAC,sBAAsB,IAAI,MAAM,GAAG,SAAS;IAInD,+EAA+E;IAC/E,MAAM,CAAC,sBAAsB,IAAI,MAAM,GAAG,SAAS;IAInD;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAkBtC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAcpH,MAAM,CAAC,0BAA0B,CAAC,OAAO,EAAE,2BAA2B,GAAG,0BAA0B;IA+BnG,0BAA0B,IAAI,0BAA0B;IAQlD,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IA+B/D,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAIrE,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMjD,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,GAAG,SAAS;IAevE,oBAAoB,CAAC,IAAI,EAAE;QACzB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,SAAS,CAAC,EAAE,GAAG,CAAC;QAChB,kBAAkB,CAAC,EAAE,GAAG,CAAC;KAC1B,GAAG,oBAAoB;CA0JzB"}
@@ -10,7 +10,7 @@ import {
10
10
  } from "@mastra/core/llm";
11
11
  import { wrapLanguageModel } from "ai";
12
12
  import { AuthStorage } from "../auth/storage.js";
13
- import { getCustomProviderId, loadSettings, MEMORY_GATEWAY_PROVIDER } from "../onboarding/settings.js";
13
+ import { getCustomProviderId, loadSettings, MASTRA_GATEWAY_PROVIDER } from "../onboarding/settings.js";
14
14
  import {
15
15
  buildAnthropicOAuthFetch,
16
16
  claudeCodeMiddleware,
@@ -104,8 +104,8 @@ function getProviderAuthKey(providerId) {
104
104
  }
105
105
  return authStorage.getStoredApiKey(authProviderId)?.trim() || void 0;
106
106
  }
107
- function resolveAuth(request, memoryGatewayApiKey) {
108
- return MastraCodeGateway.resolveProviderAuth(request, memoryGatewayApiKey);
107
+ function resolveAuth(request, mastraGatewayApiKey) {
108
+ return MastraCodeGateway.resolveProviderAuth(request, mastraGatewayApiKey);
109
109
  }
110
110
  function getGatewayProviderKey(gatewayId, providerId) {
111
111
  if (gatewayId === "models.dev") return providerId;
@@ -193,8 +193,12 @@ class MastraCodeGateway extends MastraModelGateway {
193
193
  this.#customProviders = customProviders;
194
194
  this.#settingsPath = settingsPath;
195
195
  }
196
+ static getMastraGatewayApiKey() {
197
+ return authStorage.getStoredApiKey(MASTRA_GATEWAY_PROVIDER) ?? process.env["MASTRA_GATEWAY_API_KEY"];
198
+ }
199
+ /** @deprecated Renamed to {@link MastraCodeGateway.getMastraGatewayApiKey}. */
196
200
  static getMemoryGatewayApiKey() {
197
- return authStorage.getStoredApiKey(MEMORY_GATEWAY_PROVIDER) ?? process.env["MASTRA_GATEWAY_API_KEY"];
201
+ return MastraCodeGateway.getMastraGatewayApiKey();
198
202
  }
199
203
  /**
200
204
  * Claim an unprefixed model id (e.g. a bare `anthropic/...`) when this gateway
@@ -219,9 +223,9 @@ class MastraCodeGateway extends MastraModelGateway {
219
223
  })
220
224
  );
221
225
  }
222
- static resolveProviderAuth(request, memoryGatewayApiKey) {
223
- if (request.gatewayId === "mastra" && memoryGatewayApiKey) {
224
- return { apiKey: memoryGatewayApiKey, source: "gateway" };
226
+ static resolveProviderAuth(request, mastraGatewayApiKey) {
227
+ if (request.gatewayId === "mastra" && mastraGatewayApiKey) {
228
+ return { apiKey: mastraGatewayApiKey, source: "gateway" };
225
229
  }
226
230
  const storedCred = authStorage.get(getAuthProviderId(request.providerId));
227
231
  if (storedCred?.type === "oauth") {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/agents/mastracode-gateway.ts"],"sourcesContent":["import { createAnthropic } from '@ai-sdk/anthropic';\nimport { createOpenAI } from '@ai-sdk/openai';\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible';\nimport type { CustomAvailableModel, CustomModelCatalogProvider } from '@mastra/core/agent-controller';\nimport {\n GATEWAY_AUTH_HEADER,\n MastraGateway,\n MastraModelGateway,\n ModelRouterLanguageModel,\n PROVIDER_REGISTRY,\n} from '@mastra/core/llm';\nimport type {\n GatewayAuthRequest,\n GatewayAuthResult,\n GatewayLanguageModel,\n MastraModelGatewayInterface,\n ProviderConfig,\n} from '@mastra/core/llm';\nimport { wrapLanguageModel } from 'ai';\nimport { AuthStorage } from '../auth/storage.js';\nimport { getCustomProviderId, loadSettings, MEMORY_GATEWAY_PROVIDER } from '../onboarding/settings.js';\nimport {\n buildAnthropicOAuthFetch,\n claudeCodeMiddleware,\n opencodeClaudeMaxProvider,\n promptCacheMiddleware,\n} from '../providers/claude-max.js';\nimport { getCopilotModelCatalog, githubCopilotProvider } from '../providers/github-copilot.js';\nimport {\n buildOpenAICodexOAuthFetch,\n createCodexMiddleware,\n getEffectiveThinkingLevel,\n openaiCodexProvider,\n THINKING_LEVEL_TO_REASONING_EFFORT,\n} from '../providers/openai-codex.js';\nimport type { ThinkingLevel } from '../providers/openai-codex.js';\n\nexport const OPENAI_PREFIX = 'openai/';\nexport const MASTRA_GATEWAY_PREFIX = 'mastra/';\nexport const MASTRACODE_GATEWAY_ID = 'mastracode';\n\nconst CODEX_OPENAI_MODEL_REMAPS: Record<string, string> = {\n 'gpt-5.3': 'gpt-5.3-codex',\n 'gpt-5.2': 'gpt-5.2-codex',\n 'gpt-5.1': 'gpt-5.1-codex',\n 'gpt-5.1-mini': 'gpt-5.1-codex-mini',\n 'gpt-5': 'gpt-5-codex',\n};\n\ntype ModelRequestHeaders = Record<string, string>;\n\nexport type MastraCodeCustomProvider = { name: string; url: string; apiKey?: string; models?: string[] };\n\nexport type MastraCodeGatewayOptions = {\n mastraGatewayBaseUrl: string;\n mastraGatewayApiKey?: string;\n routeThroughMastraGateway: boolean;\n thinkingLevel?: ThinkingLevel;\n customProviders?: MastraCodeCustomProvider[];\n settingsPath?: string;\n};\n\nconst authStorage = new AuthStorage();\n\nexport function reloadAuthStorage() {\n authStorage.reload();\n}\n\nexport function stripMastraGatewayPrefix(modelId: string): string {\n return modelId.startsWith(MASTRA_GATEWAY_PREFIX) ? modelId.substring(MASTRA_GATEWAY_PREFIX.length) : modelId;\n}\n\nfunction normalizeAnthropicModelId(modelId: string): string {\n return modelId.replace(/\\.(?=\\d)/g, '-');\n}\n\nexport function remapOpenAIModelForCodexOAuth(modelId: string): string {\n const normalizedModelId = stripMastraGatewayPrefix(modelId);\n\n if (!normalizedModelId.startsWith(OPENAI_PREFIX)) {\n return modelId;\n }\n\n const openaiModelId = normalizedModelId.substring(OPENAI_PREFIX.length);\n\n if (openaiModelId.includes('-codex')) {\n return modelId;\n }\n\n const codexModelId = CODEX_OPENAI_MODEL_REMAPS[openaiModelId];\n if (!codexModelId) {\n return modelId;\n }\n\n const remappedModelId = `${OPENAI_PREFIX}${codexModelId}`;\n return modelId.startsWith(MASTRA_GATEWAY_PREFIX) ? `${MASTRA_GATEWAY_PREFIX}${remappedModelId}` : remappedModelId;\n}\n\n/**\n * Resolve the Anthropic API key.\n * Main slot → dedicated apikey: slot → env var.\n */\nexport function getAnthropicApiKey(): string | undefined {\n const storedCred = authStorage.get('anthropic');\n if (storedCred?.type === 'api_key' && storedCred.key.trim().length > 0) {\n return storedCred.key.trim();\n }\n const dedicatedKey = authStorage.getStoredApiKey('anthropic')?.trim();\n if (dedicatedKey) return dedicatedKey;\n return process.env.ANTHROPIC_API_KEY?.trim() || undefined;\n}\n\n/**\n * Resolve the OpenAI API key.\n * Main slot → dedicated apikey: slot → env var.\n */\nexport function getOpenAIApiKey(): string | undefined {\n const storedCred = authStorage.get('openai-codex');\n if (storedCred?.type === 'api_key' && storedCred.key.trim().length > 0) {\n return storedCred.key.trim();\n }\n const dedicatedKey = authStorage.getStoredApiKey('openai-codex')?.trim();\n if (dedicatedKey) return dedicatedKey;\n return process.env.OPENAI_API_KEY?.trim() || undefined;\n}\n\nfunction anthropicApiKeyProvider(modelId: string, apiKey: string, headers?: ModelRequestHeaders) {\n const anthropic = createAnthropic({ apiKey, headers });\n return wrapLanguageModel({\n model: anthropic(modelId),\n middleware: [promptCacheMiddleware],\n });\n}\n\nfunction openaiApiKeyProvider(modelId: string, apiKey: string, headers?: ModelRequestHeaders) {\n const openai = createOpenAI({ apiKey, baseURL: process.env.OPENAI_BASE_URL, headers });\n return wrapLanguageModel({\n model: openai.responses(modelId),\n middleware: [],\n });\n}\n\nfunction getAuthProviderId(providerId: string): string {\n return providerId === 'openai' ? 'openai-codex' : providerId;\n}\n\nfunction getProviderAuthKey(providerId: string): string | undefined {\n const authProviderId = getAuthProviderId(providerId);\n const storedCred = authStorage.get(authProviderId);\n if (storedCred?.type === 'api_key' && storedCred.key.trim().length > 0) {\n return storedCred.key.trim();\n }\n return authStorage.getStoredApiKey(authProviderId)?.trim() || undefined;\n}\n\nexport function resolveAuth(request: GatewayAuthRequest, memoryGatewayApiKey?: string): GatewayAuthResult | undefined {\n return MastraCodeGateway.resolveProviderAuth(request, memoryGatewayApiKey);\n}\n\nfunction getGatewayProviderKey(gatewayId: string, providerId: string): string {\n if (gatewayId === 'models.dev') return providerId;\n return providerId === gatewayId ? gatewayId : `${gatewayId}/${providerId}`;\n}\n\nfunction parseGatewayRouterId(\n routerId: string,\n gateway: MastraModelGatewayInterface,\n): { gatewayId: string; providerId: string; modelId: string } {\n const [firstPart = '', secondPart = '', ...restParts] = routerId.split('/');\n const gatewayId = gateway.id;\n\n if (firstPart === gatewayId && secondPart) {\n return {\n gatewayId,\n providerId: secondPart,\n modelId: restParts.join('/'),\n };\n }\n\n return {\n gatewayId,\n providerId: firstPart,\n modelId: [secondPart, ...restParts].filter(Boolean).join('/'),\n };\n}\n\nfunction hasResolvedAuth(auth: GatewayAuthResult | undefined): boolean {\n if (!auth) return false;\n if (auth.apiKey || auth.bearerToken) return true;\n return auth.headers ? Object.keys(auth.headers).length > 0 : false;\n}\n\nasync function resolveGatewayProviderAuth(\n gateway: MastraModelGatewayInterface,\n routerId: string,\n): Promise<GatewayAuthResult | undefined> {\n if (!gateway.resolveAuth) return undefined;\n\n const parsed = parseGatewayRouterId(routerId, gateway);\n try {\n const result = await gateway.resolveAuth({\n gatewayId: parsed.gatewayId,\n providerId: parsed.providerId,\n modelId: parsed.modelId,\n routerId,\n });\n return hasResolvedAuth(result) ? result : undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function getMastraCodeProviderConfigs(\n gateway: MastraModelGatewayInterface,\n): Promise<Record<string, ProviderConfig>> {\n const providers: Record<string, ProviderConfig> = { ...(PROVIDER_REGISTRY as Record<string, ProviderConfig>) };\n\n try {\n const gatewayProviders = await gateway.fetchProviders();\n for (const [providerId, config] of Object.entries(gatewayProviders)) {\n providers[getGatewayProviderKey(gateway.id, providerId)] = {\n ...config,\n gateway: gateway.id,\n };\n }\n } catch (error) {\n console.warn(`Failed to load providers from gateway ${gateway.id}:`, error);\n }\n\n return providers;\n}\n\nfunction getApiKeyEnvVar(providerConfig: Pick<ProviderConfig, 'apiKeyEnvVar'> | undefined): string | undefined {\n const envVars = providerConfig?.apiKeyEnvVar;\n return Array.isArray(envVars) ? envVars[0] : envVars;\n}\n\nexport class MastraCodeGateway extends MastraModelGateway {\n readonly id = MASTRACODE_GATEWAY_ID;\n readonly name = 'MastraCode Gateway';\n\n readonly #mastraGateway: MastraGateway;\n readonly #mastraGatewayBaseUrl: string;\n readonly #mastraGatewayApiKey?: string;\n readonly #routeThroughMastraGateway: boolean;\n readonly #thinkingLevel?: ThinkingLevel;\n readonly #customProviders?: MastraCodeCustomProvider[];\n readonly #settingsPath?: string;\n\n constructor({\n mastraGatewayBaseUrl,\n mastraGatewayApiKey,\n routeThroughMastraGateway,\n thinkingLevel,\n customProviders,\n settingsPath,\n }: MastraCodeGatewayOptions) {\n super();\n this.#mastraGateway = new MastraGateway({ baseUrl: mastraGatewayBaseUrl });\n this.#mastraGatewayBaseUrl = mastraGatewayBaseUrl;\n this.#mastraGatewayApiKey = mastraGatewayApiKey;\n this.#routeThroughMastraGateway = routeThroughMastraGateway;\n this.#thinkingLevel = thinkingLevel;\n this.#customProviders = customProviders;\n this.#settingsPath = settingsPath;\n }\n\n static getMemoryGatewayApiKey(): string | undefined {\n return authStorage.getStoredApiKey(MEMORY_GATEWAY_PROVIDER) ?? process.env['MASTRA_GATEWAY_API_KEY'];\n }\n\n /**\n * Claim an unprefixed model id (e.g. a bare `anthropic/...`) when this gateway\n * can authenticate it via OAuth or a stored/env credential. This lets the\n * shared gateway router select MastraCode for auth resolution, so the status\n * bar and `/api-keys` reflect OAuth logins instead of only checking env vars.\n */\n handlesModel(modelId: string): boolean {\n const parsed = parseGatewayRouterId(modelId, this);\n if (!parsed.providerId || !parsed.modelId) return false;\n if (this.#routeThroughMastraGateway && this.#mastraGatewayApiKey) return true;\n const customProvider = this.#getCustomProviders().find(\n provider => parsed.providerId === getCustomProviderId(provider.name),\n );\n if (customProvider?.apiKey) return true;\n return hasResolvedAuth(\n MastraCodeGateway.resolveProviderAuth({\n gatewayId: this.id,\n providerId: parsed.providerId,\n modelId: parsed.modelId,\n routerId: modelId,\n }),\n );\n }\n\n static resolveProviderAuth(request: GatewayAuthRequest, memoryGatewayApiKey?: string): GatewayAuthResult | undefined {\n if (request.gatewayId === 'mastra' && memoryGatewayApiKey) {\n return { apiKey: memoryGatewayApiKey, source: 'gateway' };\n }\n\n const storedCred = authStorage.get(getAuthProviderId(request.providerId));\n if (storedCred?.type === 'oauth') {\n return { bearerToken: 'oauth', source: 'gateway' };\n }\n\n const apiKey = getProviderAuthKey(request.providerId);\n return apiKey ? { apiKey, source: 'gateway' } : undefined;\n }\n\n static createModelCatalogProvider(gateway: MastraModelGatewayInterface): CustomModelCatalogProvider {\n return async () => {\n const registry = await getMastraCodeProviderConfigs(gateway);\n const models: CustomAvailableModel[] = [];\n\n for (const [provider, providerConfig] of Object.entries(registry)) {\n const apiKeyEnvVar = getApiKeyEnvVar(providerConfig);\n const hasEnvKey = apiKeyEnvVar ? Boolean(process.env[apiKeyEnvVar]) : false;\n const modelNames = providerConfig.models;\n if (!Array.isArray(modelNames)) continue;\n\n const gatewayAuth = modelNames[0]\n ? await resolveGatewayProviderAuth(gateway, `${provider}/${modelNames[0]}`)\n : undefined;\n\n for (const modelName of modelNames) {\n const id = `${provider}/${modelName}`;\n models.push({\n id,\n provider,\n modelName,\n hasApiKey: hasEnvKey || Boolean(gatewayAuth),\n apiKeyEnvVar: apiKeyEnvVar || undefined,\n });\n }\n }\n\n return models;\n };\n }\n\n createModelCatalogProvider(): CustomModelCatalogProvider {\n return MastraCodeGateway.createModelCatalogProvider(this);\n }\n\n #getCustomProviders(): MastraCodeCustomProvider[] {\n return this.#customProviders ?? loadSettings(this.#settingsPath).customProviders;\n }\n\n async fetchProviders(): Promise<Record<string, ProviderConfig>> {\n const providers: Record<string, ProviderConfig> = {};\n for (const provider of this.#getCustomProviders()) {\n const models = provider.models ?? [];\n if (!models.length) continue;\n providers[getCustomProviderId(provider.name)] = {\n name: provider.name,\n url: provider.url,\n apiKeyEnvVar: '',\n apiKeyHeader: 'Authorization',\n gateway: this.id,\n models,\n };\n }\n\n try {\n const copilotModels = await getCopilotModelCatalog({ authStorage });\n providers['github-copilot'] = {\n name: 'GitHub Copilot',\n apiKeyEnvVar: '',\n apiKeyHeader: 'Authorization',\n gateway: this.id,\n models: copilotModels.map(model => model.id),\n };\n } catch (error) {\n console.warn('Failed to load GitHub Copilot model catalog:', error);\n }\n\n return providers;\n }\n\n buildUrl(modelId: string): string | undefined | Promise<string | undefined> {\n return this.#routeThroughMastraGateway ? this.#mastraGateway.buildUrl(modelId) : modelId;\n }\n\n async getApiKey(modelId: string): Promise<string> {\n const providerId = stripMastraGatewayPrefix(modelId).split('/', 1)[0];\n if (this.#routeThroughMastraGateway) return this.#mastraGatewayApiKey ?? '';\n return providerId ? (getProviderAuthKey(providerId) ?? '') : '';\n }\n\n resolveAuth(request: GatewayAuthRequest): GatewayAuthResult | undefined {\n if (this.#routeThroughMastraGateway && this.#mastraGatewayApiKey) {\n return { apiKey: this.#mastraGatewayApiKey, source: 'gateway' };\n }\n\n const customProvider = this.#getCustomProviders().find(\n provider => request.providerId === getCustomProviderId(provider.name),\n );\n if (customProvider?.apiKey) {\n return { apiKey: customProvider.apiKey, source: 'gateway' };\n }\n\n return MastraCodeGateway.resolveProviderAuth(request);\n }\n\n resolveLanguageModel(args: {\n modelId: string;\n providerId: string;\n apiKey: string;\n headers?: Record<string, string>;\n transport?: any;\n responsesWebSocket?: any;\n }): GatewayLanguageModel {\n const customProvider = this.#getCustomProviders().find(\n provider => args.providerId === getCustomProviderId(provider.name),\n );\n if (customProvider) {\n const provider = createOpenAICompatible({\n name: args.providerId,\n baseURL: customProvider.url,\n apiKey: args.apiKey,\n headers: args.headers,\n });\n return provider.chatModel(args.modelId) as unknown as GatewayLanguageModel;\n }\n\n if (args.providerId === 'github-copilot') {\n return githubCopilotProvider(args.modelId, { headers: args.headers }) as unknown as GatewayLanguageModel;\n }\n\n if (args.providerId === 'moonshotai') {\n if (!process.env.MOONSHOT_AI_API_KEY) {\n throw new Error(`Need MOONSHOT_AI_API_KEY`);\n }\n return createAnthropic({\n apiKey: process.env.MOONSHOT_AI_API_KEY,\n baseURL: 'https://api.moonshot.ai/anthropic/v1',\n name: 'moonshotai.anthropicv1',\n headers: args.headers,\n })(args.modelId) as unknown as GatewayLanguageModel;\n }\n\n if (args.providerId === 'anthropic') {\n return this.#resolveAnthropicModel(args);\n }\n\n if (args.providerId === 'openai') {\n const openaiModel = this.#resolveOpenAIModel(args);\n if (openaiModel) return openaiModel;\n }\n\n if (this.#routeThroughMastraGateway) {\n return this.#mastraGateway.resolveLanguageModel(args) as GatewayLanguageModel;\n }\n\n return new ModelRouterLanguageModel({\n id: `${args.providerId}/${args.modelId}` as `${string}/${string}`,\n headers: args.headers,\n }) as unknown as GatewayLanguageModel;\n }\n\n #resolveAnthropicModel(args: {\n modelId: string;\n providerId: string;\n apiKey: string;\n headers?: Record<string, string>;\n transport?: any;\n responsesWebSocket?: any;\n }): GatewayLanguageModel {\n const bareModelId = normalizeAnthropicModelId(args.modelId);\n const storedCred = authStorage.get('anthropic');\n\n if (this.#routeThroughMastraGateway) {\n if (storedCred?.type === 'oauth') {\n const anthropic = createAnthropic({\n apiKey: 'oauth-gateway-placeholder',\n baseURL: `${this.#mastraGatewayBaseUrl}/v1`,\n headers: {\n [GATEWAY_AUTH_HEADER]: `Bearer ${args.apiKey}`,\n ...args.headers,\n },\n fetch: buildAnthropicOAuthFetch({ authStorage }) as any,\n });\n\n return wrapLanguageModel({\n model: anthropic(bareModelId),\n middleware: [claudeCodeMiddleware, promptCacheMiddleware],\n }) as unknown as GatewayLanguageModel;\n }\n\n return this.#mastraGateway.resolveLanguageModel({ ...args, modelId: bareModelId }) as GatewayLanguageModel;\n }\n\n if (storedCred?.type === 'oauth') {\n return opencodeClaudeMaxProvider(bareModelId, { headers: args.headers }) as unknown as GatewayLanguageModel;\n }\n\n if (storedCred?.type === 'api_key' && storedCred.key.trim().length > 0) {\n return anthropicApiKeyProvider(\n bareModelId,\n storedCred.key.trim(),\n args.headers,\n ) as unknown as GatewayLanguageModel;\n }\n\n const apiKey = getAnthropicApiKey();\n if (apiKey) {\n return anthropicApiKeyProvider(bareModelId, apiKey, args.headers) as unknown as GatewayLanguageModel;\n }\n\n // No stored credentials: use the OAuth-backed provider so the first request can trigger login.\n return opencodeClaudeMaxProvider(bareModelId, { headers: args.headers }) as unknown as GatewayLanguageModel;\n }\n\n #resolveOpenAIModel(args: {\n modelId: string;\n providerId: string;\n apiKey: string;\n headers?: Record<string, string>;\n transport?: any;\n responsesWebSocket?: any;\n }): GatewayLanguageModel | undefined {\n const storedCred = authStorage.get('openai-codex');\n\n if (this.#routeThroughMastraGateway) {\n if (storedCred?.type === 'oauth') {\n const resolvedModelId = remapOpenAIModelForCodexOAuth(`openai/${args.modelId}`);\n const resolvedBareModelId = resolvedModelId.substring(OPENAI_PREFIX.length);\n const requestedLevel: ThinkingLevel = this.#thinkingLevel ?? 'medium';\n const effectiveLevel = getEffectiveThinkingLevel(resolvedBareModelId, requestedLevel);\n const reasoningEffort = THINKING_LEVEL_TO_REASONING_EFFORT[effectiveLevel];\n const middleware = createCodexMiddleware(reasoningEffort);\n const openai = createOpenAI({\n apiKey: 'oauth-gateway-placeholder',\n baseURL: `${this.#mastraGatewayBaseUrl}/v1`,\n headers: {\n [GATEWAY_AUTH_HEADER]: `Bearer ${args.apiKey}`,\n ...args.headers,\n },\n fetch: buildOpenAICodexOAuthFetch({ authStorage, rewriteUrl: false }) as any,\n });\n\n return wrapLanguageModel({\n model: openai.responses(resolvedBareModelId),\n middleware: [middleware],\n }) as unknown as GatewayLanguageModel;\n }\n\n return this.#mastraGateway.resolveLanguageModel(args) as GatewayLanguageModel;\n }\n\n if (storedCred?.type === 'oauth') {\n const resolvedModelId = remapOpenAIModelForCodexOAuth(`openai/${args.modelId}`);\n return openaiCodexProvider(resolvedModelId.substring(OPENAI_PREFIX.length), {\n thinkingLevel: this.#thinkingLevel,\n headers: args.headers,\n }) as unknown as GatewayLanguageModel;\n }\n\n const apiKey = getOpenAIApiKey();\n if (apiKey) {\n return openaiApiKeyProvider(args.modelId, apiKey, args.headers) as unknown as GatewayLanguageModel;\n }\n\n return undefined;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/agents/mastracode-gateway.ts"],"sourcesContent":["import { createAnthropic } from '@ai-sdk/anthropic';\nimport { createOpenAI } from '@ai-sdk/openai';\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible';\nimport type { CustomAvailableModel, CustomModelCatalogProvider } from '@mastra/core/agent-controller';\nimport {\n GATEWAY_AUTH_HEADER,\n MastraGateway,\n MastraModelGateway,\n ModelRouterLanguageModel,\n PROVIDER_REGISTRY,\n} from '@mastra/core/llm';\nimport type {\n GatewayAuthRequest,\n GatewayAuthResult,\n GatewayLanguageModel,\n MastraModelGatewayInterface,\n ProviderConfig,\n} from '@mastra/core/llm';\nimport { wrapLanguageModel } from 'ai';\nimport { AuthStorage } from '../auth/storage.js';\nimport { getCustomProviderId, loadSettings, MASTRA_GATEWAY_PROVIDER } from '../onboarding/settings.js';\nimport {\n buildAnthropicOAuthFetch,\n claudeCodeMiddleware,\n opencodeClaudeMaxProvider,\n promptCacheMiddleware,\n} from '../providers/claude-max.js';\nimport { getCopilotModelCatalog, githubCopilotProvider } from '../providers/github-copilot.js';\nimport {\n buildOpenAICodexOAuthFetch,\n createCodexMiddleware,\n getEffectiveThinkingLevel,\n openaiCodexProvider,\n THINKING_LEVEL_TO_REASONING_EFFORT,\n} from '../providers/openai-codex.js';\nimport type { ThinkingLevel } from '../providers/openai-codex.js';\n\nexport const OPENAI_PREFIX = 'openai/';\nexport const MASTRA_GATEWAY_PREFIX = 'mastra/';\nexport const MASTRACODE_GATEWAY_ID = 'mastracode';\n\nconst CODEX_OPENAI_MODEL_REMAPS: Record<string, string> = {\n 'gpt-5.3': 'gpt-5.3-codex',\n 'gpt-5.2': 'gpt-5.2-codex',\n 'gpt-5.1': 'gpt-5.1-codex',\n 'gpt-5.1-mini': 'gpt-5.1-codex-mini',\n 'gpt-5': 'gpt-5-codex',\n};\n\ntype ModelRequestHeaders = Record<string, string>;\n\nexport type MastraCodeCustomProvider = { name: string; url: string; apiKey?: string; models?: string[] };\n\nexport type MastraCodeGatewayOptions = {\n mastraGatewayBaseUrl: string;\n mastraGatewayApiKey?: string;\n routeThroughMastraGateway: boolean;\n thinkingLevel?: ThinkingLevel;\n customProviders?: MastraCodeCustomProvider[];\n settingsPath?: string;\n};\n\nconst authStorage = new AuthStorage();\n\nexport function reloadAuthStorage() {\n authStorage.reload();\n}\n\nexport function stripMastraGatewayPrefix(modelId: string): string {\n return modelId.startsWith(MASTRA_GATEWAY_PREFIX) ? modelId.substring(MASTRA_GATEWAY_PREFIX.length) : modelId;\n}\n\nfunction normalizeAnthropicModelId(modelId: string): string {\n return modelId.replace(/\\.(?=\\d)/g, '-');\n}\n\nexport function remapOpenAIModelForCodexOAuth(modelId: string): string {\n const normalizedModelId = stripMastraGatewayPrefix(modelId);\n\n if (!normalizedModelId.startsWith(OPENAI_PREFIX)) {\n return modelId;\n }\n\n const openaiModelId = normalizedModelId.substring(OPENAI_PREFIX.length);\n\n if (openaiModelId.includes('-codex')) {\n return modelId;\n }\n\n const codexModelId = CODEX_OPENAI_MODEL_REMAPS[openaiModelId];\n if (!codexModelId) {\n return modelId;\n }\n\n const remappedModelId = `${OPENAI_PREFIX}${codexModelId}`;\n return modelId.startsWith(MASTRA_GATEWAY_PREFIX) ? `${MASTRA_GATEWAY_PREFIX}${remappedModelId}` : remappedModelId;\n}\n\n/**\n * Resolve the Anthropic API key.\n * Main slot → dedicated apikey: slot → env var.\n */\nexport function getAnthropicApiKey(): string | undefined {\n const storedCred = authStorage.get('anthropic');\n if (storedCred?.type === 'api_key' && storedCred.key.trim().length > 0) {\n return storedCred.key.trim();\n }\n const dedicatedKey = authStorage.getStoredApiKey('anthropic')?.trim();\n if (dedicatedKey) return dedicatedKey;\n return process.env.ANTHROPIC_API_KEY?.trim() || undefined;\n}\n\n/**\n * Resolve the OpenAI API key.\n * Main slot → dedicated apikey: slot → env var.\n */\nexport function getOpenAIApiKey(): string | undefined {\n const storedCred = authStorage.get('openai-codex');\n if (storedCred?.type === 'api_key' && storedCred.key.trim().length > 0) {\n return storedCred.key.trim();\n }\n const dedicatedKey = authStorage.getStoredApiKey('openai-codex')?.trim();\n if (dedicatedKey) return dedicatedKey;\n return process.env.OPENAI_API_KEY?.trim() || undefined;\n}\n\nfunction anthropicApiKeyProvider(modelId: string, apiKey: string, headers?: ModelRequestHeaders) {\n const anthropic = createAnthropic({ apiKey, headers });\n return wrapLanguageModel({\n model: anthropic(modelId),\n middleware: [promptCacheMiddleware],\n });\n}\n\nfunction openaiApiKeyProvider(modelId: string, apiKey: string, headers?: ModelRequestHeaders) {\n const openai = createOpenAI({ apiKey, baseURL: process.env.OPENAI_BASE_URL, headers });\n return wrapLanguageModel({\n model: openai.responses(modelId),\n middleware: [],\n });\n}\n\nfunction getAuthProviderId(providerId: string): string {\n return providerId === 'openai' ? 'openai-codex' : providerId;\n}\n\nfunction getProviderAuthKey(providerId: string): string | undefined {\n const authProviderId = getAuthProviderId(providerId);\n const storedCred = authStorage.get(authProviderId);\n if (storedCred?.type === 'api_key' && storedCred.key.trim().length > 0) {\n return storedCred.key.trim();\n }\n return authStorage.getStoredApiKey(authProviderId)?.trim() || undefined;\n}\n\nexport function resolveAuth(request: GatewayAuthRequest, mastraGatewayApiKey?: string): GatewayAuthResult | undefined {\n return MastraCodeGateway.resolveProviderAuth(request, mastraGatewayApiKey);\n}\n\nfunction getGatewayProviderKey(gatewayId: string, providerId: string): string {\n if (gatewayId === 'models.dev') return providerId;\n return providerId === gatewayId ? gatewayId : `${gatewayId}/${providerId}`;\n}\n\nfunction parseGatewayRouterId(\n routerId: string,\n gateway: MastraModelGatewayInterface,\n): { gatewayId: string; providerId: string; modelId: string } {\n const [firstPart = '', secondPart = '', ...restParts] = routerId.split('/');\n const gatewayId = gateway.id;\n\n if (firstPart === gatewayId && secondPart) {\n return {\n gatewayId,\n providerId: secondPart,\n modelId: restParts.join('/'),\n };\n }\n\n return {\n gatewayId,\n providerId: firstPart,\n modelId: [secondPart, ...restParts].filter(Boolean).join('/'),\n };\n}\n\nfunction hasResolvedAuth(auth: GatewayAuthResult | undefined): boolean {\n if (!auth) return false;\n if (auth.apiKey || auth.bearerToken) return true;\n return auth.headers ? Object.keys(auth.headers).length > 0 : false;\n}\n\nasync function resolveGatewayProviderAuth(\n gateway: MastraModelGatewayInterface,\n routerId: string,\n): Promise<GatewayAuthResult | undefined> {\n if (!gateway.resolveAuth) return undefined;\n\n const parsed = parseGatewayRouterId(routerId, gateway);\n try {\n const result = await gateway.resolveAuth({\n gatewayId: parsed.gatewayId,\n providerId: parsed.providerId,\n modelId: parsed.modelId,\n routerId,\n });\n return hasResolvedAuth(result) ? result : undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function getMastraCodeProviderConfigs(\n gateway: MastraModelGatewayInterface,\n): Promise<Record<string, ProviderConfig>> {\n const providers: Record<string, ProviderConfig> = { ...(PROVIDER_REGISTRY as Record<string, ProviderConfig>) };\n\n try {\n const gatewayProviders = await gateway.fetchProviders();\n for (const [providerId, config] of Object.entries(gatewayProviders)) {\n providers[getGatewayProviderKey(gateway.id, providerId)] = {\n ...config,\n gateway: gateway.id,\n };\n }\n } catch (error) {\n console.warn(`Failed to load providers from gateway ${gateway.id}:`, error);\n }\n\n return providers;\n}\n\nfunction getApiKeyEnvVar(providerConfig: Pick<ProviderConfig, 'apiKeyEnvVar'> | undefined): string | undefined {\n const envVars = providerConfig?.apiKeyEnvVar;\n return Array.isArray(envVars) ? envVars[0] : envVars;\n}\n\nexport class MastraCodeGateway extends MastraModelGateway {\n readonly id = MASTRACODE_GATEWAY_ID;\n readonly name = 'MastraCode Gateway';\n\n readonly #mastraGateway: MastraGateway;\n readonly #mastraGatewayBaseUrl: string;\n readonly #mastraGatewayApiKey?: string;\n readonly #routeThroughMastraGateway: boolean;\n readonly #thinkingLevel?: ThinkingLevel;\n readonly #customProviders?: MastraCodeCustomProvider[];\n readonly #settingsPath?: string;\n\n constructor({\n mastraGatewayBaseUrl,\n mastraGatewayApiKey,\n routeThroughMastraGateway,\n thinkingLevel,\n customProviders,\n settingsPath,\n }: MastraCodeGatewayOptions) {\n super();\n this.#mastraGateway = new MastraGateway({ baseUrl: mastraGatewayBaseUrl });\n this.#mastraGatewayBaseUrl = mastraGatewayBaseUrl;\n this.#mastraGatewayApiKey = mastraGatewayApiKey;\n this.#routeThroughMastraGateway = routeThroughMastraGateway;\n this.#thinkingLevel = thinkingLevel;\n this.#customProviders = customProviders;\n this.#settingsPath = settingsPath;\n }\n\n static getMastraGatewayApiKey(): string | undefined {\n return authStorage.getStoredApiKey(MASTRA_GATEWAY_PROVIDER) ?? process.env['MASTRA_GATEWAY_API_KEY'];\n }\n\n /** @deprecated Renamed to {@link MastraCodeGateway.getMastraGatewayApiKey}. */\n static getMemoryGatewayApiKey(): string | undefined {\n return MastraCodeGateway.getMastraGatewayApiKey();\n }\n\n /**\n * Claim an unprefixed model id (e.g. a bare `anthropic/...`) when this gateway\n * can authenticate it via OAuth or a stored/env credential. This lets the\n * shared gateway router select MastraCode for auth resolution, so the status\n * bar and `/api-keys` reflect OAuth logins instead of only checking env vars.\n */\n handlesModel(modelId: string): boolean {\n const parsed = parseGatewayRouterId(modelId, this);\n if (!parsed.providerId || !parsed.modelId) return false;\n if (this.#routeThroughMastraGateway && this.#mastraGatewayApiKey) return true;\n const customProvider = this.#getCustomProviders().find(\n provider => parsed.providerId === getCustomProviderId(provider.name),\n );\n if (customProvider?.apiKey) return true;\n return hasResolvedAuth(\n MastraCodeGateway.resolveProviderAuth({\n gatewayId: this.id,\n providerId: parsed.providerId,\n modelId: parsed.modelId,\n routerId: modelId,\n }),\n );\n }\n\n static resolveProviderAuth(request: GatewayAuthRequest, mastraGatewayApiKey?: string): GatewayAuthResult | undefined {\n if (request.gatewayId === 'mastra' && mastraGatewayApiKey) {\n return { apiKey: mastraGatewayApiKey, source: 'gateway' };\n }\n\n const storedCred = authStorage.get(getAuthProviderId(request.providerId));\n if (storedCred?.type === 'oauth') {\n return { bearerToken: 'oauth', source: 'gateway' };\n }\n\n const apiKey = getProviderAuthKey(request.providerId);\n return apiKey ? { apiKey, source: 'gateway' } : undefined;\n }\n\n static createModelCatalogProvider(gateway: MastraModelGatewayInterface): CustomModelCatalogProvider {\n return async () => {\n const registry = await getMastraCodeProviderConfigs(gateway);\n const models: CustomAvailableModel[] = [];\n\n for (const [provider, providerConfig] of Object.entries(registry)) {\n const apiKeyEnvVar = getApiKeyEnvVar(providerConfig);\n const hasEnvKey = apiKeyEnvVar ? Boolean(process.env[apiKeyEnvVar]) : false;\n const modelNames = providerConfig.models;\n if (!Array.isArray(modelNames)) continue;\n\n const gatewayAuth = modelNames[0]\n ? await resolveGatewayProviderAuth(gateway, `${provider}/${modelNames[0]}`)\n : undefined;\n\n for (const modelName of modelNames) {\n const id = `${provider}/${modelName}`;\n models.push({\n id,\n provider,\n modelName,\n hasApiKey: hasEnvKey || Boolean(gatewayAuth),\n apiKeyEnvVar: apiKeyEnvVar || undefined,\n });\n }\n }\n\n return models;\n };\n }\n\n createModelCatalogProvider(): CustomModelCatalogProvider {\n return MastraCodeGateway.createModelCatalogProvider(this);\n }\n\n #getCustomProviders(): MastraCodeCustomProvider[] {\n return this.#customProviders ?? loadSettings(this.#settingsPath).customProviders;\n }\n\n async fetchProviders(): Promise<Record<string, ProviderConfig>> {\n const providers: Record<string, ProviderConfig> = {};\n for (const provider of this.#getCustomProviders()) {\n const models = provider.models ?? [];\n if (!models.length) continue;\n providers[getCustomProviderId(provider.name)] = {\n name: provider.name,\n url: provider.url,\n apiKeyEnvVar: '',\n apiKeyHeader: 'Authorization',\n gateway: this.id,\n models,\n };\n }\n\n try {\n const copilotModels = await getCopilotModelCatalog({ authStorage });\n providers['github-copilot'] = {\n name: 'GitHub Copilot',\n apiKeyEnvVar: '',\n apiKeyHeader: 'Authorization',\n gateway: this.id,\n models: copilotModels.map(model => model.id),\n };\n } catch (error) {\n console.warn('Failed to load GitHub Copilot model catalog:', error);\n }\n\n return providers;\n }\n\n buildUrl(modelId: string): string | undefined | Promise<string | undefined> {\n return this.#routeThroughMastraGateway ? this.#mastraGateway.buildUrl(modelId) : modelId;\n }\n\n async getApiKey(modelId: string): Promise<string> {\n const providerId = stripMastraGatewayPrefix(modelId).split('/', 1)[0];\n if (this.#routeThroughMastraGateway) return this.#mastraGatewayApiKey ?? '';\n return providerId ? (getProviderAuthKey(providerId) ?? '') : '';\n }\n\n resolveAuth(request: GatewayAuthRequest): GatewayAuthResult | undefined {\n if (this.#routeThroughMastraGateway && this.#mastraGatewayApiKey) {\n return { apiKey: this.#mastraGatewayApiKey, source: 'gateway' };\n }\n\n const customProvider = this.#getCustomProviders().find(\n provider => request.providerId === getCustomProviderId(provider.name),\n );\n if (customProvider?.apiKey) {\n return { apiKey: customProvider.apiKey, source: 'gateway' };\n }\n\n return MastraCodeGateway.resolveProviderAuth(request);\n }\n\n resolveLanguageModel(args: {\n modelId: string;\n providerId: string;\n apiKey: string;\n headers?: Record<string, string>;\n transport?: any;\n responsesWebSocket?: any;\n }): GatewayLanguageModel {\n const customProvider = this.#getCustomProviders().find(\n provider => args.providerId === getCustomProviderId(provider.name),\n );\n if (customProvider) {\n const provider = createOpenAICompatible({\n name: args.providerId,\n baseURL: customProvider.url,\n apiKey: args.apiKey,\n headers: args.headers,\n });\n return provider.chatModel(args.modelId) as unknown as GatewayLanguageModel;\n }\n\n if (args.providerId === 'github-copilot') {\n return githubCopilotProvider(args.modelId, { headers: args.headers }) as unknown as GatewayLanguageModel;\n }\n\n if (args.providerId === 'moonshotai') {\n if (!process.env.MOONSHOT_AI_API_KEY) {\n throw new Error(`Need MOONSHOT_AI_API_KEY`);\n }\n return createAnthropic({\n apiKey: process.env.MOONSHOT_AI_API_KEY,\n baseURL: 'https://api.moonshot.ai/anthropic/v1',\n name: 'moonshotai.anthropicv1',\n headers: args.headers,\n })(args.modelId) as unknown as GatewayLanguageModel;\n }\n\n if (args.providerId === 'anthropic') {\n return this.#resolveAnthropicModel(args);\n }\n\n if (args.providerId === 'openai') {\n const openaiModel = this.#resolveOpenAIModel(args);\n if (openaiModel) return openaiModel;\n }\n\n if (this.#routeThroughMastraGateway) {\n return this.#mastraGateway.resolveLanguageModel(args) as GatewayLanguageModel;\n }\n\n return new ModelRouterLanguageModel({\n id: `${args.providerId}/${args.modelId}` as `${string}/${string}`,\n headers: args.headers,\n }) as unknown as GatewayLanguageModel;\n }\n\n #resolveAnthropicModel(args: {\n modelId: string;\n providerId: string;\n apiKey: string;\n headers?: Record<string, string>;\n transport?: any;\n responsesWebSocket?: any;\n }): GatewayLanguageModel {\n const bareModelId = normalizeAnthropicModelId(args.modelId);\n const storedCred = authStorage.get('anthropic');\n\n if (this.#routeThroughMastraGateway) {\n if (storedCred?.type === 'oauth') {\n const anthropic = createAnthropic({\n apiKey: 'oauth-gateway-placeholder',\n baseURL: `${this.#mastraGatewayBaseUrl}/v1`,\n headers: {\n [GATEWAY_AUTH_HEADER]: `Bearer ${args.apiKey}`,\n ...args.headers,\n },\n fetch: buildAnthropicOAuthFetch({ authStorage }) as any,\n });\n\n return wrapLanguageModel({\n model: anthropic(bareModelId),\n middleware: [claudeCodeMiddleware, promptCacheMiddleware],\n }) as unknown as GatewayLanguageModel;\n }\n\n return this.#mastraGateway.resolveLanguageModel({ ...args, modelId: bareModelId }) as GatewayLanguageModel;\n }\n\n if (storedCred?.type === 'oauth') {\n return opencodeClaudeMaxProvider(bareModelId, { headers: args.headers }) as unknown as GatewayLanguageModel;\n }\n\n if (storedCred?.type === 'api_key' && storedCred.key.trim().length > 0) {\n return anthropicApiKeyProvider(\n bareModelId,\n storedCred.key.trim(),\n args.headers,\n ) as unknown as GatewayLanguageModel;\n }\n\n const apiKey = getAnthropicApiKey();\n if (apiKey) {\n return anthropicApiKeyProvider(bareModelId, apiKey, args.headers) as unknown as GatewayLanguageModel;\n }\n\n // No stored credentials: use the OAuth-backed provider so the first request can trigger login.\n return opencodeClaudeMaxProvider(bareModelId, { headers: args.headers }) as unknown as GatewayLanguageModel;\n }\n\n #resolveOpenAIModel(args: {\n modelId: string;\n providerId: string;\n apiKey: string;\n headers?: Record<string, string>;\n transport?: any;\n responsesWebSocket?: any;\n }): GatewayLanguageModel | undefined {\n const storedCred = authStorage.get('openai-codex');\n\n if (this.#routeThroughMastraGateway) {\n if (storedCred?.type === 'oauth') {\n const resolvedModelId = remapOpenAIModelForCodexOAuth(`openai/${args.modelId}`);\n const resolvedBareModelId = resolvedModelId.substring(OPENAI_PREFIX.length);\n const requestedLevel: ThinkingLevel = this.#thinkingLevel ?? 'medium';\n const effectiveLevel = getEffectiveThinkingLevel(resolvedBareModelId, requestedLevel);\n const reasoningEffort = THINKING_LEVEL_TO_REASONING_EFFORT[effectiveLevel];\n const middleware = createCodexMiddleware(reasoningEffort);\n const openai = createOpenAI({\n apiKey: 'oauth-gateway-placeholder',\n baseURL: `${this.#mastraGatewayBaseUrl}/v1`,\n headers: {\n [GATEWAY_AUTH_HEADER]: `Bearer ${args.apiKey}`,\n ...args.headers,\n },\n fetch: buildOpenAICodexOAuthFetch({ authStorage, rewriteUrl: false }) as any,\n });\n\n return wrapLanguageModel({\n model: openai.responses(resolvedBareModelId),\n middleware: [middleware],\n }) as unknown as GatewayLanguageModel;\n }\n\n return this.#mastraGateway.resolveLanguageModel(args) as GatewayLanguageModel;\n }\n\n if (storedCred?.type === 'oauth') {\n const resolvedModelId = remapOpenAIModelForCodexOAuth(`openai/${args.modelId}`);\n return openaiCodexProvider(resolvedModelId.substring(OPENAI_PREFIX.length), {\n thinkingLevel: this.#thinkingLevel,\n headers: args.headers,\n }) as unknown as GatewayLanguageModel;\n }\n\n const apiKey = getOpenAIApiKey();\n if (apiKey) {\n return openaiApiKeyProvider(args.modelId, apiKey, args.headers) as unknown as GatewayLanguageModel;\n }\n\n return undefined;\n }\n}\n"],"mappings":"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","names":[]}
@@ -62,7 +62,7 @@ function resolveModel(modelId, options) {
62
62
  });
63
63
  }
64
64
  const routerId = `${MASTRACODE_GATEWAY_ID}/${normalizedModelId}`;
65
- const mgApiKey = MastraCodeGateway.getMemoryGatewayApiKey();
65
+ const mgApiKey = MastraCodeGateway.getMastraGatewayApiKey();
66
66
  const rawGatewayBase = settings.memoryGateway?.baseUrl ?? process.env["MASTRA_GATEWAY_URL"] ?? "https://gateway-api.mastra.ai";
67
67
  const gateway = createMastraCodeGateway({
68
68
  mastraGatewayBaseUrl: rawGatewayBase.replace(/\/+$/, "").replace(/\/v1$/, ""),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/agents/model.ts"],"sourcesContent":["import type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { GatewayLanguageModel, MastraModelGatewayInterface } from '@mastra/core/llm';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport { loadSettings } from '../onboarding/settings.js';\nimport { AMAZON_BEDROCK_GATEWAY_ID, createAmazonBedrockGateway } from '../providers/amazon-bedrock-gateway.js';\nimport type { ThinkingLevel } from '../providers/openai-codex.js';\nimport {\n MASTRA_GATEWAY_PREFIX,\n MASTRACODE_GATEWAY_ID,\n MastraCodeGateway,\n reloadAuthStorage,\n stripMastraGatewayPrefix,\n} from './mastracode-gateway.js';\nimport type { MastraCodeGatewayOptions } from './mastracode-gateway.js';\n\nexport {\n getAnthropicApiKey,\n getOpenAIApiKey,\n MASTRACODE_GATEWAY_ID,\n MastraCodeGateway,\n remapOpenAIModelForCodexOAuth,\n resolveAuth,\n} from './mastracode-gateway.js';\nexport type { MastraCodeCustomProvider, MastraCodeGatewayOptions } from './mastracode-gateway.js';\n\ntype ResolvedModel = GatewayLanguageModel;\ntype ModelRequestHeaders = Record<string, string>;\n\nfunction getAgentControllerHeaders(requestContext?: RequestContext): ModelRequestHeaders | undefined {\n const agentControllerContext = requestContext?.get('controller') as AgentControllerRequestContext<any> | undefined;\n const headers = {\n ...(agentControllerContext?.threadId ? { 'x-thread-id': agentControllerContext.threadId } : {}),\n ...(agentControllerContext?.resourceId ? { 'x-resource-id': agentControllerContext.resourceId } : {}),\n };\n\n return Object.keys(headers).length > 0 ? headers : undefined;\n}\n\nexport function createMastraCodeGateway(options: MastraCodeGatewayOptions): MastraCodeGateway {\n return new MastraCodeGateway(options);\n}\n\nexport function createMastraCodeModelCatalogProvider(gateway: MastraModelGatewayInterface) {\n return gateway instanceof MastraCodeGateway\n ? gateway.createModelCatalogProvider()\n : MastraCodeGateway.createModelCatalogProvider(gateway);\n}\n\n/**\n * Placeholder for future model ID normalization.\n * Currently returns the input unchanged, but exists as a seam\n * for aliasing, casing fixes, or validation in the future.\n */\nexport function resolveModelId(modelId: string): string {\n return modelId;\n}\n\n/**\n * Resolve a model ID to the correct provider instance.\n * Shared by the main agent, observer, and reflector.\n *\n * - For anthropic/* models: Uses stored OAuth credentials when present, otherwise direct API key\n * - For openai/* models: Uses OAuth when configured, otherwise direct API key from AuthStorage\n * - For moonshotai/* models: Uses Moonshot AI Anthropic-compatible endpoint\n * - For all other providers: Uses Mastra's model router (models.dev gateway)\n */\nexport function resolveModel(\n modelId: string,\n options?: { thinkingLevel?: ThinkingLevel; remapForCodexOAuth?: boolean; requestContext?: RequestContext },\n): GatewayLanguageModel {\n reloadAuthStorage();\n const headers = getAgentControllerHeaders(options?.requestContext);\n const settings = loadSettings();\n // Bedrock was previously cataloged under the MastraCode gateway namespace\n // (`mastracode/amazon-bedrock/<model>`). Normalize any legacy saved ids to the\n // standalone `amazon-bedrock/<model>` form so they resolve through the\n // dedicated Bedrock gateway.\n const bedrockLegacyPrefix = `${MASTRACODE_GATEWAY_ID}/amazon-bedrock/`;\n const normalizedInput = modelId.startsWith(bedrockLegacyPrefix)\n ? modelId.slice(MASTRACODE_GATEWAY_ID.length + 1)\n : modelId;\n const isMastraGatewayModel = normalizedInput.startsWith(MASTRA_GATEWAY_PREFIX);\n const normalizedModelId = stripMastraGatewayPrefix(normalizedInput);\n const [providerId, ...modelParts] = normalizedModelId.split('/');\n const bareModelId = modelParts.join('/');\n if (!providerId || !bareModelId) {\n throw new Error(`Invalid model id: ${modelId}`);\n }\n\n if (providerId === AMAZON_BEDROCK_GATEWAY_ID) {\n const bedrockGateway = createAmazonBedrockGateway();\n const routerId = `${AMAZON_BEDROCK_GATEWAY_ID}/${bareModelId}`;\n const auth = bedrockGateway.resolveAuth({\n gatewayId: AMAZON_BEDROCK_GATEWAY_ID,\n providerId: AMAZON_BEDROCK_GATEWAY_ID,\n modelId: bareModelId,\n routerId,\n });\n return bedrockGateway.resolveLanguageModel({\n providerId: AMAZON_BEDROCK_GATEWAY_ID,\n modelId: bareModelId,\n apiKey: auth?.apiKey ?? '',\n headers,\n });\n }\n\n const routerId = `${MASTRACODE_GATEWAY_ID}/${normalizedModelId}`;\n\n const mgApiKey = MastraCodeGateway.getMemoryGatewayApiKey();\n const rawGatewayBase =\n settings.memoryGateway?.baseUrl ?? process.env['MASTRA_GATEWAY_URL'] ?? 'https://gateway-api.mastra.ai';\n const gateway = createMastraCodeGateway({\n mastraGatewayBaseUrl: rawGatewayBase.replace(/\\/+$/, '').replace(/\\/v1$/, ''),\n mastraGatewayApiKey: mgApiKey,\n routeThroughMastraGateway: Boolean(mgApiKey && isMastraGatewayModel),\n thinkingLevel: options?.thinkingLevel,\n customProviders: settings.customProviders,\n });\n\n const auth = gateway.resolveAuth({\n gatewayId: MASTRACODE_GATEWAY_ID,\n providerId,\n modelId: bareModelId,\n routerId,\n });\n\n return gateway.resolveLanguageModel({\n providerId,\n modelId: bareModelId,\n apiKey: auth?.apiKey ?? mgApiKey ?? '',\n headers,\n });\n}\n\n/**\n * Dynamic model function that reads the current model from controller state.\n * This allows runtime model switching via the /models picker.\n */\nexport function getDynamicModel({ requestContext }: { requestContext: RequestContext }): ResolvedModel {\n const agentControllerContext = requestContext.get('controller') as AgentControllerRequestContext<any> | undefined;\n\n const modelId = agentControllerContext?.session?.modelId;\n if (!modelId) {\n throw new Error('No model selected. Use /models to select a model first.');\n }\n\n const thinkingLevel = agentControllerContext?.state?.thinkingLevel as ThinkingLevel | undefined;\n\n return resolveModel(modelId, { thinkingLevel, remapForCodexOAuth: true, requestContext });\n}\n\n/**\n * Goal judge model resolver for the agent's `goal.judge` config. Resolves the\n * configured goal judge model through mastracode's gateway so provider\n * credentials (stored in auth storage, not just env) are injected — a bare model\n * id handed to core's default model router would fail to find the API key.\n *\n * Returns `undefined` when no judge model is configured, which keeps the goal\n * step a complete no-op (the goal mechanism requires a judge to do anything).\n *\n * `settingsPath` must be the same source `createMastraCode()` reads from so the\n * judge model and the goal budget (`goalMaxTurns`) come from one config — with a\n * custom `settingsPath` a bare `loadSettings()` here could read a different file\n * and silently turn the goal step into a no-op.\n */\nexport function getGoalJudgeModel(\n { requestContext }: { requestContext: RequestContext },\n settingsPath?: string,\n): ResolvedModel | undefined {\n const judgeModelId = loadSettings(settingsPath).models.goalJudgeModel;\n if (!judgeModelId) return undefined;\n return resolveModel(judgeModelId, { remapForCodexOAuth: true, requestContext });\n}\n"],"mappings":"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","names":["MASTRACODE_GATEWAY_ID","MastraCodeGateway","routerId","auth"]}
1
+ {"version":3,"sources":["../../src/agents/model.ts"],"sourcesContent":["import type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { GatewayLanguageModel, MastraModelGatewayInterface } from '@mastra/core/llm';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport { loadSettings } from '../onboarding/settings.js';\nimport { AMAZON_BEDROCK_GATEWAY_ID, createAmazonBedrockGateway } from '../providers/amazon-bedrock-gateway.js';\nimport type { ThinkingLevel } from '../providers/openai-codex.js';\nimport {\n MASTRA_GATEWAY_PREFIX,\n MASTRACODE_GATEWAY_ID,\n MastraCodeGateway,\n reloadAuthStorage,\n stripMastraGatewayPrefix,\n} from './mastracode-gateway.js';\nimport type { MastraCodeGatewayOptions } from './mastracode-gateway.js';\n\nexport {\n getAnthropicApiKey,\n getOpenAIApiKey,\n MASTRACODE_GATEWAY_ID,\n MastraCodeGateway,\n remapOpenAIModelForCodexOAuth,\n resolveAuth,\n} from './mastracode-gateway.js';\nexport type { MastraCodeCustomProvider, MastraCodeGatewayOptions } from './mastracode-gateway.js';\n\ntype ResolvedModel = GatewayLanguageModel;\ntype ModelRequestHeaders = Record<string, string>;\n\nfunction getAgentControllerHeaders(requestContext?: RequestContext): ModelRequestHeaders | undefined {\n const agentControllerContext = requestContext?.get('controller') as AgentControllerRequestContext<any> | undefined;\n const headers = {\n ...(agentControllerContext?.threadId ? { 'x-thread-id': agentControllerContext.threadId } : {}),\n ...(agentControllerContext?.resourceId ? { 'x-resource-id': agentControllerContext.resourceId } : {}),\n };\n\n return Object.keys(headers).length > 0 ? headers : undefined;\n}\n\nexport function createMastraCodeGateway(options: MastraCodeGatewayOptions): MastraCodeGateway {\n return new MastraCodeGateway(options);\n}\n\nexport function createMastraCodeModelCatalogProvider(gateway: MastraModelGatewayInterface) {\n return gateway instanceof MastraCodeGateway\n ? gateway.createModelCatalogProvider()\n : MastraCodeGateway.createModelCatalogProvider(gateway);\n}\n\n/**\n * Placeholder for future model ID normalization.\n * Currently returns the input unchanged, but exists as a seam\n * for aliasing, casing fixes, or validation in the future.\n */\nexport function resolveModelId(modelId: string): string {\n return modelId;\n}\n\n/**\n * Resolve a model ID to the correct provider instance.\n * Shared by the main agent, observer, and reflector.\n *\n * - For anthropic/* models: Uses stored OAuth credentials when present, otherwise direct API key\n * - For openai/* models: Uses OAuth when configured, otherwise direct API key from AuthStorage\n * - For moonshotai/* models: Uses Moonshot AI Anthropic-compatible endpoint\n * - For all other providers: Uses Mastra's model router (models.dev gateway)\n */\nexport function resolveModel(\n modelId: string,\n options?: { thinkingLevel?: ThinkingLevel; remapForCodexOAuth?: boolean; requestContext?: RequestContext },\n): GatewayLanguageModel {\n reloadAuthStorage();\n const headers = getAgentControllerHeaders(options?.requestContext);\n const settings = loadSettings();\n // Bedrock was previously cataloged under the MastraCode gateway namespace\n // (`mastracode/amazon-bedrock/<model>`). Normalize any legacy saved ids to the\n // standalone `amazon-bedrock/<model>` form so they resolve through the\n // dedicated Bedrock gateway.\n const bedrockLegacyPrefix = `${MASTRACODE_GATEWAY_ID}/amazon-bedrock/`;\n const normalizedInput = modelId.startsWith(bedrockLegacyPrefix)\n ? modelId.slice(MASTRACODE_GATEWAY_ID.length + 1)\n : modelId;\n const isMastraGatewayModel = normalizedInput.startsWith(MASTRA_GATEWAY_PREFIX);\n const normalizedModelId = stripMastraGatewayPrefix(normalizedInput);\n const [providerId, ...modelParts] = normalizedModelId.split('/');\n const bareModelId = modelParts.join('/');\n if (!providerId || !bareModelId) {\n throw new Error(`Invalid model id: ${modelId}`);\n }\n\n if (providerId === AMAZON_BEDROCK_GATEWAY_ID) {\n const bedrockGateway = createAmazonBedrockGateway();\n const routerId = `${AMAZON_BEDROCK_GATEWAY_ID}/${bareModelId}`;\n const auth = bedrockGateway.resolveAuth({\n gatewayId: AMAZON_BEDROCK_GATEWAY_ID,\n providerId: AMAZON_BEDROCK_GATEWAY_ID,\n modelId: bareModelId,\n routerId,\n });\n return bedrockGateway.resolveLanguageModel({\n providerId: AMAZON_BEDROCK_GATEWAY_ID,\n modelId: bareModelId,\n apiKey: auth?.apiKey ?? '',\n headers,\n });\n }\n\n const routerId = `${MASTRACODE_GATEWAY_ID}/${normalizedModelId}`;\n\n const mgApiKey = MastraCodeGateway.getMastraGatewayApiKey();\n const rawGatewayBase =\n settings.memoryGateway?.baseUrl ?? process.env['MASTRA_GATEWAY_URL'] ?? 'https://gateway-api.mastra.ai';\n const gateway = createMastraCodeGateway({\n mastraGatewayBaseUrl: rawGatewayBase.replace(/\\/+$/, '').replace(/\\/v1$/, ''),\n mastraGatewayApiKey: mgApiKey,\n routeThroughMastraGateway: Boolean(mgApiKey && isMastraGatewayModel),\n thinkingLevel: options?.thinkingLevel,\n customProviders: settings.customProviders,\n });\n\n const auth = gateway.resolveAuth({\n gatewayId: MASTRACODE_GATEWAY_ID,\n providerId,\n modelId: bareModelId,\n routerId,\n });\n\n return gateway.resolveLanguageModel({\n providerId,\n modelId: bareModelId,\n apiKey: auth?.apiKey ?? mgApiKey ?? '',\n headers,\n });\n}\n\n/**\n * Dynamic model function that reads the current model from controller state.\n * This allows runtime model switching via the /models picker.\n */\nexport function getDynamicModel({ requestContext }: { requestContext: RequestContext }): ResolvedModel {\n const agentControllerContext = requestContext.get('controller') as AgentControllerRequestContext<any> | undefined;\n\n const modelId = agentControllerContext?.session?.modelId;\n if (!modelId) {\n throw new Error('No model selected. Use /models to select a model first.');\n }\n\n const thinkingLevel = agentControllerContext?.state?.thinkingLevel as ThinkingLevel | undefined;\n\n return resolveModel(modelId, { thinkingLevel, remapForCodexOAuth: true, requestContext });\n}\n\n/**\n * Goal judge model resolver for the agent's `goal.judge` config. Resolves the\n * configured goal judge model through mastracode's gateway so provider\n * credentials (stored in auth storage, not just env) are injected — a bare model\n * id handed to core's default model router would fail to find the API key.\n *\n * Returns `undefined` when no judge model is configured, which keeps the goal\n * step a complete no-op (the goal mechanism requires a judge to do anything).\n *\n * `settingsPath` must be the same source `createMastraCode()` reads from so the\n * judge model and the goal budget (`goalMaxTurns`) come from one config — with a\n * custom `settingsPath` a bare `loadSettings()` here could read a different file\n * and silently turn the goal step into a no-op.\n */\nexport function getGoalJudgeModel(\n { requestContext }: { requestContext: RequestContext },\n settingsPath?: string,\n): ResolvedModel | undefined {\n const judgeModelId = loadSettings(settingsPath).models.goalJudgeModel;\n if (!judgeModelId) return undefined;\n return resolveModel(judgeModelId, { remapForCodexOAuth: true, requestContext });\n}\n"],"mappings":"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","names":["MASTRACODE_GATEWAY_ID","MastraCodeGateway","routerId","auth"]}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/agents/workspace.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAwB,MAAM,wBAAwB,CAAC;AAiFxG,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,SAAe,EACtB,gBAAgB,GAAE,MAAM,EAAO,GAC9B,MAAM,EAAE,CAiBV;AAgFD,wBAAsB,mBAAmB,CAAC,EACxC,cAAc,EACd,MAAM,GACP,EAAE;IACD,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,wNA2EA;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,cAAc,EACd,MAAM,GACP,EAAE;IACD,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAclC"}
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/agents/workspace.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAwB,MAAM,wBAAwB,CAAC;AA2GxG,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,SAAe,EACtB,gBAAgB,GAAE,MAAM,EAAO,GAC9B,MAAM,EAAE,CA0BV;AAgFD,wBAAsB,mBAAmB,CAAC,EACxC,cAAc,EACd,MAAM,GACP,EAAE;IACD,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,wNA2EA;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,cAAc,EACd,MAAM,GACP,EAAE;IACD,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAclC"}
@@ -5,6 +5,7 @@ import { fileURLToPath } from "node:url";
5
5
  import { Workspace, LocalFilesystem, LocalSandbox, createWorkspaceTools } from "@mastra/core/workspace";
6
6
  import { DEFAULT_CONFIG_DIR } from "../constants.js";
7
7
  import { loadSettings } from "../onboarding/settings.js";
8
+ import { isPathWithinRoot } from "../utils/path-security.js";
8
9
  import { getPlansDir } from "../utils/plans.js";
9
10
  import { SandboxFilesystem } from "./sandbox-filesystem.js";
10
11
  import { reattachProjectSandbox } from "./sandbox-reattach.js";
@@ -21,29 +22,52 @@ function buildSandboxEnv() {
21
22
  DEBIAN_FRONTEND: "noninteractive"
22
23
  };
23
24
  }
24
- function collectSkillPaths(skillsDirs) {
25
+ function collectSkillPaths(skillsDirs, allowedRoot) {
25
26
  const paths = [];
26
27
  const seen = /* @__PURE__ */ new Set();
28
+ let realAllowedRoot;
29
+ if (allowedRoot) {
30
+ try {
31
+ realAllowedRoot = fs.realpathSync(allowedRoot);
32
+ } catch {
33
+ return [];
34
+ }
35
+ }
27
36
  for (const skillsDir of skillsDirs) {
37
+ const skillsDirExists = fs.existsSync(skillsDir);
38
+ if (skillsDirExists && realAllowedRoot) {
39
+ try {
40
+ const realSkillsDir = fs.realpathSync(skillsDir);
41
+ if (!isPathWithinRoot(realSkillsDir, realAllowedRoot)) continue;
42
+ } catch {
43
+ continue;
44
+ }
45
+ }
28
46
  const resolved = path.resolve(skillsDir);
29
47
  if (!seen.has(resolved)) {
30
48
  seen.add(resolved);
31
49
  paths.push(skillsDir);
32
50
  }
33
- if (!fs.existsSync(skillsDir)) continue;
51
+ if (!skillsDirExists) continue;
34
52
  try {
35
53
  const entries = fs.readdirSync(skillsDir, { withFileTypes: true });
36
54
  for (const entry of entries) {
37
55
  if (entry.isSymbolicLink()) {
38
- const linkPath = path.join(skillsDir, entry.name);
39
- const realPath = fs.realpathSync(linkPath);
40
- const stat = fs.statSync(realPath);
41
- if (stat.isDirectory()) {
42
- const realParent = path.dirname(realPath);
43
- if (!seen.has(realParent)) {
44
- seen.add(realParent);
45
- paths.push(realParent);
56
+ try {
57
+ const linkPath = path.join(skillsDir, entry.name);
58
+ const realPath = fs.realpathSync(linkPath);
59
+ if (realAllowedRoot && !isPathWithinRoot(realPath, realAllowedRoot)) continue;
60
+ const stat = fs.statSync(realPath);
61
+ if (stat.isDirectory()) {
62
+ const realParent = path.dirname(realPath);
63
+ if (realAllowedRoot && !isPathWithinRoot(realParent, realAllowedRoot)) continue;
64
+ if (!seen.has(realParent)) {
65
+ seen.add(realParent);
66
+ paths.push(realParent);
67
+ }
46
68
  }
69
+ } catch {
70
+ continue;
47
71
  }
48
72
  }
49
73
  }
@@ -59,15 +83,23 @@ function buildSkillPaths(projectPath, configDir, homeDir = os.homedir(), pluginS
59
83
  const mastraCodeGlobalSkillsPath = path.join(homeDir, configDir, "skills");
60
84
  const claudeGlobalSkillsPath = path.join(homeDir, ".claude", "skills");
61
85
  const agentSkillsGlobalPath = path.join(homeDir, ".agents", "skills");
62
- return collectSkillPaths([
63
- mastraCodeLocalSkillsPath,
64
- claudeLocalSkillsPath,
65
- agentSkillsLocalPath,
66
- mastraCodeGlobalSkillsPath,
67
- claudeGlobalSkillsPath,
68
- agentSkillsGlobalPath,
69
- ...pluginSkillPaths
70
- ]);
86
+ const paths = [
87
+ ...collectSkillPaths([mastraCodeLocalSkillsPath, claudeLocalSkillsPath, agentSkillsLocalPath], projectPath),
88
+ ...collectSkillPaths([mastraCodeGlobalSkillsPath, claudeGlobalSkillsPath, agentSkillsGlobalPath]),
89
+ ...pluginSkillPaths.flatMap((pluginSkillPath) => collectSkillPaths([pluginSkillPath], pluginSkillPath))
90
+ ];
91
+ const seenPaths = /* @__PURE__ */ new Set();
92
+ return paths.filter((skillPath) => {
93
+ let resolved;
94
+ try {
95
+ resolved = fs.realpathSync(skillPath);
96
+ } catch {
97
+ resolved = path.resolve(skillPath);
98
+ }
99
+ if (seenPaths.has(resolved)) return false;
100
+ seenPaths.add(resolved);
101
+ return true;
102
+ });
71
103
  }
72
104
  const DEFAULT_ALLOWED_PATHS = [os.tmpdir(), "/tmp", getPlansDir()].reduce((acc, p) => {
73
105
  const resolved = path.resolve(p);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/agents/workspace.ts"],"sourcesContent":["import fs, { existsSync } from 'node:fs';\nimport os from 'node:os';\nimport path, { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { ToolsInput } from '@mastra/core/agent';\nimport type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport { Workspace, LocalFilesystem, LocalSandbox, createWorkspaceTools } from '@mastra/core/workspace';\nimport type { LSPConfig } from '@mastra/core/workspace';\nimport { DEFAULT_CONFIG_DIR } from '../constants.js';\nimport { loadSettings } from '../onboarding/settings.js';\nimport type { MastraCodeState } from '../schema.js';\nimport { getPlansDir } from '../utils/plans.js';\nimport { SandboxFilesystem } from './sandbox-filesystem.js';\nimport { reattachProjectSandbox } from './sandbox-reattach.js';\nimport { GOAL_JUDGE_READONLY_TOOLS, MASTRACODE_WORKSPACE_TOOLS } from './tool-availability.js';\n\n// =============================================================================\n// Sandbox Environment\n// =============================================================================\n\nfunction buildSandboxEnv(): NodeJS.ProcessEnv {\n return {\n ...process.env,\n // Explicit overrides for non-interactive subprocess execution\n FORCE_COLOR: '1',\n CLICOLOR_FORCE: '1',\n TERM: process.env.TERM || 'xterm-256color',\n CI: 'true',\n NONINTERACTIVE: '1',\n DEBIAN_FRONTEND: 'noninteractive',\n };\n}\n\n// =============================================================================\n// Create Workspace with Skills\n// =============================================================================\n\n// We support multiple skill locations for compatibility:\n// 1. Project-local: <configDir>/skills (project-specific mastracode skills)\n// 2. Project-local: .claude/skills (Claude Code compatible skills)\n// 3. Project-local: .agents/skills (Agent Skills spec compatible)\n// 4. Global: ~/<configDir>/skills (user-wide mastracode skills)\n// 5. Global: ~/.claude/skills (user-wide Claude Code skills)\n// 6. Global: ~/.agents/skills (user-wide Agent Skills spec compatible)\n\n// Mastra's LocalSkillSource.readdir uses Node's Dirent.isDirectory() which\n// returns false for symlinks. Tools like `npx skills add` install skills as\n// symlinks, so we need to resolve them. For each symlinked skill directory,\n// we add the real (resolved) parent path as an additional skill scan path.\nfunction collectSkillPaths(skillsDirs: string[]): string[] {\n const paths: string[] = [];\n const seen = new Set<string>();\n\n for (const skillsDir of skillsDirs) {\n const resolved = path.resolve(skillsDir);\n if (!seen.has(resolved)) {\n seen.add(resolved);\n paths.push(skillsDir);\n }\n\n if (!fs.existsSync(skillsDir)) continue;\n\n try {\n const entries = fs.readdirSync(skillsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isSymbolicLink()) {\n const linkPath = path.join(skillsDir, entry.name);\n const realPath = fs.realpathSync(linkPath);\n const stat = fs.statSync(realPath);\n if (stat.isDirectory()) {\n const realParent = path.dirname(realPath);\n if (!seen.has(realParent)) {\n seen.add(realParent);\n paths.push(realParent);\n }\n }\n }\n }\n } catch {\n // Ignore errors during symlink resolution\n }\n }\n\n return paths;\n}\n\n// Build skill paths dynamically based on configDir and projectPath\nexport function buildSkillPaths(\n projectPath: string,\n configDir: string,\n homeDir = os.homedir(),\n pluginSkillPaths: string[] = [],\n): string[] {\n const mastraCodeLocalSkillsPath = path.join(projectPath, configDir, 'skills');\n const claudeLocalSkillsPath = path.join(projectPath, '.claude', 'skills');\n const agentSkillsLocalPath = path.join(projectPath, '.agents', 'skills');\n const mastraCodeGlobalSkillsPath = path.join(homeDir, configDir, 'skills');\n const claudeGlobalSkillsPath = path.join(homeDir, '.claude', 'skills');\n const agentSkillsGlobalPath = path.join(homeDir, '.agents', 'skills');\n\n return collectSkillPaths([\n mastraCodeLocalSkillsPath,\n claudeLocalSkillsPath,\n agentSkillsLocalPath,\n mastraCodeGlobalSkillsPath,\n claudeGlobalSkillsPath,\n agentSkillsGlobalPath,\n ...pluginSkillPaths,\n ]);\n}\n\n/**\n * Paths the agent is always allowed to access (in addition to the project root\n * and any per-thread sandboxAllowedPaths). The OS temp directory is included\n * so the agent can use it as a scratchpad without requesting access every time.\n */\nconst DEFAULT_ALLOWED_PATHS: string[] = [os.tmpdir(), '/tmp', getPlansDir()].reduce<string[]>((acc, p) => {\n const resolved = path.resolve(p);\n if (!acc.includes(resolved)) acc.push(resolved);\n return acc;\n}, []);\n\nconst WORKSPACE_ID_PREFIX = 'mastra-code-workspace';\n\n/**\n * Detect the project's package runner from lock files.\n * Used as a fallback packageRunner for LSP when no binary is found locally or on PATH.\n */\nfunction detectPackageRunner(projectPath: string): string | undefined {\n if (existsSync(join(projectPath, 'pnpm-lock.yaml'))) return 'pnpm dlx';\n if (existsSync(join(projectPath, 'bun.lockb')) || existsSync(join(projectPath, 'bun.lock'))) return 'bunx';\n if (existsSync(join(projectPath, 'yarn.lock'))) return 'yarn dlx';\n if (existsSync(join(projectPath, 'package-lock.json'))) return 'npx --yes';\n return 'npx --yes';\n}\n\n/**\n * Build (or reuse) a sandbox-backed Workspace for a GitHub project. The sandbox\n * is reattached by its persisted provider id and a `SandboxFilesystem` is layered\n * over the in-sandbox checkout so file tools and command tools share one VM.\n */\nasync function getSandboxWorkspace({\n githubProjectId,\n sandboxId,\n workdir,\n worktreePath,\n mastra,\n}: {\n githubProjectId: string;\n sandboxId: string;\n workdir: string;\n worktreePath?: string;\n mastra?: Mastra;\n}): Promise<Workspace> {\n // Bind the workspace to the active worktree when one is set, so file tools and\n // command tools operate inside the feature branch's working tree rather than\n // the base checkout. Falls back to the repo root when no worktree is active.\n const boundWorkdir = worktreePath || workdir;\n\n // Include the sandbox id *and* worktree path in the reuse key: a new sandbox\n // (e.g. the previous one expired) or a different worktree must each get a\n // fresh Workspace/ProcessManager instead of reusing one bound to a stale\n // sandbox or the wrong working tree.\n const workspaceId = `${WORKSPACE_ID_PREFIX}-gh-${githubProjectId}-${sandboxId}-${boundWorkdir}`;\n\n // Reuse the existing remote workspace if already registered (preserves the\n // reattached sandbox + ProcessManager state across re-opens).\n try {\n const existing = mastra?.getWorkspaceById(workspaceId) as Workspace | undefined;\n if (existing) {\n existing.setToolsConfig(MASTRACODE_WORKSPACE_TOOLS);\n return existing;\n }\n } catch {\n // Not registered yet.\n }\n\n const sandbox = await reattachProjectSandbox(sandboxId);\n const filesystem = new SandboxFilesystem({ sandbox, workdir: boundWorkdir });\n\n return new Workspace({\n id: workspaceId,\n name: 'Mastra Code Sandbox Workspace',\n filesystem,\n sandbox: sandbox as unknown as ConstructorParameters<typeof Workspace>[0]['sandbox'],\n tools: MASTRACODE_WORKSPACE_TOOLS,\n });\n}\n\nexport async function getDynamicWorkspace({\n requestContext,\n mastra,\n}: {\n requestContext: RequestContext;\n mastra?: Mastra;\n}) {\n const ctx = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n const state = ctx?.getState();\n\n // GitHub/cloud-sandbox-backed project: the repo lives inside a remote sandbox,\n // not on the server host. Reattach to the already-provisioned + materialized\n // sandbox (the SPA called `.../ensure` first, persisting sandboxId/workdir on\n // controller state) and build a sandbox-backed Workspace. LSP/host skill paths\n // are skipped for these workspaces (follow-up).\n if (state?.githubProjectId && state.sandboxId && state.sandboxWorkdir) {\n return getSandboxWorkspace({\n githubProjectId: state.githubProjectId,\n sandboxId: state.sandboxId,\n workdir: state.sandboxWorkdir,\n worktreePath: state.worktreePath,\n mastra,\n });\n }\n\n const rawProjectPath = state?.projectPath;\n\n if (!rawProjectPath) {\n throw new Error('Project path is required');\n }\n\n const projectPath = path.resolve(rawProjectPath);\n const configDir = state?.configDir ?? DEFAULT_CONFIG_DIR;\n const skillPaths = buildSkillPaths(projectPath, configDir, state?.homeDir, state?.pluginSkillPaths ?? []);\n const workspaceId = `${WORKSPACE_ID_PREFIX}-${projectPath}`;\n const sandboxPaths = state?.sandboxAllowedPaths ?? [];\n const allowedPaths = [...skillPaths, ...DEFAULT_ALLOWED_PATHS, ...sandboxPaths.map((p: string) => path.resolve(p))];\n\n // All modes share the same workspace tool configuration. Per-mode tool\n // visibility is enforced at LLM-call time via `availableTools` /\n // `activeTools` on the AgentController, not by mutating workspace capabilities.\n const workspaceTools = MASTRACODE_WORKSPACE_TOOLS;\n\n // Reuse existing workspace if already registered (preserves ProcessManager state)\n let existing: Workspace<LocalFilesystem, LocalSandbox> | undefined;\n try {\n existing = mastra?.getWorkspaceById(workspaceId) as Workspace<LocalFilesystem, LocalSandbox>;\n } catch {\n // Not registered yet\n }\n\n if (existing) {\n existing.filesystem.setAllowedPaths(allowedPaths);\n existing.setToolsConfig(workspaceTools);\n return existing;\n }\n\n const userLsp = loadSettings().lsp ?? {};\n const mcModulePath = join(dirname(fileURLToPath(import.meta.url)), '..');\n const lspConfig: LSPConfig = {\n ...userLsp,\n packageRunner: userLsp.packageRunner || detectPackageRunner(projectPath), // Detected runner is the fallback — user's packageRunner always wins\n searchPaths: [mcModulePath, ...(userLsp.searchPaths ?? [])],\n };\n\n // First call for this project — create the workspace\n return new Workspace({\n id: workspaceId,\n name: 'Mastra Code Workspace',\n filesystem: new LocalFilesystem({\n basePath: projectPath,\n allowedPaths,\n }),\n sandbox: new LocalSandbox({\n workingDirectory: projectPath,\n env: buildSandboxEnv(),\n }),\n tools: workspaceTools,\n ...(skillPaths.length > 0 ? { skills: skillPaths } : {}),\n lsp: lspConfig,\n });\n}\n\n/**\n * Resolver for the agent's `goal.tools` config. Builds the request's workspace\n * (same per-request resolution as the agent's own tools) and returns only the\n * read-only verification subset, remapped to mastracode's tool names (`view`,\n * `search_content`, etc.). Returns `undefined` when no workspace can be resolved\n * (e.g. no project path), keeping the default judge text-only rather than\n * throwing inside the goal step.\n */\nexport async function getGoalJudgeTools({\n requestContext,\n mastra,\n}: {\n requestContext: RequestContext;\n mastra?: Mastra;\n}): Promise<ToolsInput | undefined> {\n let workspace: Workspace;\n try {\n workspace = await getDynamicWorkspace({ requestContext, mastra });\n } catch {\n return undefined;\n }\n\n const allTools = await createWorkspaceTools(workspace, { requestContext, workspace });\n const readonly: ToolsInput = {};\n for (const name of GOAL_JUDGE_READONLY_TOOLS) {\n if (allTools[name]) readonly[name] = allTools[name];\n }\n return Object.keys(readonly).length > 0 ? readonly : undefined;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/agents/workspace.ts"],"sourcesContent":["import fs, { existsSync } from 'node:fs';\nimport os from 'node:os';\nimport path, { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { ToolsInput } from '@mastra/core/agent';\nimport type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport { Workspace, LocalFilesystem, LocalSandbox, createWorkspaceTools } from '@mastra/core/workspace';\nimport type { LSPConfig } from '@mastra/core/workspace';\nimport { DEFAULT_CONFIG_DIR } from '../constants.js';\nimport { loadSettings } from '../onboarding/settings.js';\nimport type { MastraCodeState } from '../schema.js';\nimport { isPathWithinRoot } from '../utils/path-security.js';\nimport { getPlansDir } from '../utils/plans.js';\nimport { SandboxFilesystem } from './sandbox-filesystem.js';\nimport { reattachProjectSandbox } from './sandbox-reattach.js';\nimport { GOAL_JUDGE_READONLY_TOOLS, MASTRACODE_WORKSPACE_TOOLS } from './tool-availability.js';\n\n// =============================================================================\n// Sandbox Environment\n// =============================================================================\n\nfunction buildSandboxEnv(): NodeJS.ProcessEnv {\n return {\n ...process.env,\n // Explicit overrides for non-interactive subprocess execution\n FORCE_COLOR: '1',\n CLICOLOR_FORCE: '1',\n TERM: process.env.TERM || 'xterm-256color',\n CI: 'true',\n NONINTERACTIVE: '1',\n DEBIAN_FRONTEND: 'noninteractive',\n };\n}\n\n// =============================================================================\n// Create Workspace with Skills\n// =============================================================================\n\n// We support multiple skill locations for compatibility:\n// 1. Project-local: <configDir>/skills (project-specific mastracode skills)\n// 2. Project-local: .claude/skills (Claude Code compatible skills)\n// 3. Project-local: .agents/skills (Agent Skills spec compatible)\n// 4. Global: ~/<configDir>/skills (user-wide mastracode skills)\n// 5. Global: ~/.claude/skills (user-wide Claude Code skills)\n// 6. Global: ~/.agents/skills (user-wide Agent Skills spec compatible)\n\n// Mastra's LocalSkillSource.readdir uses Node's Dirent.isDirectory() which\n// returns false for symlinks. Tools like `npx skills add` install skills as\n// symlinks, so we need to resolve them. For each symlinked skill directory,\n// we add the real (resolved) parent path as an additional skill scan path.\nfunction collectSkillPaths(skillsDirs: string[], allowedRoot?: string): string[] {\n const paths: string[] = [];\n const seen = new Set<string>();\n let realAllowedRoot: string | undefined;\n\n if (allowedRoot) {\n try {\n realAllowedRoot = fs.realpathSync(allowedRoot);\n } catch {\n return [];\n }\n }\n\n for (const skillsDir of skillsDirs) {\n const skillsDirExists = fs.existsSync(skillsDir);\n if (skillsDirExists && realAllowedRoot) {\n try {\n const realSkillsDir = fs.realpathSync(skillsDir);\n if (!isPathWithinRoot(realSkillsDir, realAllowedRoot)) continue;\n } catch {\n continue;\n }\n }\n\n const resolved = path.resolve(skillsDir);\n if (!seen.has(resolved)) {\n seen.add(resolved);\n paths.push(skillsDir);\n }\n\n if (!skillsDirExists) continue;\n\n try {\n const entries = fs.readdirSync(skillsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isSymbolicLink()) {\n try {\n const linkPath = path.join(skillsDir, entry.name);\n const realPath = fs.realpathSync(linkPath);\n if (realAllowedRoot && !isPathWithinRoot(realPath, realAllowedRoot)) continue;\n const stat = fs.statSync(realPath);\n if (stat.isDirectory()) {\n const realParent = path.dirname(realPath);\n if (realAllowedRoot && !isPathWithinRoot(realParent, realAllowedRoot)) continue;\n if (!seen.has(realParent)) {\n seen.add(realParent);\n paths.push(realParent);\n }\n }\n } catch {\n continue;\n }\n }\n }\n } catch {\n // Ignore errors during symlink resolution\n }\n }\n\n return paths;\n}\n\n// Build skill paths dynamically based on configDir and projectPath\nexport function buildSkillPaths(\n projectPath: string,\n configDir: string,\n homeDir = os.homedir(),\n pluginSkillPaths: string[] = [],\n): string[] {\n const mastraCodeLocalSkillsPath = path.join(projectPath, configDir, 'skills');\n const claudeLocalSkillsPath = path.join(projectPath, '.claude', 'skills');\n const agentSkillsLocalPath = path.join(projectPath, '.agents', 'skills');\n const mastraCodeGlobalSkillsPath = path.join(homeDir, configDir, 'skills');\n const claudeGlobalSkillsPath = path.join(homeDir, '.claude', 'skills');\n const agentSkillsGlobalPath = path.join(homeDir, '.agents', 'skills');\n\n const paths = [\n ...collectSkillPaths([mastraCodeLocalSkillsPath, claudeLocalSkillsPath, agentSkillsLocalPath], projectPath),\n ...collectSkillPaths([mastraCodeGlobalSkillsPath, claudeGlobalSkillsPath, agentSkillsGlobalPath]),\n ...pluginSkillPaths.flatMap(pluginSkillPath => collectSkillPaths([pluginSkillPath], pluginSkillPath)),\n ];\n\n const seenPaths = new Set<string>();\n return paths.filter(skillPath => {\n let resolved: string;\n try {\n resolved = fs.realpathSync(skillPath);\n } catch {\n resolved = path.resolve(skillPath);\n }\n if (seenPaths.has(resolved)) return false;\n seenPaths.add(resolved);\n return true;\n });\n}\n\n/**\n * Paths the agent is always allowed to access (in addition to the project root\n * and any per-thread sandboxAllowedPaths). The OS temp directory is included\n * so the agent can use it as a scratchpad without requesting access every time.\n */\nconst DEFAULT_ALLOWED_PATHS: string[] = [os.tmpdir(), '/tmp', getPlansDir()].reduce<string[]>((acc, p) => {\n const resolved = path.resolve(p);\n if (!acc.includes(resolved)) acc.push(resolved);\n return acc;\n}, []);\n\nconst WORKSPACE_ID_PREFIX = 'mastra-code-workspace';\n\n/**\n * Detect the project's package runner from lock files.\n * Used as a fallback packageRunner for LSP when no binary is found locally or on PATH.\n */\nfunction detectPackageRunner(projectPath: string): string | undefined {\n if (existsSync(join(projectPath, 'pnpm-lock.yaml'))) return 'pnpm dlx';\n if (existsSync(join(projectPath, 'bun.lockb')) || existsSync(join(projectPath, 'bun.lock'))) return 'bunx';\n if (existsSync(join(projectPath, 'yarn.lock'))) return 'yarn dlx';\n if (existsSync(join(projectPath, 'package-lock.json'))) return 'npx --yes';\n return 'npx --yes';\n}\n\n/**\n * Build (or reuse) a sandbox-backed Workspace for a GitHub project. The sandbox\n * is reattached by its persisted provider id and a `SandboxFilesystem` is layered\n * over the in-sandbox checkout so file tools and command tools share one VM.\n */\nasync function getSandboxWorkspace({\n githubProjectId,\n sandboxId,\n workdir,\n worktreePath,\n mastra,\n}: {\n githubProjectId: string;\n sandboxId: string;\n workdir: string;\n worktreePath?: string;\n mastra?: Mastra;\n}): Promise<Workspace> {\n // Bind the workspace to the active worktree when one is set, so file tools and\n // command tools operate inside the feature branch's working tree rather than\n // the base checkout. Falls back to the repo root when no worktree is active.\n const boundWorkdir = worktreePath || workdir;\n\n // Include the sandbox id *and* worktree path in the reuse key: a new sandbox\n // (e.g. the previous one expired) or a different worktree must each get a\n // fresh Workspace/ProcessManager instead of reusing one bound to a stale\n // sandbox or the wrong working tree.\n const workspaceId = `${WORKSPACE_ID_PREFIX}-gh-${githubProjectId}-${sandboxId}-${boundWorkdir}`;\n\n // Reuse the existing remote workspace if already registered (preserves the\n // reattached sandbox + ProcessManager state across re-opens).\n try {\n const existing = mastra?.getWorkspaceById(workspaceId) as Workspace | undefined;\n if (existing) {\n existing.setToolsConfig(MASTRACODE_WORKSPACE_TOOLS);\n return existing;\n }\n } catch {\n // Not registered yet.\n }\n\n const sandbox = await reattachProjectSandbox(sandboxId);\n const filesystem = new SandboxFilesystem({ sandbox, workdir: boundWorkdir });\n\n return new Workspace({\n id: workspaceId,\n name: 'Mastra Code Sandbox Workspace',\n filesystem,\n sandbox: sandbox as unknown as ConstructorParameters<typeof Workspace>[0]['sandbox'],\n tools: MASTRACODE_WORKSPACE_TOOLS,\n });\n}\n\nexport async function getDynamicWorkspace({\n requestContext,\n mastra,\n}: {\n requestContext: RequestContext;\n mastra?: Mastra;\n}) {\n const ctx = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n const state = ctx?.getState();\n\n // GitHub/cloud-sandbox-backed project: the repo lives inside a remote sandbox,\n // not on the server host. Reattach to the already-provisioned + materialized\n // sandbox (the SPA called `.../ensure` first, persisting sandboxId/workdir on\n // controller state) and build a sandbox-backed Workspace. LSP/host skill paths\n // are skipped for these workspaces (follow-up).\n if (state?.githubProjectId && state.sandboxId && state.sandboxWorkdir) {\n return getSandboxWorkspace({\n githubProjectId: state.githubProjectId,\n sandboxId: state.sandboxId,\n workdir: state.sandboxWorkdir,\n worktreePath: state.worktreePath,\n mastra,\n });\n }\n\n const rawProjectPath = state?.projectPath;\n\n if (!rawProjectPath) {\n throw new Error('Project path is required');\n }\n\n const projectPath = path.resolve(rawProjectPath);\n const configDir = state?.configDir ?? DEFAULT_CONFIG_DIR;\n const skillPaths = buildSkillPaths(projectPath, configDir, state?.homeDir, state?.pluginSkillPaths ?? []);\n const workspaceId = `${WORKSPACE_ID_PREFIX}-${projectPath}`;\n const sandboxPaths = state?.sandboxAllowedPaths ?? [];\n const allowedPaths = [...skillPaths, ...DEFAULT_ALLOWED_PATHS, ...sandboxPaths.map((p: string) => path.resolve(p))];\n\n // All modes share the same workspace tool configuration. Per-mode tool\n // visibility is enforced at LLM-call time via `availableTools` /\n // `activeTools` on the AgentController, not by mutating workspace capabilities.\n const workspaceTools = MASTRACODE_WORKSPACE_TOOLS;\n\n // Reuse existing workspace if already registered (preserves ProcessManager state)\n let existing: Workspace<LocalFilesystem, LocalSandbox> | undefined;\n try {\n existing = mastra?.getWorkspaceById(workspaceId) as Workspace<LocalFilesystem, LocalSandbox>;\n } catch {\n // Not registered yet\n }\n\n if (existing) {\n existing.filesystem.setAllowedPaths(allowedPaths);\n existing.setToolsConfig(workspaceTools);\n return existing;\n }\n\n const userLsp = loadSettings().lsp ?? {};\n const mcModulePath = join(dirname(fileURLToPath(import.meta.url)), '..');\n const lspConfig: LSPConfig = {\n ...userLsp,\n packageRunner: userLsp.packageRunner || detectPackageRunner(projectPath), // Detected runner is the fallback — user's packageRunner always wins\n searchPaths: [mcModulePath, ...(userLsp.searchPaths ?? [])],\n };\n\n // First call for this project — create the workspace\n return new Workspace({\n id: workspaceId,\n name: 'Mastra Code Workspace',\n filesystem: new LocalFilesystem({\n basePath: projectPath,\n allowedPaths,\n }),\n sandbox: new LocalSandbox({\n workingDirectory: projectPath,\n env: buildSandboxEnv(),\n }),\n tools: workspaceTools,\n ...(skillPaths.length > 0 ? { skills: skillPaths } : {}),\n lsp: lspConfig,\n });\n}\n\n/**\n * Resolver for the agent's `goal.tools` config. Builds the request's workspace\n * (same per-request resolution as the agent's own tools) and returns only the\n * read-only verification subset, remapped to mastracode's tool names (`view`,\n * `search_content`, etc.). Returns `undefined` when no workspace can be resolved\n * (e.g. no project path), keeping the default judge text-only rather than\n * throwing inside the goal step.\n */\nexport async function getGoalJudgeTools({\n requestContext,\n mastra,\n}: {\n requestContext: RequestContext;\n mastra?: Mastra;\n}): Promise<ToolsInput | undefined> {\n let workspace: Workspace;\n try {\n workspace = await getDynamicWorkspace({ requestContext, mastra });\n } catch {\n return undefined;\n }\n\n const allTools = await createWorkspaceTools(workspace, { requestContext, workspace });\n const readonly: ToolsInput = {};\n for (const name of GOAL_JUDGE_READONLY_TOOLS) {\n if (allTools[name]) readonly[name] = allTools[name];\n }\n return Object.keys(readonly).length > 0 ? readonly : undefined;\n}\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -43,7 +43,7 @@ import { createMcpManager } from "./mcp/index.js";
43
43
  import { getAvailableModePacks, getAvailableOmPacks } from "./onboarding/packs.js";
44
44
  import {
45
45
  loadSettings,
46
- MEMORY_GATEWAY_PROVIDER,
46
+ MASTRA_GATEWAY_PROVIDER,
47
47
  OBSERVABILITY_AUTH_PREFIX,
48
48
  resolveModelDefaults,
49
49
  resolveOmRoleModel,
@@ -141,7 +141,7 @@ async function createMastraCodeAgentController(config) {
141
141
  }
142
142
  const authStorage = createAuthStorage();
143
143
  const globalSettings = loadSettings(config?.settingsPath);
144
- const storedGatewayKey = authStorage.getStoredApiKey(MEMORY_GATEWAY_PROVIDER);
144
+ const storedGatewayKey = authStorage.getStoredApiKey(MASTRA_GATEWAY_PROVIDER);
145
145
  const storedGatewayUrl = globalSettings.memoryGateway?.baseUrl;
146
146
  if (storedGatewayKey) {
147
147
  process.env["MASTRA_GATEWAY_API_KEY"] ??= storedGatewayKey;
@@ -156,11 +156,11 @@ async function createMastraCodeAgentController(config) {
156
156
  const envVars = cfg?.apiKeyEnvVar;
157
157
  providerEnvVars[provider] = Array.isArray(envVars) ? envVars[0] : envVars;
158
158
  }
159
- providerEnvVars[MEMORY_GATEWAY_PROVIDER] ??= "MASTRA_GATEWAY_API_KEY";
159
+ providerEnvVars[MASTRA_GATEWAY_PROVIDER] ??= "MASTRA_GATEWAY_API_KEY";
160
160
  authStorage.loadStoredApiKeysIntoEnv(providerEnvVars);
161
161
  } catch {
162
162
  authStorage.loadStoredApiKeysIntoEnv({
163
- [MEMORY_GATEWAY_PROVIDER]: "MASTRA_GATEWAY_API_KEY",
163
+ [MASTRA_GATEWAY_PROVIDER]: "MASTRA_GATEWAY_API_KEY",
164
164
  anthropic: "ANTHROPIC_API_KEY",
165
165
  openai: "OPENAI_API_KEY",
166
166
  google: "GOOGLE_GENERATIVE_AI_API_KEY",