@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.
- package/.turbo/turbo-build.log +12 -0
- package/CHANGELOG.md +7 -16
- package/README.md +4 -17
- package/dist/_tsup-dts-rollup.d.cts +2442 -618
- package/dist/_tsup-dts-rollup.d.ts +2442 -618
- package/dist/index.cjs +1134 -549
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1131 -553
- package/integration-tests/CHANGELOG.md +4 -15
- package/integration-tests/docker-compose.yml +3 -3
- package/integration-tests/package.json +3 -3
- package/integration-tests/src/agent-template-behavior.test.ts +1 -1
- package/integration-tests/src/fixtures/minimal-mastra-project/package.json +2 -2
- package/integration-tests/src/fixtures/minimal-mastra-project/src/mastra/tools/weather.ts +2 -1
- package/integration-tests/src/template-integration.test.ts +8 -8
- package/integration-tests/tsconfig.json +2 -6
- package/integration-tests/vitest.config.ts +1 -0
- package/package.json +7 -6
- package/src/agent/index.ts +187 -0
- package/src/agent-builder.test.ts +34 -12
- package/src/defaults.ts +292 -144
- package/src/index.ts +3 -187
- package/src/processors/tool-summary.ts +18 -9
- package/src/processors/write-file.ts +1 -1
- package/src/types.ts +188 -3
- package/src/utils.ts +289 -13
- package/src/workflows/index.ts +1 -1541
- package/src/workflows/template-builder.ts +1682 -0
|
@@ -1,20 +1,9 @@
|
|
|
1
1
|
# @mastra/agent-builder-integration-tests
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.1.1-alpha.0
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
- Updated dependencies [
|
|
8
|
-
-
|
|
9
|
-
-
|
|
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
|
-
- '
|
|
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
|
-
- '
|
|
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
|
-
- '
|
|
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.
|
|
4
|
+
"version": "0.1.1-alpha.0",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"test": "vitest run
|
|
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": "
|
|
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
|
-
},
|
|
102
|
+
}, 600000); // Longer timeout for full merge operation
|
|
103
103
|
});
|
|
@@ -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
|
|
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 {
|
|
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
|
-
|
|
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(`
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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(`
|
|
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
|
-
},
|
|
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"]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/agent-builder",
|
|
3
|
-
"version": "0.0.
|
|
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.
|
|
27
|
-
"@mastra/memory": "0.
|
|
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
|
-
"@
|
|
38
|
-
"@
|
|
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-
|
|
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('
|
|
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
|
-
|
|
30
|
-
tokenLimit: 10000,
|
|
29
|
+
lastMessages: 20,
|
|
31
30
|
});
|
|
32
31
|
});
|
|
33
32
|
|
|
34
|
-
it('should have default tools', () => {
|
|
35
|
-
|
|
36
|
-
expect(
|
|
37
|
-
expect(
|
|
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(
|
|
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
|
});
|