mastra 0.1.57-unstable.57 → 0.1.57-unstable.88

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.
Files changed (61) hide show
  1. package/dist/commands/create/create.d.ts +8 -0
  2. package/dist/commands/create/create.d.ts.map +1 -0
  3. package/dist/commands/create/create.js +35 -0
  4. package/dist/commands/create/utils.d.ts +4 -0
  5. package/dist/commands/create/utils.d.ts.map +1 -0
  6. package/dist/commands/create/utils.js +58 -0
  7. package/dist/commands/deploy/cloudflare/index.d.ts.map +1 -1
  8. package/dist/commands/deploy/cloudflare/index.js +2 -0
  9. package/dist/commands/deploy/netlify/index.d.ts.map +1 -1
  10. package/dist/commands/deploy/netlify/index.js +2 -0
  11. package/dist/commands/deploy/vercel/index.d.ts.map +1 -1
  12. package/dist/commands/deploy/vercel/index.js +2 -0
  13. package/dist/commands/dev.d.ts.map +1 -1
  14. package/dist/commands/dev.js +97 -10
  15. package/dist/commands/engine/down.d.ts +1 -1
  16. package/dist/commands/engine/down.d.ts.map +1 -1
  17. package/dist/commands/engine/down.js +3 -2
  18. package/dist/commands/engine/up.d.ts +1 -1
  19. package/dist/commands/engine/up.d.ts.map +1 -1
  20. package/dist/commands/engine/up.js +3 -2
  21. package/dist/commands/init/init.d.ts +2 -2
  22. package/dist/commands/init/init.d.ts.map +1 -1
  23. package/dist/commands/init/init.js +33 -9
  24. package/dist/commands/init/utils.d.ts +21 -9
  25. package/dist/commands/init/utils.d.ts.map +1 -1
  26. package/dist/commands/init/utils.js +64 -74
  27. package/dist/index.d.ts +2 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +54 -56
  30. package/dist/services/service.deps.d.ts +1 -0
  31. package/dist/services/service.deps.d.ts.map +1 -1
  32. package/dist/services/service.deps.js +8 -0
  33. package/dist/services/service.docker.d.ts +1 -0
  34. package/dist/services/service.docker.d.ts.map +1 -1
  35. package/dist/services/service.docker.js +20 -0
  36. package/dist/src/starter-files/config.ts +28 -0
  37. package/dist/src/starter-files/mastra-pg.docker-compose.yaml +15 -0
  38. package/dist/src/starter-files/tools.ts +95 -0
  39. package/dist/src/starter-files/workflow.ts +173 -0
  40. package/dist/templates/express-server.d.ts.map +1 -1
  41. package/dist/templates/express-server.js +30 -31
  42. package/dist/templates/netlify.d.ts.map +1 -1
  43. package/dist/templates/netlify.js +199 -34
  44. package/dist/templates/worker.d.ts.map +1 -1
  45. package/dist/templates/worker.js +255 -35
  46. package/dist/utils/bundle.d.ts +1 -0
  47. package/dist/utils/bundle.d.ts.map +1 -1
  48. package/dist/utils/bundle.js +8 -8
  49. package/package.json +5 -3
  50. package/src/playground/dist/assets/{hcl-Cztwc-HH.js → hcl-_Zu0RE-q.js} +1 -1
  51. package/src/playground/dist/assets/index-BiEU7Tmg.js +389 -0
  52. package/src/playground/dist/assets/{index-Dx4A5Op9.js → index-Cke4BidO.js} +2 -2
  53. package/src/playground/dist/assets/{vue-html-x3hEOujm.js → vue-html-59TQSa_j.js} +1 -1
  54. package/src/playground/dist/assets/vue-srE0XGv_.js +1 -0
  55. package/src/playground/dist/index.html +1 -1
  56. package/src/starter-files/tools.ts +88 -14
  57. package/src/starter-files/workflow.ts +160 -21
  58. package/src/playground/dist/assets/index-DY22QVI1.js +0 -389
  59. package/src/playground/dist/assets/vue-xldAUJov.js +0 -1
  60. package/src/starter-files/api.ts +0 -11
  61. package/src/starter-files/framework-utils.ts +0 -33
