@mastra/agent-builder 0.0.0-experimental-agent-builder-20250815195917 → 0.0.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,20 +1,9 @@
1
1
  # @mastra/agent-builder-integration-tests
2
2
 
3
- ## 0.0.0-experimental-agent-builder-20250815195917
3
+ ## 0.1.1-alpha.0
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - Updated dependencies [8e59433]
8
- - Updated dependencies [49281f5]
9
- - Updated dependencies [6faaee5]
10
- - Updated dependencies [4232b14]
11
- - Updated dependencies [6720c51]
12
- - Updated dependencies [2256977]
13
- - Updated dependencies [c597dc5]
14
- - Updated dependencies [a722c0b]
15
- - Updated dependencies [c30bca8]
16
- - Updated dependencies [7444737]
17
- - Updated dependencies [83d180b]
18
- - Updated dependencies [3b5fec7]
19
- - @mastra/core@0.0.0-experimental-agent-builder-20250815195917
20
- - @mastra/agent-builder@0.0.0-experimental-agent-builder-20250815195917
7
+ - Updated dependencies [[`aedbbfa`](https://github.com/mastra-ai/mastra/commit/aedbbfa064124ddde039111f12629daebfea7e48), [`f643c65`](https://github.com/mastra-ai/mastra/commit/f643c651bdaf57c2343cf9dbfc499010495701fb), [`fef7375`](https://github.com/mastra-ai/mastra/commit/fef737534574f41b432a7361a285f776c3bac42b), [`e3d8fea`](https://github.com/mastra-ai/mastra/commit/e3d8feaacfb8b5c5c03c13604cc06ea2873d45fe), [`48b9e55`](https://github.com/mastra-ai/mastra/commit/48b9e553a39528dcc20fbbeb798c3b1a1961468e), [`3412597`](https://github.com/mastra-ai/mastra/commit/3412597a6644c0b6bf3236d6e319ed1450c5bae8)]:
8
+ - @mastra/core@0.15.3-alpha.3
9
+ - @mastra/agent-builder@0.0.1-alpha.1
@@ -2,7 +2,7 @@ services:
2
2
  postgres:
3
3
  image: ankane/pgvector:v0.5.1
4
4
  ports:
5
- - '5434:5432'
5
+ - '5435:5432'
6
6
  environment:
7
7
  POSTGRES_USER: postgres
8
8
  POSTGRES_PASSWORD: password
@@ -17,7 +17,7 @@ services:
17
17
  redis:
18
18
  image: redis:7-alpine
19
19
  ports:
20
- - '6370:6379'
20
+ - '6371:6379'
21
21
  command: redis-server --requirepass redis_password
22
22
  healthcheck:
23
23
  test: ['CMD', 'redis-cli', 'ping']
@@ -27,7 +27,7 @@ services:
27
27
  serverless-redis-http:
28
28
  image: hiett/serverless-redis-http:latest
29
29
  ports:
30
- - '8079:80'
30
+ - '8080:80'
31
31
  environment:
32
32
  SRH_MODE: env
33
33
  SRH_TOKEN: test_token
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@mastra/agent-builder-integration-tests",
3
3
  "private": true,
4
- "version": "0.0.0-experimental-agent-builder-20250815195917",
4
+ "version": "0.1.1-alpha.0",
5
5
  "scripts": {
6
- "test": "vitest run ./src/**/*.test.ts",
6
+ "test": "vitest run",
7
7
  "test:agent": "vitest run ./src/agent-template-behavior.test.ts",
8
8
  "test:template": "vitest run ./src/template-integration.test.ts",
9
9
  "dev": "mastra dev"
@@ -33,6 +33,6 @@
33
33
  "vitest": "^3.2.4"
34
34
  },
35
35
  "peerDependencies": {
36
- "@mastra/core": "workspace:*"
36
+ "@mastra/core": ">=0.15.2-0 <0.16.0-0"
37
37
  }
38
38
  }
@@ -99,5 +99,5 @@ Template repository: ${realTemplateGit}`;
99
99
 
100
100
  // Verify response contains confirmation
101
101
  expect(response.text.toLowerCase()).toMatch(/merge|template|success|applied|complete/);
102
- }, 300000); // Longer timeout for full merge operation
102
+ }, 600000); // Longer timeout for full merge operation
103
103
  });
@@ -7,8 +7,8 @@
7
7
  "build": "mastra build"
8
8
  },
9
9
  "dependencies": {
10
- "@mastra/core": "workspace:*",
11
- "@mastra/mcp": "workspace:*",
10
+ "@mastra/core": "latest",
11
+ "@mastra/mcp": "latest",
12
12
  "zod": "^3.25.0"
13
13
  },
14
14
  "devDependencies": {
@@ -7,7 +7,8 @@ export const weatherTool = createTool({
7
7
  inputSchema: z.object({
8
8
  postalCode: z.string().describe('The location to get the weather for'),
9
9
  }),
10
- execute: async ({ context: { postalCode } }) => {
10
+ execute: async ({ context }) => {
11
+ const { postalCode } = context;
11
12
  return `The weather in ${postalCode} is sunny. It is currently 70 degrees and feels like 65 degrees.`;
12
13
  },
13
14
  });
@@ -6,7 +6,7 @@ import { join, resolve } from 'node:path';
6
6
  import { Mastra } from '@mastra/core';
7
7
  import { describe, expect, it, beforeAll, afterAll } from 'vitest';
8
8
  import { fetchMastraTemplates } from '../../src/utils';
9
- import { mergeTemplateWorkflow } from '../../src/workflows';
9
+ import { agentBuilderTemplateWorkflow } from '../../src/workflows';
10
10
 
11
11
  function exec(cmd: string, cwd?: string): string {
12
12
  return execSync(cmd, { stdio: 'pipe', cwd, encoding: 'utf-8' });
@@ -36,7 +36,7 @@ describe('Template Workflow Integration Tests', () => {
36
36
  beforeAll(async () => {
37
37
  mastraInstance = new Mastra({
38
38
  workflows: {
39
- mergeTemplateWorkflow,
39
+ agentBuilderTemplateWorkflow,
40
40
  },
41
41
  });
42
42
 
@@ -92,7 +92,7 @@ describe('Template Workflow Integration Tests', () => {
92
92
 
93
93
  console.log(`Starting template merge workflow in ${targetRepo}`);
94
94
 
95
- const templateWorkflow = mastraInstance.getWorkflow(`mergeTemplateWorkflow`);
95
+ const templateWorkflow = mastraInstance.getWorkflow(`agentBuilderTemplateWorkflow`);
96
96
 
97
97
  // Run the merge template workflow
98
98
  const workflowRun = await templateWorkflow.createRunAsync();
@@ -141,7 +141,7 @@ describe('Template Workflow Integration Tests', () => {
141
141
  expect(hasTemplateScript).toBe(true);
142
142
 
143
143
  console.log('Template merge completed successfully');
144
- }, 300000); // 5 minute timeout for full workflow
144
+ }, 600000); // 10 minute timeout for full workflow
145
145
 
146
146
  it('should start Mastra server and validate both original and new agents work', async () => {
147
147
  // Skip test if no OPENAI_API_KEY available
@@ -164,7 +164,7 @@ describe('Template Workflow Integration Tests', () => {
164
164
  let output = '';
165
165
  const timeout = setTimeout(() => {
166
166
  reject(new Error('Mastra server failed to start within timeout'));
167
- }, 300000);
167
+ }, 600000);
168
168
 
169
169
  mastraServer.stdout?.on('data', data => {
170
170
  output += data.toString();
@@ -248,7 +248,7 @@ describe('Template Workflow Integration Tests', () => {
248
248
  expect(hasCSVWorkflow).toBe(true);
249
249
 
250
250
  console.log('All agent and workflow tests passed!');
251
- }, 300000); // 5 minute timeout for server startup and testing
251
+ }, 600000); // 10 minute timeout for server startup and testing
252
252
 
253
253
  it('should validate git history shows proper template integration', async () => {
254
254
  // Check git log for template commits
@@ -285,7 +285,7 @@ describe('Template Workflow Integration Tests', () => {
285
285
 
286
286
  console.log('Testing duplicate template merge...');
287
287
 
288
- const templateWorkflow = mastraInstance.getWorkflow(`mergeTemplateWorkflow`);
288
+ const templateWorkflow = mastraInstance.getWorkflow(`agentBuilderTemplateWorkflow`);
289
289
  const workflowRun = await templateWorkflow.createRunAsync();
290
290
  const result = await workflowRun.start({
291
291
  inputData: {
@@ -308,5 +308,5 @@ describe('Template Workflow Integration Tests', () => {
308
308
  }
309
309
 
310
310
  console.log('Duplicate merge test completed');
311
- }, 300000);
311
+ }, 600000);
312
312
  });
@@ -1,12 +1,8 @@
1
1
  {
2
+ "extends": "../../../tsconfig.node.json",
2
3
  "compilerOptions": {
3
- "target": "ES2020",
4
4
  "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "strict": true,
7
- "esModuleInterop": true,
8
- "skipLibCheck": true,
9
- "forceConsistentCasingInFileNames": true
5
+ "moduleResolution": "bundler"
10
6
  },
11
7
  "include": ["src/**/*"],
12
8
  "exclude": ["node_modules"]
@@ -5,6 +5,7 @@ export default defineConfig({
5
5
  pool: 'forks',
6
6
  globals: true,
7
7
  environment: 'node',
8
+ include: ['src/**/*.test.ts'],
8
9
  testTimeout: 120000,
9
10
  hookTimeout: 60000,
10
11
  coverage: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/agent-builder",
3
- "version": "0.0.0-experimental-agent-builder-20250815195917",
3
+ "version": "0.0.1-alpha.1",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,11 +20,12 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@ai-sdk/openai": "^1.3.0",
23
+ "ignore": "^7.0.5",
23
24
  "semver": "^7.7.2",
24
25
  "swpm": "^2.6.0",
25
26
  "zod": "^3.25.67",
26
- "@mastra/mcp": "0.0.0-experimental-agent-builder-20250815195917",
27
- "@mastra/memory": "0.0.0-experimental-agent-builder-20250815195917"
27
+ "@mastra/mcp": "0.11.3-alpha.0",
28
+ "@mastra/memory": "0.14.3-alpha.0"
28
29
  },
29
30
  "devDependencies": {
30
31
  "@types/node": "^20.19.0",
@@ -34,11 +35,11 @@
34
35
  "typescript": "^5.8.3",
35
36
  "typescript-eslint": "^8.38.0",
36
37
  "vitest": "^3.2.4",
37
- "@internal/lint": "0.0.0-experimental-agent-builder-20250815195917",
38
- "@mastra/core": "0.0.0-experimental-agent-builder-20250815195917"
38
+ "@mastra/core": "0.15.3-alpha.3",
39
+ "@internal/lint": "0.0.34"
39
40
  },
40
41
  "peerDependencies": {
41
- "@mastra/core": "0.0.0-experimental-agent-builder-20250815195917"
42
+ "@mastra/core": ">=0.10.7-0 <0.14.0-0"
42
43
  },
43
44
  "engines": {
44
45
  "node": ">=20"
@@ -0,0 +1,187 @@
1
+ import type { CoreMessage } from '@mastra/core';
2
+ import { Agent } from '@mastra/core/agent';
3
+ import type { AiMessageType, AgentGenerateOptions, AgentStreamOptions } from '@mastra/core/agent';
4
+ import { Memory } from '@mastra/memory';
5
+ import { TokenLimiter } from '@mastra/memory/processors';
6
+ import { AgentBuilderDefaults } from '../defaults';
7
+ import { ToolSummaryProcessor } from '../processors/tool-summary';
8
+ import { WriteToDiskProcessor } from '../processors/write-file';
9
+ import type { AgentBuilderConfig, GenerateAgentOptions } from '../types';
10
+ import { agentBuilderTemplateWorkflow } from '../workflows';
11
+
12
+ // =============================================================================
13
+ // Template Merge Workflow Implementation
14
+ // =============================================================================
15
+ //
16
+ // This workflow implements a comprehensive template merging system that:
17
+ // 1. Clones template repositories at specific refs (tags/commits)
18
+ // 2. Discovers units (agents, workflows, MCP servers/tools) in templates
19
+ // 3. Topologically orders units based on dependencies
20
+ // 4. Analyzes conflicts and creates safety classifications
21
+ // 5. Applies changes with git branching and checkpoints per unit
22
+ //
23
+ // The workflow follows the "auto-decide vs ask" principles:
24
+ // - Auto: adding new files, missing deps, appending arrays, new scripts with template:slug:* namespace
25
+ // - Prompt: overwriting files, major upgrades, renaming conflicts, new ports, postInstall commands
26
+ // - Block: removing files, downgrading deps, changing TS target/module, modifying CI/CD secrets
27
+ //
28
+ // Usage with Mastra templates (see https://mastra.ai/api/templates.json):
29
+ // const run = await agentBuilderTemplateWorkflow.createRunAsync();
30
+ // const result = await run.start({
31
+ // inputData: {
32
+ // repo: 'https://github.com/mastra-ai/template-pdf-questions',
33
+ // ref: 'main', // optional
34
+ // targetPath: './my-project', // optional, defaults to cwd
35
+ // }
36
+ // });
37
+ // // The workflow will automatically analyze and merge the template structure
38
+ //
39
+ // =============================================================================
40
+
41
+ export class AgentBuilder extends Agent {
42
+ private builderConfig: AgentBuilderConfig;
43
+
44
+ /**
45
+ * Constructor for AgentBuilder
46
+ */
47
+ constructor(config: AgentBuilderConfig) {
48
+ const additionalInstructions = config.instructions ? `## Priority Instructions \n\n${config.instructions}` : '';
49
+ const combinedInstructions = additionalInstructions + AgentBuilderDefaults.DEFAULT_INSTRUCTIONS(config.projectPath);
50
+
51
+ const agentConfig = {
52
+ name: 'agent-builder',
53
+ description:
54
+ 'An AI agent specialized in generating Mastra agents, tools, and workflows from natural language requirements.',
55
+ instructions: combinedInstructions,
56
+ model: config.model,
57
+ tools: async () => {
58
+ return {
59
+ ...(await AgentBuilderDefaults.DEFAULT_TOOLS(config.projectPath, config.mode)),
60
+ ...(config.tools || {}),
61
+ };
62
+ },
63
+ workflows: {
64
+ 'merge-template': agentBuilderTemplateWorkflow,
65
+ },
66
+ memory: new Memory({
67
+ options: AgentBuilderDefaults.DEFAULT_MEMORY_CONFIG,
68
+ processors: [
69
+ new WriteToDiskProcessor({ prefix: 'before-filter' }),
70
+ new ToolSummaryProcessor({ summaryModel: config.summaryModel || config.model }),
71
+ new TokenLimiter(100000),
72
+ new WriteToDiskProcessor({ prefix: 'after-filter' }),
73
+ ],
74
+ }),
75
+ };
76
+
77
+ super(agentConfig);
78
+ this.builderConfig = config;
79
+ }
80
+
81
+ /**
82
+ * Enhanced generate method with AgentBuilder-specific configuration
83
+ * Overrides the base Agent generate method to provide additional project context
84
+ */
85
+ generate: Agent['generate'] = async (
86
+ messages: string | string[] | CoreMessage[] | AiMessageType[],
87
+ generateOptions: (GenerateAgentOptions & AgentGenerateOptions<any, any>) | undefined = {},
88
+ ): Promise<any> => {
89
+ const { ...baseOptions } = generateOptions;
90
+
91
+ const originalInstructions = await this.getInstructions({ runtimeContext: generateOptions?.runtimeContext });
92
+ const additionalInstructions = baseOptions.instructions;
93
+
94
+ let enhancedInstructions = originalInstructions as string;
95
+ if (additionalInstructions) {
96
+ enhancedInstructions = `${originalInstructions}\n\n${additionalInstructions}`;
97
+ }
98
+
99
+ const enhancedContext = [...(baseOptions.context || [])];
100
+
101
+ const enhancedOptions = {
102
+ ...baseOptions,
103
+ maxSteps: 300, // Higher default for code generation
104
+ temperature: 0.3, // Lower temperature for more consistent code generation
105
+ instructions: enhancedInstructions,
106
+ context: enhancedContext,
107
+ } satisfies AgentGenerateOptions<any, any>;
108
+
109
+ this.logger.debug(`[AgentBuilder:${this.name}] Starting generation with enhanced context`, {
110
+ projectPath: this.builderConfig.projectPath,
111
+ });
112
+
113
+ return super.generate(messages, enhancedOptions);
114
+ };
115
+
116
+ /**
117
+ * Enhanced stream method with AgentBuilder-specific configuration
118
+ * Overrides the base Agent stream method to provide additional project context
119
+ */
120
+ stream: Agent['stream'] = async (
121
+ messages: string | string[] | CoreMessage[] | AiMessageType[],
122
+ streamOptions: (GenerateAgentOptions & AgentStreamOptions<any, any>) | undefined = {},
123
+ ): Promise<any> => {
124
+ const { ...baseOptions } = streamOptions;
125
+
126
+ const originalInstructions = await this.getInstructions({ runtimeContext: streamOptions?.runtimeContext });
127
+ const additionalInstructions = baseOptions.instructions;
128
+
129
+ let enhancedInstructions = originalInstructions as string;
130
+ if (additionalInstructions) {
131
+ enhancedInstructions = `${originalInstructions}\n\n${additionalInstructions}`;
132
+ }
133
+ const enhancedContext = [...(baseOptions.context || [])];
134
+
135
+ const enhancedOptions = {
136
+ ...baseOptions,
137
+ maxSteps: 100, // Higher default for code generation
138
+ temperature: 0.3, // Lower temperature for more consistent code generation
139
+ instructions: enhancedInstructions,
140
+ context: enhancedContext,
141
+ };
142
+
143
+ this.logger.debug(`[AgentBuilder:${this.name}] Starting streaming with enhanced context`, {
144
+ projectPath: this.builderConfig.projectPath,
145
+ });
146
+
147
+ return super.stream(messages, enhancedOptions);
148
+ };
149
+
150
+ /**
151
+ * Generate a Mastra agent from natural language requirements
152
+ */
153
+ async generateAgent(
154
+ requirements: string,
155
+ options?: {
156
+ outputFormat?: 'code' | 'explanation' | 'both';
157
+ runtimeContext?: any;
158
+ },
159
+ ) {
160
+ const prompt = `Generate a Mastra agent based on these requirements: ${requirements}
161
+
162
+ Please provide:
163
+ 1. Complete agent code with proper configuration
164
+ 2. Any custom tools the agent needs
165
+ 3. Example usage
166
+ 4. Testing recommendations
167
+
168
+ ${options?.outputFormat === 'explanation' ? 'Focus on explaining the approach and architecture.' : ''}
169
+ ${options?.outputFormat === 'code' ? 'Focus on providing complete, working code.' : ''}
170
+ ${!options?.outputFormat || options.outputFormat === 'both' ? 'Provide both explanation and complete code.' : ''}`;
171
+
172
+ return this.generate(prompt, {
173
+ runtimeContext: options?.runtimeContext,
174
+ });
175
+ }
176
+
177
+ /**
178
+ * Get the default configuration for AgentBuilder
179
+ */
180
+ static defaultConfig(projectPath?: string) {
181
+ return {
182
+ instructions: AgentBuilderDefaults.DEFAULT_INSTRUCTIONS(projectPath),
183
+ memoryConfig: AgentBuilderDefaults.DEFAULT_MEMORY_CONFIG,
184
+ tools: AgentBuilderDefaults.DEFAULT_TOOLS,
185
+ };
186
+ }
187
+ }
@@ -21,20 +21,20 @@ const mockConfig = {
21
21
  describe('AgentBuilder', () => {
22
22
  describe('AgentBuilderDefaults', () => {
23
23
  it('should have default instructions', () => {
24
- expect(AgentBuilderDefaults.DEFAULT_INSTRUCTIONS).toContain('expert Mastra Agent Builder');
24
+ expect(AgentBuilderDefaults.DEFAULT_INSTRUCTIONS()).toContain('Mastra Expert Agent');
25
25
  });
26
26
 
27
27
  it('should have default memory config', () => {
28
28
  expect(AgentBuilderDefaults.DEFAULT_MEMORY_CONFIG).toEqual({
29
- maxMessages: 20,
30
- tokenLimit: 10000,
29
+ lastMessages: 20,
31
30
  });
32
31
  });
33
32
 
34
- it('should have default tools', () => {
35
- expect(AgentBuilderDefaults.DEFAULT_TOOLS).toHaveProperty('manageProject');
36
- expect(AgentBuilderDefaults.DEFAULT_TOOLS).toHaveProperty('searchReplace');
37
- expect(AgentBuilderDefaults.DEFAULT_TOOLS).toHaveProperty('validateCode');
33
+ it('should have default tools', async () => {
34
+ const tools = await AgentBuilderDefaults.DEFAULT_TOOLS('test');
35
+ expect(tools).toHaveProperty('manageProject');
36
+ expect(tools).toHaveProperty('multiEdit');
37
+ expect(tools).toHaveProperty('validateCode');
38
38
  });
39
39
  });
40
40
 
@@ -170,6 +170,32 @@ describe('AgentBuilder', () => {
170
170
  expect(key1).toBe(key2);
171
171
  expect(key1).toBe('myTool:{"a":1,"b":2}');
172
172
  });
173
+
174
+ it('should use Promise.allSettled for resilient parallel processing', async () => {
175
+ // This test verifies that the ToolSummaryProcessor uses Promise.allSettled
176
+ // instead of Promise.all, so that one failed summary doesn't break all summaries
177
+
178
+ const processor = new ToolSummaryProcessor({ summaryModel: mockModel });
179
+
180
+ // Test that the processor handles empty messages gracefully
181
+ const emptyMessages: any[] = [];
182
+ const result = await processor.process(emptyMessages);
183
+ expect(result).toEqual([]);
184
+
185
+ // Test that the processor doesn't throw when processing messages
186
+ // (the actual resilience testing would require more complex mocking,
187
+ // but this ensures the basic structure works)
188
+ const basicMessages = [
189
+ {
190
+ role: 'user' as const,
191
+ content: 'Hello',
192
+ },
193
+ ];
194
+
195
+ const basicResult = await processor.process(basicMessages);
196
+ expect(basicResult).toHaveLength(1);
197
+ expect(basicResult[0].content).toBe('Hello');
198
+ });
173
199
  });
174
200
 
175
201
  describe('Server Management Tools', () => {
@@ -279,13 +305,9 @@ Found 2 errors in 2 files.`;
279
305
  it('should include validation workflow in instructions', () => {
280
306
  const instructions = AgentBuilderDefaults.DEFAULT_INSTRUCTIONS('/test/path');
281
307
 
282
- expect(instructions).toContain('VALIDATE CODE AFTER CHANGES');
283
308
  expect(instructions).toContain('validateCode');
284
- expect(instructions).toContain("['types', 'lint']");
309
+ expect(instructions).toContain('Run \`validateCode\` with types and lint checks');
285
310
  expect(instructions).toContain('Re-validate until clean');
286
- expect(instructions).toContain(
287
- 'Documentation → Web Research → Clarification → Project Exploration → Implementation → Validation',
288
- );
289
311
  });
290
312
  });
291
313
  });