@mastra/code-sdk 0.2.0-alpha.4 → 0.2.0-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/dist/agents/credential-resolver.d.ts +51 -0
  3. package/dist/agents/credential-resolver.d.ts.map +1 -0
  4. package/dist/agents/credential-resolver.js +41 -0
  5. package/dist/agents/credential-resolver.js.map +1 -0
  6. package/dist/agents/instructions.d.ts.map +1 -1
  7. package/dist/agents/instructions.js.map +1 -1
  8. package/dist/agents/mastracode-gateway.d.ts +11 -4
  9. package/dist/agents/mastracode-gateway.d.ts.map +1 -1
  10. package/dist/agents/mastracode-gateway.js +51 -30
  11. package/dist/agents/mastracode-gateway.js.map +1 -1
  12. package/dist/agents/model.d.ts +2 -0
  13. package/dist/agents/model.d.ts.map +1 -1
  14. package/dist/agents/model.js +13 -2
  15. package/dist/agents/model.js.map +1 -1
  16. package/dist/agents/workspace.d.ts +11 -1
  17. package/dist/agents/workspace.d.ts.map +1 -1
  18. package/dist/agents/workspace.js +31 -13
  19. package/dist/agents/workspace.js.map +1 -1
  20. package/dist/auth/authorization-input.d.ts +16 -0
  21. package/dist/auth/authorization-input.d.ts.map +1 -0
  22. package/dist/auth/authorization-input.js +28 -0
  23. package/dist/auth/authorization-input.js.map +1 -0
  24. package/dist/auth/device-code.d.ts +93 -0
  25. package/dist/auth/device-code.d.ts.map +1 -0
  26. package/dist/auth/device-code.js +97 -0
  27. package/dist/auth/device-code.js.map +1 -0
  28. package/dist/auth/index.d.ts +1 -0
  29. package/dist/auth/index.d.ts.map +1 -1
  30. package/dist/auth/index.js +3 -1
  31. package/dist/auth/index.js.map +1 -1
  32. package/dist/auth/providers/anthropic.d.ts +24 -1
  33. package/dist/auth/providers/anthropic.d.ts.map +1 -1
  34. package/dist/auth/providers/anthropic.js +21 -8
  35. package/dist/auth/providers/anthropic.js.map +1 -1
  36. package/dist/auth/providers/github-copilot.d.ts +54 -0
  37. package/dist/auth/providers/github-copilot.d.ts.map +1 -1
  38. package/dist/auth/providers/github-copilot.js +88 -61
  39. package/dist/auth/providers/github-copilot.js.map +1 -1
  40. package/dist/auth/providers/openai-codex.d.ts +44 -0
  41. package/dist/auth/providers/openai-codex.d.ts.map +1 -1
  42. package/dist/auth/providers/openai-codex.js +79 -69
  43. package/dist/auth/providers/openai-codex.js.map +1 -1
  44. package/dist/auth/providers/xai.d.ts +64 -0
  45. package/dist/auth/providers/xai.d.ts.map +1 -0
  46. package/dist/auth/providers/xai.js +171 -0
  47. package/dist/auth/providers/xai.js.map +1 -0
  48. package/dist/auth/storage.d.ts.map +1 -1
  49. package/dist/auth/storage.js +5 -2
  50. package/dist/auth/storage.js.map +1 -1
  51. package/dist/auth/types.d.ts +21 -0
  52. package/dist/auth/types.d.ts.map +1 -1
  53. package/dist/hooks/types.d.ts.map +1 -1
  54. package/dist/hooks/types.js.map +1 -1
  55. package/dist/index.d.ts +12 -11
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +49 -35
  58. package/dist/index.js.map +1 -1
  59. package/dist/providers/amazon-bedrock-gateway.d.ts +7 -0
  60. package/dist/providers/amazon-bedrock-gateway.d.ts.map +1 -1
  61. package/dist/providers/amazon-bedrock-gateway.js +66 -2
  62. package/dist/providers/amazon-bedrock-gateway.js.map +1 -1
  63. package/dist/providers/claude-max.d.ts +3 -1
  64. package/dist/providers/claude-max.d.ts.map +1 -1
  65. package/dist/providers/claude-max.js +1 -1
  66. package/dist/providers/claude-max.js.map +1 -1
  67. package/dist/providers/github-copilot.d.ts +3 -1
  68. package/dist/providers/github-copilot.d.ts.map +1 -1
  69. package/dist/providers/github-copilot.js +1 -1
  70. package/dist/providers/github-copilot.js.map +1 -1
  71. package/dist/providers/openai-codex.d.ts +3 -1
  72. package/dist/providers/openai-codex.d.ts.map +1 -1
  73. package/dist/providers/openai-codex.js +1 -1
  74. package/dist/providers/openai-codex.js.map +1 -1
  75. package/dist/providers/xai.d.ts +33 -0
  76. package/dist/providers/xai.d.ts.map +1 -0
  77. package/dist/providers/xai.js +63 -0
  78. package/dist/providers/xai.js.map +1 -0
  79. package/dist/tools/request-sandbox-access.d.ts.map +1 -1
  80. package/dist/tools/request-sandbox-access.js.map +1 -1
  81. package/package.json +11 -11
