@mastra/mcp-docs-server 0.13.2-alpha.1 → 0.13.2-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/organized/changelogs/%40mastra%2Fastra.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fchroma.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fclickhouse.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fclient-js.md +18 -18
- package/.docs/organized/changelogs/%40mastra%2Fcloudflare-d1.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fcloudflare.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fcore.md +15 -15
- package/.docs/organized/changelogs/%40mastra%2Fcouchbase.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-cloudflare.md +20 -20
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-netlify.md +24 -24
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-vercel.md +24 -24
- package/.docs/organized/changelogs/%40mastra%2Fdeployer.md +22 -22
- package/.docs/organized/changelogs/%40mastra%2Fdynamodb.md +21 -21
- package/.docs/organized/changelogs/%40mastra%2Flance.md +13 -0
- package/.docs/organized/changelogs/%40mastra%2Flibsql.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fmcp-docs-server.md +17 -17
- package/.docs/organized/changelogs/%40mastra%2Fmcp.md +9 -9
- package/.docs/organized/changelogs/%40mastra%2Fmemory.md +22 -22
- package/.docs/organized/changelogs/%40mastra%2Fmongodb.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fopensearch.md +13 -0
- package/.docs/organized/changelogs/%40mastra%2Fpg.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fpinecone.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fplayground-ui.md +27 -27
- package/.docs/organized/changelogs/%40mastra%2Fqdrant.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fserver.md +20 -20
- package/.docs/organized/changelogs/%40mastra%2Fturbopuffer.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fupstash.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fvectorize.md +14 -14
- package/.docs/organized/changelogs/mastra.md +22 -22
- package/.docs/organized/code-examples/agent.md +182 -5
- package/.docs/organized/code-examples/assistant-ui.md +1 -1
- package/.docs/organized/code-examples/bird-checker-with-nextjs-and-eval.md +1 -1
- package/.docs/organized/code-examples/bird-checker-with-nextjs.md +1 -1
- package/.docs/organized/code-examples/crypto-chatbot.md +2 -2
- package/.docs/organized/code-examples/openapi-spec-writer.md +1 -1
- package/.docs/raw/agents/using-tools-and-mcp.mdx +3 -2
- package/.docs/raw/course/01-first-agent/04-project-structure.md +8 -3
- package/.docs/raw/course/01-first-agent/07-creating-your-agent.md +5 -3
- package/.docs/raw/course/01-first-agent/08-exporting-your-agent.md +20 -6
- package/.docs/raw/course/01-first-agent/11-creating-transactions-tool.md +5 -3
- package/.docs/raw/course/01-first-agent/12-connecting-tool-to-agent.md +2 -2
- package/.docs/raw/course/04-workflows/01-introduction-to-workflows.md +44 -0
- package/.docs/raw/course/04-workflows/02-understanding-steps.md +53 -0
- package/.docs/raw/course/04-workflows/03-creating-your-first-step.md +57 -0
- package/.docs/raw/course/04-workflows/04-creating-a-second-step.md +58 -0
- package/.docs/raw/course/04-workflows/05-chaining-steps-together.md +56 -0
- package/.docs/raw/course/04-workflows/06-registering-with-mastra.md +24 -0
- package/.docs/raw/course/04-workflows/07-using-playground.md +58 -0
- package/.docs/raw/course/04-workflows/08-running-workflows-programmatically.md +77 -0
- package/.docs/raw/course/04-workflows/09-adding-a-third-step.md +70 -0
- package/.docs/raw/course/04-workflows/10-updating-the-workflow.md +55 -0
- package/.docs/raw/course/04-workflows/11-creating-an-ai-agent.md +67 -0
- package/.docs/raw/course/04-workflows/12-using-agent-in-workflow.md +91 -0
- package/.docs/raw/course/04-workflows/13-creating-ai-enhanced-workflow.md +75 -0
- package/.docs/raw/course/04-workflows/14-understanding-parallel-execution.md +38 -0
- package/.docs/raw/course/04-workflows/15-creating-parallel-steps.md +115 -0
- package/.docs/raw/course/04-workflows/16-building-parallel-workflow.md +100 -0
- package/.docs/raw/course/04-workflows/17-testing-parallel-performance.md +40 -0
- package/.docs/raw/course/04-workflows/18-understanding-conditional-branching.md +58 -0
- package/.docs/raw/course/04-workflows/19-creating-conditional-steps.md +128 -0
- package/.docs/raw/course/04-workflows/20-building-conditional-workflow.md +60 -0
- package/.docs/raw/course/04-workflows/21-testing-conditional-logic.md +58 -0
- package/.docs/raw/course/04-workflows/22-conclusion.md +58 -0
- package/.docs/raw/deployment/cloud-providers/digital-ocean.mdx +111 -0
- package/.docs/raw/deployment/cloud-providers/index.mdx +15 -0
- package/.docs/raw/memory/working-memory.mdx +56 -0
- package/.docs/raw/networks-vnext/complex-task-execution.mdx +137 -0
- package/.docs/raw/networks-vnext/overview.mdx +85 -0
- package/.docs/raw/networks-vnext/single-task-execution.mdx +131 -0
- package/.docs/raw/reference/client-js/agents.mdx +41 -0
- package/.docs/raw/reference/deployer/netlify.mdx +22 -68
- package/.docs/raw/reference/deployer/vercel.mdx +7 -77
- package/.docs/raw/reference/tools/mcp-client.mdx +244 -0
- package/.docs/raw/reference/tools/mcp-server.mdx +186 -0
- package/.docs/raw/reference/workflows/create-run.mdx +1 -1
- package/.docs/raw/reference/workflows/resume.mdx +1 -1
- package/.docs/raw/reference/workflows/start.mdx +1 -1
- package/.docs/raw/reference/workflows/stream.mdx +1 -1
- package/.docs/raw/reference/workflows/watch.mdx +1 -1
- package/.docs/raw/reference/workflows/workflow.mdx +6 -2
- package/.docs/raw/workflows/control-flow.mdx +42 -1
- package/.docs/raw/workflows/overview.mdx +73 -5
- package/.docs/raw/workflows/pausing-execution.mdx +1 -1
- package/.docs/raw/workflows/suspend-and-resume.mdx +68 -23
- package/.docs/raw/workflows/using-with-agents-and-tools.mdx +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Registering with Mastra
|
|
2
|
+
|
|
3
|
+
Now you'll register your workflow with the main Mastra instance so you can use it alongside agents and tools.
|
|
4
|
+
|
|
5
|
+
## Updating Your Mastra Configuration
|
|
6
|
+
|
|
7
|
+
Open your `src/mastra/index.ts` file and add your workflow:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// Import your workflow
|
|
11
|
+
import { contentWorkflow } from "./workflows/content-workflow";
|
|
12
|
+
|
|
13
|
+
export const mastra = new Mastra({
|
|
14
|
+
// Register your workflow here
|
|
15
|
+
workflows: {
|
|
16
|
+
contentWorkflow,
|
|
17
|
+
},
|
|
18
|
+
// ...Existing code
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Note: You may already have workflows registered, in which case, this workflow should be added to the workflows object.
|
|
23
|
+
|
|
24
|
+
Your workflow is now registered with Mastra! Next, you'll learn how to use it in the playground.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Using the Playground
|
|
2
|
+
|
|
3
|
+
The Mastra Playground provides a visual interface to test and run your workflows. Let's see your workflow in action!
|
|
4
|
+
|
|
5
|
+
## Starting the Development Server
|
|
6
|
+
|
|
7
|
+
Start your Mastra development server using the `mastra dev` command. If you are using npm the command is:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm run dev
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
You should see output like:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
🚀 Mastra Dev Server starting...
|
|
17
|
+
📊 Playground available at: http://localhost:4111
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Accessing Workflows in Playground
|
|
21
|
+
|
|
22
|
+
1. Open your browser and go to `http://localhost:4111`
|
|
23
|
+
2. Click on "Workflows" in the navigation
|
|
24
|
+
3. You should see your `contentWorkflow` listed
|
|
25
|
+
|
|
26
|
+
## Testing Your Workflow
|
|
27
|
+
|
|
28
|
+
1. Click on your `contentWorkflow`
|
|
29
|
+
2. You'll see an input form based on your workflow's input schema
|
|
30
|
+
3. Enter some test content in the form:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"content": "Machine learning is revolutionizing healthcare by enabling faster diagnoses and personalized treatments.",
|
|
35
|
+
"type": "article"
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
4. Click "Run Workflow"
|
|
40
|
+
5. Watch the execution progress and see the results
|
|
41
|
+
|
|
42
|
+
## Understanding the Interface
|
|
43
|
+
|
|
44
|
+
The playground shows you:
|
|
45
|
+
|
|
46
|
+
- **Input Schema**: What data your workflow expects
|
|
47
|
+
- **Execution Progress**: Real-time updates as steps complete
|
|
48
|
+
- **Output**: The final result from your workflow
|
|
49
|
+
- **Execution Time**: How long the workflow took to run
|
|
50
|
+
|
|
51
|
+
## Benefits of the Playground
|
|
52
|
+
|
|
53
|
+
- **Visual Testing**: Easy way to test workflows without writing code
|
|
54
|
+
- **Schema Validation**: Automatic form generation from your schemas
|
|
55
|
+
- **Real-time Feedback**: See exactly what's happening during execution
|
|
56
|
+
- **Easy Debugging**: Quickly test different inputs and view traces from workflow runs
|
|
57
|
+
|
|
58
|
+
Great! You can now visually test your workflow. Next, you'll learn how to run workflows programmatically.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Running Workflows Programmatically
|
|
2
|
+
|
|
3
|
+
Learn how to execute your workflows from code, which is essential for integrating them into applications.
|
|
4
|
+
|
|
5
|
+
## Creating a Workflow Runner
|
|
6
|
+
|
|
7
|
+
Create a new file to test programmatic execution:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// src/run-workflow.ts
|
|
11
|
+
import { mastra } from "./mastra";
|
|
12
|
+
|
|
13
|
+
async function runContentWorkflow() {
|
|
14
|
+
console.log("🚀 Running workflow programmatically...\n");
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
// Get the workflow instance
|
|
18
|
+
const workflow = mastra.getWorkflow("contentWorkflow");
|
|
19
|
+
|
|
20
|
+
if (!workflow) {
|
|
21
|
+
throw new Error("Workflow not found");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Create a run instance
|
|
25
|
+
const run = workflow.createRun();
|
|
26
|
+
|
|
27
|
+
// Execute with test data
|
|
28
|
+
const result = await run.start({
|
|
29
|
+
inputData: {
|
|
30
|
+
content:
|
|
31
|
+
"Climate change is one of the most pressing challenges of our time, requiring immediate action from governments, businesses, and individuals worldwide.",
|
|
32
|
+
type: "blog",
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (result.status === "success") {
|
|
37
|
+
console.log("✅ Success!");
|
|
38
|
+
console.log(
|
|
39
|
+
"📊 Reading time:",
|
|
40
|
+
result.result.metadata.readingTime,
|
|
41
|
+
"minutes",
|
|
42
|
+
);
|
|
43
|
+
console.log("🎯 Difficulty:", result.result.metadata.difficulty);
|
|
44
|
+
console.log("📅 Processed at:", result.result.metadata.processedAt);
|
|
45
|
+
}
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error("❌ Error:", (error as Error).message);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Run the workflow
|
|
52
|
+
runContentWorkflow();
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Running the Code
|
|
56
|
+
|
|
57
|
+
Execute your workflow runner:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx tsx src/run-workflow.ts
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Key Methods
|
|
64
|
+
|
|
65
|
+
- **`mastra.getWorkflow(id)`**: Gets a registered workflow by ID
|
|
66
|
+
- **`workflow.createRun()`**: Creates a new execution instance
|
|
67
|
+
- **`run.start(inputData)`**: Executes the workflow with provided data
|
|
68
|
+
|
|
69
|
+
## Return Value
|
|
70
|
+
|
|
71
|
+
The `start()` method returns:
|
|
72
|
+
|
|
73
|
+
- **`success`**: Boolean indicating if workflow completed successfully
|
|
74
|
+
- **`result`**: The final output from the workflow
|
|
75
|
+
- **`executionTime`**: How long the workflow took to run
|
|
76
|
+
|
|
77
|
+
Your workflow can now be run from anywhere in your application! Next, you'll learn about error handling.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Adding a Third Step
|
|
2
|
+
|
|
3
|
+
Let's extend your workflow by adding a third step that generates a summary of the content.
|
|
4
|
+
|
|
5
|
+
## Creating the Summary Step
|
|
6
|
+
|
|
7
|
+
Add this new step to your workflow file:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
const generateSummaryStep = createStep({
|
|
11
|
+
id: "generate-summary",
|
|
12
|
+
description: "Creates a summary of the content",
|
|
13
|
+
inputSchema: z.object({
|
|
14
|
+
content: z.string(),
|
|
15
|
+
type: z.string(),
|
|
16
|
+
wordCount: z.number(),
|
|
17
|
+
metadata: z.object({
|
|
18
|
+
readingTime: z.number(),
|
|
19
|
+
difficulty: z.enum(["easy", "medium", "hard"]),
|
|
20
|
+
processedAt: z.string(),
|
|
21
|
+
}),
|
|
22
|
+
}),
|
|
23
|
+
outputSchema: z.object({
|
|
24
|
+
content: z.string(),
|
|
25
|
+
type: z.string(),
|
|
26
|
+
wordCount: z.number(),
|
|
27
|
+
metadata: z.object({
|
|
28
|
+
readingTime: z.number(),
|
|
29
|
+
difficulty: z.enum(["easy", "medium", "hard"]),
|
|
30
|
+
processedAt: z.string(),
|
|
31
|
+
}),
|
|
32
|
+
summary: z.string(),
|
|
33
|
+
}),
|
|
34
|
+
execute: async ({ inputData }) => {
|
|
35
|
+
const { content, type, wordCount, metadata } = inputData;
|
|
36
|
+
|
|
37
|
+
// Create a simple summary from first sentence
|
|
38
|
+
const sentences = content
|
|
39
|
+
.split(/[.!?]+/)
|
|
40
|
+
.filter((s) => s.trim().length > 0);
|
|
41
|
+
const firstSentence = sentences[0]?.trim() + ".";
|
|
42
|
+
|
|
43
|
+
// Generate summary based on content length
|
|
44
|
+
let summary = firstSentence;
|
|
45
|
+
if (wordCount > 50) {
|
|
46
|
+
summary += ` This ${type} contains ${wordCount} words and takes approximately ${metadata.readingTime} minute(s) to read.`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
console.log(`📝 Generated summary: ${summary.length} characters`);
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
content,
|
|
53
|
+
type,
|
|
54
|
+
wordCount,
|
|
55
|
+
metadata,
|
|
56
|
+
summary,
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Understanding the Pattern
|
|
63
|
+
|
|
64
|
+
Notice how this step:
|
|
65
|
+
|
|
66
|
+
- Takes the output from the previous step as input
|
|
67
|
+
- Adds new data (`summary`) while preserving existing data
|
|
68
|
+
- Follows the same structure as other steps
|
|
69
|
+
|
|
70
|
+
Your third step is ready! Next, you'll update the workflow to include all three steps.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Updating the Workflow
|
|
2
|
+
|
|
3
|
+
Now you'll update your workflow to include all three steps: validate, enhance, and summarize.
|
|
4
|
+
|
|
5
|
+
## Updating the Workflow Definition
|
|
6
|
+
|
|
7
|
+
Replace your existing workflow with this updated version:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
export const contentWorkflow = createWorkflow({
|
|
11
|
+
id: "content-processing-workflow",
|
|
12
|
+
description: "Validates, enhances, and summarizes content",
|
|
13
|
+
inputSchema: z.object({
|
|
14
|
+
content: z.string(),
|
|
15
|
+
type: z.enum(["article", "blog", "social"]).default("article"),
|
|
16
|
+
}),
|
|
17
|
+
outputSchema: z.object({
|
|
18
|
+
content: z.string(),
|
|
19
|
+
type: z.string(),
|
|
20
|
+
wordCount: z.number(),
|
|
21
|
+
metadata: z.object({
|
|
22
|
+
readingTime: z.number(),
|
|
23
|
+
difficulty: z.enum(["easy", "medium", "hard"]),
|
|
24
|
+
processedAt: z.string(),
|
|
25
|
+
}),
|
|
26
|
+
summary: z.string(),
|
|
27
|
+
}),
|
|
28
|
+
})
|
|
29
|
+
.then(validateContentStep)
|
|
30
|
+
.then(enhanceContentStep)
|
|
31
|
+
.then(generateSummaryStep)
|
|
32
|
+
.commit();
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## What Changed
|
|
36
|
+
|
|
37
|
+
- **Description**: Updated to reflect the new functionality
|
|
38
|
+
- **Output Schema**: Now includes the `summary` field
|
|
39
|
+
- **Steps**: Added the third step to the chain
|
|
40
|
+
|
|
41
|
+
## Testing the Updated Workflow
|
|
42
|
+
|
|
43
|
+
You can now test this workflow in the playground to validate it works as expected.
|
|
44
|
+
|
|
45
|
+
## The Complete Flow
|
|
46
|
+
|
|
47
|
+
Your workflow now:
|
|
48
|
+
|
|
49
|
+
1. **Validates** content and counts words
|
|
50
|
+
2. **Enhances** with metadata like reading time and difficulty
|
|
51
|
+
3. **Summarizes** the content for quick understanding
|
|
52
|
+
|
|
53
|
+
Each step builds on the previous one, creating a comprehensive content processing pipeline!
|
|
54
|
+
|
|
55
|
+
Next, you'll learn about using workflows with agents.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Creating an AI Agent
|
|
2
|
+
|
|
3
|
+
Learn how to create an Mastra agent that can be used within your workflows for more intelligent content processing.
|
|
4
|
+
|
|
5
|
+
## Creating a Content Analysis Agent
|
|
6
|
+
|
|
7
|
+
Create a new file for your agent in the `src/mastra/agents` directory. Use `content-agent.ts` as the name of the file with the following contents:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// src/mastra/agents/content-agent.ts
|
|
11
|
+
import { openai } from "@ai-sdk/openai";
|
|
12
|
+
import { Agent } from "@mastra/core/agent";
|
|
13
|
+
|
|
14
|
+
export const contentAgent = new Agent({
|
|
15
|
+
name: "Content Agent",
|
|
16
|
+
description: "AI agent for analyzing and improving content",
|
|
17
|
+
instructions: `
|
|
18
|
+
You are a professional content analyst. Your role is to:
|
|
19
|
+
1. Analyze content for clarity and engagement
|
|
20
|
+
2. Identify the main themes and topics
|
|
21
|
+
3. Provide a quality score from 1-10
|
|
22
|
+
4. Suggest specific improvements
|
|
23
|
+
|
|
24
|
+
Always provide constructive, actionable feedback.
|
|
25
|
+
`,
|
|
26
|
+
model: openai("gpt-4o-mini"),
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Understanding the Agent
|
|
31
|
+
|
|
32
|
+
- **Name**: Unique identifier for the agent
|
|
33
|
+
- **Description**: What the agent does
|
|
34
|
+
- **Instructions**: Detailed prompts that guide the AI's behavior
|
|
35
|
+
- **Model**: Which AI model to use (GPT-4o-mini is fast and cost-effective)
|
|
36
|
+
|
|
37
|
+
## Registering and Testing Your Agent
|
|
38
|
+
|
|
39
|
+
Open your `src/mastra/index.ts` file and add your agent (you may need to append it to the agents object in the Mastra class):
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// Import your workflow
|
|
43
|
+
import { contentAgent } from "./agents/content-agent";
|
|
44
|
+
|
|
45
|
+
export const mastra = new Mastra({
|
|
46
|
+
// Register your agent here
|
|
47
|
+
agents: {
|
|
48
|
+
contentAgent,
|
|
49
|
+
},
|
|
50
|
+
// ...Existing code
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
You can test this agent in the Playground by navigating to the Agents tab and selecting `content-agent`. Use the chat interface to validate the agent is working.
|
|
55
|
+
|
|
56
|
+
The agent should provide analysis of the content, including themes, quality assessment, and improvement suggestions.
|
|
57
|
+
|
|
58
|
+
## Why Use Agents in Workflows?
|
|
59
|
+
|
|
60
|
+
Agents add intelligence to workflows by:
|
|
61
|
+
|
|
62
|
+
- **Understanding context**: AI can interpret meaning, not just process data
|
|
63
|
+
- **Generating insights**: Provide analysis that simple logic cannot
|
|
64
|
+
- **Adapting responses**: Give different feedback based on content type
|
|
65
|
+
- **Natural language output**: Communicate results in human-readable form
|
|
66
|
+
|
|
67
|
+
Your AI agent is ready! Next, you'll learn how to integrate it into a workflow step.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Using Agent in Workflow
|
|
2
|
+
|
|
3
|
+
Now you'll create a workflow step that uses your AI agent to provide intelligent content analysis.
|
|
4
|
+
|
|
5
|
+
In each step, in the execute function, you have access to the `mastra` class which provides you the ability to access Agents, Tools, and even other Workflows. In this case, we use the `mastra` class to get our agent and call that agent's `generate()` function.
|
|
6
|
+
|
|
7
|
+
## Creating an AI Analysis Step
|
|
8
|
+
|
|
9
|
+
Add this step to your workflow file:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
const aiAnalysisStep = createStep({
|
|
13
|
+
id: "ai-analysis",
|
|
14
|
+
description: "AI-powered content analysis",
|
|
15
|
+
inputSchema: z.object({
|
|
16
|
+
content: z.string(),
|
|
17
|
+
type: z.string(),
|
|
18
|
+
wordCount: z.number(),
|
|
19
|
+
metadata: z.object({
|
|
20
|
+
readingTime: z.number(),
|
|
21
|
+
difficulty: z.enum(["easy", "medium", "hard"]),
|
|
22
|
+
processedAt: z.string(),
|
|
23
|
+
}),
|
|
24
|
+
summary: z.string(),
|
|
25
|
+
}),
|
|
26
|
+
outputSchema: z.object({
|
|
27
|
+
content: z.string(),
|
|
28
|
+
type: z.string(),
|
|
29
|
+
wordCount: z.number(),
|
|
30
|
+
metadata: z.object({
|
|
31
|
+
readingTime: z.number(),
|
|
32
|
+
difficulty: z.enum(["easy", "medium", "hard"]),
|
|
33
|
+
processedAt: z.string(),
|
|
34
|
+
}),
|
|
35
|
+
summary: z.string(),
|
|
36
|
+
aiAnalysis: z.object({
|
|
37
|
+
score: z.number(),
|
|
38
|
+
feedback: z.string(),
|
|
39
|
+
}),
|
|
40
|
+
}),
|
|
41
|
+
execute: async ({ inputData, mastra }) => {
|
|
42
|
+
const { content, type, wordCount, metadata, summary } = inputData;
|
|
43
|
+
|
|
44
|
+
// Create prompt for the AI agent
|
|
45
|
+
const prompt = `
|
|
46
|
+
Analyze this ${type} content:
|
|
47
|
+
|
|
48
|
+
Content: "${content}"
|
|
49
|
+
Word count: ${wordCount}
|
|
50
|
+
Reading time: ${metadata.readingTime} minutes
|
|
51
|
+
Difficulty: ${metadata.difficulty}
|
|
52
|
+
|
|
53
|
+
Please provide:
|
|
54
|
+
1. A quality score from 1-10
|
|
55
|
+
2. Brief feedback on strengths and areas for improvement
|
|
56
|
+
|
|
57
|
+
Format as JSON: {"score": number, "feedback": "your feedback here"}
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
// Get the contentAgent from the mastra instance.
|
|
61
|
+
const contentAgent = mastra.getAgent("contentAgent");
|
|
62
|
+
const { text } = await contentAgent.generate([
|
|
63
|
+
{ role: "user", content: prompt },
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
// Parse AI response (with fallback)
|
|
67
|
+
let aiAnalysis;
|
|
68
|
+
try {
|
|
69
|
+
aiAnalysis = JSON.parse(text);
|
|
70
|
+
} catch {
|
|
71
|
+
aiAnalysis = {
|
|
72
|
+
score: 7,
|
|
73
|
+
feedback: "AI analysis completed. " + text,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.log(`🤖 AI Score: ${aiAnalysis.score}/10`);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
content,
|
|
81
|
+
type,
|
|
82
|
+
wordCount,
|
|
83
|
+
metadata,
|
|
84
|
+
summary,
|
|
85
|
+
aiAnalysis,
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Your agent-powered step is ready! Next, you'll add it to your workflow for complete AI-enhanced content processing.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Creating AI-Enhanced Workflow
|
|
2
|
+
|
|
3
|
+
Now you'll create a new workflow that includes agent analysis alongside your existing content processing steps.
|
|
4
|
+
|
|
5
|
+
## Creating the Enhanced Workflow
|
|
6
|
+
|
|
7
|
+
Add this new workflow to your file:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
export const aiContentWorkflow = createWorkflow({
|
|
11
|
+
id: "ai-content-workflow",
|
|
12
|
+
description: "AI-enhanced content processing with analysis",
|
|
13
|
+
inputSchema: z.object({
|
|
14
|
+
content: z.string(),
|
|
15
|
+
type: z.enum(["article", "blog", "social"]).default("article"),
|
|
16
|
+
}),
|
|
17
|
+
outputSchema: z.object({
|
|
18
|
+
content: z.string(),
|
|
19
|
+
type: z.string(),
|
|
20
|
+
wordCount: z.number(),
|
|
21
|
+
metadata: z.object({
|
|
22
|
+
readingTime: z.number(),
|
|
23
|
+
difficulty: z.enum(["easy", "medium", "hard"]),
|
|
24
|
+
processedAt: z.string(),
|
|
25
|
+
}),
|
|
26
|
+
summary: z.string(),
|
|
27
|
+
aiAnalysis: z.object({
|
|
28
|
+
score: z.number(),
|
|
29
|
+
feedback: z.string(),
|
|
30
|
+
}),
|
|
31
|
+
}),
|
|
32
|
+
})
|
|
33
|
+
.then(validateContentStep)
|
|
34
|
+
.then(enhanceContentStep)
|
|
35
|
+
.then(generateSummaryStep)
|
|
36
|
+
.then(aiAnalysisStep)
|
|
37
|
+
.commit();
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Registering the New Workflow
|
|
41
|
+
|
|
42
|
+
Update your Mastra configuration to include both workflows and ensure the contentAgent has been added.
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// In src/mastra/index.ts
|
|
46
|
+
import {
|
|
47
|
+
contentWorkflow,
|
|
48
|
+
aiContentWorkflow,
|
|
49
|
+
} from "./workflows/content-workflow";
|
|
50
|
+
import { contentAgent } from "./agents/content-agent";
|
|
51
|
+
|
|
52
|
+
export const mastra = new Mastra({
|
|
53
|
+
workflows: {
|
|
54
|
+
contentWorkflow,
|
|
55
|
+
aiContentWorkflow, // Add the AI-enhanced version
|
|
56
|
+
},
|
|
57
|
+
agents: { contentAgent },
|
|
58
|
+
// ... rest of configuration
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Testing the Agent-Enhanced Workflow
|
|
63
|
+
|
|
64
|
+
You can now access this new Workflow inside the Mastra playground. Select this new `ai-content-workflow` workflow from the Workflows tab and run a test to validate it works as expected.
|
|
65
|
+
|
|
66
|
+
## The Complete AI Pipeline
|
|
67
|
+
|
|
68
|
+
Your AI-enhanced workflow now:
|
|
69
|
+
|
|
70
|
+
1. **Validates** content and counts words
|
|
71
|
+
2. **Enhances** with metadata
|
|
72
|
+
3. **Summarizes** the content
|
|
73
|
+
4. **Analyzes** with AI for quality scoring and feedback
|
|
74
|
+
|
|
75
|
+
This creates a comprehensive, AI-powered content processing system! Next, you'll learn about parallel execution.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Understanding Parallel Execution
|
|
2
|
+
|
|
3
|
+
Learn how to run multiple workflow steps simultaneously to improve performance when steps don't depend on each other.
|
|
4
|
+
|
|
5
|
+
## When to Use Parallel Execution
|
|
6
|
+
|
|
7
|
+
Use parallel execution when you have steps that:
|
|
8
|
+
|
|
9
|
+
- **Don't depend on each other**: Can run independently
|
|
10
|
+
- **Take time**: Network requests, AI calls, or heavy computations
|
|
11
|
+
- **Process the same input**: Multiple analyses of the same data
|
|
12
|
+
|
|
13
|
+
## Example Scenario
|
|
14
|
+
|
|
15
|
+
Imagine you want to analyze content in three different ways:
|
|
16
|
+
|
|
17
|
+
1. SEO analysis
|
|
18
|
+
2. Readability analysis
|
|
19
|
+
3. Sentiment analysis
|
|
20
|
+
|
|
21
|
+
These can all run at the same time since they don't depend on each other!
|
|
22
|
+
|
|
23
|
+
## Creating Parallel Steps
|
|
24
|
+
|
|
25
|
+
The .parallel() method on a workflow executes multiple steps in parallel.
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
workflow.parallel([stepOne, stepTwo]);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Performance Benefits
|
|
32
|
+
|
|
33
|
+
Running steps in parallel:
|
|
34
|
+
|
|
35
|
+
- **Faster execution**: Steps run simultaneously instead of waiting
|
|
36
|
+
- **Improved user experience**: Shorter wait times
|
|
37
|
+
|
|
38
|
+
Next, you'll create the other parallel steps and see how to combine them!
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Creating Parallel Steps
|
|
2
|
+
|
|
3
|
+
Let's create three analysis steps that can run simultaneously to analyze different aspects of content.
|
|
4
|
+
|
|
5
|
+
## Creating the Analysis Steps
|
|
6
|
+
|
|
7
|
+
Add these three steps to your workflow file:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// SEO Analysis
|
|
11
|
+
const seoAnalysisStep = createStep({
|
|
12
|
+
id: "seo-analysis",
|
|
13
|
+
description: "SEO optimization analysis",
|
|
14
|
+
inputSchema: z.object({
|
|
15
|
+
content: z.string(),
|
|
16
|
+
type: z.enum(["article", "blog", "social"]).default("article"),
|
|
17
|
+
}),
|
|
18
|
+
outputSchema: z.object({
|
|
19
|
+
seoScore: z.number(),
|
|
20
|
+
keywords: z.array(z.string()),
|
|
21
|
+
}),
|
|
22
|
+
execute: async ({ inputData }) => {
|
|
23
|
+
console.log("🔍 Running SEO analysis...");
|
|
24
|
+
await new Promise((resolve) => setTimeout(resolve, 800));
|
|
25
|
+
|
|
26
|
+
const words = inputData.content.toLowerCase().split(/\s+/);
|
|
27
|
+
const keywords = words.filter((word) => word.length > 4).slice(0, 3);
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
seoScore: Math.floor(Math.random() * 40) + 60,
|
|
31
|
+
keywords,
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Readability Analysis
|
|
37
|
+
const readabilityStep = createStep({
|
|
38
|
+
id: "readability-analysis",
|
|
39
|
+
description: "Content readability analysis",
|
|
40
|
+
inputSchema: z.object({
|
|
41
|
+
content: z.string(),
|
|
42
|
+
type: z.enum(["article", "blog", "social"]).default("article"),
|
|
43
|
+
}),
|
|
44
|
+
outputSchema: z.object({
|
|
45
|
+
readabilityScore: z.number(),
|
|
46
|
+
gradeLevel: z.string(),
|
|
47
|
+
}),
|
|
48
|
+
execute: async ({ inputData }) => {
|
|
49
|
+
console.log("📖 Running readability analysis...");
|
|
50
|
+
await new Promise((resolve) => setTimeout(resolve, 600));
|
|
51
|
+
|
|
52
|
+
const sentences = inputData.content.split(/[.!?]+/).length;
|
|
53
|
+
const words = inputData.content.split(/\s+/).length;
|
|
54
|
+
const avgWordsPerSentence = words / sentences;
|
|
55
|
+
|
|
56
|
+
const score = Math.max(0, 100 - avgWordsPerSentence * 3);
|
|
57
|
+
const gradeLevel = score > 80 ? "Easy" : score > 60 ? "Medium" : "Hard";
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
readabilityScore: Math.floor(score),
|
|
61
|
+
gradeLevel,
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Sentiment Analysis
|
|
67
|
+
const sentimentStep = createStep({
|
|
68
|
+
id: "sentiment-analysis",
|
|
69
|
+
description: "Content sentiment analysis",
|
|
70
|
+
inputSchema: z.object({
|
|
71
|
+
content: z.string(),
|
|
72
|
+
type: z.enum(["article", "blog", "social"]).default("article"),
|
|
73
|
+
}),
|
|
74
|
+
outputSchema: z.object({
|
|
75
|
+
sentiment: z.enum(["positive", "neutral", "negative"]),
|
|
76
|
+
confidence: z.number(),
|
|
77
|
+
}),
|
|
78
|
+
execute: async ({ inputData }) => {
|
|
79
|
+
console.log("😊 Running sentiment analysis...");
|
|
80
|
+
await new Promise((resolve) => setTimeout(resolve, 700));
|
|
81
|
+
|
|
82
|
+
const content = inputData.content.toLowerCase();
|
|
83
|
+
const positiveWords = ["good", "great", "excellent", "amazing"];
|
|
84
|
+
const negativeWords = ["bad", "terrible", "awful", "horrible"];
|
|
85
|
+
|
|
86
|
+
const positive = positiveWords.filter((word) =>
|
|
87
|
+
content.includes(word),
|
|
88
|
+
).length;
|
|
89
|
+
const negative = negativeWords.filter((word) =>
|
|
90
|
+
content.includes(word),
|
|
91
|
+
).length;
|
|
92
|
+
|
|
93
|
+
let sentiment: "positive" | "neutral" | "negative" = "neutral";
|
|
94
|
+
if (positive > negative) sentiment = "positive";
|
|
95
|
+
if (negative > positive) sentiment = "negative";
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
sentiment,
|
|
99
|
+
confidence: Math.random() * 0.3 + 0.7, // 0.7-1.0
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Notice the Timing
|
|
106
|
+
|
|
107
|
+
Each step has a different simulated processing time:
|
|
108
|
+
|
|
109
|
+
- SEO: 800ms
|
|
110
|
+
- Readability: 600ms
|
|
111
|
+
- Sentiment: 700ms
|
|
112
|
+
|
|
113
|
+
When run sequentially, total time would be ~2.2 seconds. When run in parallel, total time will be ~800ms (the longest step)!
|
|
114
|
+
|
|
115
|
+
Next, you'll learn how to run these steps in parallel using the `.parallel()` method.
|