@mastra/deployer 0.0.0-commonjs-20250227130920

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 (86) hide show
  1. package/.turbo/turbo-build.log +41 -0
  2. package/CHANGELOG.md +897 -0
  3. package/LICENSE +44 -0
  4. package/README.md +159 -0
  5. package/dist/_tsup-dts-rollup.d.cts +360 -0
  6. package/dist/_tsup-dts-rollup.d.ts +360 -0
  7. package/dist/build/analyze.cjs +367 -0
  8. package/dist/build/analyze.d.cts +1 -0
  9. package/dist/build/analyze.d.ts +1 -0
  10. package/dist/build/analyze.js +2 -0
  11. package/dist/build/bundler.cjs +353 -0
  12. package/dist/build/bundler.d.cts +2 -0
  13. package/dist/build/bundler.d.ts +2 -0
  14. package/dist/build/bundler.js +2 -0
  15. package/dist/build/index.cjs +1146 -0
  16. package/dist/build/index.d.cts +10 -0
  17. package/dist/build/index.d.ts +10 -0
  18. package/dist/build/index.js +5 -0
  19. package/dist/bundler/index.cjs +999 -0
  20. package/dist/bundler/index.d.cts +1 -0
  21. package/dist/bundler/index.d.ts +1 -0
  22. package/dist/bundler/index.js +5 -0
  23. package/dist/chunk-3ONBKVC4.js +113 -0
  24. package/dist/chunk-AXS5WSIK.js +290 -0
  25. package/dist/chunk-DTSFVNIF.js +260 -0
  26. package/dist/chunk-JMH7HCD6.js +274 -0
  27. package/dist/chunk-SGK37ZWD.js +254 -0
  28. package/dist/chunk-YNXJO2XU.js +69 -0
  29. package/dist/index.cjs +1229 -0
  30. package/dist/index.d.cts +6 -0
  31. package/dist/index.d.ts +6 -0
  32. package/dist/index.js +131 -0
  33. package/dist/server/index.cjs +4930 -0
  34. package/dist/server/index.d.cts +2 -0
  35. package/dist/server/index.d.ts +2 -0
  36. package/dist/server/index.js +4923 -0
  37. package/dist/templates/instrumentation-template.js +86 -0
  38. package/eslint.config.js +6 -0
  39. package/global.d.ts +0 -0
  40. package/package.json +112 -0
  41. package/public/templates/instrumentation-template.js +86 -0
  42. package/src/build/analyze.ts +279 -0
  43. package/src/build/babel/fix-libsql.ts +41 -0
  44. package/src/build/babel/get-deployer.ts +54 -0
  45. package/src/build/babel/get-telemetry-config.ts +62 -0
  46. package/src/build/babel/remove-deployer.ts +43 -0
  47. package/src/build/bundle.ts +139 -0
  48. package/src/build/bundler.ts +135 -0
  49. package/src/build/deployer.ts +67 -0
  50. package/src/build/deps.ts +149 -0
  51. package/src/build/env.ts +76 -0
  52. package/src/build/fs.ts +66 -0
  53. package/src/build/index.ts +7 -0
  54. package/src/build/isNodeBuiltin.ts +7 -0
  55. package/src/build/plugins/fix-libsql.ts +69 -0
  56. package/src/build/plugins/hono-alias.ts +17 -0
  57. package/src/build/plugins/pino.ts +93 -0
  58. package/src/build/plugins/remove-deployer.ts +37 -0
  59. package/src/build/plugins/telemetry-fix.ts +54 -0
  60. package/src/build/telemetry.ts +76 -0
  61. package/src/build/utils.ts +12 -0
  62. package/src/build/watcher.ts +43 -0
  63. package/src/bundler/index.ts +144 -0
  64. package/src/deploy/base.ts +30 -0
  65. package/src/deploy/index.ts +2 -0
  66. package/src/deploy/log.ts +61 -0
  67. package/src/index.ts +3 -0
  68. package/src/server/handlers/agents.ts +209 -0
  69. package/src/server/handlers/client.ts +36 -0
  70. package/src/server/handlers/error.ts +29 -0
  71. package/src/server/handlers/logs.ts +53 -0
  72. package/src/server/handlers/memory.ts +196 -0
  73. package/src/server/handlers/prompt.ts +128 -0
  74. package/src/server/handlers/root.ts +6 -0
  75. package/src/server/handlers/telemetry.ts +48 -0
  76. package/src/server/handlers/tools.ts +114 -0
  77. package/src/server/handlers/utils.ts +15 -0
  78. package/src/server/handlers/vector.ts +149 -0
  79. package/src/server/handlers/workflows.ts +119 -0
  80. package/src/server/index.ts +1355 -0
  81. package/src/server/openapi.json +434 -0
  82. package/src/server/openapi.script.js +22 -0
  83. package/src/server/types.ts +4 -0
  84. package/src/server/welcome.ts +105 -0
  85. package/tsconfig.json +5 -0
  86. package/vitest.config.ts +8 -0
