create-mastra 0.1.2 → 0.1.3

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/dist/index.js CHANGED
@@ -857,6 +857,29 @@ function createLogger(options) {
857
857
  return new Logger(options);
858
858
  }
859
859
 
860
+ function getPackageManager() {
861
+ const userAgent = process.env.npm_config_user_agent || "";
862
+ const execPath = process.env.npm_execpath || "";
863
+ if (userAgent.includes("yarn")) {
864
+ return "yarn";
865
+ }
866
+ if (userAgent.includes("pnpm")) {
867
+ return "pnpm";
868
+ }
869
+ if (userAgent.includes("npm")) {
870
+ return "npm";
871
+ }
872
+ if (execPath.includes("yarn")) {
873
+ return "yarn";
874
+ }
875
+ if (execPath.includes("pnpm")) {
876
+ return "pnpm";
877
+ }
878
+ if (execPath.includes("npm")) {
879
+ return "npm";
880
+ }
881
+ return "npm";
882
+ }
860
883
  var DepsService = class {
861
884
  packageManager;
862
885
  constructor() {
@@ -1073,7 +1096,7 @@ var getAISDKPackage = (llmProvider) => {
1073
1096
  return "@ai-sdk/openai";
1074
1097
  }
1075
1098
  };
1076
- async function writeAgentSample(llmProvider, destPath, addExampleTool) {
1099
+ var getProviderImportAndModelItem = (llmProvider) => {
1077
1100
  let providerImport = "";
1078
1101
  let modelItem = "";
1079
1102
  if (llmProvider === "openai") {
@@ -1086,6 +1109,10 @@ async function writeAgentSample(llmProvider, destPath, addExampleTool) {
1086
1109
  providerImport = `import { groq } from '${getAISDKPackage(llmProvider)}';`;
1087
1110
  modelItem = `groq('llama3-groq-70b-8192-tool-use-preview')`;
1088
1111
  }
1112
+ return { providerImport, modelItem };
1113
+ };
1114
+ async function writeAgentSample(llmProvider, destPath, addExampleTool) {
1115
+ const { providerImport, modelItem } = getProviderImportAndModelItem(llmProvider);
1089
1116
  const instructions = `
1090
1117
  You are a helpful weather assistant that provides accurate weather information.
1091
1118
 
@@ -1116,9 +1143,196 @@ export const weatherAgent = new Agent({
1116
1143
  await fs4.writeFile(destPath, "");
1117
1144
  await fs4.writeFile(destPath, formattedContent);
1118
1145
  }
1119
- async function writeWorkflowSample(destPath) {
1120
- const fileService = new FileService();
1121
- await fileService.copyStarterFile("workflow.ts", destPath);
1146
+ async function writeWorkflowSample(destPath, llmProvider) {
1147
+ const { providerImport, modelItem } = getProviderImportAndModelItem(llmProvider);
1148
+ const content = `${providerImport}
1149
+ import { Agent } from '@mastra/core/agent';
1150
+ import { Step, Workflow } from '@mastra/core/workflows';
1151
+ import { z } from 'zod';
1152
+
1153
+ const llm = ${modelItem};
1154
+
1155
+ const agent = new Agent({
1156
+ name: 'Weather Agent',
1157
+ model: llm,
1158
+ instructions: \`
1159
+ You are a local activities and travel expert who excels at weather-based planning. Analyze the weather data and provide practical activity recommendations.
1160
+
1161
+ For each day in the forecast, structure your response exactly as follows:
1162
+
1163
+ \u{1F4C5} [Day, Month Date, Year]
1164
+ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1165
+
1166
+ \u{1F321}\uFE0F WEATHER SUMMARY
1167
+ \u2022 Conditions: [brief description]
1168
+ \u2022 Temperature: [X\xB0C/Y\xB0F to A\xB0C/B\xB0F]
1169
+ \u2022 Precipitation: [X% chance]
1170
+
1171
+ \u{1F305} MORNING ACTIVITIES
1172
+ Outdoor:
1173
+ \u2022 [Activity Name] - [Brief description including specific location/route]
1174
+ Best timing: [specific time range]
1175
+ Note: [relevant weather consideration]
1176
+
1177
+ \u{1F31E} AFTERNOON ACTIVITIES
1178
+ Outdoor:
1179
+ \u2022 [Activity Name] - [Brief description including specific location/route]
1180
+ Best timing: [specific time range]
1181
+ Note: [relevant weather consideration]
1182
+
1183
+ \u{1F3E0} INDOOR ALTERNATIVES
1184
+ \u2022 [Activity Name] - [Brief description including specific venue]
1185
+ Ideal for: [weather condition that would trigger this alternative]
1186
+
1187
+ \u26A0\uFE0F SPECIAL CONSIDERATIONS
1188
+ \u2022 [Any relevant weather warnings, UV index, wind conditions, etc.]
1189
+
1190
+ Guidelines:
1191
+ - Suggest 2-3 time-specific outdoor activities per day
1192
+ - Include 1-2 indoor backup options
1193
+ - For precipitation >50%, lead with indoor activities
1194
+ - All activities must be specific to the location
1195
+ - Include specific venues, trails, or locations
1196
+ - Consider activity intensity based on temperature
1197
+ - Keep descriptions concise but informative
1198
+
1199
+ Maintain this exact formatting for consistency, using the emoji and section headers as shown.
1200
+ \`,
1201
+ });
1202
+
1203
+ const fetchWeather = new Step({
1204
+ id: 'fetch-weather',
1205
+ description: 'Fetches weather forecast for a given city',
1206
+ inputSchema: z.object({
1207
+ city: z.string().describe('The city to get the weather for'),
1208
+ }),
1209
+ execute: async ({ context }) => {
1210
+ const triggerData = context?.getStepPayload<{ city: string }>('trigger');
1211
+
1212
+ if (!triggerData) {
1213
+ throw new Error('Trigger data not found');
1214
+ }
1215
+
1216
+ const geocodingUrl = \`https://geocoding-api.open-meteo.com/v1/search?name=\${encodeURIComponent(triggerData.city)}&count=1\`;
1217
+ const geocodingResponse = await fetch(geocodingUrl);
1218
+ const geocodingData = (await geocodingResponse.json()) as {
1219
+ results: { latitude: number; longitude: number; name: string }[];
1220
+ };
1221
+
1222
+ if (!geocodingData.results?.[0]) {
1223
+ throw new Error(\`Location '\${triggerData.city}' not found\`);
1224
+ }
1225
+
1226
+ const { latitude, longitude, name } = geocodingData.results[0];
1227
+
1228
+ const weatherUrl = \`https://api.open-meteo.com/v1/forecast?latitude=\${latitude}&longitude=\${longitude}&daily=temperature_2m_max,temperature_2m_min,precipitation_probability_mean,weathercode&timezone=auto\`;
1229
+ const response = await fetch(weatherUrl);
1230
+ const data = (await response.json()) as {
1231
+ daily: {
1232
+ time: string[];
1233
+ temperature_2m_max: number[];
1234
+ temperature_2m_min: number[];
1235
+ precipitation_probability_mean: number[];
1236
+ weathercode: number[];
1237
+ };
1238
+ };
1239
+
1240
+ const forecast = data.daily.time.map((date: string, index: number) => ({
1241
+ date,
1242
+ maxTemp: data.daily.temperature_2m_max[index],
1243
+ minTemp: data.daily.temperature_2m_min[index],
1244
+ precipitationChance: data.daily.precipitation_probability_mean[index],
1245
+ condition: getWeatherCondition(data.daily.weathercode[index]!),
1246
+ location: name,
1247
+ }));
1248
+
1249
+ return forecast;
1250
+ },
1251
+ });
1252
+
1253
+ const forecastSchema = z.array(
1254
+ z.object({
1255
+ date: z.string(),
1256
+ maxTemp: z.number(),
1257
+ minTemp: z.number(),
1258
+ precipitationChance: z.number(),
1259
+ condition: z.string(),
1260
+ location: z.string(),
1261
+ }),
1262
+ );
1263
+
1264
+ const planActivities = new Step({
1265
+ id: 'plan-activities',
1266
+ description: 'Suggests activities based on weather conditions',
1267
+ inputSchema: forecastSchema,
1268
+ execute: async ({ context, mastra }) => {
1269
+ const forecast = context?.getStepPayload<z.infer<typeof forecastSchema>>('fetch-weather');
1270
+
1271
+ if (!forecast || forecast.length === 0) {
1272
+ throw new Error('Forecast data not found');
1273
+ }
1274
+
1275
+ const prompt = \`Based on the following weather forecast for \${forecast[0]?.location}, suggest appropriate activities:
1276
+ \${JSON.stringify(forecast, null, 2)}
1277
+ \`;
1278
+
1279
+ const response = await agent.stream([
1280
+ {
1281
+ role: 'user',
1282
+ content: prompt,
1283
+ },
1284
+ ]);
1285
+
1286
+ for await (const chunk of response.textStream) {
1287
+ process.stdout.write(chunk);
1288
+ }
1289
+
1290
+ return {
1291
+ activities: response.text,
1292
+ };
1293
+ },
1294
+ });
1295
+
1296
+ function getWeatherCondition(code: number): string {
1297
+ const conditions: Record<number, string> = {
1298
+ 0: 'Clear sky',
1299
+ 1: 'Mainly clear',
1300
+ 2: 'Partly cloudy',
1301
+ 3: 'Overcast',
1302
+ 45: 'Foggy',
1303
+ 48: 'Depositing rime fog',
1304
+ 51: 'Light drizzle',
1305
+ 53: 'Moderate drizzle',
1306
+ 55: 'Dense drizzle',
1307
+ 61: 'Slight rain',
1308
+ 63: 'Moderate rain',
1309
+ 65: 'Heavy rain',
1310
+ 71: 'Slight snow fall',
1311
+ 73: 'Moderate snow fall',
1312
+ 75: 'Heavy snow fall',
1313
+ 95: 'Thunderstorm',
1314
+ };
1315
+ return conditions[code] || 'Unknown';
1316
+ }
1317
+
1318
+ const weatherWorkflow = new Workflow({
1319
+ name: 'weather-workflow',
1320
+ triggerSchema: z.object({
1321
+ city: z.string().describe('The city to get the weather for'),
1322
+ }),
1323
+ })
1324
+ .step(fetchWeather)
1325
+ .then(planActivities);
1326
+
1327
+ weatherWorkflow.commit();
1328
+
1329
+ export { weatherWorkflow };`;
1330
+ const formattedContent = await prettier.format(content, {
1331
+ parser: "typescript",
1332
+ semi: true,
1333
+ singleQuote: true
1334
+ });
1335
+ await fs4.writeFile(destPath, formattedContent);
1122
1336
  }
1123
1337
  async function writeToolSample(destPath) {
1124
1338
  const fileService = new FileService();
@@ -1131,7 +1345,7 @@ async function writeCodeSampleForComponents(llmprovider, component, destPath, im
1131
1345
  case "tools":
1132
1346
  return writeToolSample(destPath);
1133
1347
  case "workflows":
1134
- return writeWorkflowSample(destPath);
1348
+ return writeWorkflowSample(destPath, llmprovider);
1135
1349
  default:
1136
1350
  return "";
1137
1351
  }
@@ -1326,7 +1540,7 @@ var init = async ({
1326
1540
  }
1327
1541
  const key = await getAPIKey(llmProvider || "openai");
1328
1542
  const aiSdkPackage = getAISDKPackage(llmProvider);
1329
- await exec2(`npm i ${aiSdkPackage}`);
1543
+ await exec2(`${getPackageManager()} i ${aiSdkPackage}`);
1330
1544
  s.stop();
1331
1545
  if (!llmApiKey) {
1332
1546
  me(`
@@ -1371,15 +1585,6 @@ var execWithTimeout = async (command, timeoutMs = 18e4) => {
1371
1585
  throw error;
1372
1586
  }
1373
1587
  };
1374
- function getPackageManager() {
1375
- const userAgent = process.env.npm_config_user_agent || `npm`;
1376
- if (userAgent.includes(`pnpm/`)) {
1377
- return `pnpm`;
1378
- } else if (userAgent.includes(`yarn/`)) {
1379
- return `yarn`;
1380
- }
1381
- return `npm`;
1382
- }
1383
1588
  var createMastraProject = async () => {
1384
1589
  pe(color2.inverse("Mastra Create"));
1385
1590
  const projectName = await ae({