@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/CHANGELOG.md +16 -0
- package/README.md +3 -3
- package/dist/agent/index.d.ts +9 -5863
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/defaults.d.ts +126 -3107
- package/dist/defaults.d.ts.map +1 -1
- package/dist/index.js +870 -840
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +24 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +9 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/workflows/task-planning/schema.d.ts +10 -10
- package/dist/workflows/task-planning/task-planning.d.ts +20 -20
- package/dist/workflows/task-planning/task-planning.d.ts.map +1 -1
- package/dist/workflows/template-builder/template-builder.d.ts +64 -6
- package/dist/workflows/template-builder/template-builder.d.ts.map +1 -1
- package/dist/workflows/workflow-builder/schema.d.ts +22 -22
- package/dist/workflows/workflow-builder/workflow-builder.d.ts +56 -56
- package/dist/workflows/workflow-builder/workflow-builder.d.ts.map +1 -1
- package/dist/workflows/workflow-map.d.ts +93 -60
- package/dist/workflows/workflow-map.d.ts.map +1 -1
- package/package.json +12 -4
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/
|
|
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"
|
|
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
|
|
932
|
-
|
|
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
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
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
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
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
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
).
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
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
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
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:
|
|
1541
|
+
message: "Packages array is required for install action"
|
|
1468
1542
|
};
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
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
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
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
|
-
|
|
1537
|
-
|
|
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
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
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: "
|
|
1548
|
-
message: `
|
|
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
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
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
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
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
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
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
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
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
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
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
|
-
|
|
3301
|
-
|
|
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
|
|
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
|
|
3436
|
-
|
|
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
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
4250
|
+
msgId: chunkData.messageId
|
|
4122
4251
|
});
|
|
4123
4252
|
} else {
|
|
4124
4253
|
console.log(JSON.stringify(chunk, null, 2));
|
|
4125
|
-
if (chunk.type === "tool-result"
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
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
|
|
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
|
|
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
|
|
4349
|
-
|
|
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:
|
|
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
|
-
|
|
4365
|
-
|
|
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
|
|
4547
|
+
success,
|
|
4401
4548
|
applied: true,
|
|
4402
|
-
message: `Validation completed in ${currentIteration} iteration${currentIteration > 1 ? "s" : ""}. ${validationResults.valid ? "All issues resolved!" : `${validationResults.remainingErrors}
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|