@@ -0,0 +1,128 @@
1
+ import type { Mastra } from '@mastra/core';
2
+ import { Agent } from '@mastra/core/agent';
3
+ import type { Context } from 'hono';
4
+ import { z } from 'zod';
5
+
6
+ import { handleError } from './error';
7
+
8
+ export async function generateSystemPromptHandler(c: Context) {
9
+ try {
10
+ // Check if this is a playground request
11
+ const agentId = c.req.param('agentId');
12
+ const isPlayground = c.get('playground') === true;
13
+ if (!isPlayground) {
14
+ return c.json({ error: 'This API is only available in the playground environment' }, 403);
15
+ }
16
+
17
+ const { instructions, comment } = await c.req.json();
18
+
19
+ if (!instructions) {
20
+ return c.json({ error: 'Missing instructions in request body' }, 400);
21
+ }
22
+
23
+ const mastra: Mastra<any> = c.get('mastra');
24
+ const agent = mastra.getAgent(agentId);
25
+
26
+ if (!agent) {
27
+ return c.json({ error: 'Agent not found' }, 404);
28
+ }
29
+
30
+ let evalSummary = '';
31
+
32
+ try {
33
+ // Get both test and live evals
34
+ const testEvals = (await mastra.storage?.getEvalsByAgentName?.(agent.name, 'test')) || [];
35
+ const liveEvals = (await mastra.storage?.getEvalsByAgentName?.(agent.name, 'live')) || [];
36
+ // Format eval results for the prompt
37
+ const evalsMapped = [...testEvals, ...liveEvals].filter(
38
+ ({ instructions: evalInstructions }) => evalInstructions === instructions,
39
+ );
40
+
41
+ evalSummary = evalsMapped
42
+ .map(
43
+ ({ input, output, result }) => `
44
+ Input: ${input}\n
45
+ Output: ${output}\n
46
+ Result: ${JSON.stringify(result)}
47
+
48
+ `,
49
+ )
50
+ .join('');
51
+ } catch (error) {
52
+ mastra.getLogger().error(`Error fetching evals`, { error });
53
+ }
54
+
55
+ const ENHANCE_SYSTEM_PROMPT_INSTRUCTIONS = `
56
+ You are an expert system prompt engineer, specialized in analyzing and enhancing instructions to create clear, effective, and comprehensive system prompts. Your goal is to help users transform their basic instructions into well-structured system prompts that will guide AI behavior effectively.
57
+ Follow these steps to analyze and enhance the instructions:
58
+ 1. ANALYSIS PHASE
59
+ - Identify the core purpose and goals
60
+ - Extract key constraints and requirements
61
+ - Recognize domain-specific terminology and concepts
62
+ - Note any implicit assumptions that should be made explicit
63
+ 2. PROMPT STRUCTURE
64
+ Create a system prompt with these components:
65
+ a) ROLE DEFINITION
66
+ - Clear statement of the AI's role and purpose
67
+ - Key responsibilities and scope
68
+ - Primary stakeholders and users
69
+ b) CORE CAPABILITIES
70
+ - Main functions and abilities
71
+ - Specific domain knowledge required
72
+ - Tools and resources available
73
+ c) BEHAVIORAL GUIDELINES
74
+ - Communication style and tone
75
+ - Decision-making framework
76
+ - Error handling approach
77
+ - Ethical considerations
78
+ d) CONSTRAINTS & BOUNDARIES
79
+ - Explicit limitations
80
+ - Out-of-scope activities
81
+ - Security and privacy considerations
82
+ e) SUCCESS CRITERIA
83
+ - Quality standards
84
+ - Expected outcomes
85
+ - Performance metrics
86
+ 3. QUALITY CHECKS
87
+ Ensure the prompt is:
88
+ - Clear and unambiguous
89
+ - Comprehensive yet concise
90
+ - Properly scoped
91
+ - Technically accurate
92
+ - Ethically sound
93
+ 4. OUTPUT FORMAT
94
+ Return a structured response with:
95
+ - Enhanced system prompt
96
+ - Analysis of key components
97
+ - Identified goals and constraints
98
+ - Core domain concepts
99
+ Remember: A good system prompt should be specific enough to guide behavior but flexible enough to handle edge cases.
100
+ Focus on creating prompts that are clear, actionable, and aligned with the intended use case.
101
+ `;
102
+
103
+ const systemPromptAgent = new Agent({
104
+ name: 'system-prompt-enhancer',
105
+ instructions: ENHANCE_SYSTEM_PROMPT_INSTRUCTIONS,
106
+ model: agent.llm?.getModel(),
107
+ });
108
+
109
+ const result = await systemPromptAgent.generate(
110
+ `
111
+ We need to improve the system prompt.
112
+ Current: ${instructions}
113
+ ${comment ? `User feedback: ${comment}` : ''}
114
+ ${evalSummary ? `\nEvaluation Results:\n${evalSummary}` : ''}
115
+ `,
116
+ {
117
+ output: z.object({
118
+ new_prompt: z.string(),
119
+ explanation: z.string(),
120
+ }),
121
+ },
122
+ );
123
+
124
+ return c.json(result?.object || {});
125
+ } catch (error) {
126
+ return handleError(error, 'Error generating system prompt');
127
+ }
128
+ }
@@ -0,0 +1,6 @@
1
+ import type { Context } from 'hono';
2
+
3
+ // Root handler
4
+ export async function rootHandler(c: Context) {
5
+ return c.text('Hello to the Mastra API!');
6
+ }
@@ -0,0 +1,48 @@
1
+ import type { MastraStorage } from '@mastra/core/storage';
2
+ import type { Telemetry } from '@mastra/core/telemetry';
3
+ import type { Context } from 'hono';
4
+
5
+ import { HTTPException } from 'hono/http-exception';
6
+
7
+ import { handleError } from './error';
8
+
9
+ export async function getTelemetryHandler(c: Context) {
10
+ try {
11
+ const mastra = c.get('mastra');
12
+ const telemetry: Telemetry = mastra.telemetry;
13
+ const storage: MastraStorage = mastra.storage;
14
+
15
+ const { name, scope, page, perPage } = c.req.query();
16
+ const attribute = c.req.queries('attribute');
17
+
18
+ if (!telemetry) {
19
+ throw new HTTPException(400, { message: 'Telemetry is not initialized' });
20
+ }
21
+
22
+ if (!storage) {
23
+ throw new HTTPException(400, { message: 'Storage is not initialized' });
24
+ }
25
+
26
+ // Parse attribute query parameter if present
27
+ const attributes = attribute
28
+ ? Object.fromEntries(
29
+ (Array.isArray(attribute) ? attribute : [attribute]).map(attr => {
30
+ const [key, value] = attr.split(':');
31
+ return [key, value];
32
+ }),
33
+ )
34
+ : undefined;
35
+
36
+ const traces = await storage.getTraces({
37
+ name,
38
+ scope,
39
+ page: Number(page ?? 0),
40
+ perPage: Number(perPage ?? 100),
41
+ attributes,
42
+ });
43
+
44
+ return c.json({ traces });
45
+ } catch (error) {
46
+ return handleError(error, 'Error saving messages');
47
+ }
48
+ }
@@ -0,0 +1,114 @@
1
+ import type { Context } from 'hono';
2
+ import { HTTPException } from 'hono/http-exception';
3
+ import { stringify } from 'superjson';
4
+ import zodToJsonSchema from 'zod-to-json-schema';
5
+
6
+ import { handleError } from './error';
7
+
8
+ // Tool handlers
9
+ export async function getToolsHandler(c: Context) {
10
+ try {
11
+ const tools = c.get('tools');
12
+
13
+ if (!tools) {
14
+ return c.json({});
15
+ }
16
+
17
+ const serializedTools = Object.entries(tools).reduce(
18
+ (acc, [id, _tool]) => {
19
+ const tool = _tool as any;
20
+ acc[id] = {
21
+ ...tool,
22
+ inputSchema: tool.inputSchema ? stringify(zodToJsonSchema(tool.inputSchema)) : undefined,
23
+ outputSchema: tool.outputSchema ? stringify(zodToJsonSchema(tool.outputSchema)) : undefined,
24
+ };
25
+ return acc;
26
+ },
27
+ {} as Record<string, any>,
28
+ );
29
+
30
+ return c.json(serializedTools);
31
+ } catch (error) {
32
+ return handleError(error, 'Error getting tools');
33
+ }
34
+ }
35
+
36
+ export async function getToolByIdHandler(c: Context) {
37
+ try {
38
+ const tools = c.get('tools');
39
+ const toolId = c.req.param('toolId');
40
+ const tool = Object.values(tools || {}).find((tool: any) => tool.id === toolId) as any;
41
+
42
+ if (!tool) {
43
+ throw new HTTPException(404, { message: 'Tool not found' });
44
+ }
45
+
46
+ const serializedTool = {
47
+ ...tool,
48
+ inputSchema: tool.inputSchema ? stringify(zodToJsonSchema(tool.inputSchema)) : undefined,
49
+ outputSchema: tool.outputSchema ? stringify(zodToJsonSchema(tool.outputSchema)) : undefined,
50
+ };
51
+
52
+ return c.json(serializedTool);
53
+ } catch (error) {
54
+ return handleError(error, 'Error getting tool');
55
+ }
56
+ }
57
+
58
+ export function executeToolHandler(tools: Record<string, any>) {
59
+ return async (c: Context) => {
60
+ try {
61
+ const toolId = decodeURIComponent(c.req.param('toolId'));
62
+ const tool = Object.values(tools || {}).find((tool: any) => tool.id === toolId) as any;
63
+
64
+ if (!tool) {
65
+ return c.json({ error: 'Tool not found' }, 404);
66
+ }
67
+
68
+ if (!tool?.execute) {
69
+ return c.json({ error: 'Tool is not executable' }, 400);
70
+ }
71
+
72
+ const { data } = await c.req.json();
73
+ const mastra = c.get('mastra');
74
+ const result = await tool.execute({
75
+ context: data,
76
+ mastra,
77
+ runId: mastra.runId,
78
+ });
79
+
80
+ return c.json(result);
81
+ } catch (error) {
82
+ return handleError(error, 'Error executing tool');
83
+ }
84
+ };
85
+ }
86
+
87
+ export async function executeAgentToolHandler(c: Context) {
88
+ try {
89
+ const mastra = c.get('mastra');
90
+ const agentId = c.req.param('agentId');
91
+ const toolId = c.req.param('toolId');
92
+ const agent = mastra.getAgent(agentId);
93
+ const tool = Object.values(agent?.tools || {}).find((tool: any) => tool.id === toolId) as any;
94
+
95
+ if (!tool) {
96
+ throw new HTTPException(404, { message: 'Tool not found' });
97
+ }
98
+
99
+ if (!tool?.execute) {
100
+ return c.json({ error: 'Tool is not executable' }, 400);
101
+ }
102
+
103
+ const { data } = await c.req.json();
104
+ const result = await tool.execute({
105
+ context: data,
106
+ mastra,
107
+ runId: agentId,
108
+ });
109
+
110
+ return c.json(result);
111
+ } catch (error) {
112
+ return handleError(error, 'Error executing tool');
113
+ }
114
+ }
@@ -0,0 +1,15 @@
1
+ import { HTTPException } from 'hono/http-exception';
2
+
3
+ // Validation helper
4
+ export function validateBody(body: Record<string, unknown>) {
5
+ const errorResponse = Object.entries(body).reduce<Record<string, string>>((acc, [key, value]) => {
6
+ if (!value) {
7
+ acc[key] = `${key} is required`;
8
+ }
9
+ return acc;
10
+ }, {});
11
+
12
+ if (Object.keys(errorResponse).length > 0) {
13
+ throw new HTTPException(400, { message: JSON.stringify(errorResponse) });
14
+ }
15
+ }
@@ -0,0 +1,149 @@
1
+ import type { MastraVector, QueryResult, IndexStats } from '@mastra/core/vector';
2
+ import type { Context } from 'hono';
3
+
4
+ import { HTTPException } from 'hono/http-exception';
5
+
6
+ import { handleError } from './error';
7
+
8
+ interface UpsertRequest {
9
+ indexName: string;
10
+ vectors: number[][];
11
+ metadata?: Record<string, any>[];
12
+ ids?: string[];
13
+ }
14
+
15
+ interface CreateIndexRequest {
16
+ indexName: string;
17
+ dimension: number;
18
+ metric?: 'cosine' | 'euclidean' | 'dotproduct';
19
+ }
20
+
21
+ interface QueryRequest {
22
+ indexName: string;
23
+ queryVector: number[];
24
+ topK?: number;
25
+ filter?: Record<string, any>;
26
+ includeVector?: boolean;
27
+ }
28
+
29
+ export const getVector = (c: Context, vectorName: string): MastraVector => {
30
+ const vector = c.get('mastra').getVector(vectorName);
31
+ if (!vector) {
32
+ throw new HTTPException(404, { message: `Vector store ${vectorName} not found` });
33
+ }
34
+ return vector;
35
+ };
36
+
37
+ // Upsert vectors
38
+ export async function upsertVectors(c: Context) {
39
+ try {
40
+ const vectorName = c.req.param('vectorName');
41
+ const { indexName, vectors, metadata, ids } = await c.req.json<UpsertRequest>();
42
+
43
+ if (!indexName || !vectors || !Array.isArray(vectors)) {
44
+ throw new HTTPException(400, { message: 'Invalid request body. indexName and vectors array are required.' });
45
+ }
46
+
47
+ const vector = getVector(c, vectorName);
48
+ const result = await vector.upsert(indexName, vectors, metadata, ids);
49
+ return c.json({ ids: result });
50
+ } catch (error) {
51
+ return handleError(error, 'Error upserting vectors');
52
+ }
53
+ }
54
+
55
+ // Create index
56
+ export async function createIndex(c: Context) {
57
+ try {
58
+ const vectorName = c.req.param('vectorName');
59
+ const { indexName, dimension, metric } = await c.req.json<CreateIndexRequest>();
60
+
61
+ if (!indexName || typeof dimension !== 'number' || dimension <= 0) {
62
+ throw new HTTPException(400, {
63
+ message: 'Invalid request body. indexName and positive dimension number are required.',
64
+ });
65
+ }
66
+
67
+ if (metric && !['cosine', 'euclidean', 'dotproduct'].includes(metric)) {
68
+ throw new HTTPException(400, { message: 'Invalid metric. Must be one of: cosine, euclidean, dotproduct' });
69
+ }
70
+
71
+ const vector = getVector(c, vectorName);
72
+ await vector.createIndex(indexName, dimension, metric);
73
+ return c.json({ success: true });
74
+ } catch (error) {
75
+ return handleError(error, 'Error creating index');
76
+ }
77
+ }
78
+
79
+ // Query vectors
80
+ export async function queryVectors(c: Context) {
81
+ try {
82
+ const vectorName = c.req.param('vectorName');
83
+ const { indexName, queryVector, topK = 10, filter, includeVector = false } = await c.req.json<QueryRequest>();
84
+
85
+ if (!indexName || !queryVector || !Array.isArray(queryVector)) {
86
+ throw new HTTPException(400, { message: 'Invalid request body. indexName and queryVector array are required.' });
87
+ }
88
+
89
+ const vector = getVector(c, vectorName);
90
+ const results: QueryResult[] = await vector.query(indexName, queryVector, topK, filter, includeVector);
91
+ return c.json({ results });
92
+ } catch (error) {
93
+ return handleError(error, 'Error querying vectors');
94
+ }
95
+ }
96
+
97
+ // List indexes
98
+ export async function listIndexes(c: Context) {
99
+ try {
100
+ const vectorName = c.req.param('vectorName');
101
+ const vector = getVector(c, vectorName);
102
+
103
+ const indexes = await vector.listIndexes();
104
+ return c.json({ indexes: indexes.filter(Boolean) });
105
+ } catch (error) {
106
+ return handleError(error, 'Error listing indexes');
107
+ }
108
+ }
109
+
110
+ // Describe index
111
+ export async function describeIndex(c: Context) {
112
+ try {
113
+ const vectorName = c.req.param('vectorName');
114
+ const indexName = c.req.param('indexName');
115
+
116
+ if (!indexName) {
117
+ throw new HTTPException(400, { message: 'Index name is required' });
118
+ }
119
+
120
+ const vector = getVector(c, vectorName);
121
+ const stats: IndexStats = await vector.describeIndex(indexName);
122
+
123
+ return c.json({
124
+ dimension: stats.dimension,
125
+ count: stats.count,
126
+ metric: stats.metric?.toLowerCase(),
127
+ });
128
+ } catch (error) {
129
+ return handleError(error, 'Error describing index');
130
+ }
131
+ }
132
+
133
+ // Delete index
134
+ export async function deleteIndex(c: Context) {
135
+ try {
136
+ const vectorName = c.req.param('vectorName');
137
+ const indexName = c.req.param('indexName');
138
+
139
+ if (!indexName) {
140
+ throw new HTTPException(400, { message: 'Index name is required' });
141
+ }
142
+
143
+ const vector = getVector(c, vectorName);
144
+ await vector.deleteIndex(indexName);
145
+ return c.json({ success: true });
146
+ } catch (error) {
147
+ return handleError(error, 'Error deleting index');
148
+ }
149
+ }
@@ -0,0 +1,119 @@
1
+ import type { Mastra } from '@mastra/core';
2
+ import type { Context } from 'hono';
3
+ import { streamText } from 'hono/streaming';
4
+ import { stringify } from 'superjson';
5
+ import zodToJsonSchema from 'zod-to-json-schema';
6
+
7
+
8
+ import { handleError } from './error';
9
+
10
+ export async function getWorkflowsHandler(c: Context) {
11
+ try {
12
+ const mastra: Mastra = c.get('mastra');
13
+ const workflows = mastra.getWorkflows({ serialized: true });
14
+ return c.json(workflows);
15
+ } catch (error) {
16
+ return handleError(error, 'Error getting workflows');
17
+ }
18
+ }
19
+
20
+ export async function getWorkflowByIdHandler(c: Context) {
21
+ try {
22
+ const mastra: Mastra = c.get('mastra');
23
+ const workflowId = c.req.param('workflowId');
24
+ const workflow = mastra.getWorkflow(workflowId);
25
+
26
+ const triggerSchema = workflow?.triggerSchema;
27
+ const stepGraph = workflow.stepGraph;
28
+ const stepSubscriberGraph = workflow.stepSubscriberGraph;
29
+ const serializedSteps = Object.entries(workflow.steps).reduce<any>((acc, [key, step]) => {
30
+ const _step = step as any;
31
+ acc[key] = {
32
+ ..._step,
33
+ inputSchema: _step.inputSchema ? stringify(zodToJsonSchema(_step.inputSchema)) : undefined,
34
+ outputSchema: _step.outputSchema ? stringify(zodToJsonSchema(_step.outputSchema)) : undefined,
35
+ };
36
+ return acc;
37
+ }, {});
38
+
39
+ return c.json({
40
+ name: workflow.name,
41
+ triggerSchema: triggerSchema ? stringify(zodToJsonSchema(triggerSchema)) : undefined,
42
+ steps: serializedSteps,
43
+ stepGraph,
44
+ stepSubscriberGraph,
45
+ });
46
+ } catch (error) {
47
+ return handleError(error, 'Error getting workflow');
48
+ }
49
+ }
50
+
51
+ export async function executeWorkflowHandler(c: Context) {
52
+ try {
53
+ const mastra: Mastra = c.get('mastra');
54
+ const workflowId = c.req.param('workflowId');
55
+ const workflow = mastra.getWorkflow(workflowId);
56
+ const body = await c.req.json();
57
+
58
+ const { start } = workflow.createRun();
59
+
60
+ const result = await start({
61
+ triggerData: body,
62
+ });
63
+ return c.json(result);
64
+ } catch (error) {
65
+ return handleError(error, 'Error executing workflow');
66
+ }
67
+ }
68
+
69
+ export async function watchWorkflowHandler(c: Context) {
70
+ try {
71
+ const mastra: Mastra = c.get('mastra');
72
+ const logger = mastra.getLogger();
73
+ const workflowId = c.req.param('workflowId');
74
+ const workflow = mastra.getWorkflow(workflowId);
75
+
76
+ return streamText(
77
+ c,
78
+ async stream => {
79
+ // NOTE: looks like the UI is closing the watch request, so as long as that is the case
80
+ // this promise doesn't need to be resolved or rejected
81
+ return new Promise((_resolve, _reject) => {
82
+ let unwatch: () => void = workflow.watch(({ activePaths, context }) => {
83
+ void stream.write(JSON.stringify({ activePaths, context }) + '\x1E');
84
+ });
85
+
86
+ stream.onAbort(() => {
87
+ unwatch?.();
88
+ });
89
+ });
90
+ },
91
+ async (err, stream) => {
92
+ logger.error('Error in watch stream: ' + err?.message);
93
+ stream.abort();
94
+ await stream.close();
95
+ },
96
+ );
97
+ } catch (error) {
98
+ return handleError(error, 'Error watching workflow');
99
+ }
100
+ }
101
+
102
+ export async function resumeWorkflowHandler(c: Context) {
103
+ try {
104
+ const mastra: Mastra = c.get('mastra');
105
+ const workflowId = c.req.param('workflowId');
106
+ const workflow = mastra.getWorkflow(workflowId);
107
+ const { stepId, runId, context } = await c.req.json();
108
+
109
+ const result = await workflow.resume({
110
+ stepId,
111
+ runId,
112
+ context,
113
+ });
114
+
115
+ return c.json(result);
116
+ } catch (error) {
117
+ return handleError(error, 'Error resuming workflow step');
118
+ }
119
+ }