@mastra/agent-builder 0.0.1 → 0.0.2-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import { z } from 'zod';
10
10
  import { existsSync, readFileSync } from 'fs';
11
11
  import { createRequire } from 'module';
12
12
  import { promisify } from 'util';
13
- import { openai as openai$1 } from '@ai-sdk/openai_v5';
13
+ import { openai as openai$1 } from '@ai-sdk/openai-v5';
14
14
  import { MemoryProcessor } from '@mastra/core/memory';
15
15
  import { tmpdir } from 'os';
16
16
  import { openai } from '@ai-sdk/openai';
@@ -34,7 +34,8 @@ var AgentBuilderInputSchema = z.object({
34
34
  repo: z.string().describe("Git URL or local path of the template repo"),
35
35
  ref: z.string().optional().describe("Tag/branch/commit to checkout (defaults to main/master)"),
36
36
  slug: z.string().optional().describe("Slug for branch/scripts; defaults to inferred from repo"),
37
- targetPath: z.string().optional().describe("Project path to merge into; defaults to current directory")
37
+ targetPath: z.string().optional().describe("Project path to merge into; defaults to current directory"),
38
+ variables: z.record(z.string()).optional().describe("Environment variables to set in .env file")
38
39
  });
39
40
  z.object({
40
41
  slug: z.string(),
@@ -64,7 +65,8 @@ var FileCopyInputSchema = z.object({
64
65
  templateDir: z.string(),
65
66
  commitSha: z.string(),
66
67
  slug: z.string(),
67
- targetPath: z.string().optional()
68
+ targetPath: z.string().optional(),
69
+ variables: z.record(z.string()).optional()
68
70
  });
69
71
  var FileCopyResultSchema = z.object({
70
72
  success: z.boolean(),
@@ -100,7 +102,9 @@ var IntelligentMergeResultSchema = z.object({
100
102
  var ValidationResultsSchema = z.object({
101
103
  valid: z.boolean(),
102
104
  errorsFixed: z.number(),
103
- remainingErrors: z.number()
105
+ remainingErrors: z.number(),
106
+ errors: z.array(z.any()).optional()
107
+ // Include specific validation errors
104
108
  });
105
109
  var ValidationFixInputSchema = z.object({
106
110
  commitSha: z.string(),
@@ -148,7 +152,8 @@ var CloneTemplateResultSchema = z.object({
148
152
  commitSha: z.string(),
149
153
  slug: z.string(),
150
154
  success: z.boolean().optional(),
151
- error: z.string().optional()
155
+ error: z.string().optional(),
156
+ targetPath: z.string().optional()
152
157
  });
153
158
  var PackageAnalysisSchema = z.object({
154
159
  name: z.string().optional(),
@@ -493,21 +498,8 @@ async function renameAndCopyFile(sourceFile, targetFile) {
493
498
  console.log(`\u{1F4DD} Copied with unique name: ${basename(uniqueTargetFile)}`);
494
499
  return uniqueTargetFile;
495
500
  }
496
- var resolveModel = (runtimeContext) => {
497
- const modelFromContext = runtimeContext.get("model");
498
- if (modelFromContext) {
499
- console.log(`Using model: ${modelFromContext}`);
500
- if (isValidMastraLanguageModel(modelFromContext)) {
501
- return modelFromContext;
502
- }
503
- throw new Error(
504
- 'Invalid model provided. Model must be a MastraLanguageModel instance (e.g., openai("gpt-4"), anthropic("claude-3-5-sonnet"), etc.)'
505
- );
506
- }
507
- return openai$1("gpt-4.1");
508
- };
509
501
  var isValidMastraLanguageModel = (model) => {
510
- return model && typeof model === "object" && typeof model.modelId === "string" && typeof model.generate === "function";
502
+ return model && typeof model === "object" && typeof model.modelId === "string";
511
503
  };
512
504
  var resolveTargetPath = (inputData, runtimeContext) => {
513
505
  if (inputData.targetPath) {
@@ -529,6 +521,208 @@ var resolveTargetPath = (inputData, runtimeContext) => {
529
521
  }
530
522
  return cwd;
531
523
  };
524
+ var mergeGitignoreFiles = (targetContent, templateContent, templateSlug) => {
525
+ const targetLines = targetContent.replace(/\r\n/g, "\n").split("\n");
526
+ const templateLines = templateContent.replace(/\r\n/g, "\n").split("\n");
527
+ const existingEntries = /* @__PURE__ */ new Set();
528
+ for (const line of targetLines) {
529
+ const trimmed = line.trim();
530
+ if (trimmed && !trimmed.startsWith("#")) {
531
+ const normalized = trimmed.replace(/^\.\//, "").replace(/\\/g, "/");
532
+ existingEntries.add(normalized);
533
+ }
534
+ }
535
+ const newEntries = [];
536
+ for (const line of templateLines) {
537
+ const trimmed = line.trim();
538
+ if (trimmed && !trimmed.startsWith("#")) {
539
+ const normalized = trimmed.replace(/^\.\//, "").replace(/\\/g, "/");
540
+ if (!existingEntries.has(normalized)) {
541
+ const isNegation = normalized.startsWith("!");
542
+ const basePath = isNegation ? normalized.slice(1) : normalized;
543
+ const hasConflict = isNegation ? existingEntries.has(basePath) : existingEntries.has("!" + basePath);
544
+ if (!hasConflict) {
545
+ newEntries.push(trimmed);
546
+ } else {
547
+ console.log(`\u26A0 Skipping conflicting .gitignore rule: ${trimmed} (conflicts with existing rule)`);
548
+ }
549
+ }
550
+ }
551
+ }
552
+ if (newEntries.length === 0) {
553
+ return targetContent;
554
+ }
555
+ const result = [...targetLines];
556
+ const lastLine = result[result.length - 1];
557
+ if (result.length > 0 && lastLine && lastLine.trim() !== "") {
558
+ result.push("");
559
+ }
560
+ result.push(`# Added by template: ${templateSlug}`);
561
+ result.push(...newEntries);
562
+ return result.join("\n");
563
+ };
564
+ var mergeEnvFiles = (targetContent, templateVariables, templateSlug) => {
565
+ const targetLines = targetContent.replace(/\r\n/g, "\n").split("\n");
566
+ const existingVars = /* @__PURE__ */ new Set();
567
+ for (const line of targetLines) {
568
+ const trimmed = line.trim();
569
+ if (trimmed && !trimmed.startsWith("#")) {
570
+ const equalIndex = trimmed.indexOf("=");
571
+ if (equalIndex > 0) {
572
+ const varName = trimmed.substring(0, equalIndex).trim();
573
+ existingVars.add(varName);
574
+ }
575
+ }
576
+ }
577
+ const newVars = [];
578
+ for (const [key, value] of Object.entries(templateVariables)) {
579
+ if (!existingVars.has(key)) {
580
+ newVars.push({ key, value });
581
+ } else {
582
+ console.log(`\u26A0 Skipping existing environment variable: ${key} (already exists in .env)`);
583
+ }
584
+ }
585
+ if (newVars.length === 0) {
586
+ return targetContent;
587
+ }
588
+ const result = [...targetLines];
589
+ const lastLine = result[result.length - 1];
590
+ if (result.length > 0 && lastLine && lastLine.trim() !== "") {
591
+ result.push("");
592
+ }
593
+ result.push(`# Added by template: ${templateSlug}`);
594
+ for (const { key, value } of newVars) {
595
+ result.push(`${key}=${value}`);
596
+ }
597
+ return result.join("\n");
598
+ };
599
+ var detectAISDKVersion = async (projectPath) => {
600
+ try {
601
+ const packageJsonPath = join(projectPath, "package.json");
602
+ if (!existsSync(packageJsonPath)) {
603
+ console.log("No package.json found, defaulting to v2");
604
+ return "v2";
605
+ }
606
+ const packageContent = await readFile(packageJsonPath, "utf-8");
607
+ const packageJson = JSON.parse(packageContent);
608
+ const allDeps = {
609
+ ...packageJson.dependencies,
610
+ ...packageJson.devDependencies,
611
+ ...packageJson.peerDependencies
612
+ };
613
+ const providerPackages = ["@ai-sdk/openai", "@ai-sdk/anthropic", "@ai-sdk/google", "@ai-sdk/groq", "@ai-sdk/xai"];
614
+ for (const pkg of providerPackages) {
615
+ const version = allDeps[pkg];
616
+ if (version) {
617
+ const versionMatch = version.match(/(\d+)/);
618
+ if (versionMatch) {
619
+ const majorVersion = parseInt(versionMatch[1]);
620
+ if (majorVersion >= 2) {
621
+ console.log(`Detected ${pkg} v${majorVersion} -> using v2 specification`);
622
+ return "v2";
623
+ } else {
624
+ console.log(`Detected ${pkg} v${majorVersion} -> using v1 specification`);
625
+ return "v1";
626
+ }
627
+ }
628
+ }
629
+ }
630
+ console.log("No AI SDK version detected, defaulting to v2");
631
+ return "v2";
632
+ } catch (error) {
633
+ console.warn(`Failed to detect AI SDK version: ${error instanceof Error ? error.message : String(error)}`);
634
+ return "v2";
635
+ }
636
+ };
637
+ var createModelInstance = async (provider, modelId, version = "v2") => {
638
+ try {
639
+ const providerMap = {
640
+ v1: {
641
+ openai: async () => {
642
+ const { openai: openai2 } = await import('@ai-sdk/openai');
643
+ return openai2(modelId);
644
+ },
645
+ anthropic: async () => {
646
+ const { anthropic } = await import('@ai-sdk/anthropic');
647
+ return anthropic(modelId);
648
+ },
649
+ groq: async () => {
650
+ const { groq } = await import('@ai-sdk/groq');
651
+ return groq(modelId);
652
+ },
653
+ xai: async () => {
654
+ const { xai } = await import('@ai-sdk/xai');
655
+ return xai(modelId);
656
+ },
657
+ google: async () => {
658
+ const { google } = await import('@ai-sdk/google');
659
+ return google(modelId);
660
+ }
661
+ },
662
+ v2: {
663
+ openai: async () => {
664
+ const { openai: openai2 } = await import('@ai-sdk/openai-v5');
665
+ return openai2(modelId);
666
+ },
667
+ anthropic: async () => {
668
+ const { anthropic } = await import('@ai-sdk/anthropic-v5');
669
+ return anthropic(modelId);
670
+ },
671
+ groq: async () => {
672
+ const { groq } = await import('@ai-sdk/groq-v5');
673
+ return groq(modelId);
674
+ },
675
+ xai: async () => {
676
+ const { xai } = await import('@ai-sdk/xai-v5');
677
+ return xai(modelId);
678
+ },
679
+ google: async () => {
680
+ const { google } = await import('@ai-sdk/google-v5');
681
+ return google(modelId);
682
+ }
683
+ }
684
+ };
685
+ const providerFn = providerMap[version][provider];
686
+ if (!providerFn) {
687
+ console.error(`Unsupported provider: ${provider}`);
688
+ return null;
689
+ }
690
+ const modelInstance = await providerFn();
691
+ console.log(`Created ${provider} model instance (${version}): ${modelId}`);
692
+ return modelInstance;
693
+ } catch (error) {
694
+ console.error(`Failed to create model instance: ${error instanceof Error ? error.message : String(error)}`);
695
+ return null;
696
+ }
697
+ };
698
+ var resolveModel = async ({
699
+ runtimeContext,
700
+ defaultModel = openai$1("gpt-4.1"),
701
+ projectPath
702
+ }) => {
703
+ const modelFromContext = runtimeContext.get("model");
704
+ if (modelFromContext) {
705
+ console.log("Using model from runtime context");
706
+ if (isValidMastraLanguageModel(modelFromContext)) {
707
+ return modelFromContext;
708
+ }
709
+ throw new Error(
710
+ 'Invalid model provided. Model must be a MastraLanguageModel instance (e.g., openai("gpt-4"), anthropic("claude-3-5-sonnet"), etc.)'
711
+ );
712
+ }
713
+ const selectedModel = runtimeContext.get("selectedModel");
714
+ if (selectedModel?.provider && selectedModel?.modelId && projectPath) {
715
+ console.log(`Resolving selected model: ${selectedModel.provider}/${selectedModel.modelId}`);
716
+ const version = await detectAISDKVersion(projectPath);
717
+ const modelInstance = await createModelInstance(selectedModel.provider, selectedModel.modelId, version);
718
+ if (modelInstance) {
719
+ runtimeContext.set("model", modelInstance);
720
+ return modelInstance;
721
+ }
722
+ }
723
+ console.log("Using default model");
724
+ return defaultModel;
725
+ };
532
726
 
533
727
  // src/defaults.ts
534
728
  var AgentBuilderDefaults = class _AgentBuilderDefaults {
@@ -710,7 +904,6 @@ You have access to an enhanced set of tools based on production coding agent pat
710
904
  **Important**: All file paths are resolved relative to the project directory unless absolute paths are provided.
711
905
 
712
906
  ### Communication & Workflow
713
- - **askClarification**: Ask users for clarification when requirements are unclear or multiple options exist.
714
907
  - **attemptCompletion**: Signal task completion with validation status and confidence metrics.
715
908
 
716
909
  ### Guidelines for Enhanced Tools:
@@ -928,8 +1121,8 @@ export const mastra = new Mastra({
928
1121
  "mcp-server": "src/mastra/mcp",
929
1122
  network: "src/mastra/networks"
930
1123
  };
931
- static DEFAULT_TOOLS = async (projectPath, mode = "code-editor") => {
932
- const agentBuilderTools = {
1124
+ static DEFAULT_TOOLS = async (projectPath) => {
1125
+ return {
933
1126
  readFile: createTool({
934
1127
  id: "read-file",
935
1128
  description: "Read contents of a file with optional line range selection.",
@@ -1162,37 +1355,6 @@ export const mastra = new Mastra({
1162
1355
  return await _AgentBuilderDefaults.showFileLines({ ...context, projectPath });
1163
1356
  }
1164
1357
  }),
1165
- // Interactive Communication
1166
- askClarification: createTool({
1167
- id: "ask-clarification",
1168
- description: "Ask the user for clarification when requirements are unclear or when multiple options exist.",
1169
- inputSchema: z.object({
1170
- question: z.string().describe("The specific question to ask"),
1171
- options: z.array(
1172
- z.object({
1173
- id: z.string(),
1174
- description: z.string(),
1175
- implications: z.string().optional()
1176
- })
1177
- ).optional().describe("Multiple choice options if applicable"),
1178
- context: z.string().optional().describe("Additional context about why clarification is needed"),
1179
- urgency: z.enum(["low", "medium", "high"]).default("medium").describe("How urgent the clarification is")
1180
- }),
1181
- outputSchema: z.object({
1182
- questionId: z.string(),
1183
- question: z.string(),
1184
- options: z.array(
1185
- z.object({
1186
- id: z.string(),
1187
- description: z.string()
1188
- })
1189
- ).optional(),
1190
- awaitingResponse: z.boolean()
1191
- }),
1192
- execute: async ({ context }) => {
1193
- return await _AgentBuilderDefaults.askClarification(context);
1194
- }
1195
- }),
1196
1358
  // Enhanced Pattern Search
1197
1359
  smartSearch: createTool({
1198
1360
  id: "smart-search",
@@ -1276,332 +1438,305 @@ export const mastra = new Mastra({
1276
1438
  files
1277
1439
  });
1278
1440
  }
1279
- })
1280
- };
1281
- if (mode === "template") {
1282
- return agentBuilderTools;
1283
- } else {
1284
- return {
1285
- ...agentBuilderTools,
1286
- // Web Search (replaces MCP web search)
1287
- webSearch: createTool({
1288
- id: "web-search",
1289
- description: "Search the web for current information and return structured results.",
1290
- inputSchema: z.object({
1291
- query: z.string().describe("Search query"),
1292
- maxResults: z.number().default(10).describe("Maximum number of results to return"),
1293
- region: z.string().default("us").describe("Search region/country code"),
1294
- language: z.string().default("en").describe("Search language"),
1295
- includeImages: z.boolean().default(false).describe("Include image results"),
1296
- dateRange: z.enum(["day", "week", "month", "year", "all"]).default("all").describe("Date range filter")
1297
- }),
1298
- outputSchema: z.object({
1299
- success: z.boolean(),
1300
- query: z.string(),
1301
- results: z.array(
1302
- z.object({
1303
- title: z.string(),
1304
- url: z.string(),
1305
- snippet: z.string(),
1306
- domain: z.string(),
1307
- publishDate: z.string().optional(),
1308
- relevanceScore: z.number().optional()
1309
- })
1310
- ),
1311
- totalResults: z.number(),
1312
- searchTime: z.number(),
1313
- suggestions: z.array(z.string()).optional(),
1314
- error: z.string().optional()
1315
- }),
1316
- execute: async ({ context }) => {
1317
- return await _AgentBuilderDefaults.webSearch(context);
1318
- }
1441
+ }),
1442
+ // Web Search (replaces MCP web search)
1443
+ webSearch: createTool({
1444
+ id: "web-search",
1445
+ description: "Search the web for current information and return structured results.",
1446
+ inputSchema: z.object({
1447
+ query: z.string().describe("Search query"),
1448
+ maxResults: z.number().default(10).describe("Maximum number of results to return"),
1449
+ region: z.string().default("us").describe("Search region/country code"),
1450
+ language: z.string().default("en").describe("Search language"),
1451
+ includeImages: z.boolean().default(false).describe("Include image results"),
1452
+ dateRange: z.enum(["day", "week", "month", "year", "all"]).default("all").describe("Date range filter")
1319
1453
  }),
1320
- // Enhanced Code Discovery
1321
- codeAnalyzer: createTool({
1322
- id: "code-analyzer",
1323
- description: "Analyze codebase structure, discover definitions, and understand architecture patterns.",
1324
- inputSchema: z.object({
1325
- action: z.enum(["definitions", "dependencies", "patterns", "structure"]).describe("Type of analysis to perform"),
1326
- path: z.string().describe("Directory or file path to analyze"),
1327
- language: z.string().optional().describe("Programming language filter"),
1328
- depth: z.number().default(3).describe("Directory traversal depth"),
1329
- includeTests: z.boolean().default(false).describe("Include test files in analysis")
1330
- }),
1331
- outputSchema: z.object({
1332
- success: z.boolean(),
1333
- analysis: z.object({
1334
- definitions: z.array(
1335
- z.object({
1336
- name: z.string(),
1337
- type: z.string(),
1338
- file: z.string(),
1339
- line: z.number().optional(),
1340
- scope: z.string().optional()
1341
- })
1342
- ).optional(),
1343
- dependencies: z.array(
1344
- z.object({
1345
- name: z.string(),
1346
- type: z.enum(["import", "require", "include"]),
1347
- source: z.string(),
1348
- target: z.string()
1349
- })
1350
- ).optional(),
1351
- patterns: z.array(
1352
- z.object({
1353
- pattern: z.string(),
1354
- description: z.string(),
1355
- files: z.array(z.string())
1356
- })
1357
- ).optional(),
1358
- structure: z.object({
1359
- directories: z.number(),
1360
- files: z.number(),
1361
- languages: z.record(z.number()),
1362
- complexity: z.string()
1363
- }).optional()
1364
- }),
1365
- message: z.string()
1366
- }),
1367
- execute: async ({ context }) => {
1368
- return await _AgentBuilderDefaults.analyzeCode(context);
1369
- }
1454
+ outputSchema: z.object({
1455
+ success: z.boolean(),
1456
+ query: z.string(),
1457
+ results: z.array(
1458
+ z.object({
1459
+ title: z.string(),
1460
+ url: z.string(),
1461
+ snippet: z.string(),
1462
+ domain: z.string(),
1463
+ publishDate: z.string().optional(),
1464
+ relevanceScore: z.number().optional()
1465
+ })
1466
+ ),
1467
+ totalResults: z.number(),
1468
+ searchTime: z.number(),
1469
+ suggestions: z.array(z.string()).optional(),
1470
+ error: z.string().optional()
1370
1471
  }),
1371
- // Task Completion Signaling
1372
- attemptCompletion: createTool({
1373
- id: "attempt-completion",
1374
- description: "Signal that you believe the requested task has been completed and provide a summary.",
1375
- inputSchema: z.object({
1376
- summary: z.string().describe("Summary of what was accomplished"),
1377
- changes: z.array(
1378
- z.object({
1379
- type: z.enum([
1380
- "file_created",
1381
- "file_modified",
1382
- "file_deleted",
1383
- "command_executed",
1384
- "dependency_added"
1385
- ]),
1386
- description: z.string(),
1387
- path: z.string().optional()
1388
- })
1389
- ).describe("List of changes made"),
1390
- validation: z.object({
1391
- testsRun: z.boolean().default(false),
1392
- buildsSuccessfully: z.boolean().default(false),
1393
- manualTestingRequired: z.boolean().default(false)
1394
- }).describe("Validation status"),
1395
- nextSteps: z.array(z.string()).optional().describe("Suggested next steps or follow-up actions")
1396
- }),
1397
- outputSchema: z.object({
1398
- completionId: z.string(),
1399
- status: z.enum(["completed", "needs_review", "needs_testing"]),
1400
- summary: z.string(),
1401
- confidence: z.number().min(0).max(100)
1402
- }),
1403
- execute: async ({ context }) => {
1404
- return await _AgentBuilderDefaults.signalCompletion(context);
1405
- }
1472
+ execute: async ({ context }) => {
1473
+ return await _AgentBuilderDefaults.webSearch(context);
1474
+ }
1475
+ }),
1476
+ // Task Completion Signaling
1477
+ attemptCompletion: createTool({
1478
+ id: "attempt-completion",
1479
+ description: "Signal that you believe the requested task has been completed and provide a summary.",
1480
+ inputSchema: z.object({
1481
+ summary: z.string().describe("Summary of what was accomplished"),
1482
+ changes: z.array(
1483
+ z.object({
1484
+ type: z.enum(["file_created", "file_modified", "file_deleted", "command_executed", "dependency_added"]),
1485
+ description: z.string(),
1486
+ path: z.string().optional()
1487
+ })
1488
+ ).describe("List of changes made"),
1489
+ validation: z.object({
1490
+ testsRun: z.boolean().default(false),
1491
+ buildsSuccessfully: z.boolean().default(false),
1492
+ manualTestingRequired: z.boolean().default(false)
1493
+ }).describe("Validation status"),
1494
+ nextSteps: z.array(z.string()).optional().describe("Suggested next steps or follow-up actions")
1406
1495
  }),
1407
- manageProject: createTool({
1408
- id: "manage-project",
1409
- description: "Handles project management including creating project structures, managing dependencies, and package operations.",
1410
- inputSchema: z.object({
1411
- action: z.enum(["create", "install", "upgrade"]).describe("The action to perform"),
1412
- features: z.array(z.string()).optional().describe('Mastra features to include (e.g., ["agents", "memory", "workflows"])'),
1413
- packages: z.array(
1414
- z.object({
1415
- name: z.string(),
1416
- version: z.string().optional()
1417
- })
1418
- ).optional().describe("Packages to install/upgrade")
1419
- }),
1420
- outputSchema: z.object({
1421
- success: z.boolean(),
1422
- installed: z.array(z.string()).optional(),
1423
- upgraded: z.array(z.string()).optional(),
1424
- warnings: z.array(z.string()).optional(),
1425
- message: z.string().optional(),
1426
- details: z.string().optional(),
1427
- error: z.string().optional()
1428
- }),
1429
- execute: async ({ context }) => {
1430
- const { action, features, packages } = context;
1431
- try {
1432
- switch (action) {
1433
- case "create":
1434
- return await _AgentBuilderDefaults.createMastraProject({
1435
- projectName: projectPath,
1436
- features
1437
- });
1438
- case "install":
1439
- if (!packages?.length) {
1440
- return {
1441
- success: false,
1442
- message: "Packages array is required for install action"
1443
- };
1444
- }
1445
- return await _AgentBuilderDefaults.installPackages({
1446
- packages,
1447
- projectPath
1448
- });
1449
- case "upgrade":
1450
- if (!packages?.length) {
1451
- return {
1452
- success: false,
1453
- message: "Packages array is required for upgrade action"
1454
- };
1455
- }
1456
- return await _AgentBuilderDefaults.upgradePackages({
1457
- packages,
1458
- projectPath
1459
- });
1460
- // case 'check':
1461
- // return await AgentBuilderDefaults.checkProject({
1462
- // projectPath,
1463
- // });
1464
- default:
1496
+ outputSchema: z.object({
1497
+ completionId: z.string(),
1498
+ status: z.enum(["completed", "needs_review", "needs_testing"]),
1499
+ summary: z.string(),
1500
+ confidence: z.number().min(0).max(100)
1501
+ }),
1502
+ execute: async ({ context }) => {
1503
+ return await _AgentBuilderDefaults.signalCompletion(context);
1504
+ }
1505
+ }),
1506
+ manageProject: createTool({
1507
+ id: "manage-project",
1508
+ description: "Handles project management including creating project structures, managing dependencies, and package operations.",
1509
+ inputSchema: z.object({
1510
+ action: z.enum(["create", "install", "upgrade"]).describe("The action to perform"),
1511
+ features: z.array(z.string()).optional().describe('Mastra features to include (e.g., ["agents", "memory", "workflows"])'),
1512
+ packages: z.array(
1513
+ z.object({
1514
+ name: z.string(),
1515
+ version: z.string().optional()
1516
+ })
1517
+ ).optional().describe("Packages to install/upgrade")
1518
+ }),
1519
+ outputSchema: z.object({
1520
+ success: z.boolean(),
1521
+ installed: z.array(z.string()).optional(),
1522
+ upgraded: z.array(z.string()).optional(),
1523
+ warnings: z.array(z.string()).optional(),
1524
+ message: z.string().optional(),
1525
+ details: z.string().optional(),
1526
+ error: z.string().optional()
1527
+ }),
1528
+ execute: async ({ context }) => {
1529
+ const { action, features, packages } = context;
1530
+ try {
1531
+ switch (action) {
1532
+ case "create":
1533
+ return await _AgentBuilderDefaults.createMastraProject({
1534
+ projectName: projectPath,
1535
+ features
1536
+ });
1537
+ case "install":
1538
+ if (!packages?.length) {
1465
1539
  return {
1466
1540
  success: false,
1467
- message: `Unknown action: ${action}`
1541
+ message: "Packages array is required for install action"
1468
1542
  };
1469
- }
1470
- } catch (error) {
1471
- return {
1472
- success: false,
1473
- message: `Error executing ${action}: ${error instanceof Error ? error.message : String(error)}`
1474
- };
1543
+ }
1544
+ return await _AgentBuilderDefaults.installPackages({
1545
+ packages,
1546
+ projectPath
1547
+ });
1548
+ case "upgrade":
1549
+ if (!packages?.length) {
1550
+ return {
1551
+ success: false,
1552
+ message: "Packages array is required for upgrade action"
1553
+ };
1554
+ }
1555
+ return await _AgentBuilderDefaults.upgradePackages({
1556
+ packages,
1557
+ projectPath
1558
+ });
1559
+ default:
1560
+ return {
1561
+ success: false,
1562
+ message: `Unknown action: ${action}`
1563
+ };
1475
1564
  }
1565
+ } catch (error) {
1566
+ return {
1567
+ success: false,
1568
+ message: `Error executing ${action}: ${error instanceof Error ? error.message : String(error)}`
1569
+ };
1476
1570
  }
1571
+ }
1572
+ }),
1573
+ manageServer: createTool({
1574
+ id: "manage-server",
1575
+ description: "Manages the Mastra server - start, stop, restart, and check status, use the terminal tool to make curl requests to the server. There is an openapi spec for the server at http://localhost:{port}/openapi.json",
1576
+ inputSchema: z.object({
1577
+ action: z.enum(["start", "stop", "restart", "status"]).describe("Server management action"),
1578
+ port: z.number().optional().default(4200).describe("Port to run the server on")
1477
1579
  }),
1478
- manageServer: createTool({
1479
- id: "manage-server",
1480
- description: "Manages the Mastra server - start, stop, restart, and check status, use the terminal tool to make curl requests to the server. There is an openapi spec for the server at http://localhost:{port}/openapi.json",
1481
- inputSchema: z.object({
1482
- action: z.enum(["start", "stop", "restart", "status"]).describe("Server management action"),
1483
- port: z.number().optional().default(4200).describe("Port to run the server on")
1484
- }),
1485
- outputSchema: z.object({
1486
- success: z.boolean(),
1487
- status: z.enum(["running", "stopped", "starting", "stopping", "unknown"]),
1488
- pid: z.number().optional(),
1489
- port: z.number().optional(),
1490
- url: z.string().optional(),
1491
- message: z.string().optional(),
1492
- stdout: z.array(z.string()).optional().describe("Server output lines captured during startup"),
1493
- error: z.string().optional()
1494
- }),
1495
- execute: async ({ context }) => {
1496
- const { action, port } = context;
1497
- try {
1498
- switch (action) {
1499
- case "start":
1500
- return await _AgentBuilderDefaults.startMastraServer({
1501
- port,
1502
- projectPath
1503
- });
1504
- case "stop":
1505
- return await _AgentBuilderDefaults.stopMastraServer({
1506
- port,
1507
- projectPath
1508
- });
1509
- case "restart":
1510
- const stopResult = await _AgentBuilderDefaults.stopMastraServer({
1511
- port,
1512
- projectPath
1513
- });
1514
- if (!stopResult.success) {
1515
- return {
1516
- success: false,
1517
- status: "unknown",
1518
- message: `Failed to restart: could not stop server on port ${port}`,
1519
- error: stopResult.error || "Unknown stop error"
1520
- };
1521
- }
1522
- await new Promise((resolve4) => setTimeout(resolve4, 500));
1523
- const startResult = await _AgentBuilderDefaults.startMastraServer({
1524
- port,
1525
- projectPath
1526
- });
1527
- if (!startResult.success) {
1528
- return {
1529
- success: false,
1530
- status: "stopped",
1531
- message: `Failed to restart: server stopped successfully but failed to start on port ${port}`,
1532
- error: startResult.error || "Unknown start error"
1533
- };
1534
- }
1580
+ outputSchema: z.object({
1581
+ success: z.boolean(),
1582
+ status: z.enum(["running", "stopped", "starting", "stopping", "unknown"]),
1583
+ pid: z.number().optional(),
1584
+ port: z.number().optional(),
1585
+ url: z.string().optional(),
1586
+ message: z.string().optional(),
1587
+ stdout: z.array(z.string()).optional().describe("Server output lines captured during startup"),
1588
+ error: z.string().optional()
1589
+ }),
1590
+ execute: async ({ context }) => {
1591
+ const { action, port } = context;
1592
+ try {
1593
+ switch (action) {
1594
+ case "start":
1595
+ return await _AgentBuilderDefaults.startMastraServer({
1596
+ port,
1597
+ projectPath
1598
+ });
1599
+ case "stop":
1600
+ return await _AgentBuilderDefaults.stopMastraServer({
1601
+ port,
1602
+ projectPath
1603
+ });
1604
+ case "restart":
1605
+ const stopResult = await _AgentBuilderDefaults.stopMastraServer({
1606
+ port,
1607
+ projectPath
1608
+ });
1609
+ if (!stopResult.success) {
1535
1610
  return {
1536
- ...startResult,
1537
- message: `Mastra server restarted successfully on port ${port}`
1611
+ success: false,
1612
+ status: "unknown",
1613
+ message: `Failed to restart: could not stop server on port ${port}`,
1614
+ error: stopResult.error || "Unknown stop error"
1538
1615
  };
1539
- case "status":
1540
- return await _AgentBuilderDefaults.checkMastraServerStatus({
1541
- port,
1542
- projectPath
1543
- });
1544
- default:
1616
+ }
1617
+ await new Promise((resolve4) => setTimeout(resolve4, 500));
1618
+ const startResult = await _AgentBuilderDefaults.startMastraServer({
1619
+ port,
1620
+ projectPath
1621
+ });
1622
+ if (!startResult.success) {
1545
1623
  return {
1546
1624
  success: false,
1547
- status: "unknown",
1548
- message: `Unknown action: ${action}`
1625
+ status: "stopped",
1626
+ message: `Failed to restart: server stopped successfully but failed to start on port ${port}`,
1627
+ error: startResult.error || "Unknown start error"
1549
1628
  };
1550
- }
1551
- } catch (error) {
1552
- return {
1553
- success: false,
1554
- status: "unknown",
1555
- message: `Error managing server: ${error instanceof Error ? error.message : String(error)}`
1556
- };
1629
+ }
1630
+ return {
1631
+ ...startResult,
1632
+ message: `Mastra server restarted successfully on port ${port}`
1633
+ };
1634
+ case "status":
1635
+ return await _AgentBuilderDefaults.checkMastraServerStatus({
1636
+ port,
1637
+ projectPath
1638
+ });
1639
+ default:
1640
+ return {
1641
+ success: false,
1642
+ status: "unknown",
1643
+ message: `Unknown action: ${action}`
1644
+ };
1557
1645
  }
1646
+ } catch (error) {
1647
+ return {
1648
+ success: false,
1649
+ status: "unknown",
1650
+ message: `Error managing server: ${error instanceof Error ? error.message : String(error)}`
1651
+ };
1558
1652
  }
1653
+ }
1654
+ }),
1655
+ httpRequest: createTool({
1656
+ id: "http-request",
1657
+ description: "Makes HTTP requests to the Mastra server or external APIs for testing and integration",
1658
+ inputSchema: z.object({
1659
+ method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH"]).describe("HTTP method"),
1660
+ url: z.string().describe("Full URL or path (if baseUrl provided)"),
1661
+ baseUrl: z.string().optional().describe("Base URL for the server (e.g., http://localhost:4200)"),
1662
+ headers: z.record(z.string()).optional().describe("HTTP headers"),
1663
+ body: z.any().optional().describe("Request body (will be JSON stringified if object)"),
1664
+ timeout: z.number().optional().default(3e4).describe("Request timeout in milliseconds")
1559
1665
  }),
1560
- httpRequest: createTool({
1561
- id: "http-request",
1562
- description: "Makes HTTP requests to the Mastra server or external APIs for testing and integration",
1563
- inputSchema: z.object({
1564
- method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH"]).describe("HTTP method"),
1565
- url: z.string().describe("Full URL or path (if baseUrl provided)"),
1566
- baseUrl: z.string().optional().describe("Base URL for the server (e.g., http://localhost:4200)"),
1567
- headers: z.record(z.string()).optional().describe("HTTP headers"),
1568
- body: z.any().optional().describe("Request body (will be JSON stringified if object)"),
1569
- timeout: z.number().optional().default(3e4).describe("Request timeout in milliseconds")
1570
- }),
1571
- outputSchema: z.object({
1572
- success: z.boolean(),
1573
- status: z.number().optional(),
1574
- statusText: z.string().optional(),
1575
- headers: z.record(z.string()).optional(),
1576
- data: z.any().optional(),
1577
- error: z.string().optional(),
1578
- url: z.string(),
1579
- method: z.string()
1580
- }),
1581
- execute: async ({ context }) => {
1582
- const { method, url, baseUrl, headers, body, timeout } = context;
1583
- try {
1584
- return await _AgentBuilderDefaults.makeHttpRequest({
1585
- method,
1586
- url,
1587
- baseUrl,
1588
- headers,
1589
- body,
1590
- timeout
1591
- });
1592
- } catch (error) {
1593
- return {
1594
- success: false,
1595
- url: baseUrl ? `${baseUrl}${url}` : url,
1596
- method,
1597
- error: error instanceof Error ? error.message : String(error)
1598
- };
1599
- }
1666
+ outputSchema: z.object({
1667
+ success: z.boolean(),
1668
+ status: z.number().optional(),
1669
+ statusText: z.string().optional(),
1670
+ headers: z.record(z.string()).optional(),
1671
+ data: z.any().optional(),
1672
+ error: z.string().optional(),
1673
+ url: z.string(),
1674
+ method: z.string()
1675
+ }),
1676
+ execute: async ({ context }) => {
1677
+ const { method, url, baseUrl, headers, body, timeout } = context;
1678
+ try {
1679
+ return await _AgentBuilderDefaults.makeHttpRequest({
1680
+ method,
1681
+ url,
1682
+ baseUrl,
1683
+ headers,
1684
+ body,
1685
+ timeout
1686
+ });
1687
+ } catch (error) {
1688
+ return {
1689
+ success: false,
1690
+ url: baseUrl ? `${baseUrl}${url}` : url,
1691
+ method,
1692
+ error: error instanceof Error ? error.message : String(error)
1693
+ };
1600
1694
  }
1601
- })
1602
- };
1603
- }
1695
+ }
1696
+ })
1697
+ };
1604
1698
  };
1699
+ /**
1700
+ * Filter tools for template builder mode (excludes web search and other advanced tools)
1701
+ */
1702
+ static filterToolsForTemplateBuilder(tools) {
1703
+ const templateBuilderTools = [
1704
+ "readFile",
1705
+ "writeFile",
1706
+ "listDirectory",
1707
+ "executeCommand",
1708
+ "taskManager",
1709
+ "multiEdit",
1710
+ "replaceLines",
1711
+ "showFileLines",
1712
+ "smartSearch",
1713
+ "validateCode"
1714
+ ];
1715
+ const filtered = {};
1716
+ for (const toolName of templateBuilderTools) {
1717
+ if (tools[toolName]) {
1718
+ filtered[toolName] = tools[toolName];
1719
+ }
1720
+ }
1721
+ return filtered;
1722
+ }
1723
+ /**
1724
+ * Filter tools for code editor mode (includes all tools)
1725
+ */
1726
+ static filterToolsForCodeEditor(tools) {
1727
+ return tools;
1728
+ }
1729
+ /**
1730
+ * Get tools for a specific mode
1731
+ */
1732
+ static async getToolsForMode(projectPath, mode = "code-editor") {
1733
+ const allTools = await _AgentBuilderDefaults.DEFAULT_TOOLS(projectPath);
1734
+ if (mode === "template") {
1735
+ return _AgentBuilderDefaults.filterToolsForTemplateBuilder(allTools);
1736
+ } else {
1737
+ return _AgentBuilderDefaults.filterToolsForCodeEditor(allTools);
1738
+ }
1739
+ }
1605
1740
  /**
1606
1741
  * Create a new Mastra project using create-mastra CLI
1607
1742
  */
@@ -1679,49 +1814,6 @@ export const mastra = new Mastra({
1679
1814
  };
1680
1815
  }
1681
1816
  }
1682
- // /**
1683
- // * Check project health and status
1684
- // */
1685
- // static async checkProject({ projectPath }: { projectPath?: string }) {
1686
- // try {
1687
- // const execOptions = projectPath ? { cwd: projectPath } : {};
1688
- // let hasPackageJson = false;
1689
- // let hasMastraConfig = false;
1690
- // try {
1691
- // await exec('test -f package.json', execOptions);
1692
- // hasPackageJson = true;
1693
- // } catch {
1694
- // // ignore
1695
- // }
1696
- // try {
1697
- // await exec('test -f mastra.config.* || test -d src/mastra || test -d mastra', execOptions);
1698
- // hasMastraConfig = true;
1699
- // } catch {
1700
- // // ignore
1701
- // }
1702
- // const warnings: string[] = [];
1703
- // if (!hasPackageJson) {
1704
- // warnings.push('No package.json found - this may not be a Node.js project');
1705
- // }
1706
- // if (!hasMastraConfig) {
1707
- // warnings.push('No Mastra configuration found - run "npx create-mastra" to initialize');
1708
- // }
1709
- // return {
1710
- // success: true,
1711
- // message: `Project health check completed for ${projectPath || 'current directory'}`,
1712
- // warnings,
1713
- // checks: {
1714
- // hasPackageJson,
1715
- // hasMastraConfig,
1716
- // },
1717
- // };
1718
- // } catch (error) {
1719
- // return {
1720
- // success: false,
1721
- // message: `Failed to check project: ${error instanceof Error ? error.message : String(error)}`,
1722
- // };
1723
- // }
1724
- // }
1725
1817
  /**
1726
1818
  * Start the Mastra server
1727
1819
  */
@@ -2469,166 +2561,6 @@ export const mastra = new Mastra({
2469
2561
  };
2470
2562
  }
2471
2563
  }
2472
- /**
2473
- * Analyze codebase structure and patterns
2474
- */
2475
- static async analyzeCode(context) {
2476
- try {
2477
- const { action, path, language, depth = 3 } = context;
2478
- const ALLOWED_LANGUAGES = [
2479
- "js",
2480
- "ts",
2481
- "jsx",
2482
- "tsx",
2483
- "py",
2484
- "java",
2485
- "go",
2486
- "cpp",
2487
- "c",
2488
- "cs",
2489
- "rb",
2490
- "php",
2491
- "rs",
2492
- "kt",
2493
- "swift",
2494
- "m",
2495
- "scala",
2496
- "sh",
2497
- "json",
2498
- "yaml",
2499
- "yml",
2500
- "toml",
2501
- "ini"
2502
- ];
2503
- let languagePattern = "*";
2504
- if (language && ALLOWED_LANGUAGES.includes(language)) {
2505
- languagePattern = `*.${language}`;
2506
- }
2507
- switch (action) {
2508
- case "definitions":
2509
- const definitionPatterns = [
2510
- "function\\s+([a-zA-Z_][a-zA-Z0-9_]*)",
2511
- "class\\s+([a-zA-Z_][a-zA-Z0-9_]*)",
2512
- "interface\\s+([a-zA-Z_][a-zA-Z0-9_]*)",
2513
- "const\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*=",
2514
- "export\\s+(function|class|interface|const)\\s+([a-zA-Z_][a-zA-Z0-9_]*)"
2515
- ];
2516
- const definitions = [];
2517
- for (const pattern of definitionPatterns) {
2518
- try {
2519
- const { stdout } = await execFile("rg", [
2520
- "-n",
2521
- pattern,
2522
- path,
2523
- "--type",
2524
- languagePattern,
2525
- "--max-depth",
2526
- String(depth)
2527
- ]);
2528
- const matches = stdout.split("\n").filter((line) => line.trim());
2529
- matches.forEach((match) => {
2530
- const parts = match.split(":");
2531
- if (parts.length >= 3) {
2532
- const file = parts[0];
2533
- const lineStr = parts[1];
2534
- const line = parseInt(lineStr || "0");
2535
- const content = parts.slice(2).join(":");
2536
- const nameMatch = content.match(/([a-zA-Z_][a-zA-Z0-9_]*)/);
2537
- if (nameMatch && nameMatch[1]) {
2538
- definitions.push({
2539
- name: nameMatch[1],
2540
- type: pattern.includes("function") ? "function" : pattern.includes("class") ? "class" : pattern.includes("interface") ? "interface" : "variable",
2541
- file: file || "",
2542
- line,
2543
- scope: "top-level"
2544
- });
2545
- }
2546
- }
2547
- });
2548
- } catch {
2549
- }
2550
- }
2551
- return {
2552
- success: true,
2553
- analysis: { definitions },
2554
- message: `Found ${definitions.length} code definitions`
2555
- };
2556
- case "dependencies":
2557
- const depPatterns = [
2558
- `import\\s+.*\\s+from\\s+['"]([^'"]+)['"]`,
2559
- `require\\(['"]([^'"]+)['"]\\)`,
2560
- '#include\\s+[<"]([^>"]+)[>"]'
2561
- ];
2562
- const dependencies = [];
2563
- for (const pattern of depPatterns) {
2564
- try {
2565
- const { stdout } = await execFile("rg", ["-n", pattern, path, "--type", languagePattern]);
2566
- const matches = stdout.split("\n").filter((line) => line.trim());
2567
- matches.forEach((match) => {
2568
- const parts = match.split(":");
2569
- if (parts.length >= 3) {
2570
- const file = parts[0];
2571
- const content = parts.slice(2).join(":");
2572
- const depMatch = content.match(new RegExp(pattern));
2573
- if (depMatch && depMatch[1]) {
2574
- dependencies.push({
2575
- name: depMatch[1],
2576
- type: pattern.includes("import") ? "import" : pattern.includes("require") ? "require" : "include",
2577
- source: file || "",
2578
- target: depMatch[1]
2579
- });
2580
- }
2581
- }
2582
- });
2583
- } catch {
2584
- }
2585
- }
2586
- return {
2587
- success: true,
2588
- analysis: { dependencies },
2589
- message: `Found ${dependencies.length} dependencies`
2590
- };
2591
- case "structure":
2592
- const { stdout: lsOutput } = await execFile("find", [path, "-type", "f", "-name", languagePattern]);
2593
- const allFiles = lsOutput.split("\n").filter((line) => line.trim());
2594
- const files = allFiles.slice(0, 1e3);
2595
- const { stdout: dirOutput } = await execFile("find", [path, "-type", "d"]);
2596
- const directories = dirOutput.split("\n").filter((line) => line.trim()).length;
2597
- const languages = {};
2598
- files.forEach((file) => {
2599
- const ext = file.split(".").pop();
2600
- if (ext) {
2601
- languages[ext] = (languages[ext] || 0) + 1;
2602
- }
2603
- });
2604
- const complexity = files.length > 1e3 ? "high" : files.length > 100 ? "medium" : "low";
2605
- return {
2606
- success: true,
2607
- analysis: {
2608
- structure: {
2609
- directories,
2610
- files: files.length,
2611
- languages,
2612
- complexity
2613
- }
2614
- },
2615
- message: `Analyzed project structure: ${files.length} files in ${directories} directories`
2616
- };
2617
- default:
2618
- return {
2619
- success: false,
2620
- analysis: {},
2621
- message: `Unknown analysis action: ${action}`
2622
- };
2623
- }
2624
- } catch (error) {
2625
- return {
2626
- success: false,
2627
- analysis: {},
2628
- message: `Code analysis error: ${error instanceof Error ? error.message : String(error)}`
2629
- };
2630
- }
2631
- }
2632
2564
  /**
2633
2565
  * Perform multiple edits across files atomically
2634
2566
  */
@@ -2796,25 +2728,6 @@ export const mastra = new Mastra({
2796
2728
  };
2797
2729
  }
2798
2730
  }
2799
- /**
2800
- * Ask user for clarification
2801
- */
2802
- static async askClarification(context) {
2803
- const questionId = `q_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
2804
- if (!_AgentBuilderDefaults.pendingQuestions) {
2805
- _AgentBuilderDefaults.pendingQuestions = /* @__PURE__ */ new Map();
2806
- }
2807
- _AgentBuilderDefaults.pendingQuestions.set(questionId, {
2808
- ...context,
2809
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
2810
- });
2811
- return {
2812
- questionId,
2813
- question: context.question,
2814
- options: context.options?.map((opt) => ({ id: opt.id, description: opt.description })),
2815
- awaitingResponse: true
2816
- };
2817
- }
2818
2731
  /**
2819
2732
  * Signal task completion
2820
2733
  */
@@ -3221,90 +3134,212 @@ var ToolSummaryProcessor = class extends MemoryProcessor {
3221
3134
  this.summaryCache.clear();
3222
3135
  }
3223
3136
  /**
3224
- * Gets cache statistics
3137
+ * Gets cache statistics
3138
+ */
3139
+ getCacheStats() {
3140
+ return {
3141
+ size: this.summaryCache.size,
3142
+ keys: Array.from(this.summaryCache.keys())
3143
+ };
3144
+ }
3145
+ async process(messages) {
3146
+ const summaryTasks = [];
3147
+ for (const message of messages) {
3148
+ if (message.role === "tool" && Array.isArray(message.content) && message.content.length > 0 && message.content?.some((content) => content.type === "tool-result")) {
3149
+ for (const content of message.content) {
3150
+ if (content.type === "tool-result") {
3151
+ const assistantMessageWithToolCall = messages.find(
3152
+ (message2) => message2.role === "assistant" && Array.isArray(message2.content) && message2.content.length > 0 && message2.content?.some(
3153
+ (assistantContent) => assistantContent.type === "tool-call" && assistantContent.toolCallId === content.toolCallId
3154
+ )
3155
+ );
3156
+ const toolCall = Array.isArray(assistantMessageWithToolCall?.content) ? assistantMessageWithToolCall?.content.find(
3157
+ (assistantContent) => assistantContent.type === "tool-call" && assistantContent.toolCallId === content.toolCallId
3158
+ ) : null;
3159
+ const cacheKey = this.createCacheKey(toolCall);
3160
+ const cachedSummary = this.summaryCache.get(cacheKey);
3161
+ if (cachedSummary) {
3162
+ content.result = `Tool call summary: ${cachedSummary}`;
3163
+ } else {
3164
+ const summaryPromise = this.summaryAgent.generate(
3165
+ `Summarize the following tool call: ${JSON.stringify(toolCall)} and result: ${JSON.stringify(content)}`
3166
+ );
3167
+ summaryTasks.push({
3168
+ content,
3169
+ promise: summaryPromise,
3170
+ cacheKey
3171
+ });
3172
+ }
3173
+ }
3174
+ }
3175
+ }
3176
+ }
3177
+ if (summaryTasks.length > 0) {
3178
+ const summaryResults = await Promise.allSettled(summaryTasks.map((task) => task.promise));
3179
+ summaryTasks.forEach((task, index) => {
3180
+ const result = summaryResults[index];
3181
+ if (!result) return;
3182
+ if (result.status === "fulfilled") {
3183
+ const summaryResult = result.value;
3184
+ const summaryText = summaryResult.text;
3185
+ this.summaryCache.set(task.cacheKey, summaryText);
3186
+ task.content.result = `Tool call summary: ${summaryText}`;
3187
+ } else if (result.status === "rejected") {
3188
+ console.warn(`Failed to generate summary for tool call:`, result.reason);
3189
+ task.content.result = `Tool call summary: [Summary generation failed]`;
3190
+ }
3191
+ });
3192
+ }
3193
+ return messages;
3194
+ }
3195
+ };
3196
+
3197
+ // src/agent/index.ts
3198
+ var AgentBuilder = class extends Agent {
3199
+ builderConfig;
3200
+ /**
3201
+ * Constructor for AgentBuilder
3202
+ */
3203
+ constructor(config) {
3204
+ const additionalInstructions = config.instructions ? `## Priority Instructions
3205
+
3206
+ ${config.instructions}` : "";
3207
+ const combinedInstructions = additionalInstructions + AgentBuilderDefaults.DEFAULT_INSTRUCTIONS(config.projectPath);
3208
+ const agentConfig = {
3209
+ name: "agent-builder",
3210
+ description: "An AI agent specialized in generating Mastra agents, tools, and workflows from natural language requirements.",
3211
+ instructions: combinedInstructions,
3212
+ model: config.model,
3213
+ tools: async () => {
3214
+ return {
3215
+ ...await AgentBuilderDefaults.getToolsForMode(config.projectPath, config.mode),
3216
+ ...config.tools || {}
3217
+ };
3218
+ },
3219
+ memory: new Memory({
3220
+ options: AgentBuilderDefaults.DEFAULT_MEMORY_CONFIG,
3221
+ processors: [
3222
+ // use the write to disk processor to debug the agent's context
3223
+ // new WriteToDiskProcessor({ prefix: 'before-filter' }),
3224
+ new ToolSummaryProcessor({ summaryModel: config.summaryModel || config.model }),
3225
+ new TokenLimiter(1e5)
3226
+ // new WriteToDiskProcessor({ prefix: 'after-filter' }),
3227
+ ]
3228
+ })
3229
+ };
3230
+ super(agentConfig);
3231
+ this.builderConfig = config;
3232
+ }
3233
+ /**
3234
+ * Enhanced generate method with AgentBuilder-specific configuration
3235
+ * Overrides the base Agent generate method to provide additional project context
3236
+ */
3237
+ generate = async (messages, generateOptions = {}) => {
3238
+ const { maxSteps, ...baseOptions } = generateOptions;
3239
+ const originalInstructions = await this.getInstructions({ runtimeContext: generateOptions?.runtimeContext });
3240
+ const additionalInstructions = baseOptions.instructions;
3241
+ let enhancedInstructions = originalInstructions;
3242
+ if (additionalInstructions) {
3243
+ enhancedInstructions = `${originalInstructions}
3244
+
3245
+ ${additionalInstructions}`;
3246
+ }
3247
+ const enhancedContext = [...baseOptions.context || []];
3248
+ const enhancedOptions = {
3249
+ ...baseOptions,
3250
+ maxSteps: maxSteps || 100,
3251
+ // Higher default for code generation
3252
+ temperature: 0.3,
3253
+ // Lower temperature for more consistent code generation
3254
+ instructions: enhancedInstructions,
3255
+ context: enhancedContext
3256
+ };
3257
+ this.logger.debug(`[AgentBuilder:${this.name}] Starting generation with enhanced context`, {
3258
+ projectPath: this.builderConfig.projectPath
3259
+ });
3260
+ return super.generate(messages, enhancedOptions);
3261
+ };
3262
+ /**
3263
+ * Enhanced stream method with AgentBuilder-specific configuration
3264
+ * Overrides the base Agent stream method to provide additional project context
3265
+ */
3266
+ stream = async (messages, streamOptions = {}) => {
3267
+ const { maxSteps, ...baseOptions } = streamOptions;
3268
+ const originalInstructions = await this.getInstructions({ runtimeContext: streamOptions?.runtimeContext });
3269
+ const additionalInstructions = baseOptions.instructions;
3270
+ let enhancedInstructions = originalInstructions;
3271
+ if (additionalInstructions) {
3272
+ enhancedInstructions = `${originalInstructions}
3273
+
3274
+ ${additionalInstructions}`;
3275
+ }
3276
+ const enhancedContext = [...baseOptions.context || []];
3277
+ const enhancedOptions = {
3278
+ ...baseOptions,
3279
+ maxSteps: maxSteps || 100,
3280
+ // Higher default for code generation
3281
+ temperature: 0.3,
3282
+ // Lower temperature for more consistent code generation
3283
+ instructions: enhancedInstructions,
3284
+ context: enhancedContext
3285
+ };
3286
+ this.logger.debug(`[AgentBuilder:${this.name}] Starting streaming with enhanced context`, {
3287
+ projectPath: this.builderConfig.projectPath
3288
+ });
3289
+ return super.stream(messages, enhancedOptions);
3290
+ };
3291
+ /**
3292
+ * Enhanced stream method with AgentBuilder-specific configuration
3293
+ * Overrides the base Agent stream method to provide additional project context
3225
3294
  */
3226
- getCacheStats() {
3227
- return {
3228
- size: this.summaryCache.size,
3229
- keys: Array.from(this.summaryCache.keys())
3230
- };
3231
- }
3232
- async process(messages) {
3233
- const summaryTasks = [];
3234
- for (const message of messages) {
3235
- if (message.role === "tool" && Array.isArray(message.content) && message.content.length > 0 && message.content?.some((content) => content.type === "tool-result")) {
3236
- for (const content of message.content) {
3237
- if (content.type === "tool-result") {
3238
- const assistantMessageWithToolCall = messages.find(
3239
- (message2) => message2.role === "assistant" && Array.isArray(message2.content) && message2.content.length > 0 && message2.content?.some(
3240
- (assistantContent) => assistantContent.type === "tool-call" && assistantContent.toolCallId === content.toolCallId
3241
- )
3242
- );
3243
- const toolCall = Array.isArray(assistantMessageWithToolCall?.content) ? assistantMessageWithToolCall?.content.find(
3244
- (assistantContent) => assistantContent.type === "tool-call" && assistantContent.toolCallId === content.toolCallId
3245
- ) : null;
3246
- const cacheKey = this.createCacheKey(toolCall);
3247
- const cachedSummary = this.summaryCache.get(cacheKey);
3248
- if (cachedSummary) {
3249
- content.result = `Tool call summary: ${cachedSummary}`;
3250
- } else {
3251
- const summaryPromise = this.summaryAgent.generate(
3252
- `Summarize the following tool call: ${JSON.stringify(toolCall)} and result: ${JSON.stringify(content)}`
3253
- );
3254
- summaryTasks.push({
3255
- content,
3256
- promise: summaryPromise,
3257
- cacheKey
3258
- });
3259
- }
3260
- }
3261
- }
3262
- }
3263
- }
3264
- if (summaryTasks.length > 0) {
3265
- const summaryResults = await Promise.allSettled(summaryTasks.map((task) => task.promise));
3266
- summaryTasks.forEach((task, index) => {
3267
- const result = summaryResults[index];
3268
- if (!result) return;
3269
- if (result.status === "fulfilled") {
3270
- const summaryResult = result.value;
3271
- const summaryText = summaryResult.text;
3272
- this.summaryCache.set(task.cacheKey, summaryText);
3273
- task.content.result = `Tool call summary: ${summaryText}`;
3274
- } else if (result.status === "rejected") {
3275
- console.warn(`Failed to generate summary for tool call:`, result.reason);
3276
- task.content.result = `Tool call summary: [Summary generation failed]`;
3277
- }
3278
- });
3295
+ async streamVNext(messages, streamOptions) {
3296
+ const { ...baseOptions } = streamOptions || {};
3297
+ const originalInstructions = await this.getInstructions({ runtimeContext: streamOptions?.runtimeContext });
3298
+ const additionalInstructions = baseOptions.instructions;
3299
+ let enhancedInstructions = originalInstructions;
3300
+ if (additionalInstructions) {
3301
+ enhancedInstructions = `${originalInstructions}
3302
+
3303
+ ${additionalInstructions}`;
3279
3304
  }
3280
- return messages;
3281
- }
3282
- };
3283
- var WriteToDiskProcessor = class extends MemoryProcessor {
3284
- prefix;
3285
- constructor({ prefix = "messages" } = {}) {
3286
- super({ name: "WriteToDiskProcessor" });
3287
- this.prefix = prefix;
3288
- }
3289
- async process(messages) {
3290
- await writeFile(`${this.prefix}-${Date.now()}-${process.pid}.json`, JSON.stringify(messages, null, 2));
3291
- return messages;
3305
+ const enhancedContext = [...baseOptions.context || []];
3306
+ const enhancedOptions = {
3307
+ ...baseOptions,
3308
+ temperature: 0.3,
3309
+ // Lower temperature for more consistent code generation
3310
+ maxSteps: baseOptions?.maxSteps || 100,
3311
+ instructions: enhancedInstructions,
3312
+ context: enhancedContext
3313
+ };
3314
+ this.logger.debug(`[AgentBuilder:${this.name}] Starting streaming with enhanced context`, {
3315
+ projectPath: this.builderConfig.projectPath
3316
+ });
3317
+ return super.streamVNext(messages, enhancedOptions);
3292
3318
  }
3293
- };
3294
- var resolveModel2 = (runtimeContext) => {
3295
- const modelFromContext = runtimeContext.get("model");
3296
- if (modelFromContext) {
3297
- if (isValidMastraLanguageModel2(modelFromContext)) {
3298
- return modelFromContext;
3319
+ async generateVNext(messages, options) {
3320
+ const { ...baseOptions } = options || {};
3321
+ const originalInstructions = await this.getInstructions({ runtimeContext: options?.runtimeContext });
3322
+ const additionalInstructions = baseOptions.instructions;
3323
+ let enhancedInstructions = originalInstructions;
3324
+ if (additionalInstructions) {
3325
+ enhancedInstructions = `${originalInstructions}
3326
+
3327
+ ${additionalInstructions}`;
3299
3328
  }
3300
- throw new Error(
3301
- 'Invalid model provided. Model must be a MastraLanguageModel instance (e.g., openai("gpt-4"), anthropic("claude-3-5-sonnet"), etc.)'
3302
- );
3329
+ const enhancedContext = [...baseOptions.context || []];
3330
+ const enhancedOptions = {
3331
+ ...baseOptions,
3332
+ temperature: 0.3,
3333
+ // Lower temperature for more consistent code generation
3334
+ maxSteps: baseOptions?.maxSteps || 100,
3335
+ instructions: enhancedInstructions,
3336
+ context: enhancedContext
3337
+ };
3338
+ this.logger.debug(`[AgentBuilder:${this.name}] Starting streaming with enhanced context`, {
3339
+ projectPath: this.builderConfig.projectPath
3340
+ });
3341
+ return super.generateVNext(messages, enhancedOptions);
3303
3342
  }
3304
- return openai("gpt-4.1");
3305
- };
3306
- var isValidMastraLanguageModel2 = (model) => {
3307
- return model && typeof model === "object" && typeof model.modelId === "string" && typeof model.generate === "function";
3308
3343
  };
3309
3344
  var cloneTemplateStep = createStep({
3310
3345
  id: "clone-template",
@@ -3312,7 +3347,7 @@ var cloneTemplateStep = createStep({
3312
3347
  inputSchema: AgentBuilderInputSchema,
3313
3348
  outputSchema: CloneTemplateResultSchema,
3314
3349
  execute: async ({ inputData }) => {
3315
- const { repo, ref = "main", slug } = inputData;
3350
+ const { repo, ref = "main", slug, targetPath } = inputData;
3316
3351
  if (!repo) {
3317
3352
  throw new Error("Repository URL or path is required");
3318
3353
  }
@@ -3328,7 +3363,8 @@ var cloneTemplateStep = createStep({
3328
3363
  templateDir: tempDir,
3329
3364
  commitSha: commitSha.trim(),
3330
3365
  slug: inferredSlug,
3331
- success: true
3366
+ success: true,
3367
+ targetPath
3332
3368
  };
3333
3369
  } catch (error) {
3334
3370
  try {
@@ -3340,7 +3376,8 @@ var cloneTemplateStep = createStep({
3340
3376
  commitSha: "",
3341
3377
  slug: slug || "unknown",
3342
3378
  success: false,
3343
- error: `Failed to clone template: ${error instanceof Error ? error.message : String(error)}`
3379
+ error: `Failed to clone template: ${error instanceof Error ? error.message : String(error)}`,
3380
+ targetPath
3344
3381
  };
3345
3382
  }
3346
3383
  }
@@ -3391,10 +3428,13 @@ var discoverUnitsStep = createStep({
3391
3428
  outputSchema: DiscoveryResultSchema,
3392
3429
  execute: async ({ inputData, runtimeContext }) => {
3393
3430
  const { templateDir } = inputData;
3431
+ const targetPath = resolveTargetPath(inputData, runtimeContext);
3394
3432
  const tools = await AgentBuilderDefaults.DEFAULT_TOOLS(templateDir);
3433
+ console.log("targetPath", targetPath);
3434
+ const model = await resolveModel({ runtimeContext, projectPath: targetPath, defaultModel: openai("gpt-4.1") });
3395
3435
  try {
3396
3436
  const agent = new Agent({
3397
- model: resolveModel2(runtimeContext),
3437
+ model,
3398
3438
  instructions: `You are an expert at analyzing Mastra projects.
3399
3439
 
3400
3440
  Your task is to scan the provided directory and identify all available units (agents, workflows, tools, MCP servers, networks).
@@ -3432,8 +3472,8 @@ Return the actual exported names of the units, as well as the file names.`,
3432
3472
  listDirectory: tools.listDirectory
3433
3473
  }
3434
3474
  });
3435
- const result = await agent.generate(
3436
- `Analyze the Mastra project directory structure at "${templateDir}".
3475
+ const isV2 = model.specificationVersion === "v2";
3476
+ const prompt = `Analyze the Mastra project directory structure at "${templateDir}".
3437
3477
 
3438
3478
  List directory contents using listDirectory tool, and then analyze each file with readFile tool.
3439
3479
  IMPORTANT:
@@ -3442,19 +3482,22 @@ Return the actual exported names of the units, as well as the file names.`,
3442
3482
  - Return the actual exported variable names, as well as the file names
3443
3483
  - If a directory doesn't exist or has no files, return an empty array
3444
3484
 
3445
- Return the analysis in the exact format specified in the output schema.`,
3446
- {
3447
- experimental_output: z.object({
3448
- agents: z.array(z.object({ name: z.string(), file: z.string() })).optional(),
3449
- workflows: z.array(z.object({ name: z.string(), file: z.string() })).optional(),
3450
- tools: z.array(z.object({ name: z.string(), file: z.string() })).optional(),
3451
- mcp: z.array(z.object({ name: z.string(), file: z.string() })).optional(),
3452
- networks: z.array(z.object({ name: z.string(), file: z.string() })).optional(),
3453
- other: z.array(z.object({ name: z.string(), file: z.string() })).optional()
3454
- }),
3455
- maxSteps: 100
3456
- }
3457
- );
3485
+ Return the analysis in the exact format specified in the output schema.`;
3486
+ const output = z.object({
3487
+ agents: z.array(z.object({ name: z.string(), file: z.string() })).optional(),
3488
+ workflows: z.array(z.object({ name: z.string(), file: z.string() })).optional(),
3489
+ tools: z.array(z.object({ name: z.string(), file: z.string() })).optional(),
3490
+ mcp: z.array(z.object({ name: z.string(), file: z.string() })).optional(),
3491
+ networks: z.array(z.object({ name: z.string(), file: z.string() })).optional(),
3492
+ other: z.array(z.object({ name: z.string(), file: z.string() })).optional()
3493
+ });
3494
+ const result = isV2 ? await agent.generateVNext(prompt, {
3495
+ output,
3496
+ maxSteps: 100
3497
+ }) : await agent.generate(prompt, {
3498
+ experimental_output: output,
3499
+ maxSteps: 100
3500
+ });
3458
3501
  const template = result.object ?? {};
3459
3502
  const units = [];
3460
3503
  template.agents?.forEach((agentId) => {
@@ -3875,7 +3918,7 @@ var programmaticFileCopyStep = createStep({
3875
3918
  destination: targetMastraIndex,
3876
3919
  unit: { kind: "other", id: "mastra-index" }
3877
3920
  });
3878
- console.log("\u2713 Copied src/mastra/index.ts from template to target");
3921
+ console.log("\u2713 Copied Mastra index file from template");
3879
3922
  }
3880
3923
  }
3881
3924
  } catch (e) {
@@ -3886,6 +3929,88 @@ var programmaticFileCopyStep = createStep({
3886
3929
  targetFile: "src/mastra/index.ts"
3887
3930
  });
3888
3931
  }
3932
+ try {
3933
+ const targetGitignore = resolve(targetPath, ".gitignore");
3934
+ const templateGitignore = resolve(templateDir, ".gitignore");
3935
+ const targetExists = existsSync(targetGitignore);
3936
+ const templateExists = existsSync(templateGitignore);
3937
+ if (templateExists) {
3938
+ if (!targetExists) {
3939
+ await copyFile(templateGitignore, targetGitignore);
3940
+ copiedFiles.push({
3941
+ source: templateGitignore,
3942
+ destination: targetGitignore,
3943
+ unit: { kind: "other", id: "gitignore" }
3944
+ });
3945
+ console.log("\u2713 Copied .gitignore from template to target");
3946
+ } else {
3947
+ const targetContent = await readFile(targetGitignore, "utf-8");
3948
+ const templateContent = await readFile(templateGitignore, "utf-8");
3949
+ const mergedContent = mergeGitignoreFiles(targetContent, templateContent, slug);
3950
+ if (mergedContent !== targetContent) {
3951
+ const addedLines = mergedContent.split("\n").length - targetContent.split("\n").length;
3952
+ await writeFile(targetGitignore, mergedContent, "utf-8");
3953
+ copiedFiles.push({
3954
+ source: templateGitignore,
3955
+ destination: targetGitignore,
3956
+ unit: { kind: "other", id: "gitignore-merge" }
3957
+ });
3958
+ console.log(`\u2713 Merged template .gitignore entries into existing .gitignore (${addedLines} new entries)`);
3959
+ } else {
3960
+ console.log("\u2139 No new .gitignore entries to add from template");
3961
+ }
3962
+ }
3963
+ }
3964
+ } catch (e) {
3965
+ conflicts.push({
3966
+ unit: { kind: "other", id: "gitignore" },
3967
+ issue: `Failed to handle .gitignore file: ${e instanceof Error ? e.message : String(e)}`,
3968
+ sourceFile: ".gitignore",
3969
+ targetFile: ".gitignore"
3970
+ });
3971
+ }
3972
+ try {
3973
+ const { variables } = inputData;
3974
+ if (variables && Object.keys(variables).length > 0) {
3975
+ const targetEnv = resolve(targetPath, ".env");
3976
+ const targetExists = existsSync(targetEnv);
3977
+ if (!targetExists) {
3978
+ const envContent = [
3979
+ `# Environment variables for ${slug}`,
3980
+ ...Object.entries(variables).map(([key, value]) => `${key}=${value}`)
3981
+ ].join("\n");
3982
+ await writeFile(targetEnv, envContent, "utf-8");
3983
+ copiedFiles.push({
3984
+ source: "[template variables]",
3985
+ destination: targetEnv,
3986
+ unit: { kind: "other", id: "env" }
3987
+ });
3988
+ console.log(`\u2713 Created .env file with ${Object.keys(variables).length} template variables`);
3989
+ } else {
3990
+ const targetContent = await readFile(targetEnv, "utf-8");
3991
+ const mergedContent = mergeEnvFiles(targetContent, variables, slug);
3992
+ if (mergedContent !== targetContent) {
3993
+ const addedLines = mergedContent.split("\n").length - targetContent.split("\n").length;
3994
+ await writeFile(targetEnv, mergedContent, "utf-8");
3995
+ copiedFiles.push({
3996
+ source: "[template variables]",
3997
+ destination: targetEnv,
3998
+ unit: { kind: "other", id: "env-merge" }
3999
+ });
4000
+ console.log(`\u2713 Merged new environment variables into existing .env file (${addedLines} new entries)`);
4001
+ } else {
4002
+ console.log("\u2139 No new environment variables to add (all already exist in .env)");
4003
+ }
4004
+ }
4005
+ }
4006
+ } catch (e) {
4007
+ conflicts.push({
4008
+ unit: { kind: "other", id: "env" },
4009
+ issue: `Failed to handle .env file: ${e instanceof Error ? e.message : String(e)}`,
4010
+ sourceFile: ".env",
4011
+ targetFile: ".env"
4012
+ });
4013
+ }
3889
4014
  if (copiedFiles.length > 0) {
3890
4015
  try {
3891
4016
  const fileList = copiedFiles.map((f) => f.destination);
@@ -3930,6 +4055,7 @@ var intelligentMergeStep = createStep({
3930
4055
  const { conflicts, copiedFiles, commitSha, slug, templateDir, branchName } = inputData;
3931
4056
  const targetPath = resolveTargetPath(inputData, runtimeContext);
3932
4057
  try {
4058
+ const model = await resolveModel({ runtimeContext, projectPath: targetPath, defaultModel: openai("gpt-4.1") });
3933
4059
  const copyFileTool = createTool({
3934
4060
  id: "copy-file",
3935
4061
  description: "Copy a file from template to target project (use only for edge cases - most files are already copied programmatically).",
@@ -3967,7 +4093,7 @@ var intelligentMergeStep = createStep({
3967
4093
  const agentBuilder = new AgentBuilder({
3968
4094
  projectPath: targetPath,
3969
4095
  mode: "template",
3970
- model: resolveModel2(runtimeContext),
4096
+ model,
3971
4097
  instructions: `
3972
4098
  You are an expert at integrating Mastra template components into existing projects.
3973
4099
 
@@ -4070,7 +4196,7 @@ Template information:
4070
4196
  console.log(`Creating task list with ${tasks.length} tasks...`);
4071
4197
  await AgentBuilderDefaults.manageTaskList({ action: "create", tasks });
4072
4198
  await logGitState(targetPath, "before intelligent merge");
4073
- const result = await agentBuilder.stream(`
4199
+ const prompt = `
4074
4200
  You need to work through a task list to complete the template integration.
4075
4201
 
4076
4202
  CRITICAL INSTRUCTIONS:
@@ -4112,31 +4238,37 @@ For each task:
4112
4238
  - DO NOT perform validation - that's handled by the dedicated validation step
4113
4239
 
4114
4240
  Start by listing your tasks and work through them systematically!
4115
- `);
4241
+ `;
4242
+ const isV2 = model.specificationVersion === "v2";
4243
+ const result = isV2 ? await agentBuilder.streamVNext(prompt) : await agentBuilder.stream(prompt);
4116
4244
  const actualResolutions = [];
4117
4245
  for await (const chunk of result.fullStream) {
4118
4246
  if (chunk.type === "step-finish" || chunk.type === "step-start") {
4247
+ const chunkData = "payload" in chunk ? chunk.payload : chunk;
4119
4248
  console.log({
4120
4249
  type: chunk.type,
4121
- msgId: chunk.messageId
4250
+ msgId: chunkData.messageId
4122
4251
  });
4123
4252
  } else {
4124
4253
  console.log(JSON.stringify(chunk, null, 2));
4125
- if (chunk.type === "tool-result" && chunk.toolName === "manageTaskList") {
4126
- try {
4127
- const toolResult = chunk.result;
4128
- if (toolResult.action === "update" && toolResult.status === "completed") {
4129
- actualResolutions.push({
4130
- taskId: toolResult.taskId || "",
4131
- action: toolResult.action,
4132
- status: toolResult.status,
4133
- content: toolResult.content || "",
4134
- notes: toolResult.notes
4135
- });
4136
- console.log(`\u{1F4CB} Task completed: ${toolResult.taskId} - ${toolResult.content}`);
4254
+ if (chunk.type === "tool-result") {
4255
+ const chunkData = "payload" in chunk ? chunk.payload : chunk;
4256
+ if (chunkData.toolName === "manageTaskList") {
4257
+ try {
4258
+ const toolResult = chunkData.result;
4259
+ if (toolResult.action === "update" && toolResult.status === "completed") {
4260
+ actualResolutions.push({
4261
+ taskId: toolResult.taskId || "",
4262
+ action: toolResult.action,
4263
+ status: toolResult.status,
4264
+ content: toolResult.content || "",
4265
+ notes: toolResult.notes
4266
+ });
4267
+ console.log(`\u{1F4CB} Task completed: ${toolResult.taskId} - ${toolResult.content}`);
4268
+ }
4269
+ } catch (parseError) {
4270
+ console.warn("Failed to parse task management result:", parseError);
4137
4271
  }
4138
- } catch (parseError) {
4139
- console.warn("Failed to parse task management result:", parseError);
4140
4272
  }
4141
4273
  }
4142
4274
  }
@@ -4209,7 +4341,8 @@ var validationAndFixStep = createStep({
4209
4341
  );
4210
4342
  let currentIteration = 1;
4211
4343
  try {
4212
- const allTools = await AgentBuilderDefaults.DEFAULT_TOOLS(targetPath, "template");
4344
+ const model = await resolveModel({ runtimeContext, projectPath: targetPath, defaultModel: openai("gpt-4.1") });
4345
+ const allTools = await AgentBuilderDefaults.getToolsForMode(targetPath, "template");
4213
4346
  const validationAgent = new Agent({
4214
4347
  name: "code-validator-fixer",
4215
4348
  description: "Specialized agent for validating and fixing template integration issues",
@@ -4318,7 +4451,7 @@ INTEGRATED UNITS:
4318
4451
  ${JSON.stringify(orderedUnits, null, 2)}
4319
4452
 
4320
4453
  Be thorough and methodical. Always use listDirectory to verify actual file existence before fixing imports.`,
4321
- model: resolveModel2(runtimeContext),
4454
+ model,
4322
4455
  tools: {
4323
4456
  validateCode: allTools.validateCode,
4324
4457
  readFile: allTools.readFile,
@@ -4335,7 +4468,9 @@ Be thorough and methodical. Always use listDirectory to verify actual file exist
4335
4468
  errorsFixed: 0,
4336
4469
  remainingErrors: 1,
4337
4470
  // Start with 1 to enter the loop
4338
- iteration: currentIteration
4471
+ iteration: currentIteration,
4472
+ lastValidationErrors: []
4473
+ // Store the actual error details
4339
4474
  };
4340
4475
  while (validationResults.remainingErrors > 0 && currentIteration <= maxIterations) {
4341
4476
  console.log(`
@@ -4345,24 +4480,32 @@ Be thorough and methodical. Always use listDirectory to verify actual file exist
4345
4480
  Start by running validateCode with all validation types to get a complete picture of any issues, then systematically fix them.` : `Continue validation and fixing for the template integration at ${targetPath}. This is iteration ${currentIteration} of validation.
4346
4481
 
4347
4482
  Previous iterations may have fixed some issues, so start by re-running validateCode to see the current state, then fix any remaining issues.`;
4348
- const result = await validationAgent.stream(iterationPrompt, {
4349
- experimental_output: z.object({ success: z.boolean() })
4483
+ const isV2 = model.specificationVersion === "v2";
4484
+ const output = z.object({ success: z.boolean() });
4485
+ const result = isV2 ? await validationAgent.streamVNext(iterationPrompt, {
4486
+ output
4487
+ }) : await validationAgent.stream(iterationPrompt, {
4488
+ experimental_output: output
4350
4489
  });
4351
4490
  let iterationErrors = 0;
4352
4491
  let previousErrors = validationResults.remainingErrors;
4492
+ let lastValidationResult = null;
4353
4493
  for await (const chunk of result.fullStream) {
4354
4494
  if (chunk.type === "step-finish" || chunk.type === "step-start") {
4495
+ const chunkData = "payload" in chunk ? chunk.payload : chunk;
4355
4496
  console.log({
4356
4497
  type: chunk.type,
4357
- msgId: chunk.messageId,
4498
+ msgId: chunkData.messageId,
4358
4499
  iteration: currentIteration
4359
4500
  });
4360
4501
  } else {
4361
4502
  console.log(JSON.stringify(chunk, null, 2));
4362
4503
  }
4363
4504
  if (chunk.type === "tool-result") {
4364
- if (chunk.toolName === "validateCode") {
4365
- const toolResult = chunk.result;
4505
+ const chunkData = "payload" in chunk ? chunk.payload : chunk;
4506
+ if (chunkData.toolName === "validateCode") {
4507
+ const toolResult = chunkData.result;
4508
+ lastValidationResult = toolResult;
4366
4509
  if (toolResult?.summary) {
4367
4510
  iterationErrors = toolResult.summary.totalErrors || 0;
4368
4511
  console.log(`Iteration ${currentIteration}: Found ${iterationErrors} errors`);
@@ -4374,6 +4517,9 @@ Previous iterations may have fixed some issues, so start by re-running validateC
4374
4517
  validationResults.errorsFixed += Math.max(0, previousErrors - iterationErrors);
4375
4518
  validationResults.valid = iterationErrors === 0;
4376
4519
  validationResults.iteration = currentIteration;
4520
+ if (iterationErrors > 0 && lastValidationResult?.errors) {
4521
+ validationResults.lastValidationErrors = lastValidationResult.errors;
4522
+ }
4377
4523
  console.log(`Iteration ${currentIteration} complete: ${iterationErrors} errors remaining`);
4378
4524
  if (iterationErrors === 0) {
4379
4525
  console.log(`\u2705 All validation issues resolved in ${currentIteration} iterations!`);
@@ -4396,14 +4542,16 @@ Previous iterations may have fixed some issues, so start by re-running validateC
4396
4542
  } catch (commitError) {
4397
4543
  console.warn("Failed to commit validation fixes:", commitError);
4398
4544
  }
4545
+ const success = validationResults.valid;
4399
4546
  return {
4400
- success: true,
4547
+ success,
4401
4548
  applied: true,
4402
- message: `Validation completed in ${currentIteration} iteration${currentIteration > 1 ? "s" : ""}. ${validationResults.valid ? "All issues resolved!" : `${validationResults.remainingErrors} issues remaining`}`,
4549
+ message: `Validation completed in ${currentIteration} iteration${currentIteration > 1 ? "s" : ""}. ${validationResults.valid ? "All issues resolved!" : `${validationResults.remainingErrors} issue${validationResults.remainingErrors > 1 ? "s" : ""} remaining`}`,
4403
4550
  validationResults: {
4404
4551
  valid: validationResults.valid,
4405
4552
  errorsFixed: validationResults.errorsFixed,
4406
- remainingErrors: validationResults.remainingErrors
4553
+ remainingErrors: validationResults.remainingErrors,
4554
+ errors: validationResults.lastValidationErrors
4407
4555
  }
4408
4556
  };
4409
4557
  } catch (error) {
@@ -4497,7 +4645,8 @@ var agentBuilderTemplateWorkflow = createWorkflow({
4497
4645
  templateDir: cloneResult.templateDir,
4498
4646
  commitSha: cloneResult.commitSha,
4499
4647
  slug: cloneResult.slug,
4500
- targetPath: initData.targetPath
4648
+ targetPath: initData.targetPath,
4649
+ variables: initData.variables
4501
4650
  };
4502
4651
  }).then(programmaticFileCopyStep).map(async ({ getStepResult, getInitData }) => {
4503
4652
  const copyResult = getStepResult(programmaticFileCopyStep);
@@ -4564,6 +4713,9 @@ var agentBuilderTemplateWorkflow = createWorkflow({
4564
4713
  if (validationResult.validationResults?.errorsFixed > 0) {
4565
4714
  messages.push(`${validationResult.validationResults.errorsFixed} validation errors fixed`);
4566
4715
  }
4716
+ if (validationResult.validationResults?.remainingErrors > 0) {
4717
+ messages.push(`${validationResult.validationResults.remainingErrors} validation issues remain`);
4718
+ }
4567
4719
  const comprehensiveMessage = messages.length > 0 ? `Template merge completed: ${messages.join(", ")}` : validationResult.message || "Template merge completed";
4568
4720
  return {
4569
4721
  success: overallSuccess,
@@ -4935,8 +5087,9 @@ var planningIterationStep = createStep({
4935
5087
  `Current Q&A state: ${storedQAPairs.length} question-answer pairs, ${storedQAPairs.filter((p) => p.answer).length} answered`
4936
5088
  );
4937
5089
  try {
5090
+ const model = await resolveModel({ runtimeContext });
4938
5091
  const planningAgent = new Agent({
4939
- model: resolveModel(runtimeContext),
5092
+ model,
4940
5093
  instructions: taskPlanningPrompts.planningAgent.instructions({
4941
5094
  storedQAPairs
4942
5095
  }),
@@ -5662,8 +5815,9 @@ var workflowResearchStep = createStep({
5662
5815
  execute: async ({ inputData, runtimeContext }) => {
5663
5816
  console.log("Starting workflow research...");
5664
5817
  try {
5818
+ const model = await resolveModel({ runtimeContext });
5665
5819
  const researchAgent = new Agent({
5666
- model: resolveModel(runtimeContext),
5820
+ model,
5667
5821
  instructions: workflowBuilderPrompts.researchAgent.instructions,
5668
5822
  name: "Workflow Research Agent"
5669
5823
  // tools: filteredMcpTools,
@@ -5740,6 +5894,7 @@ var taskExecutionStep = createStep({
5740
5894
  console.log(`Starting task execution for ${action}ing workflow: ${workflowName}`);
5741
5895
  console.log(`Executing ${tasks.length} tasks using AgentBuilder stream...`);
5742
5896
  try {
5897
+ const model = await resolveModel({ runtimeContext });
5743
5898
  const currentProjectPath = projectPath || process.cwd();
5744
5899
  console.log("Pre-populating taskManager with planned tasks...");
5745
5900
  const taskManagerContext = {
@@ -5760,7 +5915,7 @@ var taskExecutionStep = createStep({
5760
5915
  }
5761
5916
  const executionAgent = new AgentBuilder({
5762
5917
  projectPath: currentProjectPath,
5763
- model: resolveModel(runtimeContext),
5918
+ model,
5764
5919
  tools: {
5765
5920
  "task-manager": restrictedTaskManager
5766
5921
  },
@@ -5827,7 +5982,7 @@ ${workflowBuilderPrompts.validation.instructions}`;
5827
5982
  const stream = await executionAgent.streamVNext(iterationPrompt, {
5828
5983
  structuredOutput: {
5829
5984
  schema: TaskExecutionIterationInputSchema(tasks.length),
5830
- model: resolveModel(runtimeContext)
5985
+ model
5831
5986
  },
5832
5987
  ...enhancedOptions
5833
5988
  });
@@ -5992,131 +6147,6 @@ var agentBuilderWorkflows = {
5992
6147
  "workflow-builder": workflowBuilderWorkflow
5993
6148
  };
5994
6149
 
5995
- // src/agent/index.ts
5996
- var AgentBuilder = class extends Agent {
5997
- builderConfig;
5998
- /**
5999
- * Constructor for AgentBuilder
6000
- */
6001
- constructor(config) {
6002
- const additionalInstructions = config.instructions ? `## Priority Instructions
6003
-
6004
- ${config.instructions}` : "";
6005
- const combinedInstructions = additionalInstructions + AgentBuilderDefaults.DEFAULT_INSTRUCTIONS(config.projectPath);
6006
- const agentConfig = {
6007
- name: "agent-builder",
6008
- description: "An AI agent specialized in generating Mastra agents, tools, and workflows from natural language requirements.",
6009
- instructions: combinedInstructions,
6010
- model: config.model,
6011
- tools: async () => {
6012
- return {
6013
- ...await AgentBuilderDefaults.DEFAULT_TOOLS(config.projectPath, config.mode),
6014
- ...config.tools || {}
6015
- };
6016
- },
6017
- workflows: agentBuilderWorkflows,
6018
- memory: new Memory({
6019
- options: AgentBuilderDefaults.DEFAULT_MEMORY_CONFIG,
6020
- processors: [
6021
- new WriteToDiskProcessor({ prefix: "before-filter" }),
6022
- new ToolSummaryProcessor({ summaryModel: config.summaryModel || config.model }),
6023
- new TokenLimiter(1e5),
6024
- new WriteToDiskProcessor({ prefix: "after-filter" })
6025
- ]
6026
- })
6027
- };
6028
- super(agentConfig);
6029
- this.builderConfig = config;
6030
- }
6031
- /**
6032
- * Enhanced generate method with AgentBuilder-specific configuration
6033
- * Overrides the base Agent generate method to provide additional project context
6034
- */
6035
- generate = async (messages, generateOptions = {}) => {
6036
- const { ...baseOptions } = generateOptions;
6037
- const originalInstructions = await this.getInstructions({ runtimeContext: generateOptions?.runtimeContext });
6038
- const additionalInstructions = baseOptions.instructions;
6039
- let enhancedInstructions = originalInstructions;
6040
- if (additionalInstructions) {
6041
- enhancedInstructions = `${originalInstructions}
6042
-
6043
- ${additionalInstructions}`;
6044
- }
6045
- const enhancedContext = [...baseOptions.context || []];
6046
- const enhancedOptions = {
6047
- ...baseOptions,
6048
- maxSteps: 300,
6049
- // Higher default for code generation
6050
- temperature: 0.3,
6051
- // Lower temperature for more consistent code generation
6052
- instructions: enhancedInstructions,
6053
- context: enhancedContext
6054
- };
6055
- this.logger.debug(`[AgentBuilder:${this.name}] Starting generation with enhanced context`, {
6056
- projectPath: this.builderConfig.projectPath
6057
- });
6058
- return super.generate(messages, enhancedOptions);
6059
- };
6060
- /**
6061
- * Enhanced stream method with AgentBuilder-specific configuration
6062
- * Overrides the base Agent stream method to provide additional project context
6063
- */
6064
- stream = async (messages, streamOptions = {}) => {
6065
- const { ...baseOptions } = streamOptions;
6066
- const originalInstructions = await this.getInstructions({ runtimeContext: streamOptions?.runtimeContext });
6067
- const additionalInstructions = baseOptions.instructions;
6068
- let enhancedInstructions = originalInstructions;
6069
- if (additionalInstructions) {
6070
- enhancedInstructions = `${originalInstructions}
6071
-
6072
- ${additionalInstructions}`;
6073
- }
6074
- const enhancedContext = [...baseOptions.context || []];
6075
- const enhancedOptions = {
6076
- ...baseOptions,
6077
- maxSteps: 100,
6078
- // Higher default for code generation
6079
- temperature: 0.3,
6080
- // Lower temperature for more consistent code generation
6081
- instructions: enhancedInstructions,
6082
- context: enhancedContext
6083
- };
6084
- this.logger.debug(`[AgentBuilder:${this.name}] Starting streaming with enhanced context`, {
6085
- projectPath: this.builderConfig.projectPath
6086
- });
6087
- return super.stream(messages, enhancedOptions);
6088
- };
6089
- /**
6090
- * Generate a Mastra agent from natural language requirements
6091
- */
6092
- async generateAgent(requirements, options) {
6093
- const prompt = `Generate a Mastra agent based on these requirements: ${requirements}
6094
-
6095
- Please provide:
6096
- 1. Complete agent code with proper configuration
6097
- 2. Any custom tools the agent needs
6098
- 3. Example usage
6099
- 4. Testing recommendations
6100
-
6101
- ${options?.outputFormat === "explanation" ? "Focus on explaining the approach and architecture." : ""}
6102
- ${options?.outputFormat === "code" ? "Focus on providing complete, working code." : ""}
6103
- ${!options?.outputFormat || options.outputFormat === "both" ? "Provide both explanation and complete code." : ""}`;
6104
- return this.generate(prompt, {
6105
- runtimeContext: options?.runtimeContext
6106
- });
6107
- }
6108
- /**
6109
- * Get the default configuration for AgentBuilder
6110
- */
6111
- static defaultConfig(projectPath) {
6112
- return {
6113
- instructions: AgentBuilderDefaults.DEFAULT_INSTRUCTIONS(projectPath),
6114
- memoryConfig: AgentBuilderDefaults.DEFAULT_MEMORY_CONFIG,
6115
- tools: AgentBuilderDefaults.DEFAULT_TOOLS
6116
- };
6117
- }
6118
- };
6119
-
6120
6150
  export { AgentBuilder, AgentBuilderDefaults, agentBuilderTemplateWorkflow, agentBuilderWorkflows, mergeTemplateBySlug, planningAndApprovalWorkflow, workflowBuilderWorkflow };
6121
6151
  //# sourceMappingURL=index.js.map
6122
6152
  //# sourceMappingURL=index.js.map