@@ -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, 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":[]}
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 type { CredentialStore } from '../auth/types.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';\nimport { xaiProvider } from '../providers/xai.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 * Per-tenant credential source for this gateway instance. Defaults to the\n * server-global file-backed `AuthStorage`; deployed web passes the calling\n * tenant's store so model calls use the caller's own credentials.\n */\n credentialStore?: CredentialStore;\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(credentials: CredentialStore = authStorage): string | undefined {\n const storedCred = credentials.get('anthropic');\n if (storedCred?.type === 'api_key' && storedCred.key.trim().length > 0) {\n return storedCred.key.trim();\n }\n const dedicatedKey = credentials.getStoredApiKey('anthropic')?.trim();\n if (dedicatedKey) return dedicatedKey;\n return credentials.allowEnvironmentFallback === false\n ? undefined\n : 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(credentials: CredentialStore = authStorage): string | undefined {\n const storedCred = credentials.get('openai-codex');\n if (storedCred?.type === 'api_key' && storedCred.key.trim().length > 0) {\n return storedCred.key.trim();\n }\n const dedicatedKey = credentials.getStoredApiKey('openai-codex')?.trim();\n if (dedicatedKey) return dedicatedKey;\n return credentials.allowEnvironmentFallback === false ? undefined : 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, credentials: CredentialStore = authStorage): string | undefined {\n const authProviderId = getAuthProviderId(providerId);\n const storedCred = credentials.get(authProviderId);\n if (storedCred?.type === 'api_key' && storedCred.key.trim().length > 0) {\n return storedCred.key.trim();\n }\n return credentials.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 readonly #credentials: CredentialStore;\n\n constructor({\n mastraGatewayBaseUrl,\n mastraGatewayApiKey,\n routeThroughMastraGateway,\n thinkingLevel,\n customProviders,\n settingsPath,\n credentialStore,\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 this.#credentials = credentialStore ?? authStorage;\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(\n request: GatewayAuthRequest,\n mastraGatewayApiKey?: string,\n credentials: CredentialStore = authStorage,\n ): GatewayAuthResult | undefined {\n if (request.gatewayId === 'mastra' && mastraGatewayApiKey) {\n return { apiKey: mastraGatewayApiKey, source: 'gateway' };\n }\n\n const storedCred = credentials.get(getAuthProviderId(request.providerId));\n if (storedCred?.type === 'oauth') {\n return { bearerToken: 'oauth', source: 'gateway' };\n }\n\n const apiKey = getProviderAuthKey(request.providerId, credentials);\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, this.#credentials) ?? '') : '';\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, undefined, this.#credentials);\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, {\n headers: args.headers,\n authStorage: this.#credentials,\n }) as unknown as GatewayLanguageModel;\n }\n\n if (args.providerId === 'moonshotai') {\n // Prefer the gateway-resolved key (stored credentials), then the canonical\n // registry env var. Keep the legacy typo name as a fallback for anyone who\n // set it because of the previous error message.\n const apiKey =\n args.apiKey?.trim() || process.env.MOONSHOT_API_KEY?.trim() || process.env.MOONSHOT_AI_API_KEY?.trim();\n if (!apiKey) {\n throw new Error('Need MOONSHOT_API_KEY');\n }\n return createAnthropic({\n apiKey,\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 (args.providerId === 'xai' && this.#credentials.get('xai')?.type === 'oauth') {\n return xaiProvider(args.modelId, {\n headers: args.headers,\n authStorage: this.#credentials,\n }) as unknown as GatewayLanguageModel;\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 = this.#credentials.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: this.#credentials }) 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, {\n headers: args.headers,\n authStorage: this.#credentials,\n }) 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(this.#credentials);\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, {\n headers: args.headers,\n authStorage: this.#credentials,\n }) 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 = this.#credentials.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: this.#credentials, 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 authStorage: this.#credentials,\n }) as unknown as GatewayLanguageModel;\n }\n\n const apiKey = getOpenAIApiKey(this.#credentials);\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":[]}
@@ -5,6 +5,8 @@ import { MastraCodeGateway } from './mastracode-gateway.js';
5
5
  import type { MastraCodeGatewayOptions } from './mastracode-gateway.js';
