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