mastra 1.22.0 → 1.23.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # mastra
2
2
 
3
+ ## 1.23.0-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Improved the default agent harness to use Mastra's built-in web search and web fetch tools across supported model providers. ([#20697](https://github.com/mastra-ai/mastra/pull/20697))
8
+
9
+ - Updated dependencies [[`89200ba`](https://github.com/mastra-ai/mastra/commit/89200bafa05444bb7949b363ce7b743e29867561), [`c950138`](https://github.com/mastra-ai/mastra/commit/c950138e72e4f317a40187e3800588731ab790ce), [`063c8b2`](https://github.com/mastra-ai/mastra/commit/063c8b2eb14e4e5ca021779bc33e8c3c031c8604), [`f4e964c`](https://github.com/mastra-ai/mastra/commit/f4e964cad57057301d6bed5c55bcdd730175b941), [`1f7bbd7`](https://github.com/mastra-ai/mastra/commit/1f7bbd7785a8d230aad02454ecabeb4a0b2cc96f), [`e47ff36`](https://github.com/mastra-ai/mastra/commit/e47ff36945720f4ee4caa09f6e83514d7d188608), [`fb9a6ac`](https://github.com/mastra-ai/mastra/commit/fb9a6ac11c9560518742ece60b49d6b062845fd3), [`fb9a6ac`](https://github.com/mastra-ai/mastra/commit/fb9a6ac11c9560518742ece60b49d6b062845fd3), [`aa2cec8`](https://github.com/mastra-ai/mastra/commit/aa2cec8501f634d51c2f3ebfb3dd3aa7af8d2ca2), [`2adf8eb`](https://github.com/mastra-ai/mastra/commit/2adf8eb4a70ed2b6cff2dd39281496ea0e025fac), [`8264611`](https://github.com/mastra-ai/mastra/commit/8264611510e421b818bc7395dc2ae4d9c2d518b2), [`44fc98b`](https://github.com/mastra-ai/mastra/commit/44fc98b9d1242aa87a3ab44bdce9e9f12c44d8c9), [`0f2ef41`](https://github.com/mastra-ai/mastra/commit/0f2ef4118da022e4f30dac4e9856cc3a8c97671c)]:
10
+ - @mastra/core@1.57.0-alpha.1
11
+ - @mastra/deployer@1.57.0-alpha.1
12
+
13
+ ## 1.22.1-alpha.0
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies [[`c8002da`](https://github.com/mastra-ai/mastra/commit/c8002da7775c468e2965b6ff5f82045450fa8cb9)]:
18
+ - @mastra/core@1.56.1-alpha.0
19
+ - @mastra/deployer@1.56.1-alpha.0
20
+
3
21
  ## 1.22.0
4
22
 
5
23
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/create/create.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAa9D,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,aAAa,EACb,6BAA6B,EAC7B,sBAAsB,EACtB,kBAAkB,EAClB,qBAAqB,EACrB,6BAA6B,EAC7B,mBAAmB,EACpB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAS9G,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,aAAa,EACb,6BAA6B,EAC7B,sBAAsB,EACtB,kBAAkB,EAClB,qBAAqB,EACrB,6BAA6B,EAC7B,mBAAmB,GACpB,CAAC;AACF,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,UAAU,EAAE,uBAAuB,EAAE,CAAC;AAa7F,qBAAa,oBAAqB,SAAQ,KAAK;;CAK9C;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAEpF;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,oBAAoB;;;;EAMvE;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACtD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAqID,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,oBAAoB,EAC7B,YAAY,GAAE,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,mBAAmB,CAAM,GACxE,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,eAAO,MAAM,MAAM,GAAU,MAAM,aAAa,KAAG,OAAO,CAAC,IAAI,CA0Q9D,CAAC"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/create/create.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAa9D,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,aAAa,EACb,6BAA6B,EAC7B,sBAAsB,EACtB,kBAAkB,EAClB,qBAAqB,EACrB,6BAA6B,EAC7B,mBAAmB,EACpB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAS9G,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,aAAa,EACb,6BAA6B,EAC7B,sBAAsB,EACtB,kBAAkB,EAClB,qBAAqB,EACrB,6BAA6B,EAC7B,mBAAmB,GACpB,CAAC;AACF,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,UAAU,EAAE,uBAAuB,EAAE,CAAC;AAa7F,qBAAa,oBAAqB,SAAQ,KAAK;;CAK9C;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAEpF;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,oBAAoB;;;;EAMvE;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACtD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAqID,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,oBAAoB,EAC7B,YAAY,GAAE,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,mBAAmB,CAAM,GACxE,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,eAAO,MAAM,MAAM,GAAU,MAAM,aAAa,KAAG,OAAO,CAAC,IAAI,CAiR9D,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import { B as validateProjectName, F as normalizeCreateCommandOptions, I as parseCreateLLMProvider, L as parseCreateTimeout, M as CREATE_LLM_PROVIDERS, N as configureCreateCommand, P as getCreateMode, R as selectMatchingDistTag, z as validateCreateOptionConflicts } from "../../analytics-CzFlN5Uy.js";
2
- import { a as runCreateCommand, i as isCreateCancelledError, n as create, r as getCreateCommandAnalyticsArgs, t as CreateCancelledError } from "../../create-DxtDgme6.js";
2
+ import { a as runCreateCommand, i as isCreateCancelledError, n as create, r as getCreateCommandAnalyticsArgs, t as CreateCancelledError } from "../../create-fMweiYxb.js";
3
3
  export { CREATE_LLM_PROVIDERS, CreateCancelledError, configureCreateCommand, create, getCreateCommandAnalyticsArgs, getCreateMode, isCreateCancelledError, normalizeCreateCommandOptions, parseCreateLLMProvider, parseCreateTimeout, runCreateCommand, selectMatchingDistTag, validateCreateOptionConflicts, validateProjectName };
@@ -2,20 +2,15 @@ import type { PackageManager } from '../../utils/package-manager.js';
2
2
  import type { CreateLLMProvider } from './command.js';
3
3
  export interface ManagedProviderConfig {
4
4
  displayName: string;
5
- sdkPackage: string;
6
- sdkVersion?: string;
7
- providerIdentifier: string;
8
5
  primaryModel?: string;
9
6
  observationalModel?: string;
10
7
  apiKeyEnv: string;
11
- apiKeyPrerequisite: string;
12
- featureDescription: string;
13
- webSearchEntry?: string;
14
- }
15
- interface ResolvedManagedProviderConfig extends ManagedProviderConfig {
16
- sdkVersion: string;
17
8
  }
18
9
  export declare const MANAGED_PROVIDER_CONFIGS: Record<CreateLLMProvider, ManagedProviderConfig>;
10
+ interface ManagedTemplateAdaptationResult extends ManagedProviderConfig {
11
+ apiKeyWritten: boolean;
12
+ adaptationFailed: boolean;
13
+ }
19
14
  export declare function adaptDefaultTemplate({ projectPath, projectName, packageManager, provider, apiKey, versionTag, }: {
20
15
  projectPath: string;
21
16
  projectName: string;
@@ -23,6 +18,6 @@ export declare function adaptDefaultTemplate({ projectPath, projectName, package
23
18
  provider: CreateLLMProvider;
24
19
  apiKey?: string;
25
20
  versionTag: string;
26
- }): Promise<ResolvedManagedProviderConfig>;
21
+ }): Promise<ManagedTemplateAdaptationResult>;
27
22
  export {};
28
23
  //# sourceMappingURL=provider-adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider-adapter.d.ts","sourceRoot":"","sources":["../../../src/commands/create/provider-adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAKnD,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,6BAA8B,SAAQ,qBAAqB;IACnE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,CA6CrF,CAAC;AA0OF,wBAAsB,oBAAoB,CAAC,EACzC,WAAW,EACX,WAAW,EACX,cAAc,EACd,QAAQ,EACR,MAAM,EACN,UAAU,GACX,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,6BAA6B,CAAC,CA2DzC"}
1
+ {"version":3,"file":"provider-adapter.d.ts","sourceRoot":"","sources":["../../../src/commands/create/provider-adapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAKnD,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,CAuBrF,CAAC;AAMF,UAAU,+BAAgC,SAAQ,qBAAqB;IACrE,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAgJD,wBAAsB,oBAAoB,CAAC,EACzC,WAAW,EACX,WAAW,EACX,cAAc,EACd,QAAQ,EACR,MAAM,EACN,UAAU,GACX,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,+BAA+B,CAAC,CA+F3C"}
@@ -3,6 +3,7 @@ import { o as platformFetch, r as authHeaders, t as MASTRA_PLATFORM_API_URL } fr
3
3
  import { i as getToken, t as LoginCancelledError } from "./credentials-CE1thn6C.js";
4
4
  import { r as resolveCurrentOrg, t as OrgSelectionCancelledError } from "./orgs-DOhO9kNz.js";
5
5
  import color from "picocolors";
6
+ import { randomUUID } from "crypto";
6
7
  import fs, { constants } from "fs";
7
8
  import path from "path";
8
9
  import fsPromises from "fs/promises";
@@ -536,69 +537,52 @@ async function writeEmptyScaffold({ projectPath, projectName, versionTag, packag
536
537
  const MANAGED_PROVIDER_CONFIGS = {
537
538
  openai: {
538
539
  displayName: "OpenAI",
539
- sdkPackage: "@ai-sdk/openai",
540
- providerIdentifier: "openai",
541
- apiKeyEnv: "OPENAI_API_KEY",
542
- apiKeyPrerequisite: "An OpenAI API key",
543
- featureDescription: "OpenAI web search and direct web page fetching"
540
+ apiKeyEnv: "OPENAI_API_KEY"
544
541
  },
545
542
  anthropic: {
546
543
  displayName: "Anthropic",
547
- sdkPackage: "@ai-sdk/anthropic",
548
- sdkVersion: "^3.0.96",
549
- providerIdentifier: "anthropic",
550
544
  primaryModel: "anthropic/claude-sonnet-5",
551
545
  observationalModel: "anthropic/claude-haiku-4-5",
552
- apiKeyEnv: "ANTHROPIC_API_KEY",
553
- apiKeyPrerequisite: "An Anthropic API key",
554
- featureDescription: "Anthropic web search and direct web page fetching",
555
- webSearchEntry: "anthropic.tools.webSearch_20250305()"
546
+ apiKeyEnv: "ANTHROPIC_API_KEY"
556
547
  },
557
548
  google: {
558
549
  displayName: "Google Gemini",
559
- sdkPackage: "@ai-sdk/google",
560
- sdkVersion: "^3.0.91",
561
- providerIdentifier: "google",
562
550
  primaryModel: "google/gemini-3.5-flash",
563
551
  observationalModel: "google/gemini-3.5-flash",
564
- apiKeyEnv: "GOOGLE_GENERATIVE_AI_API_KEY",
565
- apiKeyPrerequisite: "A Google Gemini API key",
566
- featureDescription: "Google Gemini web search and direct web page fetching",
567
- webSearchEntry: "google.tools.googleSearch({})"
552
+ apiKeyEnv: "GOOGLE_GENERATIVE_AI_API_KEY"
568
553
  },
569
554
  xai: {
570
555
  displayName: "xAI",
571
- sdkPackage: "@ai-sdk/xai",
572
- sdkVersion: "^3.0.106",
573
- providerIdentifier: "xai",
574
556
  primaryModel: "xai/grok-4.3",
575
557
  observationalModel: "xai/grok-4.3",
576
- apiKeyEnv: "XAI_API_KEY",
577
- apiKeyPrerequisite: "An xAI API key",
578
- featureDescription: "xAI web search and direct web page fetching",
579
- webSearchEntry: "xai.tools.webSearch()"
558
+ apiKeyEnv: "XAI_API_KEY"
580
559
  }
581
560
  };
582
- const PROVIDER_SDK_PACKAGES = Object.values(MANAGED_PROVIDER_CONFIGS).map((config) => config.sdkPackage);
583
- const OPENAI_SDK_PACKAGE = "@ai-sdk/openai";
584
561
  const OPENAI_API_KEY = "OPENAI_API_KEY";
585
- const OPENAI_IMPORT = /^import\s*\{\s*openai\s*\}\s*from\s*['"]@ai-sdk\/openai['"];?\s*$/m;
586
- const OPENAI_MODEL = /(\bmodel\s*:\s*['"])openai\/[^'"]+(['"])/g;
587
- const WEB_SEARCH_PROPERTY = /^([ \t]*)web_search\s*:\s*([^\n]+?)(?:,)?\s*$/m;
562
+ const PRIMARY_OPENAI_MODEL = /(\bmodel\s*:\s*['"])openai\/[^'"]+(['"])(?=\s*,?\s*\n\s*defaultOptions\s*:)/g;
563
+ const OBSERVATIONAL_OPENAI_MODEL = /(observationalMemory\s*:\s*\{[^{}]*?\bmodel\s*:\s*['"])openai\/[^'"]+(['"])/g;
588
564
  function findMatches(content, pattern) {
589
565
  const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
590
566
  return [...content.matchAll(new RegExp(pattern.source, flags))];
591
567
  }
592
- function replaceSingleMatch(content, pattern, replacement, description, fileName) {
593
- const matches = findMatches(content, pattern);
594
- if (matches.length !== 1) throw new Error(`Default template compatibility error: expected one ${description} in ${fileName}, found ${matches.length}.`);
595
- if (typeof replacement === "string") return content.replace(pattern, replacement);
596
- return content.replace(pattern, replacement);
568
+ function replaceSingleMatch(content, pattern, replacement) {
569
+ if (findMatches(content, pattern).length !== 1) return {
570
+ applied: false,
571
+ content
572
+ };
573
+ if (typeof replacement === "string") return {
574
+ applied: true,
575
+ content: content.replace(pattern, replacement)
576
+ };
577
+ return {
578
+ applied: true,
579
+ content: content.replace(pattern, replacement)
580
+ };
597
581
  }
598
582
  function getDependencyMap(manifest, section) {
599
583
  const value = manifest[section];
600
584
  if (value === void 0 && section === "devDependencies") return void 0;
601
- if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`Default template compatibility error: package.json has invalid ${section}.`);
585
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
602
586
  return value;
603
587
  }
604
588
  function collectMastraPackages(manifestSource) {
@@ -617,118 +601,155 @@ function collectMastraPackages(manifestSource) {
617
601
  }
618
602
  return [...names];
619
603
  }
620
- function normalizeManagedManifest(content, provider, mastraVersions, fallbackTag) {
604
+ function normalizeManagedManifest(content, mastraVersions, fallbackTag) {
621
605
  let manifest;
622
606
  try {
623
607
  manifest = JSON.parse(content);
624
608
  } catch {
625
- throw new Error("Default template compatibility error: package.json is not valid JSON.");
609
+ return {
610
+ applied: false,
611
+ content
612
+ };
626
613
  }
627
- const dependencySections = [getDependencyMap(manifest, "dependencies"), getDependencyMap(manifest, "devDependencies")].filter((section) => section !== void 0);
628
- const openAiLocations = dependencySections.filter((section) => Object.hasOwn(section, OPENAI_SDK_PACKAGE));
629
- if (openAiLocations.length !== 1) throw new Error(`Default template compatibility error: package.json must contain ${OPENAI_SDK_PACKAGE} in exactly one dependency section.`);
630
- const sourceSection = openAiLocations[0];
631
- const templateOpenAiVersion = sourceSection[OPENAI_SDK_PACKAGE];
632
- if (typeof templateOpenAiVersion !== "string" || templateOpenAiVersion.trim() === "") throw new Error(`Default template compatibility error: package.json must contain a nonempty ${OPENAI_SDK_PACKAGE} version.`);
633
- for (const section of dependencySections) for (const packageName of PROVIDER_SDK_PACKAGES) delete section[packageName];
634
- const sdkVersion = provider.sdkPackage === OPENAI_SDK_PACKAGE ? templateOpenAiVersion : provider.sdkVersion;
635
- if (!sdkVersion) throw new Error(`Default template compatibility error: no SDK version is configured for ${provider.displayName}.`);
636
- sourceSection[provider.sdkPackage] = sdkVersion;
614
+ const dependencies = getDependencyMap(manifest, "dependencies");
615
+ const devDependencies = getDependencyMap(manifest, "devDependencies");
616
+ if (!dependencies || manifest.devDependencies !== void 0 && !devDependencies) return {
617
+ applied: false,
618
+ content
619
+ };
620
+ const dependencySections = [dependencies, devDependencies].filter((section) => section !== void 0);
637
621
  for (const section of dependencySections) for (const packageName of Object.keys(section)) if (packageName === "mastra" || packageName.startsWith("@mastra/")) section[packageName] = mastraVersions?.[packageName] ?? fallbackTag;
638
622
  return {
639
- content: `${JSON.stringify(manifest, null, 2)}\n`,
640
- sdkVersion
623
+ applied: true,
624
+ content: `${JSON.stringify(manifest, null, 2)}\n`
641
625
  };
642
626
  }
643
627
  function adaptAgentSource(source, provider, config) {
644
- if (provider === "openai") return source;
645
- if (!config.primaryModel || !config.observationalModel) throw new Error(`Default template compatibility error: model configuration is missing for ${config.displayName}.`);
646
- let next = replaceSingleMatch(source, OPENAI_IMPORT, `import { ${config.providerIdentifier} } from '${config.sdkPackage}';`, "OpenAI provider import", "src/mastra/agents/agent.ts");
647
- const modelMatches = findMatches(next, OPENAI_MODEL);
648
- if (modelMatches.length !== 2) throw new Error(`Default template compatibility error: expected two OpenAI model assignments in src/mastra/agents/agent.ts, found ${modelMatches.length}.`);
649
- const models = [config.primaryModel, config.observationalModel];
650
- let modelIndex = 0;
651
- next = next.replace(OPENAI_MODEL, (_match, prefix, suffix) => {
652
- return `${prefix}${models[modelIndex++]}${suffix}`;
653
- });
654
- const webSearchMatches = findMatches(next, WEB_SEARCH_PROPERTY);
655
- if (webSearchMatches.length > 1) throw new Error(`Default template compatibility error: expected at most one web_search property in src/mastra/agents/agent.ts, found ${webSearchMatches.length}.`);
656
- if (webSearchMatches.length === 1) {
657
- const match = webSearchMatches[0];
658
- if (!match[2]?.includes("openai.")) throw new Error("Default template compatibility error: the existing web_search property is not owned by the OpenAI template.");
659
- next = next.replace(WEB_SEARCH_PROPERTY, config.webSearchEntry ? `${match[1]}web_search: ${config.webSearchEntry},` : "");
660
- } else if (config.webSearchEntry) next = replaceSingleMatch(next, /^([ \t]*)web_fetch\s*:\s*[^\n]+$/m, (_line, indentation) => `${indentation}web_fetch: webFetchTool,\n${indentation}web_search: ${config.webSearchEntry},`, "web_fetch property used to place web_search", "src/mastra/agents/agent.ts");
661
- return next;
628
+ if (provider === "openai") return {
629
+ applied: true,
630
+ content: source
631
+ };
632
+ if (!config.primaryModel || !config.observationalModel) return {
633
+ applied: false,
634
+ content: source
635
+ };
636
+ if (findMatches(source, PRIMARY_OPENAI_MODEL).length !== 1) return {
637
+ applied: false,
638
+ content: source
639
+ };
640
+ if (findMatches(source, OBSERVATIONAL_OPENAI_MODEL).length !== 1) return {
641
+ applied: false,
642
+ content: source
643
+ };
644
+ return {
645
+ applied: true,
646
+ content: source.replace(PRIMARY_OPENAI_MODEL, `$1${config.primaryModel}$2`).replace(OBSERVATIONAL_OPENAI_MODEL, `$1${config.observationalModel}$2`)
647
+ };
662
648
  }
663
649
  function replaceEnvKey(source, nextKey) {
664
- return replaceSingleMatch(source, new RegExp(`^([ \\t]*)${OPENAI_API_KEY}[ \\t]*=.*$`, "m"), (_line, indentation) => `${indentation}${nextKey}=`, `${OPENAI_API_KEY} assignment`, ".env.example");
650
+ return replaceSingleMatch(source, new RegExp(`^([ \\t]*)${OPENAI_API_KEY}[ \\t]*=.*$`, "m"), (_line, indentation) => `${indentation}${nextKey}=`);
665
651
  }
666
652
  function setEnvValue(source, key, value) {
667
- return replaceSingleMatch(source, new RegExp(`^([ \\t]*)${key}[ \\t]*=.*$`, "m"), (_line, indentation) => `${indentation}${key}=${value}`, `${key} assignment`, ".env");
653
+ return replaceSingleMatch(source, new RegExp(`^([ \\t]*)${key}[ \\t]*=.*$`, "m"), (_line, indentation) => `${indentation}${key}=${value}`);
668
654
  }
669
655
  function adaptReadme(source, provider, config, projectName, packageManager) {
670
- return source.replace(/^# .+$/m, `# ${projectName}`).replaceAll("npm run dev", `${packageManager} run dev`).replace(/^- .*OpenAI web search.*$/m, `- ${config.featureDescription}`).replace(/^- .*OpenAI API key.*$/m, `- ${config.apiKeyPrerequisite}`).replace(/^([ \t]*)npx create-mastra@\S+.*$/m, `$1npx create-mastra@latest <project-name> --llm ${provider}`).replaceAll(OPENAI_API_KEY, config.apiKeyEnv);
656
+ if (!(source.includes(OPENAI_API_KEY) || /^([ \t]*)npx create-mastra@\S+.*$/m.test(source))) return {
657
+ applied: false,
658
+ content: source
659
+ };
660
+ return {
661
+ applied: true,
662
+ content: source.replace(/^# .+$/m, `# ${projectName}`).replaceAll("npm run dev", `${packageManager} run dev`).replace(/^([ \t]*)npx create-mastra@\S+.*$/m, `$1npx create-mastra@latest <project-name> --llm ${provider}`).replaceAll(OPENAI_API_KEY, config.apiKeyEnv)
663
+ };
671
664
  }
672
- function assertNoProviderResidue(provider, files) {
673
- for (const [otherProvider, config] of Object.entries(MANAGED_PROVIDER_CONFIGS)) {
674
- if (otherProvider === provider) continue;
675
- const checks = [
676
- [files.manifest, config.sdkPackage],
677
- [files.agent, `${config.providerIdentifier}/`],
678
- [files.agent, `${config.providerIdentifier}.tools`],
679
- [files.envExample, config.apiKeyEnv]
680
- ];
681
- if (files.env !== void 0) checks.push([files.env, config.apiKeyEnv]);
682
- for (const [content, residue] of checks) if (content.includes(residue)) throw new Error(`Default template compatibility error: generated project still contains ${JSON.stringify(residue)} from ${config.displayName}.`);
665
+ async function writeSecureEnv(envPath, content) {
666
+ const tempPath = path.join(path.dirname(envPath), `.env.mastra-create-${process.pid}-${randomUUID()}.tmp`);
667
+ try {
668
+ await fsPromises.writeFile(tempPath, content, {
669
+ encoding: "utf8",
670
+ flag: "wx",
671
+ mode: 384
672
+ });
673
+ if (process.platform !== "win32") await fsPromises.chmod(tempPath, 384);
674
+ await fsPromises.rename(tempPath, envPath);
675
+ return true;
676
+ } catch {
677
+ try {
678
+ await fsPromises.rm(tempPath, { force: true });
679
+ } catch {}
680
+ return false;
683
681
  }
684
682
  }
685
683
  async function adaptDefaultTemplate({ projectPath, projectName, packageManager, provider, apiKey, versionTag }) {
686
684
  const config = MANAGED_PROVIDER_CONFIGS[provider];
685
+ let adaptationFailed = false;
686
+ const write = async (filePath, content) => {
687
+ try {
688
+ await fsPromises.writeFile(filePath, content, "utf8");
689
+ return true;
690
+ } catch {
691
+ adaptationFailed = true;
692
+ return false;
693
+ }
694
+ };
687
695
  const agentPath = path.join(projectPath, "src/mastra/agents/agent.ts");
696
+ if (provider !== "openai") try {
697
+ const result = adaptAgentSource(await fsPromises.readFile(agentPath, "utf8"), provider, config);
698
+ if (!result.applied) adaptationFailed = true;
699
+ else await write(agentPath, result.content);
700
+ } catch {
701
+ adaptationFailed = true;
702
+ }
688
703
  const packageJsonPath = path.join(projectPath, "package.json");
704
+ try {
705
+ const source = await fsPromises.readFile(packageJsonPath, "utf8");
706
+ const mastraPackages = collectMastraPackages(source);
707
+ const resolvedVersions = await resolveMastraPackageVersions(mastraPackages, versionTag);
708
+ if (resolvedVersions === void 0 && mastraPackages.length > 0) console.warn(`We could not resolve exact Mastra package versions for the "${versionTag}" channel, using the channel tag instead`);
709
+ const result = normalizeManagedManifest(source, resolvedVersions, versionTag);
710
+ if (!result.applied) adaptationFailed = true;
711
+ else await write(packageJsonPath, result.content);
712
+ } catch {
713
+ adaptationFailed = true;
714
+ }
689
715
  const envExamplePath = path.join(projectPath, ".env.example");
690
716
  const envPath = path.join(projectPath, ".env");
717
+ let adaptedEnvExample;
718
+ try {
719
+ const result = replaceEnvKey(await fsPromises.readFile(envExamplePath, "utf8"), config.apiKeyEnv);
720
+ if (!result.applied) adaptationFailed = true;
721
+ else if (await write(envExamplePath, result.content)) adaptedEnvExample = result.content;
722
+ } catch {
723
+ adaptationFailed = true;
724
+ }
725
+ let apiKeyWritten = false;
726
+ if (adaptedEnvExample === void 0) {
727
+ if (apiKey) adaptationFailed = true;
728
+ } else if (apiKey) {
729
+ const result = setEnvValue(adaptedEnvExample, config.apiKeyEnv, apiKey);
730
+ if (!result.applied) adaptationFailed = true;
731
+ else {
732
+ apiKeyWritten = await writeSecureEnv(envPath, result.content);
733
+ if (!apiKeyWritten) adaptationFailed = true;
734
+ }
735
+ } else try {
736
+ await fsPromises.rm(envPath, { force: true });
737
+ } catch {
738
+ adaptationFailed = true;
739
+ }
691
740
  const readmePath = path.join(projectPath, "README.md");
692
- let agentSource;
693
- let packageJsonSource;
694
- let envExampleSource;
695
741
  try {
696
- [agentSource, packageJsonSource, envExampleSource] = await Promise.all([
697
- fsPromises.readFile(agentPath, "utf8"),
698
- fsPromises.readFile(packageJsonPath, "utf8"),
699
- fsPromises.readFile(envExamplePath, "utf8")
700
- ]);
701
- } catch (error) {
702
- throw new Error(`Default template compatibility error: required template file is missing or unreadable: ${error instanceof Error ? error.message : "Unknown error"}`);
742
+ const result = adaptReadme(await fsPromises.readFile(readmePath, "utf8"), provider, config, projectName, packageManager);
743
+ if (!result.applied) adaptationFailed = true;
744
+ else await write(readmePath, result.content);
745
+ } catch {
746
+ adaptationFailed = true;
703
747
  }
704
- const readmeSource = await fsPromises.readFile(readmePath, "utf8").catch(() => void 0);
705
- const nextAgent = adaptAgentSource(agentSource, provider, config);
706
- const mastraPackages = collectMastraPackages(packageJsonSource);
707
- const resolvedVersions = await resolveMastraPackageVersions(mastraPackages, versionTag);
708
- if (resolvedVersions === void 0 && mastraPackages.length > 0) console.warn(`We could not resolve exact Mastra package versions for the "${versionTag}" channel, using the channel tag instead`);
709
- const normalizedManifest = normalizeManagedManifest(packageJsonSource, config, resolvedVersions, versionTag);
710
- const nextEnvExample = replaceEnvKey(envExampleSource, config.apiKeyEnv);
711
- const nextEnv = apiKey ? setEnvValue(nextEnvExample, config.apiKeyEnv, apiKey) : void 0;
712
- const nextReadme = readmeSource === void 0 ? void 0 : adaptReadme(readmeSource, provider, config, projectName, packageManager);
713
- assertNoProviderResidue(provider, {
714
- agent: nextAgent,
715
- manifest: normalizedManifest.content,
716
- envExample: nextEnvExample,
717
- env: nextEnv
718
- });
719
- const writes = [
720
- fsPromises.writeFile(agentPath, nextAgent, "utf8"),
721
- fsPromises.writeFile(packageJsonPath, normalizedManifest.content, "utf8"),
722
- fsPromises.writeFile(envExamplePath, nextEnvExample, "utf8"),
723
- nextEnv === void 0 ? fsPromises.rm(envPath, { force: true }) : fsPromises.writeFile(envPath, nextEnv, "utf8")
724
- ];
725
- if (nextReadme !== void 0) writes.push(fsPromises.writeFile(readmePath, nextReadme, "utf8"));
726
- if (packageManager === "pnpm") writes.push(fsPromises.writeFile(path.join(projectPath, "pnpm-workspace.yaml"), PNPM_WORKSPACE, "utf8"));
727
- await Promise.all(writes);
728
- if (nextEnv !== void 0 && process.platform !== "win32") await fsPromises.chmod(envPath, 384);
748
+ if (packageManager === "pnpm") await write(path.join(projectPath, "pnpm-workspace.yaml"), PNPM_WORKSPACE);
729
749
  return {
730
750
  ...config,
731
- sdkVersion: normalizedManifest.sdkVersion
751
+ apiKeyWritten,
752
+ adaptationFailed
732
753
  };
733
754
  }
734
755
  //#endregion
@@ -739,7 +760,7 @@ const DEFAULT_TEMPLATE = {
739
760
  slug: "template-agent-harness",
740
761
  agents: ["agent"],
741
762
  mcp: [],
742
- tools: ["web-fetch"],
763
+ tools: [],
743
764
  networks: [],
744
765
  workflows: []
745
766
  };
@@ -959,6 +980,7 @@ const create = async (args) => {
959
980
  process.on("SIGINT", handleSigint);
960
981
  process.on("SIGTERM", handleSigterm);
961
982
  let selectedApiKeyEnv;
983
+ let selectedApiKeyWritten = false;
962
984
  let materializationError;
963
985
  try {
964
986
  if (mode === "empty") {
@@ -981,14 +1003,17 @@ const create = async (args) => {
981
1003
  ...observabilityEnabled ? { silent: true } : {}
982
1004
  });
983
1005
  if (isManaged) {
984
- selectedApiKeyEnv = (await adaptDefaultTemplate({
1006
+ const providerConfig = await adaptDefaultTemplate({
985
1007
  projectPath: staging.projectPath,
986
1008
  projectName,
987
1009
  packageManager,
988
1010
  provider: llmProvider,
989
1011
  apiKey: llmApiKey,
990
1012
  versionTag: versionTag ?? "latest"
991
- })).apiKeyEnv;
1013
+ });
1014
+ selectedApiKeyEnv = providerConfig.apiKeyEnv;
1015
+ selectedApiKeyWritten = providerConfig.apiKeyWritten;
1016
+ if (providerConfig.adaptationFailed) p.log.warn("Some provider setup could not be applied. Review the generated project before running it.");
992
1017
  materializationController.signal.throwIfAborted();
993
1018
  }
994
1019
  }
@@ -1083,7 +1108,7 @@ const create = async (args) => {
1083
1108
  observabilitySummary = `${color.yellow("Could not connect this project to Mastra platform automatically:")} ${message}\n\n${placeholderSummary}1. Visit ${color.cyan("https://projects.mastra.ai")} to create a project and an access token.\n2. Paste the token into ${color.cyan("MASTRA_PLATFORM_ACCESS_TOKEN")} and the project id into ${color.cyan("MASTRA_PROJECT_ID")}.`;
1084
1109
  }
1085
1110
  if (mode === "managed") {
1086
- const apiKeySummary = llmApiKey ? `Your ${selectedApiKeyEnv} value was written to ${color.cyan(".env")}.` : platformEnvWritten ? `Set ${selectedApiKeyEnv} in ${color.cyan(".env")} before starting.` : `Copy ${color.cyan(".env.example")} to ${color.cyan(".env")} and set ${selectedApiKeyEnv} before starting.`;
1111
+ const apiKeySummary = llmApiKey ? selectedApiKeyWritten ? `Your ${selectedApiKeyEnv} value was written to ${color.cyan(".env")}.` : `Set ${selectedApiKeyEnv} in ${color.cyan(".env")} before starting.` : platformEnvWritten ? `Set ${selectedApiKeyEnv} in ${color.cyan(".env")} before starting.` : `Copy ${color.cyan(".env.example")} to ${color.cyan(".env")} and set ${selectedApiKeyEnv} before starting.`;
1087
1112
  p.note(`${color.green("Success!")}\n\n${apiKeySummary}${observabilitySummary ? `\n\n${observabilitySummary}` : ""}`);
1088
1113
  } else if (mode === "template") p.note(`${color.green("Success!")}\n\nCreate a ${color.cyan(".env")} file if the template requires environment variables.`);
1089
1114
  postCreate({
@@ -1263,4 +1288,4 @@ async function resolveTemplate(mode, template) {
1263
1288
  //#endregion
1264
1289
  export { runCreateCommand as a, createLogger as c, isCreateCancelledError as i, logger as l, create as n, installMastraSkills as o, getCreateCommandAnalyticsArgs as r, provisionObservabilityProject as s, CreateCancelledError as t };
1265
1290
 
1266
- //# sourceMappingURL=create-DxtDgme6.js.map
1291
+ //# sourceMappingURL=create-fMweiYxb.js.map