@@ -0,0 +1,173 @@
1
+ import { Step, Workflow } from '@mastra/core';
2
+ import { z } from 'zod';
3
+
4
+ const fetchWeather = new Step({
5
+ id: 'fetch-weather',
6
+ description: 'Fetches weather forecast for a given city',
7
+ inputSchema: z.object({
8
+ city: z.string().describe('The city to get the weather for'),
9
+ }),
10
+ execute: async ({ context }) => {
11
+ const triggerData = context.machineContext?.getStepPayload<{ city: string }>('trigger');
12
+
13
+ if (!triggerData) {
14
+ throw new Error('Trigger data not found');
15
+ }
16
+
17
+ const geocodingUrl = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(triggerData.city)}&count=1`;
18
+ const geocodingResponse = await fetch(geocodingUrl);
19
+ const geocodingData = await geocodingResponse.json();
20
+
21
+ if (!geocodingData.results?.[0]) {
22
+ throw new Error(`Location '${triggerData.city}' not found`);
23
+ }
24
+
25
+ const { latitude, longitude, name } = geocodingData.results[0];
26
+
27
+ 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`;
28
+ const response = await fetch(weatherUrl);
29
+ const data = await response.json();
30
+
31
+ const forecast = data.daily.time.map((date: string, index: number) => ({
32
+ date,
33
+ maxTemp: data.daily.temperature_2m_max[index],
34
+ minTemp: data.daily.temperature_2m_min[index],
35
+ precipitationChance: data.daily.precipitation_probability_mean[index],
36
+ condition: getWeatherCondition(data.daily.weathercode[index]),
37
+ location: name,
38
+ }));
39
+
40
+ return forecast;
41
+ },
42
+ });
43
+
44
+ const forecastSchema = z.array(
45
+ z.object({
46
+ date: z.string(),
47
+ maxTemp: z.number(),
48
+ minTemp: z.number(),
49
+ precipitationChance: z.number(),
50
+ condition: z.string(),
51
+ location: z.string(),
52
+ }),
53
+ );
54
+
55
+ const planActivities = new Step({
56
+ id: 'plan-activities',
57
+ description: 'Suggests activities based on weather conditions',
58
+ inputSchema: forecastSchema,
59
+ execute: async ({ context, mastra }) => {
60
+ const forecast = context.machineContext?.getStepPayload<z.infer<typeof forecastSchema>>('fetch-weather');
61
+
62
+ if (!forecast) {
63
+ throw new Error('Forecast data not found');
64
+ }
65
+
66
+ const prompt = `Based on the following weather forecast for ${forecast[0].location}, suggest appropriate activities:
67
+ ${JSON.stringify(forecast, null, 2)}
68
+ `;
69
+
70
+ if (!mastra?.llm) {
71
+ throw new Error('Mastra not found');
72
+ }
73
+
74
+ const llm = mastra.llm({
75
+ provider: 'OPEN_AI',
76
+ name: 'gpt-4o',
77
+ });
78
+
79
+ const response = await llm.stream([
80
+ {
81
+ role: 'system',
82
+ content: `You are a local activities and travel expert who excels at weather-based planning. Analyze the weather data and provide practical activity recommendations.
83
+
84
+ For each day in the forecast, structure your response exactly as follows:
85
+
86
+ 📅 [Day, Month Date, Year]
87
+ ═══════════════════════════
88
+
89
+ 🌡️ WEATHER SUMMARY
90
+ • Conditions: [brief description]
91
+ • Temperature: [X°C/Y°F to A°C/B°F]
92
+ • Precipitation: [X% chance]
93
+
94
+ 🌅 MORNING ACTIVITIES
95
+ Outdoor:
96
+ • [Activity Name] - [Brief description including specific location/route]
97
+ Best timing: [specific time range]
98
+ Note: [relevant weather consideration]
99
+
100
+ 🌞 AFTERNOON ACTIVITIES
101
+ Outdoor:
102
+ • [Activity Name] - [Brief description including specific location/route]
103
+ Best timing: [specific time range]
104
+ Note: [relevant weather consideration]
105
+
106
+ 🏠 INDOOR ALTERNATIVES
107
+ • [Activity Name] - [Brief description including specific venue]
108
+ Ideal for: [weather condition that would trigger this alternative]
109
+
110
+ ⚠️ SPECIAL CONSIDERATIONS
111
+ • [Any relevant weather warnings, UV index, wind conditions, etc.]
112
+
113
+ Guidelines:
114
+ - Suggest 2-3 time-specific outdoor activities per day
115
+ - Include 1-2 indoor backup options
116
+ - For precipitation >50%, lead with indoor activities
117
+ - All activities must be specific to the location
118
+ - Include specific venues, trails, or locations
119
+ - Consider activity intensity based on temperature
120
+ - Keep descriptions concise but informative
121
+
122
+ Maintain this exact formatting for consistency, using the emoji and section headers as shown.`,
123
+ },
124
+ {
125
+ role: 'user',
126
+ content: prompt,
127
+ },
128
+ ]);
129
+
130
+ for await (const chunk of response.textStream) {
131
+ process.stdout.write(chunk);
132
+ }
133
+
134
+ return {
135
+ activities: response.text,
136
+ };
137
+ },
138
+ });
139
+
140
+ function getWeatherCondition(code: number): string {
141
+ const conditions: Record<number, string> = {
142
+ 0: 'Clear sky',
143
+ 1: 'Mainly clear',
144
+ 2: 'Partly cloudy',
145
+ 3: 'Overcast',
146
+ 45: 'Foggy',
147
+ 48: 'Depositing rime fog',
148
+ 51: 'Light drizzle',
149
+ 53: 'Moderate drizzle',
150
+ 55: 'Dense drizzle',
151
+ 61: 'Slight rain',
152
+ 63: 'Moderate rain',
153
+ 65: 'Heavy rain',
154
+ 71: 'Slight snow fall',
155
+ 73: 'Moderate snow fall',
156
+ 75: 'Heavy snow fall',
157
+ 95: 'Thunderstorm',
158
+ };
159
+ return conditions[code] || 'Unknown';
160
+ }
161
+
162
+ const weatherWorkflow = new Workflow({
163
+ name: 'weather-workflow',
164
+ triggerSchema: z.object({
165
+ city: z.string().describe('The city to get the weather for'),
166
+ }),
167
+ })
168
+ .step(fetchWeather)
169
+ .then(planActivities);
170
+
171
+ weatherWorkflow.commit();
172
+
173
+ export { weatherWorkflow };
@@ -1 +1 @@
1
- {"version":3,"file":"express-server.d.ts","sourceRoot":"","sources":["../../src/templates/express-server.ts"],"names":[],"mappings":"AAGA,OAAO,UAAU,MAAM,iBAAiB,CAAC;AAmhCzC,eAAO,MAAM,OAAO,oBAAkB,CAAC;AAOvC,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"express-server.d.ts","sourceRoot":"","sources":["../../src/templates/express-server.ts"],"names":[],"mappings":"AAGA,OAAO,UAAU,MAAM,iBAAiB,CAAC;AAmhCzC,eAAO,MAAM,OAAO,oBAAkB,CAAC;AAQvC,eAAe,OAAO,CAAC"}
@@ -4,13 +4,17 @@ import _path, { join } from 'path';
4
4
  import serverless from 'serverless-http';
5
5
  import { stringify } from 'superjson';
6
6
  import { fileURLToPath as _fileURLToPath } from 'url';
7
+ import { pathToFileURL } from 'url';
7
8
  import zodToJsonSchema from 'zod-to-json-schema';
8
9
  const ___filename = _fileURLToPath(import.meta.url);
9
10
  const ___dirname = _path.dirname(___filename);
10
- const { mastra } = await import(join(process.cwd(), 'mastra.mjs'));
11
+ const mastraPath = pathToFileURL(join(process.cwd(), 'mastra.mjs')).href;
12
+ const { mastra } = await import(mastraPath);
11
13
  const mastraToolsPaths = process.env.MASTRA_TOOLS_PATH;
12
14
  const toolImports = mastraToolsPaths
13
- ? await Promise.all(mastraToolsPaths.split(',').map(toolPath => import(toolPath)))
15
+ ? await Promise.all(mastraToolsPaths.split(',').map(async (toolPath) => {
16
+ return import(pathToFileURL(toolPath).href);
17
+ }))
14
18
  : [];
15
19
  const tools = toolImports.reduce((acc, toolModule) => {
16
20
  Object.entries(toolModule).forEach(([key, tool]) => {
@@ -129,7 +133,7 @@ app.get('/api/agents', async (_req, res) => {
129
133
  }
130
134
  });
131
135
  /**
132
- * POST /api/agents/{agentId}/text
136
+ * POST /api/agents/{agentId}/generate
133
137
  * @summary Send text messages to agent
134
138
  * @tags Agent
135
139
  * @param {string} agentId.path.required - Agent identifier
@@ -138,7 +142,7 @@ app.get('/api/agents', async (_req, res) => {
138
142
  * @return {Error} 400 - Validation error
139
143
  * @return {Error} 500 - Server error
140
144
  */
141
- app.post('/api/agents/:agentId/text', async (req, res) => {
145
+ app.post('/api/agents/:agentId/generate', async (req, res) => {
142
146
  try {
143
147
  const agentId = req.params.agentId;
144
148
  const agent = mastra.getAgent(agentId);
@@ -150,12 +154,12 @@ app.post('/api/agents/:agentId/text', async (req, res) => {
150
154
  res.status(400).json({ error: errorResponse });
151
155
  return;
152
156
  }
153
- if (!Array.isArray(messages)) {
154
- res.status(400).json({ error: { messages: 'Messages should be an array' } });
155
- return;
156
- }
157
157
  const result = await agent.generate(messages, { threadId, resourceid });
158
- res.json(result);
158
+ const textResult = {
159
+ text: result.text,
160
+ agent: agent.name,
161
+ };
162
+ res.json(textResult);
159
163
  }
160
164
  catch (error) {
161
165
  const apiError = error;
@@ -186,12 +190,7 @@ app.post('/api/agents/:agentId/stream', async (req, res) => {
186
190
  res.status(400).json({ error: errorResponse });
187
191
  return;
188
192
  }
189
- if (!Array.isArray(messages)) {
190
- res.status(400).json({ error: { messages: 'Messages should be an array' } });
191
- return;
192
- }
193
- const streamResult = await agent.generate(messages, {
194
- stream: true,
193
+ const streamResult = await agent.stream(messages, {
195
194
  threadId,
196
195
  resourceid,
197
196
  });
@@ -227,12 +226,12 @@ app.post('/api/agents/:agentId/text-object', async (req, res) => {
227
226
  res.status(400).json({ error: errorResponse });
228
227
  return;
229
228
  }
230
- if (!Array.isArray(messages)) {
231
- res.status(400).json({ error: { messages: 'Messages should be an array' } });
232
- return;
233
- }
234
- const result = await agent.generate(messages, { schema, threadId, resourceid });
235
- res.json(result);
229
+ const result = await agent.generate(messages, { output: schema, threadId, resourceid });
230
+ const objectResult = {
231
+ object: result.object,
232
+ agent: result.agent,
233
+ };
234
+ res.json(objectResult);
236
235
  }
237
236
  catch (error) {
238
237
  const apiError = error;
@@ -266,11 +265,7 @@ app.post('/api/agents/:agentId/stream-object', async (req, res) => {
266
265
  res.status(400).json({ error: errorResponse });
267
266
  return;
268
267
  }
269
- if (!Array.isArray(messages)) {
270
- res.status(400).json({ error: { messages: 'Messages should be an array' } });
271
- return;
272
- }
273
- const streamResult = await agent.generate(messages, { schema, stream: true, threadId, resourceid });
268
+ const streamResult = await agent.stream(messages, { output: schema, threadId, resourceid });
274
269
  streamResult.pipeTextStreamToResponse(res);
275
270
  }
276
271
  catch (error) {
@@ -323,7 +318,7 @@ app.post('/api/agents/:agentId/tools/:toolId/execute', async (req, res) => {
323
318
  */
324
319
  app.get('/api/workflows', async (_req, res) => {
325
320
  try {
326
- const workflows = mastra.getWorkflows();
321
+ const workflows = mastra.getWorkflows({ serialized: true });
327
322
  res.json(workflows);
328
323
  }
329
324
  catch (error) {
@@ -358,7 +353,7 @@ app.get('/api/workflows/:workflowId', async (req, res) => {
358
353
  return acc;
359
354
  }, {});
360
355
  res.json({
361
- ...workflow,
356
+ name: workflow.name,
362
357
  triggerSchema: triggerSchema ? stringify(zodToJsonSchema(triggerSchema)) : undefined,
363
358
  steps: serializedSteps,
364
359
  stepGraph,
@@ -377,7 +372,7 @@ app.get('/api/workflows/:workflowId', async (req, res) => {
377
372
  * @summary Execute a workflow
378
373
  * @tags Workflow
379
374
  * @param {string} workflowId.path.required - Workflow identifier
380
- * @param {object} request.body.required - Workflow input data
375
+ * @param {object} request.body.required - Workflow trigger data
381
376
  * @return {object} 200 - Workflow execution result
382
377
  * @return {Error} 500 - Server error
383
378
  */
@@ -385,8 +380,11 @@ app.post('/api/workflows/:workflowId/execute', async (req, res) => {
385
380
  try {
386
381
  const workflowId = req.params.workflowId;
387
382
  const workflow = mastra.getWorkflow(workflowId);
388
- const result = await workflow.execute(req.body);
389
- res.json(result);
383
+ const result = await workflow.execute({ triggerData: req.body });
384
+ res.json({
385
+ results: result?.results ?? {},
386
+ workflow: workflowId,
387
+ });
390
388
  }
391
389
  catch (error) {
392
390
  const apiError = error;
@@ -959,5 +957,6 @@ export const handler = serverless(app);
959
957
  app.listen(process.env.PORT || 4111, () => {
960
958
  console.log(`🦄Server running on port ${process.env.PORT || 4111}`);
961
959
  console.log(`📚 Open API documentation available at http://localhost:${process.env.PORT || 4111}/openapi.json`);
960
+ console.log(`👨‍💻 Playground available at http://localhost:${process.env.PORT || 4111}/`);
962
961
  });
963
962
  export default handler;
@@ -1 +1 @@
1
- {"version":3,"file":"netlify.d.ts","sourceRoot":"","sources":["../../src/templates/netlify.ts"],"names":[],"mappings":"AAEA,OAAO,UAAU,MAAM,iBAAiB,CAAC;AA4iBzC,eAAO,MAAM,OAAO,oBAAkB,CAAC"}
1
+ {"version":3,"file":"netlify.d.ts","sourceRoot":"","sources":["../../src/templates/netlify.ts"],"names":[],"mappings":"AAGA,OAAO,UAAU,MAAM,iBAAiB,CAAC;AA0tBzC,eAAO,MAAM,OAAO,oBAAkB,CAAC"}
@@ -2,8 +2,21 @@ import express from 'express';
2
2
  import { join } from 'path';
3
3
  import serverless from 'serverless-http';
4
4
  import { stringify } from 'superjson';
5
+ import { pathToFileURL } from 'url';
5
6
  import zodToJsonSchema from 'zod-to-json-schema';
6
7
  const { mastra } = await import(join(process.cwd(), 'mastra.mjs'));
8
+ const mastraToolsPaths = process.env.MASTRA_TOOLS_PATH;
9
+ const toolImports = mastraToolsPaths
10
+ ? await Promise.all(mastraToolsPaths.split(',').map(async (toolPath) => {
11
+ return import(pathToFileURL(toolPath).href);
12
+ }))
13
+ : [];
14
+ const tools = toolImports.reduce((acc, toolModule) => {
15
+ Object.entries(toolModule).forEach(([key, tool]) => {
16
+ acc[key] = tool;
17
+ });
18
+ return acc;
19
+ }, {});
7
20
  const app = express();
8
21
  app.use(express.json());
9
22
  const validateBody = async (body) => {
@@ -24,7 +37,24 @@ app.get('/', (_req, res) => {
24
37
  app.get('/api/agents', async (_req, res) => {
25
38
  try {
26
39
  const agents = mastra.getAgents();
27
- res.json(agents);
40
+ const serializedAgents = Object.entries(agents).reduce((acc, [_id, _agent]) => {
41
+ const agent = _agent;
42
+ const serializedAgentTools = Object.entries(agent?.tools || {}).reduce((acc, [key, tool]) => {
43
+ const _tool = tool;
44
+ acc[key] = {
45
+ ..._tool,
46
+ inputSchema: _tool.inputSchema ? stringify(zodToJsonSchema(_tool.inputSchema)) : undefined,
47
+ outputSchema: _tool.outputSchema ? stringify(zodToJsonSchema(_tool.outputSchema)) : undefined,
48
+ };
49
+ return acc;
50
+ }, {});
51
+ acc[_id] = {
52
+ ...agent,
53
+ tools: serializedAgentTools,
54
+ };
55
+ return acc;
56
+ }, {});
57
+ res.json(serializedAgents);
28
58
  }
29
59
  catch (error) {
30
60
  const apiError = error;
@@ -37,7 +67,19 @@ app.get('/api/agents/:agentId', async (req, res) => {
37
67
  try {
38
68
  const agentId = req.params.agentId;
39
69
  const agent = mastra.getAgent(agentId);
40
- res.json(agent);
70
+ const serializedAgentTools = Object.entries(agent?.tools || {}).reduce((acc, [key, tool]) => {
71
+ const _tool = tool;
72
+ acc[key] = {
73
+ ..._tool,
74
+ inputSchema: _tool.inputSchema ? stringify(zodToJsonSchema(_tool.inputSchema)) : undefined,
75
+ outputSchema: _tool.outputSchema ? stringify(zodToJsonSchema(_tool.outputSchema)) : undefined,
76
+ };
77
+ return acc;
78
+ }, {});
79
+ res.json({
80
+ ...agent,
81
+ tools: serializedAgentTools,
82
+ });
41
83
  }
42
84
  catch (error) {
43
85
  const apiError = error;
@@ -46,11 +88,11 @@ app.get('/api/agents/:agentId', async (req, res) => {
46
88
  return;
47
89
  }
48
90
  });
49
- app.post('/api/agents/:agentId/text', async (req, res) => {
91
+ app.post('/api/agents/:agentId/generate', async (req, res) => {
50
92
  try {
51
93
  const agentId = req.params.agentId;
52
94
  const agent = mastra.getAgent(agentId);
53
- const messages = req.body.messages;
95
+ const { messages, threadId, resourceid } = req.body;
54
96
  const { ok, errorResponse } = await validateBody({
55
97
  messages,
56
98
  });
@@ -58,11 +100,7 @@ app.post('/api/agents/:agentId/text', async (req, res) => {
58
100
  res.status(400).json({ error: errorResponse });
59
101
  return;
60
102
  }
61
- if (!Array.isArray(messages)) {
62
- res.status(400).json({ error: { messages: 'Messages should be an array' } });
63
- return;
64
- }
65
- const result = await agent.generate(messages);
103
+ const result = await agent.generate(messages, { threadId, resourceid });
66
104
  res.json(result);
67
105
  }
68
106
  catch (error) {
@@ -76,7 +114,7 @@ app.post('/api/agents/:agentId/stream', async (req, res) => {
76
114
  try {
77
115
  const agentId = req.params.agentId;
78
116
  const agent = mastra.getAgent(agentId);
79
- const messages = req.body.messages;
117
+ const { messages, threadId, resourceid } = req.body;
80
118
  const { ok, errorResponse } = await validateBody({
81
119
  messages,
82
120
  });
@@ -84,11 +122,10 @@ app.post('/api/agents/:agentId/stream', async (req, res) => {
84
122
  res.status(400).json({ error: errorResponse });
85
123
  return;
86
124
  }
87
- if (!Array.isArray(messages)) {
88
- res.status(400).json({ error: { messages: 'Messages should be an array' } });
89
- return;
90
- }
91
- const streamResult = await agent.generate(messages, { stream: true });
125
+ const streamResult = await agent.stream(messages, {
126
+ threadId,
127
+ resourceid,
128
+ });
92
129
  streamResult.pipeDataStreamToResponse(res);
93
130
  }
94
131
  catch (error) {
@@ -102,8 +139,7 @@ app.post('/api/agents/:agentId/text-object', async (req, res) => {
102
139
  try {
103
140
  const agentId = req.params.agentId;
104
141
  const agent = mastra.getAgent(agentId);
105
- const messages = req.body.messages;
106
- const schema = req.body.schema;
142
+ const { messages, schema, threadId, resourceid } = req.body;
107
143
  const { ok, errorResponse } = await validateBody({
108
144
  messages,
109
145
  schema,
@@ -112,11 +148,7 @@ app.post('/api/agents/:agentId/text-object', async (req, res) => {
112
148
  res.status(400).json({ error: errorResponse });
113
149
  return;
114
150
  }
115
- if (!Array.isArray(messages)) {
116
- res.status(400).json({ error: { messages: 'Messages should be an array' } });
117
- return;
118
- }
119
- const result = await agent.generate(messages, { schema });
151
+ const result = await agent.generate(messages, { output: schema, threadId, resourceid });
120
152
  res.json(result);
121
153
  }
122
154
  catch (error) {
@@ -132,8 +164,7 @@ app.post('/api/agents/:agentId/stream-object', async (req, res) => {
132
164
  try {
133
165
  const agentId = req.params.agentId;
134
166
  const agent = mastra.getAgent(agentId);
135
- const messages = req.body.messages;
136
- const schema = req.body.schema;
167
+ const { messages, schema, threadId, resourceid } = req.body;
137
168
  const { ok, errorResponse } = await validateBody({
138
169
  messages,
139
170
  schema,
@@ -142,11 +173,7 @@ app.post('/api/agents/:agentId/stream-object', async (req, res) => {
142
173
  res.status(400).json({ error: errorResponse });
143
174
  return;
144
175
  }
145
- if (!Array.isArray(messages)) {
146
- res.status(400).json({ error: { messages: 'Messages should be an array' } });
147
- return;
148
- }
149
- const streamResult = await agent.generate(messages, { schema, stream: true });
176
+ const streamResult = await agent.stream(messages, { output: schema, threadId, resourceid });
150
177
  streamResult.pipeTextStreamToResponse(res);
151
178
  }
152
179
  catch (error) {
@@ -158,9 +185,31 @@ app.post('/api/agents/:agentId/stream-object', async (req, res) => {
158
185
  return;
159
186
  }
160
187
  });
188
+ app.post('/api/agents/:agentId/tools/:toolId/execute', async (req, res) => {
189
+ try {
190
+ const agentId = req.params.agentId;
191
+ const toolId = req.params.toolId;
192
+ const agent = mastra.getAgent(agentId);
193
+ const tool = Object.values(agent?.tools || {}).find((tool) => tool.id === toolId);
194
+ const result = await tool.execute({
195
+ context: {
196
+ ...req.body,
197
+ },
198
+ mastra,
199
+ runId: agentId,
200
+ });
201
+ res.json(result);
202
+ }
203
+ catch (error) {
204
+ const apiError = error;
205
+ console.error('Error executing tool', apiError);
206
+ res.status(apiError.status || 500).json({ error: apiError.message || 'Error executing tool' });
207
+ return;
208
+ }
209
+ });
161
210
  app.get('/api/workflows', async (_req, res) => {
162
211
  try {
163
- const workflows = mastra.getWorkflows();
212
+ const workflows = mastra.getWorkflows({ serialized: true });
164
213
  res.json(workflows);
165
214
  }
166
215
  catch (error) {
@@ -175,9 +224,23 @@ app.get('/api/workflows/:workflowId', async (req, res) => {
175
224
  const workflowId = req.params.workflowId;
176
225
  const workflow = mastra.getWorkflow(workflowId);
177
226
  const triggerSchema = workflow.triggerSchema;
227
+ const stepGraph = workflow.stepGraph;
228
+ const stepSubscriberGraph = workflow.stepSubscriberGraph;
229
+ const serializedSteps = Object.entries(workflow.steps).reduce((acc, [key, step]) => {
230
+ const _step = step;
231
+ acc[key] = {
232
+ ..._step,
233
+ inputSchema: _step.inputSchema ? stringify(zodToJsonSchema(_step.inputSchema)) : undefined,
234
+ outputSchema: _step.outputSchema ? stringify(zodToJsonSchema(_step.outputSchema)) : undefined,
235
+ };
236
+ return acc;
237
+ }, {});
178
238
  res.json({
179
239
  ...workflow,
180
240
  triggerSchema: triggerSchema ? stringify(zodToJsonSchema(triggerSchema)) : undefined,
241
+ steps: serializedSteps,
242
+ stepGraph,
243
+ stepSubscriberGraph,
181
244
  });
182
245
  }
183
246
  catch (error) {
@@ -190,8 +253,7 @@ app.get('/api/workflows/:workflowId', async (req, res) => {
190
253
  app.post('/api/workflows/:workflowId/execute', async (req, res) => {
191
254
  try {
192
255
  const workflowId = req.params.workflowId;
193
- const workflow = mastra.workflows.get(workflowId);
194
- console.log('req.body', req.body);
256
+ const workflow = mastra.getWorkflow(workflowId);
195
257
  const result = await workflow.execute(req.body);
196
258
  res.json(result);
197
259
  }
@@ -202,14 +264,35 @@ app.post('/api/workflows/:workflowId/execute', async (req, res) => {
202
264
  return;
203
265
  }
204
266
  });
205
- app.get('/api/memory/threads/get-by-resourceid/:resourceid', async (req, res) => {
267
+ app.get('/api/memory/status', async (_req, res) => {
206
268
  try {
207
- const resourceid = req.params.resourceid;
269
+ const memory = mastra.memory;
270
+ if (!memory) {
271
+ res.json({ result: false });
272
+ return;
273
+ }
274
+ res.json({ result: true });
275
+ }
276
+ catch (error) {
277
+ const apiError = error;
278
+ console.error('Error getting memory status', apiError);
279
+ res.status(apiError.status || 500).json({ error: apiError.message || 'Error getting memory status' });
280
+ return;
281
+ }
282
+ });
283
+ app.get('/api/memory/threads', async (req, res) => {
284
+ try {
285
+ const resourceid = req.query.resourceid;
208
286
  const memory = mastra.memory;
209
287
  if (!memory) {
210
288
  res.status(400).json({ error: 'Memory is not initialized' });
211
289
  return;
212
290
  }
291
+ const { ok, errorResponse } = await validateBody({ resourceid });
292
+ if (!ok) {
293
+ res.status(400).json({ error: errorResponse });
294
+ return;
295
+ }
213
296
  const threads = await memory.getThreadsByResourceId({ resourceid });
214
297
  res.json(threads);
215
298
  }
@@ -485,4 +568,86 @@ app.post('/api/syncs/:syncId/execute', async (req, res) => {
485
568
  return;
486
569
  }
487
570
  });
571
+ app.get('/api/logs', async (_req, res) => {
572
+ try {
573
+ const logs = await mastra.getLogs();
574
+ res.json(logs);
575
+ }
576
+ catch (error) {
577
+ const apiError = error;
578
+ console.error('Error getting logs', apiError);
579
+ res.status(apiError.status || 500).json({ error: apiError.message || 'Error getting logs' });
580
+ return;
581
+ }
582
+ });
583
+ app.get('/api/logs/:runId', async (req, res) => {
584
+ try {
585
+ const runId = req.params.runId;
586
+ const logs = await mastra.getLogsByRunId(runId);
587
+ res.json(logs);
588
+ }
589
+ catch (error) {
590
+ const apiError = error;
591
+ console.error('Error getting logs', apiError);
592
+ res.status(apiError.status || 500).json({ error: apiError.message || 'Error getting logs' });
593
+ return;
594
+ }
595
+ });
596
+ app.get('/api/tools', async (_req, res) => {
597
+ if (tools) {
598
+ const serializedTools = Object.entries(tools).reduce((acc, [id, _tool]) => {
599
+ const tool = _tool;
600
+ acc[id] = {
601
+ ...tool,
602
+ inputSchema: tool.inputSchema ? stringify(zodToJsonSchema(tool.inputSchema)) : undefined,
603
+ outputSchema: tool.outputSchema ? stringify(zodToJsonSchema(tool.outputSchema)) : undefined,
604
+ };
605
+ return acc;
606
+ }, {});
607
+ res.json(serializedTools);
608
+ }
609
+ else {
610
+ res.status(200).json({});
611
+ }
612
+ });
613
+ app.get('/api/tools/:toolId', async (req, res) => {
614
+ const toolId = req.params.toolId;
615
+ const tool = Object.values(tools || {}).find((tool) => tool.id === toolId);
616
+ if (tool) {
617
+ const serializedTool = {
618
+ ...tool,
619
+ inputSchema: tool.inputSchema ? stringify(zodToJsonSchema(tool.inputSchema)) : undefined,
620
+ outputSchema: tool.outputSchema ? stringify(zodToJsonSchema(tool.outputSchema)) : undefined,
621
+ };
622
+ res.json(serializedTool);
623
+ }
624
+ else {
625
+ res.status(404).json({ error: 'Tool not found' });
626
+ }
627
+ });
628
+ app.post('/api/tools/:toolId/execute', async (req, res) => {
629
+ try {
630
+ const toolId = req.params.toolId;
631
+ const tool = Object.values(tools || {}).find((tool) => tool.id === toolId);
632
+ if (!tool) {
633
+ res.status(404).json({ error: 'Tool not found' });
634
+ return;
635
+ }
636
+ const { input } = req.body;
637
+ const result = await tool.execute({
638
+ context: {
639
+ ...input,
640
+ },
641
+ mastra,
642
+ runId: mastra.runId,
643
+ });
644
+ res.json(result);
645
+ }
646
+ catch (error) {
647
+ const apiError = error;
648
+ console.error('Error executing tool', apiError);
649
+ res.status(apiError.status || 500).json({ error: apiError.message || 'Error executing tool' });
650
+ return;
651
+ }
652
+ });
488
653
  export const handler = serverless(app);
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/templates/worker.ts"],"names":[],"mappings":"AAwBA,UAAU,gBAAgB;IACxB,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IACvC,sBAAsB,IAAI,IAAI,CAAC;CAChC;;mBAk0BsB,OAAO,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,gBAAgB;;AADlF,wBAQE"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/templates/worker.ts"],"names":[],"mappings":"AA0CA,UAAU,gBAAgB;IACxB,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IACvC,sBAAsB,IAAI,IAAI,CAAC;CAChC;;mBAshCsB,OAAO,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,gBAAgB;;AADlF,wBAQE"}