mastra-starter 1.0.4 → 1.0.6
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/.env.example +2 -0
- package/index.mjs +51 -3
- package/package.json +3 -2
- package/src/mastra/agents/index.ts +44 -5
- package/util.mjs +63 -4
package/.env.example
ADDED
package/index.mjs
CHANGED
@@ -2,12 +2,11 @@
|
|
2
2
|
|
3
3
|
import path from 'path';
|
4
4
|
import fs from 'fs';
|
5
|
-
import child_process from 'child_process';
|
6
5
|
|
7
6
|
import { Command } from 'commander';
|
8
7
|
import dotenv from 'dotenv';
|
9
8
|
|
10
|
-
import { runCharacter, installPackages } from './util.mjs';
|
9
|
+
import { runCharacter, installPackages, buildPackages } from './util.mjs';
|
11
10
|
|
12
11
|
const main = async () => {
|
13
12
|
dotenv.config();
|
@@ -27,7 +26,9 @@ const main = async () => {
|
|
27
26
|
const characterJsonPath = path.resolve(process.cwd(), character);
|
28
27
|
|
29
28
|
try {
|
30
|
-
await runCharacter(characterJsonPath
|
29
|
+
await runCharacter(characterJsonPath, {
|
30
|
+
env: process.env,
|
31
|
+
});
|
31
32
|
} catch (error) {
|
32
33
|
console.error(`Error in dev command: ${error.message}`);
|
33
34
|
}
|
@@ -42,6 +43,7 @@ const main = async () => {
|
|
42
43
|
.action(async (packages) => {
|
43
44
|
try {
|
44
45
|
await installPackages(packages);
|
46
|
+
await buildPackages(packages);
|
45
47
|
} catch (error) {
|
46
48
|
console.error(`Error in install command: ${error.message}`);
|
47
49
|
}
|
@@ -73,12 +75,58 @@ const main = async () => {
|
|
73
75
|
}
|
74
76
|
|
75
77
|
await installPackages([...pluginsToInstall]);
|
78
|
+
await buildPackages([...pluginsToInstall]);
|
76
79
|
} catch (error) {
|
77
80
|
console.error(`Error in installall command: ${error.message}`);
|
78
81
|
}
|
79
82
|
process.exit(1);
|
80
83
|
});
|
81
84
|
|
85
|
+
program
|
86
|
+
.command('build')
|
87
|
+
.alias('b')
|
88
|
+
.description('Build packages without installing them')
|
89
|
+
.argument('<packages...>', 'packages to build')
|
90
|
+
.action(async (packages) => {
|
91
|
+
try {
|
92
|
+
await buildPackages(packages);
|
93
|
+
} catch (error) {
|
94
|
+
console.error(`Error in build command: ${error.message}`);
|
95
|
+
}
|
96
|
+
process.exit(1);
|
97
|
+
});
|
98
|
+
|
99
|
+
program
|
100
|
+
.command('buildall')
|
101
|
+
.alias('ba')
|
102
|
+
.description('Build all plugins from character.json files')
|
103
|
+
.argument('<files...>', 'character.json file paths')
|
104
|
+
.action(async (files) => {
|
105
|
+
try {
|
106
|
+
const pluginsToBuild = new Set();
|
107
|
+
|
108
|
+
for (const file of files) {
|
109
|
+
const characterJsonPath = path.resolve(process.cwd(), file);
|
110
|
+
const characterJsonString = await fs.promises.readFile(characterJsonPath, 'utf8');
|
111
|
+
const characterJson = JSON.parse(characterJsonString);
|
112
|
+
|
113
|
+
if (characterJson.plugins && Array.isArray(characterJson.plugins)) {
|
114
|
+
characterJson.plugins.forEach(plugin => pluginsToBuild.add(plugin));
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
if (pluginsToBuild.size === 0) {
|
119
|
+
console.log('No plugins found to build');
|
120
|
+
return;
|
121
|
+
}
|
122
|
+
|
123
|
+
await buildPackages([...pluginsToBuild]);
|
124
|
+
} catch (error) {
|
125
|
+
console.error(`Error in buildall command: ${error.message}`);
|
126
|
+
}
|
127
|
+
process.exit(1);
|
128
|
+
});
|
129
|
+
|
82
130
|
program.parse(process.argv);
|
83
131
|
};
|
84
132
|
(async () => {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "mastra-starter",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.6",
|
4
4
|
"main": "index.mjs",
|
5
5
|
"bin": {
|
6
6
|
"mastra-starter": "./index.mjs"
|
@@ -15,13 +15,14 @@
|
|
15
15
|
"type": "module",
|
16
16
|
"dependencies": {
|
17
17
|
"@ai-sdk/openai": "^1.2.2",
|
18
|
+
"@mastra/composio": "^0.1.9",
|
18
19
|
"@mastra/core": "^0.5.0",
|
19
20
|
"@mastra/mcp": "^0.3.0",
|
20
21
|
"commander": "^13.1.0",
|
21
22
|
"dedent": "^1.5.3",
|
22
23
|
"dotenv": "^16.4.7",
|
23
24
|
"mastra": "^0.3.0",
|
24
|
-
"pnpm-package-lookup": "^0.0.
|
25
|
+
"pnpm-package-lookup": "^0.0.2",
|
25
26
|
"yaml": "^2.7.0",
|
26
27
|
"zod": "^3.24.2"
|
27
28
|
},
|
@@ -1,22 +1,35 @@
|
|
1
1
|
import fs from 'fs';
|
2
2
|
import path from 'path';
|
3
3
|
import { openai } from '@ai-sdk/openai';
|
4
|
-
import { Agent } from '@mastra/core/agent';
|
4
|
+
import { Agent, ToolsInput } from '@mastra/core/agent';
|
5
5
|
import dedent from 'dedent';
|
6
6
|
import { MCPConfiguration } from "@mastra/mcp";
|
7
|
+
import { ComposioIntegration } from '@mastra/composio';
|
7
8
|
import { PnpmPackageLookup } from 'pnpm-package-lookup';
|
8
9
|
|
10
|
+
// character
|
9
11
|
const packageLookup = new PnpmPackageLookup({
|
10
12
|
pnpmLockYamlPath: path.join('..', '..', 'pnpm-lock.yaml'),
|
11
13
|
});
|
12
|
-
|
13
|
-
const characterJsonPath = process.env.CHARACTER_JSON_PATH as string;
|
14
|
+
const characterJsonPath = process.env._CHARACTER_JSON_PATH as string;
|
14
15
|
const characterJsonString = await fs.promises.readFile(characterJsonPath, 'utf8');
|
15
16
|
const characterJson = JSON.parse(characterJsonString);
|
17
|
+
|
18
|
+
// sort plugins
|
16
19
|
const { plugins = [] } = characterJson;
|
20
|
+
const npmPlugins: string[] = [];
|
21
|
+
const composioPlugins: string[] = [];
|
22
|
+
for (const plugin of plugins) {
|
23
|
+
if (plugin.startsWith('composio:')) {
|
24
|
+
composioPlugins.push(plugin);
|
25
|
+
} else {
|
26
|
+
npmPlugins.push(plugin);
|
27
|
+
}
|
28
|
+
}
|
17
29
|
|
30
|
+
// resolve npm plugins
|
18
31
|
const servers: Record<string, any> = {};
|
19
|
-
for (const plugin of
|
32
|
+
for (const plugin of npmPlugins) {
|
20
33
|
// find the package name matching this specifier
|
21
34
|
const packageName = await packageLookup.getPackageNameBySpecifier(plugin);
|
22
35
|
if (!packageName) {
|
@@ -30,15 +43,41 @@ for (const plugin of plugins) {
|
|
30
43
|
env: process.env as any,
|
31
44
|
};
|
32
45
|
}
|
46
|
+
|
47
|
+
// mcp tools
|
33
48
|
const mcp = new MCPConfiguration({
|
34
49
|
servers,
|
35
50
|
});
|
51
|
+
const mcpTools = await mcp.getTools();
|
52
|
+
|
53
|
+
// composio tools
|
54
|
+
const composio = new ComposioIntegration({
|
55
|
+
config: {
|
56
|
+
API_KEY: process.env.COMPOSIO_API_KEY!,
|
57
|
+
entityId: 'default',
|
58
|
+
// connectedAccountId: '899144e5-a466-428b-8a00-7c931fb57f9f',
|
59
|
+
connectedAccountId: '4d79004e-320a-4dc9-be1a-1037a6fe9866',
|
60
|
+
},
|
61
|
+
});
|
62
|
+
// const actionsEnums = [
|
63
|
+
// 'GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER',
|
64
|
+
// 'GITHUB_ACTIVITY_LIST_STARGAZERS_FOR_REPO',
|
65
|
+
// 'GITHUB_GET_OCTOCAT',
|
66
|
+
// ];
|
67
|
+
const actionsEnums = composioPlugins.map((plugin) => plugin.replace('composio:', ''));
|
68
|
+
const composioToolset = await composio.getTools({
|
69
|
+
actions: actionsEnums,
|
70
|
+
}) as ToolsInput;
|
36
71
|
|
72
|
+
// agent
|
37
73
|
export const characterAgent = new Agent({
|
38
74
|
name: "Character",
|
39
75
|
instructions: dedent`\
|
40
76
|
You are the following character:
|
41
77
|
` + '\n' + JSON.stringify(characterJson, null, 2),
|
42
78
|
model: openai("gpt-4o"),
|
43
|
-
tools: {
|
79
|
+
tools: { // ToolsInput = string -> ToolAction
|
80
|
+
...mcpTools,
|
81
|
+
...composioToolset,
|
82
|
+
},
|
44
83
|
});
|
package/util.mjs
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
+
import path from 'path';
|
1
2
|
import child_process from "child_process";
|
3
|
+
import { PnpmPackageLookup } from 'pnpm-package-lookup';
|
2
4
|
|
3
|
-
export const runCharacter = async (characterJsonPath
|
5
|
+
export const runCharacter = async (characterJsonPath, {
|
6
|
+
env = {},
|
7
|
+
} = {}) => {
|
4
8
|
const mastraPath = import.meta.resolve('mastra').replace('file://', '');
|
5
9
|
const cp = child_process.spawn(process.execPath, [mastraPath, 'dev'], {
|
6
10
|
env: {
|
7
|
-
...
|
8
|
-
|
11
|
+
...env,
|
12
|
+
_CHARACTER_JSON_PATH: characterJsonPath,
|
9
13
|
},
|
10
14
|
});
|
11
15
|
cp.stdout.pipe(process.stdout);
|
@@ -25,7 +29,7 @@ export const runCharacter = async (characterJsonPath) => {
|
|
25
29
|
});
|
26
30
|
});
|
27
31
|
};
|
28
|
-
export const installPackages =
|
32
|
+
export const installPackages = (packageSpecifiers) => {
|
29
33
|
console.log(`Installing packages: ${packageSpecifiers.join(", ")}`);
|
30
34
|
|
31
35
|
return new Promise((resolve, reject) => {
|
@@ -49,3 +53,58 @@ export const installPackages = async (packageSpecifiers) => {
|
|
49
53
|
});
|
50
54
|
});
|
51
55
|
};
|
56
|
+
export const buildPackages = async (packageSpecifiers) => {
|
57
|
+
console.log(`Building packages: ${packageSpecifiers.join(", ")}`);
|
58
|
+
|
59
|
+
// get the packagePaths from the packageSpecifiers
|
60
|
+
const packageLookup = new PnpmPackageLookup({
|
61
|
+
pnpmLockYamlPath: path.resolve(process.cwd(), 'pnpm-lock.yaml'),
|
62
|
+
});
|
63
|
+
const packagePaths = await Promise.all(packageSpecifiers.map(async (packageSpecifier) => {
|
64
|
+
return await packageLookup.getPackageNameBySpecifier(packageSpecifier);
|
65
|
+
}));
|
66
|
+
|
67
|
+
const results = [];
|
68
|
+
let allSuccessful = true;
|
69
|
+
|
70
|
+
for (const packagePath of packagePaths) {
|
71
|
+
console.log(`Building package: ${packagePath}`);
|
72
|
+
|
73
|
+
try {
|
74
|
+
const p = path.resolve(process.cwd(), 'node_modules', packagePath);
|
75
|
+
const cp = child_process.spawn("pnpm", ["build"], {
|
76
|
+
stdio: "inherit",
|
77
|
+
cwd: p,
|
78
|
+
env: { ...process.env },
|
79
|
+
});
|
80
|
+
|
81
|
+
const result = await new Promise((resolveSpawn, rejectSpawn) => {
|
82
|
+
cp.on("error", (error) => {
|
83
|
+
console.error(`Error executing pnpm build for ${packagePath}: ${error.message}`);
|
84
|
+
resolveSpawn({ success: false, package: packagePath, error: error.message });
|
85
|
+
});
|
86
|
+
|
87
|
+
cp.on("close", (code) => {
|
88
|
+
if (code !== 0) {
|
89
|
+
console.error(`pnpm build for ${packagePath} exited with code ${code}`);
|
90
|
+
resolveSpawn({ success: false, package: packagePath, error: `exited with code ${code}` });
|
91
|
+
} else {
|
92
|
+
console.log(`Build completed successfully for ${packagePath}`);
|
93
|
+
resolveSpawn({ success: true, package: packagePath });
|
94
|
+
}
|
95
|
+
});
|
96
|
+
});
|
97
|
+
|
98
|
+
results.push(result);
|
99
|
+
if (!result.success) {
|
100
|
+
allSuccessful = false;
|
101
|
+
}
|
102
|
+
} catch (error) {
|
103
|
+
console.log('error', error);
|
104
|
+
results.push({ success: false, package: packagePath, error: error.message });
|
105
|
+
allSuccessful = false;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
return { success: allSuccessful, results };
|
110
|
+
};
|