@mastra/mcp-docs-server 1.2.15 → 1.2.16-alpha.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/.docs/docs/agents/agent-approval.md +5 -5
- package/.docs/docs/agents/overview.md +4 -4
- package/.docs/docs/browser/overview.md +1 -1
- package/.docs/docs/capabilities/channels.md +5 -5
- package/.docs/docs/capabilities/subagents.md +1 -1
- package/.docs/docs/connections/overview.md +1 -1
- package/.docs/docs/datasets/overview.md +1 -1
- package/.docs/docs/deployment/cloud-providers.md +4 -2
- package/.docs/docs/deployment/mastra-server.md +1 -1
- package/.docs/docs/deployment/monorepo.md +1 -1
- package/.docs/docs/deployment/overview.md +4 -1
- package/.docs/docs/deployment/sandbox.md +1 -1
- package/.docs/docs/deployment/web-framework.md +1 -1
- package/.docs/docs/deployment/workers.md +248 -2
- package/.docs/docs/evals/overview.md +1 -1
- package/.docs/docs/evals/quick-checks.md +1 -1
- package/.docs/docs/guides/multi-agent-systems.md +1 -1
- package/.docs/docs/harness/agent-controller.md +5 -5
- package/.docs/docs/harness/overview.md +1 -1
- package/.docs/docs/index.md +3 -3
- package/.docs/docs/long-running-agents/signal-providers.md +2 -2
- package/.docs/docs/mastra-platform/deploy.md +1 -1
- package/.docs/docs/mastra-platform/observability.md +63 -18
- package/.docs/docs/mastra-platform/overview.md +1 -1
- package/.docs/docs/mcp/overview.md +1 -1
- package/.docs/docs/memory/working-memory.md +1 -1
- package/.docs/docs/observability/integrations/exporters/mastra-storage.md +2 -2
- package/.docs/docs/observability/logging.md +1 -1
- package/.docs/docs/observability/metrics/overview.md +1 -1
- package/.docs/docs/observability/overview.md +1 -5
- package/.docs/docs/observability/tracing/overview.md +3 -6
- package/.docs/docs/server/auth/workers.md +1 -1
- package/.docs/docs/server/auth.md +5 -5
- package/.docs/docs/server/mastra-client.md +1 -1
- package/.docs/docs/server/mastra-server.md +1 -1
- package/.docs/docs/storage/overview.md +7 -6
- package/.docs/docs/workflows/human-in-the-loop.md +2 -2
- package/.docs/docs/workflows/overview.md +2 -2
- package/.docs/docs/workspace/lsp.md +27 -0
- package/.docs/docs/workspace/sandbox.md +11 -12
- package/.docs/integrations/agentic-ui/ai-sdk-ui.md +1 -1
- package/.docs/integrations/agentic-ui/assistant-ui.md +1 -1
- package/.docs/integrations/agentic-ui/copilotkit.md +1 -1
- package/.docs/integrations/agentic-ui/openui.md +1 -1
- package/.docs/integrations/databases/postgresql.md +8 -8
- package/.docs/integrations/deploy/amazon-ec2.md +2 -2
- package/.docs/integrations/deploy/aws-bedrock-agentcore.md +1 -1
- package/.docs/integrations/deploy/aws-lambda.md +2 -2
- package/.docs/integrations/deploy/azure-app-services.md +2 -2
- package/.docs/integrations/deploy/cloudflare.md +2 -2
- package/.docs/integrations/deploy/digital-ocean.md +2 -2
- package/.docs/integrations/deploy/inngest.md +1 -1
- package/.docs/integrations/deploy/kubernetes.md +2 -3
- package/.docs/integrations/deploy/netlify.md +2 -2
- package/.docs/integrations/deploy/temporal.md +1 -1
- package/.docs/integrations/deploy/vercel.md +2 -2
- package/.docs/integrations/file-storage/agentfs.md +1 -1
- package/.docs/integrations/file-storage/amazon-s3.md +1 -1
- package/.docs/integrations/file-storage/archil.md +1 -1
- package/.docs/integrations/file-storage/azure-blob.md +1 -1
- package/.docs/integrations/file-storage/google-cloud-storage.md +1 -1
- package/.docs/integrations/file-storage/google-drive.md +1 -1
- package/.docs/integrations/file-storage/mesa.md +1 -1
- package/.docs/integrations/file-storage/vercel-files.md +1 -1
- package/.docs/integrations/frameworks/astro.md +1 -1
- package/.docs/integrations/frameworks/electron.md +1 -1
- package/.docs/integrations/frameworks/express.md +1 -1
- package/.docs/integrations/frameworks/hono.md +1 -1
- package/.docs/integrations/frameworks/nestjs.md +1 -1
- package/.docs/integrations/frameworks/next-js.md +1 -1
- package/.docs/integrations/frameworks/nuxt.md +1 -1
- package/.docs/integrations/frameworks/sveltekit.md +1 -1
- package/.docs/integrations/frameworks/vite-react.md +1 -1
- package/.docs/integrations/sandboxes/agentcore.md +1 -1
- package/.docs/integrations/sandboxes/apple-container.md +1 -1
- package/.docs/integrations/sandboxes/blaxel.md +1 -1
- package/.docs/integrations/sandboxes/daytona.md +1 -1
- package/.docs/integrations/sandboxes/docker.md +1 -1
- package/.docs/integrations/sandboxes/e2b.md +1 -1
- package/.docs/integrations/sandboxes/modal.md +1 -1
- package/.docs/integrations/sandboxes/railway.md +1 -1
- package/.docs/integrations/sandboxes/vercel.md +3 -1
- package/.docs/integrations/tools/firecrawl.md +2 -2
- package/.docs/integrations/voice/livekit.md +3 -3
- package/.docs/integrations.md +108 -108
- package/.docs/models/environment-variables.md +2 -0
- package/.docs/models/gateways/openrouter.md +5 -1
- package/.docs/models/gateways/vercel.md +3 -2
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/aiand.md +3 -2
- package/.docs/models/providers/digitalocean.md +3 -2
- package/.docs/models/providers/edenai.md +88 -0
- package/.docs/models/providers/hyper.md +3 -3
- package/.docs/models/providers/inceptron.md +8 -9
- package/.docs/models/providers/kilo.md +11 -6
- package/.docs/models/providers/llmgateway.md +3 -1
- package/.docs/models/providers/merge-gateway.md +262 -0
- package/.docs/models/providers/nano-gpt.md +13 -37
- package/.docs/models/providers/opencode.md +2 -2
- package/.docs/models/providers/tinfoil.md +9 -8
- package/.docs/models/providers/xai.md +2 -1
- package/.docs/models/providers.md +2 -0
- package/.docs/reference/agents/getVoice.md +1 -1
- package/.docs/reference/configuration.md +1 -1
- package/.docs/reference/index.md +5 -1
- package/.docs/reference/manual-install.md +1 -1
- package/.docs/reference/migrations/network-to-supervisor.md +1 -1
- package/.docs/reference/migrations/upgrade-to-v1/tracing.md +1 -3
- package/.docs/reference/observability/tracing/exporters/cloud-exporter.md +0 -1
- package/.docs/reference/observability/tracing/exporters/console-exporter.md +0 -1
- package/.docs/reference/observability/tracing/exporters/default-exporter.md +0 -1
- package/.docs/reference/observability/tracing/exporters/mastra-platform-exporter.md +0 -1
- package/.docs/reference/observability/tracing/exporters/mastra-storage-exporter.md +0 -1
- package/.docs/reference/observability/tracing/processors/sensitive-data-filter.md +111 -99
- package/.docs/reference/observability/tracing/span-filtering.md +1 -1
- package/.docs/reference/storage/overview.md +1 -1
- package/.docs/reference/templates/overview.md +1 -1
- package/.docs/{guides → reference}/voice/overview.md +3 -3
- package/.docs/{guides → reference}/voice/speech-to-speech.md +1 -1
- package/.docs/{guides → reference}/voice/speech-to-text.md +1 -1
- package/.docs/{guides → reference}/voice/text-to-speech.md +2 -2
- package/CHANGELOG.md +14 -0
- package/package.json +4 -4
- package/.docs/docs/observability/integrations/exporters/mastra-platform.md +0 -201
- package/.docs/docs/observability/integrations/overview.md +0 -47
- package/.docs/docs/observability/integrations/processors/sensitive-data-filter.md +0 -302
- package/.docs/guides/deployment/mastra-workers.md +0 -578
- package/.docs/guides/getting-started/quickstart.md +0 -88
- package/.docs/guides/guide/ai-recruiter.md +0 -228
- package/.docs/guides/guide/code-review-bot.md +0 -228
- package/.docs/guides/guide/coding-agent.md +0 -392
- package/.docs/guides/guide/dev-assistant.md +0 -309
- package/.docs/guides/guide/docs-manager.md +0 -240
- package/.docs/guides/guide/github-actions-pr-description.md +0 -238
- package/.docs/guides/guide/notes-mcp-server.md +0 -418
- package/.docs/guides/guide/research-assistant.md +0 -350
- package/.docs/guides/guide/research-coordinator.md +0 -418
- package/.docs/guides/guide/signal-provider.md +0 -221
- package/.docs/guides/index.md +0 -24
- /package/.docs/{reference → docs}/mastra-platform/api.md +0 -0
- /package/.docs/{guides/agent-frameworks/ai-sdk.md → reference/ai-sdk/overview.md} +0 -0
|
@@ -1,392 +0,0 @@
|
|
|
1
|
-
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
|
|
2
|
-
|
|
3
|
-
# Building a coding agent
|
|
4
|
-
|
|
5
|
-
In this guide, you'll build a small coding-agent application in the same category as Mastra Code, Claude Code, or Codex. You'll create the coding agent with `buildBasePrompt()` and `createCodingAgent()`, wrap it in an `AgentController` for interactive sessions and tool approvals, and run the controller in a terminal UI built with pi-tui.
|
|
6
|
-
|
|
7
|
-
The video below shows the coding agent you'll build in action.
|
|
8
|
-
|
|
9
|
-
## Prerequisites
|
|
10
|
-
|
|
11
|
-
- Node.js `v22.19.0` or later installed
|
|
12
|
-
- An API key from a supported [Model Provider](https://mastra.ai/models)
|
|
13
|
-
- An existing Mastra project. Follow the [installation guide](https://mastra.ai/guides/getting-started/quickstart) if needed.
|
|
14
|
-
|
|
15
|
-
## Install the terminal dependencies
|
|
16
|
-
|
|
17
|
-
Install [pi-tui](https://github.com/earendil-works/pi/tree/main/packages/tui) and `tsx`:
|
|
18
|
-
|
|
19
|
-
**npm**:
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npm install @earendil-works/pi-tui
|
|
23
|
-
npm install --save-dev tsx
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
**pnpm**:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
pnpm add @earendil-works/pi-tui
|
|
30
|
-
pnpm add --save-dev tsx
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
**Yarn**:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
yarn add @earendil-works/pi-tui
|
|
37
|
-
yarn add --dev tsx
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
**Bun**:
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
bun add @earendil-works/pi-tui
|
|
44
|
-
bun add --dev tsx
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
pi-tui provides the terminal renderer and input editor. `tsx` runs the TypeScript entry point directly.
|
|
48
|
-
|
|
49
|
-
## Create the coding agent
|
|
50
|
-
|
|
51
|
-
Create `src/mastra/agents/coding-agent.ts`. The prompt describes the current project and maps the prompt's generic tool names to the tools supplied by the default workspace.
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
import { basename } from 'node:path'
|
|
55
|
-
import { buildBasePrompt, createCodingAgent } from '@mastra/core/coding-agent'
|
|
56
|
-
|
|
57
|
-
export const projectPath = process.cwd()
|
|
58
|
-
const model = 'openai/gpt-5.6-sol'
|
|
59
|
-
|
|
60
|
-
const instructions = buildBasePrompt({
|
|
61
|
-
projectPath,
|
|
62
|
-
projectName: basename(projectPath),
|
|
63
|
-
platform: process.platform,
|
|
64
|
-
date: new Date().toISOString().slice(0, 10),
|
|
65
|
-
mode: 'build',
|
|
66
|
-
modelId: model,
|
|
67
|
-
productName: 'My Coding Agent',
|
|
68
|
-
coAuthorName: 'My Coding Agent',
|
|
69
|
-
coAuthorEmail: 'coding-agent@example.com',
|
|
70
|
-
toolGuidance: `# Workspace tools
|
|
71
|
-
- Use mastra_workspace_read_file for view.
|
|
72
|
-
- Use mastra_workspace_list_files for find_files.
|
|
73
|
-
- Use mastra_workspace_grep for search_content.
|
|
74
|
-
- Use mastra_workspace_execute_command for execute_command.
|
|
75
|
-
- Use mastra_workspace_write_file, mastra_workspace_edit_file, and mastra_workspace_file_stat for writing, editing, and inspecting file metadata.
|
|
76
|
-
- Use only the workspace tools provided to you. Do not attempt unavailable capabilities.`,
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
export const codingAgent = createCodingAgent({
|
|
80
|
-
id: 'coding-agent',
|
|
81
|
-
name: 'Coding Agent',
|
|
82
|
-
model,
|
|
83
|
-
instructions,
|
|
84
|
-
basePath: projectPath,
|
|
85
|
-
})
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Replace the branding values with the name and co-author details for your agent. `createCodingAgent()` supplies a local filesystem and sandbox workspace, along with defaults for recovering from transient provider errors. The `basePath` scopes the filesystem tools and sets the initial working directory for commands. Any configuration you pass to the factory takes precedence over its defaults.
|
|
89
|
-
|
|
90
|
-
The default local sandbox runs commands directly on the host without isolation, so `basePath` isn't an operating-system security boundary. This example adds per-tool-call approval in the terminal, but you should still run it only against a trusted local project.
|
|
91
|
-
|
|
92
|
-
## Register the coding agent
|
|
93
|
-
|
|
94
|
-
Register the returned agent like any other Mastra agent in `src/mastra/index.ts`. Registration also makes the underlying agent available in Studio and through the Mastra server.
|
|
95
|
-
|
|
96
|
-
```typescript
|
|
97
|
-
import { Mastra } from '@mastra/core/mastra'
|
|
98
|
-
import { codingAgent } from './agents/coding-agent'
|
|
99
|
-
|
|
100
|
-
export const mastra = new Mastra({
|
|
101
|
-
agents: { codingAgent },
|
|
102
|
-
})
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Test the coding agent
|
|
106
|
-
|
|
107
|
-
Before adding the terminal interface, verify the underlying agent in Studio. When the development server starts, its working directory is `src/mastra/public`, so add a non-sensitive file there for the agent to inspect:
|
|
108
|
-
|
|
109
|
-
```md
|
|
110
|
-
# Project notes
|
|
111
|
-
|
|
112
|
-
Name: Acme support portal
|
|
113
|
-
Status: In development
|
|
114
|
-
Owner: Platform team
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
Start the development server:
|
|
118
|
-
|
|
119
|
-
**npm**:
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
npm run dev
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
**pnpm**:
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
pnpm run dev
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
**Yarn**:
|
|
132
|
-
|
|
133
|
-
```bash
|
|
134
|
-
yarn dev
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
**Bun**:
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
bun run dev
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Open [Studio](https://mastra.ai/docs/studio/overview), select **Coding Agent**, and enter:
|
|
144
|
-
|
|
145
|
-
```text
|
|
146
|
-
Inspect project-notes.md and report the project name, status, and owner. Do not modify files.
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
The response should identify the Acme support portal and describe its development status. It should report that the Platform team owns the project and leave the file unchanged. Model wording may vary.
|
|
150
|
-
|
|
151
|
-
## Create the agent controller
|
|
152
|
-
|
|
153
|
-
Create `src/mastra/coding-agent-controller.ts`. The controller owns the interactive session, exposes UI events, and pauses workspace tools for approval.
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
import { AgentController } from '@mastra/core/agent-controller'
|
|
157
|
-
import { codingAgent, projectPath } from './agents/coding-agent'
|
|
158
|
-
|
|
159
|
-
export async function createCodingAgentSession() {
|
|
160
|
-
const workspace = await codingAgent.getWorkspace()
|
|
161
|
-
|
|
162
|
-
if (!workspace) {
|
|
163
|
-
throw new Error('The coding agent requires a workspace.')
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const controller = new AgentController({
|
|
167
|
-
id: 'coding-agent-controller',
|
|
168
|
-
agent: codingAgent,
|
|
169
|
-
workspace,
|
|
170
|
-
modes: [{ id: 'build', name: 'Build', metadata: { default: true } }],
|
|
171
|
-
disableBuiltinTools: [
|
|
172
|
-
'ask_user',
|
|
173
|
-
'submit_plan',
|
|
174
|
-
'task_write',
|
|
175
|
-
'task_update',
|
|
176
|
-
'task_complete',
|
|
177
|
-
'task_check',
|
|
178
|
-
'subagent',
|
|
179
|
-
],
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
await controller.init()
|
|
183
|
-
|
|
184
|
-
const session = await controller.createSession({
|
|
185
|
-
id: 'local-session',
|
|
186
|
-
ownerId: 'local-user',
|
|
187
|
-
resourceId: projectPath,
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
return { controller, session }
|
|
191
|
-
}
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
This example uses one mode and disables the controller's additional built-in tools so the introductory UI can focus on workspace execution. The simplified setup is intended for this tutorial. In a production application, enable the built-in tools your product needs and implement their UI flows: interactive tools such as `ask_user` and `submit_plan` suspend until your interface resumes them, while task and subagent tools have their own lifecycle events. See [tool approvals and suspensions](https://mastra.ai/docs/harness/agent-controller).
|
|
195
|
-
|
|
196
|
-
The example also omits storage, so the conversation lasts only for the current process. You can add storage later when you want to resume sessions.
|
|
197
|
-
|
|
198
|
-
## Build the terminal UI
|
|
199
|
-
|
|
200
|
-
Create `src/coding-agent-tui.ts`. The UI renders assistant message updates and shows tool activity. It also asks the user to approve or decline each workspace tool call.
|
|
201
|
-
|
|
202
|
-
```typescript
|
|
203
|
-
import { pathToFileURL } from 'node:url'
|
|
204
|
-
import {
|
|
205
|
-
Editor,
|
|
206
|
-
matchesKey,
|
|
207
|
-
ProcessTerminal,
|
|
208
|
-
Text,
|
|
209
|
-
TUI,
|
|
210
|
-
type EditorTheme,
|
|
211
|
-
type Terminal,
|
|
212
|
-
} from '@earendil-works/pi-tui'
|
|
213
|
-
import { createCodingAgentSession } from './mastra/coding-agent-controller'
|
|
214
|
-
|
|
215
|
-
const plain = (text: string) => text
|
|
216
|
-
const editorTheme: EditorTheme = {
|
|
217
|
-
borderColor: plain,
|
|
218
|
-
selectList: {
|
|
219
|
-
selectedPrefix: plain,
|
|
220
|
-
selectedText: plain,
|
|
221
|
-
description: plain,
|
|
222
|
-
scrollInfo: plain,
|
|
223
|
-
noMatch: plain,
|
|
224
|
-
},
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function getText(message: { content: Array<{ type: string; text?: string }> }) {
|
|
228
|
-
return message.content
|
|
229
|
-
.filter(part => part.type === 'text')
|
|
230
|
-
.map(part => part.text ?? '')
|
|
231
|
-
.join('')
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
export async function startCodingAgentTui(terminal: Terminal = new ProcessTerminal()) {
|
|
235
|
-
const { controller, session } = await createCodingAgentSession()
|
|
236
|
-
const tui = new TUI(terminal)
|
|
237
|
-
const output = new Text('Ask me to inspect or change this project.', 1, 0)
|
|
238
|
-
const editor = new Editor(tui, editorTheme)
|
|
239
|
-
|
|
240
|
-
let busy = false
|
|
241
|
-
let pendingApproval: { toolCallId: string; toolName: string } | undefined
|
|
242
|
-
|
|
243
|
-
const showError = (error: unknown) => {
|
|
244
|
-
output.setText(`Error: ${error instanceof Error ? error.message : String(error)}`)
|
|
245
|
-
busy = false
|
|
246
|
-
pendingApproval = undefined
|
|
247
|
-
tui.requestRender()
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const unsubscribe = session.subscribe(event => {
|
|
251
|
-
if (event.type === 'message_update' && event.message.role === 'assistant') {
|
|
252
|
-
output.setText(getText(event.message))
|
|
253
|
-
} else if (event.type === 'tool_start') {
|
|
254
|
-
output.setText(`Running ${event.toolName}...`)
|
|
255
|
-
} else if (event.type === 'tool_approval_required') {
|
|
256
|
-
pendingApproval = { toolCallId: event.toolCallId, toolName: event.toolName }
|
|
257
|
-
output.setText(`Allow ${event.toolName}? Enter y or n.`)
|
|
258
|
-
} else if (event.type === 'agent_end') {
|
|
259
|
-
busy = false
|
|
260
|
-
} else if (event.type === 'error') {
|
|
261
|
-
showError(event.error)
|
|
262
|
-
return
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
tui.requestRender()
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
editor.onSubmit = value => {
|
|
269
|
-
if (pendingApproval) {
|
|
270
|
-
const answer = value.trim().toLowerCase()
|
|
271
|
-
if (answer !== 'y' && answer !== 'n') {
|
|
272
|
-
output.setText(`Allow ${pendingApproval.toolName}? Enter y or n.`)
|
|
273
|
-
tui.requestRender()
|
|
274
|
-
return
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
const approval = pendingApproval
|
|
278
|
-
pendingApproval = undefined
|
|
279
|
-
session.respondToToolApproval({
|
|
280
|
-
toolCallId: approval.toolCallId,
|
|
281
|
-
decision: answer === 'y' ? 'approve' : 'decline',
|
|
282
|
-
})
|
|
283
|
-
return
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
if (busy || !value.trim()) return
|
|
287
|
-
|
|
288
|
-
busy = true
|
|
289
|
-
output.setText('Thinking...')
|
|
290
|
-
tui.requestRender()
|
|
291
|
-
void session.sendMessage({ content: value.trim() }).catch(showError)
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
tui.addChild(new Text('My Coding Agent', 1, 0))
|
|
295
|
-
tui.addChild(output)
|
|
296
|
-
tui.addChild(editor)
|
|
297
|
-
tui.setFocus(editor)
|
|
298
|
-
|
|
299
|
-
let stopPromise: Promise<void> | undefined
|
|
300
|
-
let removeInputListener = () => {}
|
|
301
|
-
|
|
302
|
-
const stop = () => {
|
|
303
|
-
stopPromise ??= (async () => {
|
|
304
|
-
process.off('SIGINT', handleExit)
|
|
305
|
-
removeInputListener()
|
|
306
|
-
session.abort()
|
|
307
|
-
unsubscribe()
|
|
308
|
-
tui.stop()
|
|
309
|
-
await controller.destroy()
|
|
310
|
-
})()
|
|
311
|
-
return stopPromise
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
const handleExit = () => {
|
|
315
|
-
void stop().catch(error => {
|
|
316
|
-
console.error(error)
|
|
317
|
-
process.exitCode = 1
|
|
318
|
-
})
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
removeInputListener = tui.addInputListener(data => {
|
|
322
|
-
if (!matchesKey(data, 'ctrl+c')) return
|
|
323
|
-
handleExit()
|
|
324
|
-
return { consume: true }
|
|
325
|
-
})
|
|
326
|
-
process.once('SIGINT', handleExit)
|
|
327
|
-
tui.start()
|
|
328
|
-
|
|
329
|
-
return { stop }
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
333
|
-
await startCodingAgentTui()
|
|
334
|
-
}
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
The optional `Terminal` parameter supports automated tests while using `ProcessTerminal` during normal execution. The UI intentionally renders only the latest response. The `Session` still maintains the conversation context for follow-up prompts.
|
|
338
|
-
|
|
339
|
-
## Run the coding agent
|
|
340
|
-
|
|
341
|
-
Start the terminal application from the project root so `process.cwd()` points to the project you want the agent to use:
|
|
342
|
-
|
|
343
|
-
**npm**:
|
|
344
|
-
|
|
345
|
-
```bash
|
|
346
|
-
npx tsx src/coding-agent-tui.ts
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
**pnpm**:
|
|
350
|
-
|
|
351
|
-
```bash
|
|
352
|
-
pnpm dlx tsx src/coding-agent-tui.ts
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
**Yarn**:
|
|
356
|
-
|
|
357
|
-
```bash
|
|
358
|
-
yarn dlx tsx src/coding-agent-tui.ts
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
**Bun**:
|
|
362
|
-
|
|
363
|
-
```bash
|
|
364
|
-
bun x tsx src/coding-agent-tui.ts
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
Enter this prompt:
|
|
368
|
-
|
|
369
|
-
```text
|
|
370
|
-
Inspect package.json and report the package name and available scripts. Do not modify files.
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
When the controller asks whether to allow `mastra_workspace_read_file`, enter `y`. The agent reads `package.json` and reports what it finds. Model wording varies, but the response should include the package name and its scripts without changing the file.
|
|
374
|
-
|
|
375
|
-
Press **Ctrl+C** to close the application and destroy the controller.
|
|
376
|
-
|
|
377
|
-
## Next steps
|
|
378
|
-
|
|
379
|
-
You can extend this foundation to:
|
|
380
|
-
|
|
381
|
-
- Add storage to persist and resume controller sessions
|
|
382
|
-
- Add more modes with different instructions and workspace-tool allowlists
|
|
383
|
-
- Replace the latest-response component with a transcript that renders tool calls and results
|
|
384
|
-
- Add sandbox isolation before accepting untrusted prompts or distributing the application
|
|
385
|
-
|
|
386
|
-
Learn more:
|
|
387
|
-
|
|
388
|
-
- [`createCodingAgent()` reference](https://mastra.ai/reference/coding-agent/create-coding-agent)
|
|
389
|
-
- [`buildBasePrompt()` reference](https://mastra.ai/reference/coding-agent/build-base-prompt)
|
|
390
|
-
- [AgentController overview](https://mastra.ai/docs/harness/agent-controller)
|
|
391
|
-
- [`AgentController` reference](https://mastra.ai/reference/agent-controller/agent-controller-class)
|
|
392
|
-
- [Workspace overview](https://mastra.ai/docs/workspace/overview)
|
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
|
|
2
|
-
|
|
3
|
-
# Building a dev assistant
|
|
4
|
-
|
|
5
|
-
In this guide, you'll build a complete development assistant that combines all workspace features:
|
|
6
|
-
|
|
7
|
-
- [Filesystem](https://mastra.ai/docs/workspace/filesystem) for file management
|
|
8
|
-
- [Sandbox](https://mastra.ai/docs/workspace/sandbox) for code execution
|
|
9
|
-
- [Skills](https://mastra.ai/docs/workspace/skills) for coding standards
|
|
10
|
-
- [Search](https://mastra.ai/docs/workspace/search) for finding examples
|
|
11
|
-
|
|
12
|
-
You'll set up a workspace with a sample project and add coding standards as a skill. Then you'll create an agent that writes code following TDD practices. By the end, the agent can read existing code and write new implementations, then run tests in a sandbox and iterate based on the results.
|
|
13
|
-
|
|
14
|
-
## Prerequisites
|
|
15
|
-
|
|
16
|
-
- Node.js `v22.13.0` or later installed
|
|
17
|
-
- An API key from a supported [Model Provider](https://mastra.ai/models)
|
|
18
|
-
- An existing Mastra project (Follow the [installation guide](https://mastra.ai/guides/getting-started/quickstart) to set up a new project)
|
|
19
|
-
|
|
20
|
-
### Install vitest
|
|
21
|
-
|
|
22
|
-
The dev assistant will use [Vitest](https://vitest.dev/) to run tests inside the workspace sandbox. Install it as a dev dependency in your project:
|
|
23
|
-
|
|
24
|
-
**npm**:
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
npm install -D vitest
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
**pnpm**:
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
pnpm add -D vitest
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
**Yarn**:
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
yarn add --dev vitest
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
**Bun**:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
bun add --dev vitest
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Set up the workspace
|
|
49
|
-
|
|
50
|
-
The workspace uses a local filesystem to manage documentation files. The agent reads and writes files within the workspace directory. In your `src/mastra/index.ts` file, import the [`Workspace`](https://mastra.ai/reference/workspace/workspace-class), [`LocalFilesystem`](https://mastra.ai/reference/workspace/local-filesystem), and [`LocalSandbox`](https://mastra.ai/reference/workspace/local-sandbox) classes.
|
|
51
|
-
|
|
52
|
-
Additionally, enable BM25 search indexing and load skills from the `skills` directory.
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
import { Mastra } from '@mastra/core'
|
|
56
|
-
import { resolve } from 'node:path'
|
|
57
|
-
import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace'
|
|
58
|
-
|
|
59
|
-
const workspace = new Workspace({
|
|
60
|
-
filesystem: new LocalFilesystem({ basePath: resolve(import.meta.dirname, '../../workspace') }),
|
|
61
|
-
sandbox: new LocalSandbox({ workingDirectory: resolve(import.meta.dirname, '../../workspace') }),
|
|
62
|
-
skills: ['skills'],
|
|
63
|
-
bm25: true,
|
|
64
|
-
autoIndexPaths: ['docs', 'src'],
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
export const mastra = new Mastra({
|
|
68
|
-
workspace,
|
|
69
|
-
})
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
At the root of your project, create a new folder called `workspace`. This is where all files will be stored and managed by the agent.
|
|
73
|
-
|
|
74
|
-
## Add sample project files
|
|
75
|
-
|
|
76
|
-
The workspace uses the following folder structure:
|
|
77
|
-
|
|
78
|
-
- `workspace/src/`: Source code for the sample project
|
|
79
|
-
- `workspace/tests/`: Test files
|
|
80
|
-
- `workspace/docs/`: Project documentation
|
|
81
|
-
- `workspace/skills/`: Coding standards and guidelines as [Agent Skills](https://agentskills.io)
|
|
82
|
-
|
|
83
|
-
Get started by creating a `workspace/src/utils/string-helpers.ts` file with some utility functions, and a corresponding test file in `workspace/tests/string-helpers.test.ts`.
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
export function capitalize(str: string): string {
|
|
87
|
-
if (!str) return str
|
|
88
|
-
return str.charAt(0).toUpperCase() + str.slice(1)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export function slugify(str: string): string {
|
|
92
|
-
return str
|
|
93
|
-
.toLowerCase()
|
|
94
|
-
.replace(/[^\w\s-]/g, '')
|
|
95
|
-
.replace(/\s+/g, '-')
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
import { describe, it, expect } from 'vitest'
|
|
101
|
-
import { capitalize, slugify } from '../src/utils/string-helpers'
|
|
102
|
-
|
|
103
|
-
describe('String Helpers', () => {
|
|
104
|
-
describe('capitalize', () => {
|
|
105
|
-
it('capitalizes first letter', () => {
|
|
106
|
-
expect(capitalize('hello')).toBe('Hello')
|
|
107
|
-
})
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
describe('slugify', () => {
|
|
111
|
-
it('converts to lowercase and replaces spaces', () => {
|
|
112
|
-
expect(slugify('Hello World')).toBe('hello-world')
|
|
113
|
-
})
|
|
114
|
-
})
|
|
115
|
-
})
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Create a skill definition at `workspace/skills/coding-standards/SKILL.md`. This tells the agent how to write and test code:
|
|
119
|
-
|
|
120
|
-
```markdown
|
|
121
|
-
---
|
|
122
|
-
name: coding-standards
|
|
123
|
-
description: Project coding standards and testing guidelines
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
# Coding Standards
|
|
127
|
-
|
|
128
|
-
## Code quality
|
|
129
|
-
|
|
130
|
-
- Functions under 50 lines
|
|
131
|
-
- Use descriptive variable names
|
|
132
|
-
- Always add TypeScript types
|
|
133
|
-
|
|
134
|
-
## Testing
|
|
135
|
-
|
|
136
|
-
- Test all exported functions
|
|
137
|
-
- Use AAA pattern: Arrange, Act, Assert
|
|
138
|
-
- Cover happy paths and edge cases
|
|
139
|
-
|
|
140
|
-
## Before committing
|
|
141
|
-
|
|
142
|
-
1. Write implementation
|
|
143
|
-
2. Write comprehensive tests
|
|
144
|
-
3. Run tests: `npm test`
|
|
145
|
-
4. All tests must pass
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
Create a reference file at `workspace/skills/coding-standards/references/testing-guide.md` with detailed testing patterns:
|
|
149
|
-
|
|
150
|
-
````markdown
|
|
151
|
-
# Testing Guide
|
|
152
|
-
|
|
153
|
-
## AAA pattern
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
it('descriptive test name', () => {
|
|
157
|
-
// Arrange: Set up test data
|
|
158
|
-
const input = 'test'
|
|
159
|
-
|
|
160
|
-
// Act: Execute the function
|
|
161
|
-
const result = doSomething(input)
|
|
162
|
-
|
|
163
|
-
// Assert: Verify the result
|
|
164
|
-
expect(result).toBe('expected')
|
|
165
|
-
})
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## What to test
|
|
169
|
-
|
|
170
|
-
- Happy paths (normal inputs)
|
|
171
|
-
- Edge cases (empty, null, boundary values)
|
|
172
|
-
- Error cases (invalid inputs, exceptions)
|
|
173
|
-
````
|
|
174
|
-
|
|
175
|
-
## Create the dev assistant
|
|
176
|
-
|
|
177
|
-
With the workspace set up, it's time to create the development assistant agent. This agent will have instructions for adding new features using test-driven development (TDD).
|
|
178
|
-
|
|
179
|
-
Create a new file `src/mastra/agents/dev-assistant.ts` and define the agent:
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
import { Agent } from '@mastra/core/agent'
|
|
183
|
-
|
|
184
|
-
export const devAssistant = new Agent({
|
|
185
|
-
id: 'dev-assistant',
|
|
186
|
-
name: 'Dev Assistant',
|
|
187
|
-
instructions: `You are a development assistant.
|
|
188
|
-
|
|
189
|
-
When adding features:
|
|
190
|
-
1. Activate 'coding-standards' skill
|
|
191
|
-
2. Search workspace for similar code examples
|
|
192
|
-
3. Write the implementation following standards
|
|
193
|
-
4. Write comprehensive tests. Leave existing tests in place, only add your new tests
|
|
194
|
-
5. Execute the command \`npx vitest run\` to validate that all tests pass
|
|
195
|
-
6. Update documentation if needed
|
|
196
|
-
|
|
197
|
-
For every new feature: Write code → Write tests → Run tests → Update docs
|
|
198
|
-
|
|
199
|
-
Always explain your reasoning and steps.`,
|
|
200
|
-
model: 'openai/gpt-5.6-sol',
|
|
201
|
-
})
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
Define the agent by importing it inside `src/mastra/index.ts` and registering it with the `Mastra` instance:
|
|
205
|
-
|
|
206
|
-
```typescript
|
|
207
|
-
import { Mastra } from '@mastra/core'
|
|
208
|
-
import { resolve } from 'node:path'
|
|
209
|
-
import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace'
|
|
210
|
-
import { devAssistant } from './agents/dev-assistant'
|
|
211
|
-
|
|
212
|
-
const workspace = new Workspace({
|
|
213
|
-
filesystem: new LocalFilesystem({ basePath: resolve(import.meta.dirname, '../../workspace') }),
|
|
214
|
-
sandbox: new LocalSandbox({ workingDirectory: resolve(import.meta.dirname, '../../workspace') }),
|
|
215
|
-
skills: ['skills'],
|
|
216
|
-
bm25: true,
|
|
217
|
-
autoIndexPaths: ['docs', 'src'],
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
export const mastra = new Mastra({
|
|
221
|
-
workspace,
|
|
222
|
-
agents: { devAssistant },
|
|
223
|
-
})
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
## Test the assistant
|
|
227
|
-
|
|
228
|
-
Start [Studio](https://mastra.ai/docs/studio/overview) and interact with the agent to see it in action.
|
|
229
|
-
|
|
230
|
-
**npm**:
|
|
231
|
-
|
|
232
|
-
```bash
|
|
233
|
-
npm run dev
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
**pnpm**:
|
|
237
|
-
|
|
238
|
-
```bash
|
|
239
|
-
pnpm run dev
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
**Yarn**:
|
|
243
|
-
|
|
244
|
-
```bash
|
|
245
|
-
yarn dev
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
**Bun**:
|
|
249
|
-
|
|
250
|
-
```bash
|
|
251
|
-
bun run dev
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
Open [localhost:4111](http://localhost:4111) and navigate to the dev assistant.
|
|
255
|
-
|
|
256
|
-
Try asking the agent to add a new function using TDD:
|
|
257
|
-
|
|
258
|
-
```text
|
|
259
|
-
Add a 'truncate' function to string-helpers.ts that shortens strings to a max length. Add '...' if truncated.
|
|
260
|
-
|
|
261
|
-
Follow TDD: write tests first, then implementation.
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
Since agent responses are non-deterministic, the exact output will vary. However, you should see the agent follow a process similar to this:
|
|
265
|
-
|
|
266
|
-
1. Activate the coding-standards skill
|
|
267
|
-
|
|
268
|
-
2. Search the workspace for similar code patterns
|
|
269
|
-
|
|
270
|
-
3. Write tests first, for example:
|
|
271
|
-
|
|
272
|
-
```typescript
|
|
273
|
-
describe('truncate', () => {
|
|
274
|
-
it('truncates long strings', () => {
|
|
275
|
-
expect(truncate('Hello World', 5)).toBe('He...')
|
|
276
|
-
})
|
|
277
|
-
|
|
278
|
-
it('keeps short strings unchanged', () => {
|
|
279
|
-
expect(truncate('Hi', 10)).toBe('Hi')
|
|
280
|
-
})
|
|
281
|
-
|
|
282
|
-
it('handles edge cases', () => {
|
|
283
|
-
expect(truncate('', 5)).toBe('')
|
|
284
|
-
})
|
|
285
|
-
})
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
4. Write the implementation, for example:
|
|
289
|
-
|
|
290
|
-
```typescript
|
|
291
|
-
export function truncate(str: string, maxLength: number): string {
|
|
292
|
-
if (!str || maxLength < 0) return str
|
|
293
|
-
if (str.length <= maxLength) return str
|
|
294
|
-
if (maxLength === 0) return '...'
|
|
295
|
-
return str.slice(0, maxLength - 3) + '...'
|
|
296
|
-
}
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
5. Run tests and verify they pass
|
|
300
|
-
|
|
301
|
-
## Next steps
|
|
302
|
-
|
|
303
|
-
You can extend this assistant to:
|
|
304
|
-
|
|
305
|
-
- Add more skills for different languages or frameworks
|
|
306
|
-
- Create specialized agents for backend, frontend, or DevOps
|
|
307
|
-
- Integrate with GitHub for automated PR reviews
|
|
308
|
-
- Build CI/CD automation
|
|
309
|
-
- Add multi-agent workflows
|