6
6
  export { getAnthropicApiKey, getOpenAIApiKey, MASTRACODE_GATEWAY_ID, MastraCodeGateway, remapOpenAIModelForCodexOAuth, resolveAuth, } from './mastracode-gateway.js';
7
7
  export type { MastraCodeCustomProvider, MastraCodeGatewayOptions } from './mastracode-gateway.js';
8
+ export { setCredentialStoreProvider, hasCredentialStoreProvider, resolveTenantFromRequestContext, } from './credential-resolver.js';
9
+ export type { CredentialTenant, CredentialStoreProvider } from './credential-resolver.js';
8
10
  type ResolvedModel = GatewayLanguageModel;
9
11
  export declare function createMastraCodeGateway(options: MastraCodeGatewayOptions): MastraCodeGateway;
10
12
  export declare function createMastraCodeModelCatalogProvider(gateway: MastraModelGatewayInterface): import("@mastra/core/harness").CustomModelCatalogProvider;
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/agents/model.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAGL,iBAAiB,EAGlB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAExE,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,6BAA6B,EAC7B,WAAW,GACZ,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAElG,KAAK,aAAa,GAAG,oBAAoB,CAAC;AAa1C,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB,CAE5F;AAED,wBAAgB,oCAAoC,CAAC,OAAO,EAAE,2BAA2B,6DAIxF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,aAAa,CAAC;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,cAAc,CAAA;CAAE,GACzG,oBAAoB,CA+DtB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,cAAc,EAAE,EAAE;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,GAAG,aAAa,CAWrG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,cAAc,EAAE,EAAE;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,EACtD,YAAY,CAAC,EAAE,MAAM,GACpB,aAAa,GAAG,SAAS,CAI3B"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/agents/model.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,EAGL,iBAAiB,EAGlB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAExE,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,6BAA6B,EAC7B,WAAW,GACZ,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,+BAA+B,GAChC,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAE1F,KAAK,aAAa,GAAG,oBAAoB,CAAC;AAa1C,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB,CAE5F;AAED,wBAAgB,oCAAoC,CAAC,OAAO,EAAE,2BAA2B,6DAIxF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,aAAa,CAAC;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,cAAc,CAAA;CAAE,GACzG,oBAAoB,CAoEtB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,cAAc,EAAE,EAAE;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,GAAG,aAAa,CAWrG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,cAAc,EAAE,EAAE;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,EACtD,YAAY,CAAC,EAAE,MAAM,GACpB,aAAa,GAAG,SAAS,CAI3B"}
@@ -1,5 +1,6 @@
1
1
  import { loadSettings } from "../onboarding/settings.js";
2
2
  import { AMAZON_BEDROCK_GATEWAY_ID, createAmazonBedrockGateway } from "../providers/amazon-bedrock-gateway.js";
