@mastra/deployer 0.0.1-alpha.0
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/CHANGELOG.md +8 -0
- package/LICENSE +44 -0
- package/dist/build/bundle.d.ts +8 -0
- package/dist/build/bundle.d.ts.map +1 -0
- package/dist/build/deps.d.ts +21 -0
- package/dist/build/deps.d.ts.map +1 -0
- package/dist/build/env.d.ts +14 -0
- package/dist/build/env.d.ts.map +1 -0
- package/dist/build/fs.d.ts +22 -0
- package/dist/build/fs.d.ts.map +1 -0
- package/dist/build/index.d.ts +6 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/utils.d.ts +2 -0
- package/dist/build/utils.d.ts.map +1 -0
- package/dist/deploy/base.d.ts +36 -0
- package/dist/deploy/base.d.ts.map +1 -0
- package/dist/deploy/index.d.ts +2 -0
- package/dist/deploy/index.d.ts.map +1 -0
- package/dist/deployer.cjs.development.js +2872 -0
- package/dist/deployer.cjs.development.js.map +1 -0
- package/dist/deployer.cjs.production.min.js +2 -0
- package/dist/deployer.cjs.production.min.js.map +1 -0
- package/dist/deployer.esm.js +2840 -0
- package/dist/deployer.esm.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/server/handlers/agents.d.ts +6 -0
- package/dist/server/handlers/agents.d.ts.map +1 -0
- package/dist/server/handlers/client.d.ts +7 -0
- package/dist/server/handlers/client.d.ts.map +1 -0
- package/dist/server/handlers/error.d.ts +7 -0
- package/dist/server/handlers/error.d.ts.map +1 -0
- package/dist/server/handlers/logs.d.ts +4 -0
- package/dist/server/handlers/logs.d.ts.map +1 -0
- package/dist/server/handlers/memory.d.ts +17 -0
- package/dist/server/handlers/memory.d.ts.map +1 -0
- package/dist/server/handlers/root.d.ts +3 -0
- package/dist/server/handlers/root.d.ts.map +1 -0
- package/dist/server/handlers/syncs.d.ts +3 -0
- package/dist/server/handlers/syncs.d.ts.map +1 -0
- package/dist/server/handlers/tools.d.ts +8 -0
- package/dist/server/handlers/tools.d.ts.map +1 -0
- package/dist/server/handlers/utils.d.ts +2 -0
- package/dist/server/handlers/utils.d.ts.map +1 -0
- package/dist/server/handlers/workflows.d.ts +11 -0
- package/dist/server/handlers/workflows.d.ts.map +1 -0
- package/dist/server/index.d.ts +21 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +8964 -0
- package/dist/server/types.d.ts +5 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/welcome.d.ts +2 -0
- package/dist/server/welcome.d.ts.map +1 -0
- package/package.json +61 -0
- package/src/build/bundle.ts +224 -0
- package/src/build/deps.ts +128 -0
- package/src/build/env.ts +76 -0
- package/src/build/fs.ts +66 -0
- package/src/build/index.ts +5 -0
- package/src/build/utils.ts +12 -0
- package/src/deploy/base.ts +171 -0
- package/src/deploy/index.ts +1 -0
- package/src/index.ts +3 -0
- package/src/server/handlers/agents.ts +121 -0
- package/src/server/handlers/client.ts +36 -0
- package/src/server/handlers/error.ts +29 -0
- package/src/server/handlers/logs.ts +24 -0
- package/src/server/handlers/memory.ts +208 -0
- package/src/server/handlers/root.ts +6 -0
- package/src/server/handlers/syncs.ts +19 -0
- package/src/server/handlers/tools.ts +156 -0
- package/src/server/handlers/utils.ts +15 -0
- package/src/server/handlers/workflows.ts +60 -0
- package/src/server/index.ts +185 -0
- package/src/server/types.ts +4 -0
- package/src/server/welcome.ts +105 -0
- package/tsconfig.json +10 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Context } from 'hono';
|
|
2
|
+
import { stringify } from 'superjson';
|
|
3
|
+
import zodToJsonSchema from 'zod-to-json-schema';
|
|
4
|
+
|
|
5
|
+
import { HTTPException } from 'hono/http-exception';
|
|
6
|
+
|
|
7
|
+
import { handleError } from './error';
|
|
8
|
+
import { validateBody } from './utils';
|
|
9
|
+
|
|
10
|
+
// Tool handlers
|
|
11
|
+
export async function getToolsHandler(c: Context) {
|
|
12
|
+
try {
|
|
13
|
+
const tools = c.get('tools');
|
|
14
|
+
|
|
15
|
+
if (!tools) {
|
|
16
|
+
return c.json({});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const serializedTools = Object.entries(tools).reduce(
|
|
20
|
+
(acc, [id, _tool]) => {
|
|
21
|
+
const tool = _tool as any;
|
|
22
|
+
acc[id] = {
|
|
23
|
+
...tool,
|
|
24
|
+
inputSchema: tool.inputSchema ? stringify(zodToJsonSchema(tool.inputSchema)) : undefined,
|
|
25
|
+
outputSchema: tool.outputSchema ? stringify(zodToJsonSchema(tool.outputSchema)) : undefined,
|
|
26
|
+
};
|
|
27
|
+
return acc;
|
|
28
|
+
},
|
|
29
|
+
{} as Record<string, any>,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
return c.json(serializedTools);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return handleError(error, 'Error getting tools');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function getToolByIdHandler(c: Context) {
|
|
39
|
+
try {
|
|
40
|
+
const tools = c.get('tools');
|
|
41
|
+
const toolId = c.req.param('toolId');
|
|
42
|
+
const tool = Object.values(tools || {}).find((tool: any) => tool.id === toolId) as any;
|
|
43
|
+
|
|
44
|
+
if (!tool) {
|
|
45
|
+
throw new HTTPException(404, { message: 'Tool not found' });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const serializedTool = {
|
|
49
|
+
...tool,
|
|
50
|
+
inputSchema: tool.inputSchema ? stringify(zodToJsonSchema(tool.inputSchema)) : undefined,
|
|
51
|
+
outputSchema: tool.outputSchema ? stringify(zodToJsonSchema(tool.outputSchema)) : undefined,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
return c.json(serializedTool);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
return handleError(error, 'Error getting tool');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export async function getToolResultHandler(c: Context) {
|
|
61
|
+
try {
|
|
62
|
+
const mastra = c.get('mastra');
|
|
63
|
+
const memory = mastra.memory;
|
|
64
|
+
const threadId = c.req.param('threadId');
|
|
65
|
+
const { toolName, toolArgs } = await c.req.json();
|
|
66
|
+
|
|
67
|
+
if (!memory) {
|
|
68
|
+
throw new HTTPException(400, { message: 'Memory is not initialized' });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
validateBody({ toolName, toolArgs });
|
|
72
|
+
|
|
73
|
+
const thread = await memory.getThreadById({ threadId });
|
|
74
|
+
if (!thread) {
|
|
75
|
+
throw new HTTPException(404, { message: 'Thread not found' });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const result = await memory.getToolResult({ threadId, toolName, toolArgs });
|
|
79
|
+
return c.json(result);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
return handleError(error, 'Error getting tool result');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export async function validateToolCallArgsHandler(c: Context) {
|
|
86
|
+
try {
|
|
87
|
+
const mastra = c.get('mastra');
|
|
88
|
+
const memory = mastra.memory;
|
|
89
|
+
const { hashedArgs } = await c.req.json();
|
|
90
|
+
|
|
91
|
+
if (!memory) {
|
|
92
|
+
throw new HTTPException(400, { message: 'Memory is not initialized' });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
validateBody({ hashedArgs });
|
|
96
|
+
|
|
97
|
+
const result = await memory.validateToolCallArgs({ hashedArgs });
|
|
98
|
+
return c.json(result);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
return handleError(error, 'Error validating tool call args');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function executeToolHandler(tools: Record<string, any>) {
|
|
105
|
+
return async (c: Context) => {
|
|
106
|
+
try {
|
|
107
|
+
const toolId = decodeURIComponent(c.req.param('toolId'));
|
|
108
|
+
const tool = Object.values(tools || {}).find((tool: any) => tool.id === toolId) as any;
|
|
109
|
+
|
|
110
|
+
if (!tool) {
|
|
111
|
+
return c.json({ error: 'Tool not found' }, 404);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const { input } = await c.req.json();
|
|
115
|
+
const mastra = c.get('mastra');
|
|
116
|
+
const result = await tool.execute({
|
|
117
|
+
context: {
|
|
118
|
+
...input,
|
|
119
|
+
},
|
|
120
|
+
mastra,
|
|
121
|
+
runId: mastra.runId,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
return c.json(result);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
return handleError(error, 'Error executing tool');
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export async function executeAgentToolHandler(c: Context) {
|
|
132
|
+
try {
|
|
133
|
+
const mastra = c.get('mastra');
|
|
134
|
+
const agentId = c.req.param('agentId');
|
|
135
|
+
const toolId = c.req.param('toolId');
|
|
136
|
+
const agent = mastra.getAgent(agentId);
|
|
137
|
+
const tool = Object.values(agent?.tools || {}).find((tool: any) => tool.id === toolId) as any;
|
|
138
|
+
|
|
139
|
+
if (!tool) {
|
|
140
|
+
throw new HTTPException(404, { message: 'Tool not found' });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const body = await c.req.json();
|
|
144
|
+
const result = await tool.execute({
|
|
145
|
+
context: {
|
|
146
|
+
...body,
|
|
147
|
+
},
|
|
148
|
+
mastra,
|
|
149
|
+
runId: agentId,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
return c.json(result);
|
|
153
|
+
} catch (error) {
|
|
154
|
+
return handleError(error, 'Error executing tool');
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -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,60 @@
|
|
|
1
|
+
import { Context } from 'hono';
|
|
2
|
+
import { stringify } from 'superjson';
|
|
3
|
+
import zodToJsonSchema from 'zod-to-json-schema';
|
|
4
|
+
|
|
5
|
+
import { handleError } from './error';
|
|
6
|
+
|
|
7
|
+
export async function getWorkflowsHandler(c: Context) {
|
|
8
|
+
try {
|
|
9
|
+
const mastra = c.get('mastra');
|
|
10
|
+
const workflows = mastra.getWorkflows({ serialized: true });
|
|
11
|
+
return c.json(workflows);
|
|
12
|
+
} catch (error) {
|
|
13
|
+
return handleError(error, 'Error getting workflows');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function getWorkflowByIdHandler(c: Context) {
|
|
18
|
+
try {
|
|
19
|
+
const mastra = c.get('mastra');
|
|
20
|
+
const workflowId = c.req.param('workflowId');
|
|
21
|
+
const workflow = mastra.getWorkflow(workflowId);
|
|
22
|
+
|
|
23
|
+
const triggerSchema = workflow.triggerSchema;
|
|
24
|
+
const stepGraph = workflow.stepGraph;
|
|
25
|
+
const stepSubscriberGraph = workflow.stepSubscriberGraph;
|
|
26
|
+
const serializedSteps = Object.entries(workflow.steps).reduce<any>((acc, [key, step]) => {
|
|
27
|
+
const _step = step as any;
|
|
28
|
+
acc[key] = {
|
|
29
|
+
..._step,
|
|
30
|
+
inputSchema: _step.inputSchema ? stringify(zodToJsonSchema(_step.inputSchema)) : undefined,
|
|
31
|
+
outputSchema: _step.outputSchema ? stringify(zodToJsonSchema(_step.outputSchema)) : undefined,
|
|
32
|
+
};
|
|
33
|
+
return acc;
|
|
34
|
+
}, {});
|
|
35
|
+
|
|
36
|
+
return c.json({
|
|
37
|
+
name: workflow.name,
|
|
38
|
+
triggerSchema: triggerSchema ? stringify(zodToJsonSchema(triggerSchema)) : undefined,
|
|
39
|
+
steps: serializedSteps,
|
|
40
|
+
stepGraph,
|
|
41
|
+
stepSubscriberGraph,
|
|
42
|
+
});
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return handleError(error, 'Error getting workflow');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function executeWorkflowHandler(c: Context) {
|
|
49
|
+
try {
|
|
50
|
+
const mastra = c.get('mastra');
|
|
51
|
+
const workflowId = c.req.param('workflowId');
|
|
52
|
+
const workflow = mastra.getWorkflow(workflowId);
|
|
53
|
+
const body = await c.req.json();
|
|
54
|
+
|
|
55
|
+
const result = await workflow.execute(body);
|
|
56
|
+
return c.json(result);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
return handleError(error, 'Error executing workflow');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { serve } from '@hono/node-server';
|
|
2
|
+
import { serveStatic } from '@hono/node-server/serve-static';
|
|
3
|
+
import { type Mastra } from '@mastra/core';
|
|
4
|
+
import { Hono } from 'hono';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { pathToFileURL } from 'url';
|
|
7
|
+
|
|
8
|
+
import { readFile } from 'fs/promises';
|
|
9
|
+
import { cors } from 'hono/cors';
|
|
10
|
+
|
|
11
|
+
import { generateHandler, getAgentByIdHandler, getAgentsHandler, streamGenerateHandler } from './handlers/agents.js';
|
|
12
|
+
import { handleClientsRefresh } from './handlers/client.js';
|
|
13
|
+
import { handleTriggerClientsRefresh } from './handlers/client.js';
|
|
14
|
+
import { getLogsByRunIdHandler, getLogsHandler } from './handlers/logs';
|
|
15
|
+
import {
|
|
16
|
+
createThreadHandler,
|
|
17
|
+
deleteThreadHandler,
|
|
18
|
+
getContextWindowHandler,
|
|
19
|
+
getMemoryStatusHandler,
|
|
20
|
+
getMessagesHandler,
|
|
21
|
+
getThreadByIdHandler,
|
|
22
|
+
getThreadsHandler,
|
|
23
|
+
saveMessagesHandler,
|
|
24
|
+
updateThreadHandler,
|
|
25
|
+
} from './handlers/memory';
|
|
26
|
+
import { rootHandler } from './handlers/root.js';
|
|
27
|
+
import { executeSyncHandler } from './handlers/syncs.js';
|
|
28
|
+
import {
|
|
29
|
+
executeAgentToolHandler,
|
|
30
|
+
executeToolHandler,
|
|
31
|
+
getToolByIdHandler,
|
|
32
|
+
getToolResultHandler,
|
|
33
|
+
getToolsHandler,
|
|
34
|
+
validateToolCallArgsHandler,
|
|
35
|
+
} from './handlers/tools';
|
|
36
|
+
import { executeWorkflowHandler, getWorkflowByIdHandler, getWorkflowsHandler } from './handlers/workflows';
|
|
37
|
+
import { html } from './welcome.js';
|
|
38
|
+
|
|
39
|
+
type Bindings = {};
|
|
40
|
+
|
|
41
|
+
type Variables = {
|
|
42
|
+
mastra: Mastra;
|
|
43
|
+
clients: Set<{ controller: ReadableStreamDefaultController }>;
|
|
44
|
+
tools: Record<string, any>;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export async function createHonoServer(mastra: Mastra, options: { playground?: boolean } = {}) {
|
|
48
|
+
// Create typed Hono app
|
|
49
|
+
const app = new Hono<{ Bindings: Bindings; Variables: Variables }>();
|
|
50
|
+
|
|
51
|
+
// Initialize tools
|
|
52
|
+
const mastraToolsPaths = process.env.MASTRA_TOOLS_PATH;
|
|
53
|
+
const toolImports = mastraToolsPaths
|
|
54
|
+
? await Promise.all(
|
|
55
|
+
mastraToolsPaths.split(',').map(async toolPath => {
|
|
56
|
+
return import(pathToFileURL(toolPath).href);
|
|
57
|
+
}),
|
|
58
|
+
)
|
|
59
|
+
: [];
|
|
60
|
+
|
|
61
|
+
const tools = toolImports.reduce((acc, toolModule) => {
|
|
62
|
+
Object.entries(toolModule).forEach(([key, tool]) => {
|
|
63
|
+
acc[key] = tool;
|
|
64
|
+
});
|
|
65
|
+
return acc;
|
|
66
|
+
}, {});
|
|
67
|
+
|
|
68
|
+
// Middleware
|
|
69
|
+
app.use('*', cors());
|
|
70
|
+
|
|
71
|
+
// Add Mastra to context
|
|
72
|
+
app.use('*', async (c, next) => {
|
|
73
|
+
c.set('mastra', mastra);
|
|
74
|
+
c.set('tools', tools);
|
|
75
|
+
await next();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// API routes
|
|
79
|
+
app.get('/api', rootHandler);
|
|
80
|
+
|
|
81
|
+
// Agent routes
|
|
82
|
+
app.get('/api/agents', getAgentsHandler);
|
|
83
|
+
app.get('/api/agents/:agentId', getAgentByIdHandler);
|
|
84
|
+
app.post('/api/agents/:agentId/generate', generateHandler);
|
|
85
|
+
app.post('/api/agents/:agentId/stream', streamGenerateHandler);
|
|
86
|
+
app.post('/api/agents/:agentId/tools/:toolId/execute', executeAgentToolHandler);
|
|
87
|
+
|
|
88
|
+
// Memory routes
|
|
89
|
+
app.get('/api/memory/status', getMemoryStatusHandler);
|
|
90
|
+
app.get('/api/memory/threads', getThreadsHandler);
|
|
91
|
+
app.get('/api/memory/threads/:threadId', getThreadByIdHandler);
|
|
92
|
+
app.get('/api/memory/threads/:threadId/messages', getMessagesHandler);
|
|
93
|
+
app.get('/api/memory/threads/:threadId/context-window', getContextWindowHandler);
|
|
94
|
+
app.post('/api/memory/threads', createThreadHandler);
|
|
95
|
+
app.patch('/api/memory/threads/:threadId', updateThreadHandler);
|
|
96
|
+
app.delete('/api/memory/threads/:threadId', deleteThreadHandler);
|
|
97
|
+
app.post('/api/memory/save-messages', saveMessagesHandler);
|
|
98
|
+
app.post('/api/memory/threads/:threadId/tool-result', getToolResultHandler);
|
|
99
|
+
app.post('/api/memory/validate-tool-call-args', validateToolCallArgsHandler);
|
|
100
|
+
|
|
101
|
+
// Workflow routes
|
|
102
|
+
app.get('/api/workflows', getWorkflowsHandler);
|
|
103
|
+
app.get('/api/workflows/:workflowId', getWorkflowByIdHandler);
|
|
104
|
+
app.post('/api/workflows/:workflowId/execute', executeWorkflowHandler);
|
|
105
|
+
|
|
106
|
+
// Sync routes
|
|
107
|
+
app.post('/api/syncs/:syncId/execute', executeSyncHandler);
|
|
108
|
+
|
|
109
|
+
// Log routes
|
|
110
|
+
app.get('/api/logs', getLogsHandler);
|
|
111
|
+
app.get('/api/logs/:runId', getLogsByRunIdHandler);
|
|
112
|
+
|
|
113
|
+
// Tool routes
|
|
114
|
+
app.get('/api/tools', getToolsHandler);
|
|
115
|
+
app.get('/api/tools/:toolId', getToolByIdHandler);
|
|
116
|
+
app.post('/api/tools/:toolId/execute', executeToolHandler(tools));
|
|
117
|
+
|
|
118
|
+
// SSE endpoint for refresh notifications
|
|
119
|
+
app.get('/refresh-events', handleClientsRefresh);
|
|
120
|
+
|
|
121
|
+
// Trigger refresh for all clients
|
|
122
|
+
app.post('/__refresh', handleTriggerClientsRefresh);
|
|
123
|
+
|
|
124
|
+
if (options?.playground) {
|
|
125
|
+
// Playground routes - these should come after API routes
|
|
126
|
+
// Serve assets with specific MIME types
|
|
127
|
+
app.use('/assets/*', async (c, next) => {
|
|
128
|
+
const path = c.req.path;
|
|
129
|
+
if (path.endsWith('.js')) {
|
|
130
|
+
c.header('Content-Type', 'application/javascript');
|
|
131
|
+
} else if (path.endsWith('.css')) {
|
|
132
|
+
c.header('Content-Type', 'text/css');
|
|
133
|
+
}
|
|
134
|
+
await next();
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Serve assets from playground directory
|
|
138
|
+
app.use(
|
|
139
|
+
'/assets/*',
|
|
140
|
+
serveStatic({
|
|
141
|
+
root: './playground/assets',
|
|
142
|
+
}),
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// Serve static files from playground directory
|
|
146
|
+
app.use(
|
|
147
|
+
'*',
|
|
148
|
+
serveStatic({
|
|
149
|
+
root: './playground',
|
|
150
|
+
}),
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Catch-all route to serve index.html for any non-API routes
|
|
155
|
+
app.get('*', async (c, next) => {
|
|
156
|
+
// Skip if it's an API route
|
|
157
|
+
if (c.req.path.startsWith('/api/')) {
|
|
158
|
+
return await next();
|
|
159
|
+
}
|
|
160
|
+
if (options?.playground) {
|
|
161
|
+
// For all other routes, serve index.html
|
|
162
|
+
const indexHtml = await readFile(join(process.cwd(), './playground/index.html'), 'utf-8');
|
|
163
|
+
return c.newResponse(indexHtml, 200, { 'Content-Type': 'text/html' });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return c.newResponse(html, 200, { 'Content-Type': 'text/html' });
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return app;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export async function createNodeServer(mastra: Mastra, options: { playground?: boolean } = {}) {
|
|
173
|
+
const app = await createHonoServer(mastra, options);
|
|
174
|
+
return serve(
|
|
175
|
+
{
|
|
176
|
+
fetch: app.fetch,
|
|
177
|
+
port: Number(process.env.PORT) || 4111,
|
|
178
|
+
},
|
|
179
|
+
() => {
|
|
180
|
+
console.log(`🦄 Server running on port ${process.env.PORT || 4111}/api`);
|
|
181
|
+
console.log(`📚 Open API documentation available at http://localhost:${process.env.PORT || 4111}/openapi.json`);
|
|
182
|
+
console.log(`👨💻 Playground available at http://localhost:${process.env.PORT || 4111}/`);
|
|
183
|
+
},
|
|
184
|
+
);
|
|
185
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export const html = `
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Welcome to Mastra</title>
|
|
8
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/inter-ui/3.19.3/inter.min.css" />
|
|
9
|
+
<style>
|
|
10
|
+
body {
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
background-color: #0d0d0d;
|
|
14
|
+
color: #ffffff;
|
|
15
|
+
font-family:
|
|
16
|
+
'Inter',
|
|
17
|
+
-apple-system,
|
|
18
|
+
BlinkMacSystemFont,
|
|
19
|
+
system-ui,
|
|
20
|
+
sans-serif;
|
|
21
|
+
min-height: 100vh;
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
main {
|
|
27
|
+
flex: 1;
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
align-items: center;
|
|
31
|
+
justify-content: center;
|
|
32
|
+
padding: 2rem;
|
|
33
|
+
text-align: center;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
h1 {
|
|
37
|
+
font-size: 4rem;
|
|
38
|
+
font-weight: 600;
|
|
39
|
+
margin: 0 0 1rem 0;
|
|
40
|
+
background: linear-gradient(to right, #fff, #ccc);
|
|
41
|
+
-webkit-background-clip: text;
|
|
42
|
+
-webkit-text-fill-color: transparent;
|
|
43
|
+
line-height: 1.2;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.subtitle {
|
|
47
|
+
color: #9ca3af;
|
|
48
|
+
font-size: 1.25rem;
|
|
49
|
+
max-width: 600px;
|
|
50
|
+
margin: 0 auto 3rem auto;
|
|
51
|
+
line-height: 1.6;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.docs-link {
|
|
55
|
+
background-color: #1a1a1a;
|
|
56
|
+
padding: 1rem 2rem;
|
|
57
|
+
border-radius: 0.5rem;
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
gap: 1rem;
|
|
61
|
+
font-family: monospace;
|
|
62
|
+
font-size: 1rem;
|
|
63
|
+
color: #ffffff;
|
|
64
|
+
text-decoration: none;
|
|
65
|
+
transition: background-color 0.2s;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.docs-link:hover {
|
|
69
|
+
background-color: #252525;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.arrow-icon {
|
|
73
|
+
transition: transform 0.2s;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.docs-link:hover .arrow-icon {
|
|
77
|
+
transform: translateX(4px);
|
|
78
|
+
}
|
|
79
|
+
</style>
|
|
80
|
+
</head>
|
|
81
|
+
<body>
|
|
82
|
+
<main>
|
|
83
|
+
<h1>Welcome to Mastra</h1>
|
|
84
|
+
<p class="subtitle">
|
|
85
|
+
From the team that brought you Gatsby: prototype and productionize AI features with a modern JS/TS stack.
|
|
86
|
+
</p>
|
|
87
|
+
|
|
88
|
+
<a href="https://mastra.ai/docs" class="docs-link">
|
|
89
|
+
Browse the docs
|
|
90
|
+
<svg
|
|
91
|
+
class="arrow-icon"
|
|
92
|
+
width="20"
|
|
93
|
+
height="20"
|
|
94
|
+
viewBox="0 0 24 24"
|
|
95
|
+
fill="none"
|
|
96
|
+
stroke="currentColor"
|
|
97
|
+
stroke-width="2"
|
|
98
|
+
>
|
|
99
|
+
<path d="M5 12h14M12 5l7 7-7 7" />
|
|
100
|
+
</svg>
|
|
101
|
+
</a>
|
|
102
|
+
</main>
|
|
103
|
+
</body>
|
|
104
|
+
</html>
|
|
105
|
+
`;
|
package/tsconfig.json
ADDED