3
+ import { resolveCredentialStore } from "./credential-resolver.js";
3
4
  import {
4
5
  MASTRA_GATEWAY_PREFIX,
5
6
  MASTRACODE_GATEWAY_ID,
@@ -15,6 +16,11 @@ import {
15
16
  remapOpenAIModelForCodexOAuth,
16
17
  resolveAuth
17
18
  } from "./mastracode-gateway.js";
19
+ import {
20
+ setCredentialStoreProvider,
21
+ hasCredentialStoreProvider,
22
+ resolveTenantFromRequestContext
23
+ } from "./credential-resolver.js";
18
24
  function getAgentControllerHeaders(requestContext) {
19
25
  const agentControllerContext = requestContext?.get("controller");
20
26
  const headers = {
@@ -64,12 +70,14 @@ function resolveModel(modelId, options) {
64
70
  const routerId = `${MASTRACODE_GATEWAY_ID}/${normalizedModelId}`;
65
71
  const mgApiKey = MastraCodeGateway.getMastraGatewayApiKey();
66
72
  const rawGatewayBase = settings.memoryGateway?.baseUrl ?? process.env["MASTRA_GATEWAY_URL"] ?? "https://gateway-api.mastra.ai";
73
+ const credentialStore = resolveCredentialStore(options?.requestContext);
67
74
  const gateway = createMastraCodeGateway({
68
75
  mastraGatewayBaseUrl: rawGatewayBase.replace(/\/+$/, "").replace(/\/v1$/, ""),
69
76
  mastraGatewayApiKey: mgApiKey,
70
77
  routeThroughMastraGateway: Boolean(mgApiKey && isMastraGatewayModel),
71
78
  thinkingLevel: options?.thinkingLevel,
72
- customProviders: settings.customProviders
79
+ customProviders: settings.customProviders,
80
+ credentialStore
73
81
  });
74
82
  const auth = gateway.resolveAuth({
75
83
  gatewayId: MASTRACODE_GATEWAY_ID,
@@ -107,9 +115,12 @@ export {
107
115
  getDynamicModel,
108
116
  getGoalJudgeModel,
109
117
  getOpenAIApiKey,
118
+ hasCredentialStoreProvider,
110
119
  remapOpenAIModelForCodexOAuth,
111
120
  resolveAuth,
112
121
  resolveModel,
113
- resolveModelId
122
+ resolveModelId,
123
+ resolveTenantFromRequestContext,
124
+ setCredentialStoreProvider
114
125
  };
115
126
  //# sourceMappingURL=model.js.map
@@ -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.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
+ {"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 { resolveCredentialStore } from './credential-resolver.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';\nexport {\n setCredentialStoreProvider,\n hasCredentialStoreProvider,\n resolveTenantFromRequestContext,\n} from './credential-resolver.js';\nexport type { CredentialTenant, CredentialStoreProvider } from './credential-resolver.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 // Deployed web registers a per-tenant credential store provider; when the\n // request carries an authenticated tenant, resolve credentials through the\n // caller's own store (user > org > env). Undefined = global AuthStorage.\n const credentialStore = resolveCredentialStore(options?.requestContext);\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 credentialStore,\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"]}
@@ -2,10 +2,20 @@ import type { ToolsInput } from '@mastra/core/agent';
2
2
  import type { Mastra } from '@mastra/core/mastra';
3
3
  import type { RequestContext } from '@mastra/core/request-context';
4
4
  import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace';
5
+ import type { SkillSource } from '@mastra/core/workspace';
5
6
  export declare function buildSkillPaths(projectPath: string, configDir: string, homeDir?: string, pluginSkillPaths?: string[]): string[];
6
- export declare function getDynamicWorkspace({ requestContext, mastra, }: {
7
+ export interface WorkspaceSkillExtension {
8
+ /** Distinguishes extended workspaces from the default resolver cache. */
9
+ id: string;
10
+ /** Additional read-only skill roots prepended to normal project/global skill roots. */
11
+ paths: string[];
12
+ /** Compose the additional roots with the workspace's normal skill source. */
13
+ createSource: (fallback: SkillSource, fallbackSkillRoots: string[]) => SkillSource;
14
+ }
15
+ export declare function getDynamicWorkspace({ requestContext, mastra, skillExtension, }: {
7
16
  requestContext: RequestContext;
8
17
  mastra?: Mastra;
18
+ skillExtension?: WorkspaceSkillExtension;
9
19
  }): Promise<Workspace<import("@mastra/core/workspace").WorkspaceFilesystem | undefined, import("@mastra/core/workspace").WorkspaceSandbox | undefined, undefined> | Workspace<LocalFilesystem, LocalSandbox, undefined>>;
10
20
  /**
11
21
  * Resolver for the agent's `goal.tools` config. Builds the request's workspace
@@ -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;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"}
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;AACxG,OAAO,KAAK,EAAa,WAAW,EAAE,MAAM,wBAAwB,CAAC;AA0GrE,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,SAAe,EACtB,gBAAgB,GAAE,MAAM,EAAO,GAC9B,MAAM,EAAE,CA0BV;AAED,MAAM,WAAW,uBAAuB;IACtC,yEAAyE;IACzE,EAAE,EAAE,MAAM,CAAC;IACX,uFAAuF;IACvF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,6EAA6E;IAC7E,YAAY,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,EAAE,KAAK,WAAW,CAAC;CACpF;AAyFD,wBAAsB,mBAAmB,CAAC,EACxC,cAAc,EACd,MAAM,EACN,cAAc,GACf,EAAE;IACD,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,uBAAuB,CAAC;CAC1C,wNAqFA;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"}
@@ -119,10 +119,13 @@ async function getSandboxWorkspace({
119
119
  sandboxId,
120
120
  workdir,
121
121
  worktreePath,
122
- mastra
122
+ configDir,
123
+ mastra,
124
+ skillExtension
123
125
  }) {
124
126
  const boundWorkdir = worktreePath || workdir;
125
- const workspaceId = `${WORKSPACE_ID_PREFIX}-gh-${githubProjectId}-${sandboxId}-${boundWorkdir}`;
127
+ const extensionId = skillExtension ? `-${skillExtension.id}` : "";
128
+ const workspaceId = `${WORKSPACE_ID_PREFIX}-gh-${githubProjectId}-${sandboxId}-${boundWorkdir}${extensionId}`;
126
129
  try {
127
130
  const existing = mastra?.getWorkspaceById(workspaceId);
128
131
  if (existing) {
@@ -133,17 +136,22 @@ async function getSandboxWorkspace({
133
136
  }
134
137
  const sandbox = await reattachProjectSandbox(sandboxId);
135
138
  const filesystem = new SandboxFilesystem({ sandbox, workdir: boundWorkdir });
139
+ const projectSkillPaths = [path.join(configDir, "skills"), ".claude/skills", ".agents/skills"];
140
+ const skillPaths = [...skillExtension?.paths ?? [], ...projectSkillPaths];
136
141
  return new Workspace({
137
142
  id: workspaceId,
138
143
  name: "Mastra Code Sandbox Workspace",
139
144
  filesystem,
140
145
  sandbox,
141
- tools: MASTRACODE_WORKSPACE_TOOLS
146
+ tools: MASTRACODE_WORKSPACE_TOOLS,
147
+ skills: skillPaths,
148
+ skillSource: skillExtension?.createSource(filesystem, projectSkillPaths) ?? filesystem
142
149
  });
143
150
  }
144
151
  async function getDynamicWorkspace({
145
152
  requestContext,
146
- mastra
153
+ mastra,
154
+ skillExtension
147
155
  }) {
148
156
  const ctx = requestContext.get("controller");
149
157
  const state = ctx?.getState();
@@ -153,7 +161,9 @@ async function getDynamicWorkspace({
153
161
  sandboxId: state.sandboxId,
154
162
  workdir: state.sandboxWorkdir,
155
163
  worktreePath: state.worktreePath,
156
- mastra
164
+ configDir: state.configDir ?? DEFAULT_CONFIG_DIR,
165
+ mastra,
166
+ skillExtension
157
167
  });
158
168
  }
159
169
  const rawProjectPath = state?.projectPath;
@@ -162,10 +172,16 @@ async function getDynamicWorkspace({
162
172
  }
163
173
  const projectPath = path.resolve(rawProjectPath);
164
174
  const configDir = state?.configDir ?? DEFAULT_CONFIG_DIR;
165
- const skillPaths = buildSkillPaths(projectPath, configDir, state?.homeDir, state?.pluginSkillPaths ?? []);
166
- const workspaceId = `${WORKSPACE_ID_PREFIX}-${projectPath}`;
175
+ const projectSkillPaths = buildSkillPaths(projectPath, configDir, state?.homeDir, state?.pluginSkillPaths ?? []);
176
+ const skillPaths = [...skillExtension?.paths ?? [], ...projectSkillPaths];
177
+ const extensionId = skillExtension ? `-${skillExtension.id}` : "";
178
+ const workspaceId = `${WORKSPACE_ID_PREFIX}-${projectPath}${extensionId}`;
167
179
  const sandboxPaths = state?.sandboxAllowedPaths ?? [];
168
- const allowedPaths = [...skillPaths, ...DEFAULT_ALLOWED_PATHS, ...sandboxPaths.map((p) => path.resolve(p))];
180
+ const allowedPaths = [
181
+ ...projectSkillPaths,
182
+ ...DEFAULT_ALLOWED_PATHS,
183
+ ...sandboxPaths.map((p) => path.resolve(p))
184
+ ];
169
185
  const workspaceTools = MASTRACODE_WORKSPACE_TOOLS;
170
186
  let existing;
171
187
  try {
@@ -185,19 +201,21 @@ async function getDynamicWorkspace({
185
201
  // Detected runner is the fallback — user's packageRunner always wins
186
202
  searchPaths: [mcModulePath, ...userLsp.searchPaths ?? []]
187
203
  };
204
+ const filesystem = new LocalFilesystem({
205
+ basePath: projectPath,
206
+ allowedPaths
207
+ });
188
208
  return new Workspace({
189
209
  id: workspaceId,
190
210
  name: "Mastra Code Workspace",
191
- filesystem: new LocalFilesystem({
192
- basePath: projectPath,
193
- allowedPaths
194
- }),
211
+ filesystem,
195
212
  sandbox: new LocalSandbox({
196
213
  workingDirectory: projectPath,
197
214
  env: buildSandboxEnv()
198
215
  }),
199
216
  tools: workspaceTools,
200
- ...skillPaths.length > 0 ? { skills: skillPaths } : {},
217
+ skills: skillPaths,
218
+ ...skillExtension ? { skillSource: skillExtension.createSource(filesystem, projectSkillPaths) } : {},
201
219
  lsp: lspConfig
202
220
  });
203
221
  }
@@ -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 { 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":[]}
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, SkillSource } 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\nexport interface WorkspaceSkillExtension {\n /** Distinguishes extended workspaces from the default resolver cache. */\n id: string;\n /** Additional read-only skill roots prepended to normal project/global skill roots. */\n paths: string[];\n /** Compose the additional roots with the workspace's normal skill source. */\n createSource: (fallback: SkillSource, fallbackSkillRoots: string[]) => SkillSource;\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 configDir,\n mastra,\n skillExtension,\n}: {\n githubProjectId: string;\n sandboxId: string;\n workdir: string;\n worktreePath?: string;\n configDir: string;\n mastra?: Mastra;\n skillExtension?: WorkspaceSkillExtension;\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 extensionId = skillExtension ? `-${skillExtension.id}` : '';\n const workspaceId = `${WORKSPACE_ID_PREFIX}-gh-${githubProjectId}-${sandboxId}-${boundWorkdir}${extensionId}`;\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 const projectSkillPaths = [path.join(configDir, 'skills'), '.claude/skills', '.agents/skills'];\n const skillPaths = [...(skillExtension?.paths ?? []), ...projectSkillPaths];\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 skills: skillPaths,\n skillSource: skillExtension?.createSource(filesystem, projectSkillPaths) ?? filesystem,\n });\n}\n\nexport async function getDynamicWorkspace({\n requestContext,\n mastra,\n skillExtension,\n}: {\n requestContext: RequestContext;\n mastra?: Mastra;\n skillExtension?: WorkspaceSkillExtension;\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. Optional embedders\n // may add read-only skill roots while project skills remain sandbox-backed.\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 configDir: state.configDir ?? DEFAULT_CONFIG_DIR,\n mastra,\n skillExtension,\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 projectSkillPaths = buildSkillPaths(projectPath, configDir, state?.homeDir, state?.pluginSkillPaths ?? []);\n const skillPaths = [...(skillExtension?.paths ?? []), ...projectSkillPaths];\n const extensionId = skillExtension ? `-${skillExtension.id}` : '';\n const workspaceId = `${WORKSPACE_ID_PREFIX}-${projectPath}${extensionId}`;\n const sandboxPaths = state?.sandboxAllowedPaths ?? [];\n const allowedPaths = [\n ...projectSkillPaths,\n ...DEFAULT_ALLOWED_PATHS,\n ...sandboxPaths.map((p: string) => path.resolve(p)),\n ];\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 const filesystem = new LocalFilesystem({\n basePath: projectPath,\n allowedPaths,\n });\n return new Workspace({\n id: workspaceId,\n name: 'Mastra Code Workspace',\n filesystem,\n sandbox: new LocalSandbox({\n workingDirectory: projectPath,\n env: buildSandboxEnv(),\n }),\n tools: workspaceTools,\n skills: skillPaths,\n ...(skillExtension ? { skillSource: skillExtension.createSource(filesystem, projectSkillPaths) } : {}),\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":[]}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Forgiving parser for user-pasted OAuth authorization input.
3
+ *
4
+ * Accepts, in order of preference:
5
+ * - a full redirect URL (`https://.../callback?code=...&state=...`)
6
+ * - the `code#state` form shown on Anthropic's hosted callback page
7
+ * - a raw query string (`code=...&state=...`)
8
+ * - a bare authorization code
9
+ *
10
+ * Ported from pi-mono's `parseAuthorizationInput`.
11
+ */
12
+ export declare function parseAuthorizationInput(input: string): {
13
+ code?: string;
14
+ state?: string;
15
+ };
16
+ //# sourceMappingURL=authorization-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization-input.d.ts","sourceRoot":"","sources":["../../src/auth/authorization-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CA4BA"}
@@ -0,0 +1,28 @@
1
+ function parseAuthorizationInput(input) {
2
+ const value = input.trim();
3
+ if (!value) return {};
4
+ try {
5
+ const url = new URL(value);
6
+ return {
7
+ code: url.searchParams.get("code") ?? void 0,
8
+ state: url.searchParams.get("state") ?? void 0
9
+ };
10
+ } catch {
11
+ }
12
+ if (value.includes("#")) {
13
+ const [code, state] = value.split("#", 2);
14
+ return { code, state };
15
+ }
16
+ if (value.includes("code=")) {
17
+ const params = new URLSearchParams(value);
18
+ return {
19
+ code: params.get("code") ?? void 0,
20
+ state: params.get("state") ?? void 0
21
+ };
22
+ }
23
+ return { code: value };
24
+ }
25
+ export {
26
+ parseAuthorizationInput
27
+ };
28
+ //# sourceMappingURL=authorization-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/auth/authorization-input.ts"],"sourcesContent":["/**\n * Forgiving parser for user-pasted OAuth authorization input.\n *\n * Accepts, in order of preference:\n * - a full redirect URL (`https://.../callback?code=...&state=...`)\n * - the `code#state` form shown on Anthropic's hosted callback page\n * - a raw query string (`code=...&state=...`)\n * - a bare authorization code\n *\n * Ported from pi-mono's `parseAuthorizationInput`.\n */\nexport function parseAuthorizationInput(input: string): {\n code?: string;\n state?: string;\n} {\n const value = input.trim();\n if (!value) return {};\n\n try {\n const url = new URL(value);\n return {\n code: url.searchParams.get('code') ?? undefined,\n state: url.searchParams.get('state') ?? undefined,\n };\n } catch {\n // not a URL\n }\n\n if (value.includes('#')) {\n const [code, state] = value.split('#', 2);\n return { code, state };\n }\n\n if (value.includes('code=')) {\n const params = new URLSearchParams(value);\n return {\n code: params.get('code') ?? undefined,\n state: params.get('state') ?? undefined,\n };\n }\n\n return { code: value };\n}\n"],"mappings":"AAWO,SAAS,wBAAwB,OAGtC;AACA,QAAM,QAAQ,MAAM,KAAK;AACzB,MAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,KAAK;AACzB,WAAO;AAAA,MACL,MAAM,IAAI,aAAa,IAAI,MAAM,KAAK;AAAA,MACtC,OAAO,IAAI,aAAa,IAAI,OAAO,KAAK;AAAA,IAC1C;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,MAAI,MAAM,SAAS,GAAG,GAAG;AACvB,UAAM,CAAC,MAAM,KAAK,IAAI,MAAM,MAAM,KAAK,CAAC;AACxC,WAAO,EAAE,MAAM,MAAM;AAAA,EACvB;AAEA,MAAI,MAAM,SAAS,OAAO,GAAG;AAC3B,UAAM,SAAS,IAAI,gBAAgB,KAAK;AACxC,WAAO;AAAA,MACL,MAAM,OAAO,IAAI,MAAM,KAAK;AAAA,MAC5B,OAAO,OAAO,IAAI,OAAO,KAAK;AAAA,IAChC;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,MAAM;AACvB;","names":[]}