@mastra/mcp-docs-server 0.13.2-alpha.0 → 0.13.2-alpha.2

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 (115) hide show
  1. package/.docs/organized/changelogs/%40mastra%2Fagui.md +12 -0
  2. package/.docs/organized/changelogs/%40mastra%2Fastra.md +25 -25
  3. package/.docs/organized/changelogs/%40mastra%2Fchroma.md +25 -25
  4. package/.docs/organized/changelogs/%40mastra%2Fclickhouse.md +26 -26
  5. package/.docs/organized/changelogs/%40mastra%2Fclient-js.md +32 -32
  6. package/.docs/organized/changelogs/%40mastra%2Fcloudflare-d1.md +25 -25
  7. package/.docs/organized/changelogs/%40mastra%2Fcloudflare.md +26 -26
  8. package/.docs/organized/changelogs/%40mastra%2Fcore.md +26 -26
  9. package/.docs/organized/changelogs/%40mastra%2Fcouchbase.md +14 -14
  10. package/.docs/organized/changelogs/%40mastra%2Fdeployer-cloudflare.md +40 -40
  11. package/.docs/organized/changelogs/%40mastra%2Fdeployer-netlify.md +44 -44
  12. package/.docs/organized/changelogs/%40mastra%2Fdeployer-vercel.md +42 -42
  13. package/.docs/organized/changelogs/%40mastra%2Fdeployer.md +45 -45
  14. package/.docs/organized/changelogs/%40mastra%2Fdynamodb.md +27 -27
  15. package/.docs/organized/changelogs/%40mastra%2Fevals.md +13 -13
  16. package/.docs/organized/changelogs/%40mastra%2Ffirecrawl.md +16 -16
  17. package/.docs/organized/changelogs/%40mastra%2Fgithub.md +13 -13
  18. package/.docs/organized/changelogs/%40mastra%2Flance.md +25 -0
  19. package/.docs/organized/changelogs/%40mastra%2Flibsql.md +28 -28
  20. package/.docs/organized/changelogs/%40mastra%2Fmcp-docs-server.md +30 -30
  21. package/.docs/organized/changelogs/%40mastra%2Fmcp-registry-registry.md +16 -16
  22. package/.docs/organized/changelogs/%40mastra%2Fmcp.md +24 -24
  23. package/.docs/organized/changelogs/%40mastra%2Fmem0.md +13 -13
  24. package/.docs/organized/changelogs/%40mastra%2Fmemory.md +35 -35
  25. package/.docs/organized/changelogs/%40mastra%2Fmongodb.md +28 -28
  26. package/.docs/organized/changelogs/%40mastra%2Fopensearch.md +24 -0
  27. package/.docs/organized/changelogs/%40mastra%2Fpg.md +28 -28
  28. package/.docs/organized/changelogs/%40mastra%2Fpinecone.md +14 -14
  29. package/.docs/organized/changelogs/%40mastra%2Fplayground-ui.md +38 -38
  30. package/.docs/organized/changelogs/%40mastra%2Fqdrant.md +14 -14
  31. package/.docs/organized/changelogs/%40mastra%2Frag.md +14 -14
  32. package/.docs/organized/changelogs/%40mastra%2Fragie.md +13 -13
  33. package/.docs/organized/changelogs/%40mastra%2Fschema-compat.md +6 -0
  34. package/.docs/organized/changelogs/%40mastra%2Fserver.md +32 -32
  35. package/.docs/organized/changelogs/%40mastra%2Fturbopuffer.md +14 -14
  36. package/.docs/organized/changelogs/%40mastra%2Fupstash.md +26 -26
  37. package/.docs/organized/changelogs/%40mastra%2Fvectorize.md +14 -14
  38. package/.docs/organized/changelogs/%40mastra%2Fvoice-cloudflare.md +13 -13
  39. package/.docs/organized/changelogs/%40mastra%2Fvoice-deepgram.md +14 -14
  40. package/.docs/organized/changelogs/%40mastra%2Fvoice-elevenlabs.md +14 -14
  41. package/.docs/organized/changelogs/%40mastra%2Fvoice-gladia.md +12 -0
  42. package/.docs/organized/changelogs/%40mastra%2Fvoice-google.md +14 -14
  43. package/.docs/organized/changelogs/%40mastra%2Fvoice-murf.md +13 -13
  44. package/.docs/organized/changelogs/%40mastra%2Fvoice-openai.md +14 -14
  45. package/.docs/organized/changelogs/%40mastra%2Fvoice-playai.md +13 -13
  46. package/.docs/organized/changelogs/%40mastra%2Fvoice-sarvam.md +13 -13
  47. package/.docs/organized/changelogs/%40mastra%2Fvoice-speechify.md +14 -14
  48. package/.docs/organized/changelogs/create-mastra.md +7 -7
  49. package/.docs/organized/changelogs/mastra.md +48 -48
  50. package/.docs/organized/code-examples/a2a.md +1 -1
  51. package/.docs/organized/code-examples/agent-network.md +125 -7
  52. package/.docs/organized/code-examples/agent.md +183 -6
  53. package/.docs/organized/code-examples/agui.md +4 -4
  54. package/.docs/organized/code-examples/ai-sdk-useChat.md +6 -6
  55. package/.docs/organized/code-examples/assistant-ui.md +6 -6
  56. package/.docs/organized/code-examples/bird-checker-with-express.md +1 -1
  57. package/.docs/organized/code-examples/bird-checker-with-nextjs-and-eval.md +6 -6
  58. package/.docs/organized/code-examples/bird-checker-with-nextjs.md +6 -6
  59. package/.docs/organized/code-examples/client-side-tools.md +6 -6
  60. package/.docs/organized/code-examples/crypto-chatbot.md +6 -6
  61. package/.docs/organized/code-examples/experimental-auth-weather-agent.md +1 -1
  62. package/.docs/organized/code-examples/fireworks-r1.md +1 -1
  63. package/.docs/organized/code-examples/mcp-configuration.md +2 -2
  64. package/.docs/organized/code-examples/mcp-registry-registry.md +1 -1
  65. package/.docs/organized/code-examples/memory-per-resource-example.md +236 -0
  66. package/.docs/organized/code-examples/memory-with-mem0.md +1 -1
  67. package/.docs/organized/code-examples/memory-with-processors.md +1 -1
  68. package/.docs/organized/code-examples/openapi-spec-writer.md +6 -6
  69. package/.docs/organized/code-examples/quick-start.md +1 -1
  70. package/.docs/organized/code-examples/stock-price-tool.md +1 -1
  71. package/.docs/organized/code-examples/weather-agent.md +1 -1
  72. package/.docs/organized/code-examples/workflow-ai-recruiter.md +1 -1
  73. package/.docs/organized/code-examples/workflow-with-inline-steps.md +1 -1
  74. package/.docs/organized/code-examples/workflow-with-memory.md +1 -1
  75. package/.docs/organized/code-examples/workflow-with-separate-steps.md +1 -1
  76. package/.docs/raw/agents/using-tools-and-mcp.mdx +3 -2
  77. package/.docs/raw/deployment/cloud-providers/digital-ocean.mdx +111 -0
  78. package/.docs/raw/deployment/cloud-providers/index.mdx +15 -0
  79. package/.docs/raw/frameworks/agentic-uis/copilotkit.mdx +53 -10
  80. package/.docs/raw/mastra-cloud/dashboard.mdx +100 -0
  81. package/.docs/raw/mastra-cloud/observability.mdx +24 -138
  82. package/.docs/raw/mastra-cloud/overview.mdx +50 -42
  83. package/.docs/raw/mastra-cloud/setting-up.mdx +51 -87
  84. package/.docs/raw/memory/overview.mdx +4 -0
  85. package/.docs/raw/memory/working-memory.mdx +144 -1
  86. package/.docs/raw/networks-vnext/complex-task-execution.mdx +137 -0
  87. package/.docs/raw/networks-vnext/overview.mdx +85 -0
  88. package/.docs/raw/networks-vnext/single-task-execution.mdx +131 -0
  89. package/.docs/raw/observability/nextjs-tracing.mdx +2 -2
  90. package/.docs/raw/reference/client-js/agents.mdx +41 -0
  91. package/.docs/raw/reference/deployer/netlify.mdx +22 -68
  92. package/.docs/raw/reference/deployer/vercel.mdx +7 -77
  93. package/.docs/raw/reference/storage/libsql.mdx +1 -0
  94. package/.docs/raw/reference/tools/mcp-client.mdx +244 -0
  95. package/.docs/raw/reference/tools/mcp-server.mdx +186 -0
  96. package/.docs/raw/reference/tools/vector-query-tool.mdx +1 -0
  97. package/.docs/raw/reference/workflows/create-run.mdx +1 -1
  98. package/.docs/raw/reference/workflows/resume.mdx +1 -1
  99. package/.docs/raw/reference/workflows/sleep.mdx +43 -0
  100. package/.docs/raw/reference/workflows/sleepUntil.mdx +43 -0
  101. package/.docs/raw/reference/workflows/start.mdx +1 -1
  102. package/.docs/raw/reference/workflows/stream.mdx +1 -1
  103. package/.docs/raw/reference/workflows/waitForEvent.mdx +49 -0
  104. package/.docs/raw/reference/workflows/watch.mdx +1 -1
  105. package/.docs/raw/reference/workflows/workflow.mdx +6 -2
  106. package/.docs/raw/storage/overview.mdx +50 -1
  107. package/.docs/raw/tools-mcp/mcp-overview.mdx +52 -0
  108. package/.docs/raw/workflows/control-flow.mdx +42 -1
  109. package/.docs/raw/workflows/inngest-workflow.mdx +1 -1
  110. package/.docs/raw/workflows/overview.mdx +73 -5
  111. package/.docs/raw/workflows/pausing-execution.mdx +60 -0
  112. package/.docs/raw/workflows/suspend-and-resume.mdx +68 -23
  113. package/.docs/raw/workflows/using-with-agents-and-tools.mdx +1 -1
  114. package/package.json +6 -6
  115. package/.docs/raw/mastra-cloud/deploying.mdx +0 -142
@@ -2,12 +2,19 @@ import YouTube from "@/components/youtube";
2
2
 
3
3
  # Working Memory
4
4
 
5
- While [conversation history](/docs/memory/overview#conversation-history) and [semantic recall](./semantic-recall.mdx) help agents remember conversations, working memory allows them to maintain persistent information about users across interactions within a thread.
5
+ While [conversation history](/docs/memory/overview#conversation-history) and [semantic recall](./semantic-recall.mdx) help agents remember conversations, working memory allows them to maintain persistent information about users across interactions.
6
6
 
7
7
  Think of it as the agent's active thoughts or scratchpad – the key information they keep available about the user or task. It's similar to how a person would naturally remember someone's name, preferences, or important details during a conversation.
8
8
 
9
9
  This is useful for maintaining ongoing state that's always relevant and should always be available to the agent.
10
10
 
11
+ Working memory can persist at two different scopes:
12
+ - **Thread-scoped** (default): Memory is isolated per conversation thread
13
+ - **Resource-scoped**: Memory persists across all conversation threads for the same user
14
+
15
+ **Important:** Switching between scopes means the agent won't see memory from the other scope - thread-scoped memory is completely separate from resource-scoped memory.
16
+
17
+
11
18
  ## Quick Start
12
19
 
13
20
  Here's a minimal example of setting up an agent with working memory:
@@ -38,6 +45,85 @@ Working memory is a block of Markdown text that the agent is able to update over
38
45
 
39
46
  <YouTube id="ik-ld_XA96s" />
40
47
 
48
+ ## Memory Persistence Scopes
49
+
50
+ Working memory can operate in two different scopes, allowing you to choose how memory persists across conversations:
51
+
52
+ ### Thread-Scoped Memory (Default)
53
+
54
+ By default, working memory is scoped to individual conversation threads. Each thread maintains its own isolated memory:
55
+
56
+ ```typescript
57
+ const memory = new Memory({
58
+ storage,
59
+ options: {
60
+ workingMemory: {
61
+ enabled: true,
62
+ scope: 'thread', // Default - memory is isolated per thread
63
+ template: `# User Profile
64
+ - **Name**:
65
+ - **Interests**:
66
+ - **Current Goal**:
67
+ `,
68
+ },
69
+ },
70
+ });
71
+ ```
72
+
73
+ **Use cases:**
74
+ - Different conversations about separate topics
75
+ - Temporary or session-specific information
76
+ - Workflows where each thread needs working memory but threads are ephemeral and not related to each other
77
+
78
+ ### Resource-Scoped Memory
79
+
80
+ Resource-scoped memory persists across all conversation threads for the same user (resourceId), enabling persistent user memory:
81
+
82
+ ```typescript
83
+ const memory = new Memory({
84
+ storage,
85
+ options: {
86
+ workingMemory: {
87
+ enabled: true,
88
+ scope: 'resource', // Memory persists across all user threads
89
+ template: `# User Profile
90
+ - **Name**:
91
+ - **Location**:
92
+ - **Interests**:
93
+ - **Preferences**:
94
+ - **Long-term Goals**:
95
+ `,
96
+ },
97
+ },
98
+ });
99
+ ```
100
+
101
+ **Use cases:**
102
+ - Personal assistants that remember user preferences
103
+ - Customer service bots that maintain customer context
104
+ - Educational applications that track student progress
105
+
106
+ ### Usage with Agents
107
+
108
+ When using resource-scoped memory, make sure to pass the `resourceId` parameter:
109
+
110
+ ```typescript
111
+ // Resource-scoped memory requires resourceId
112
+ const response = await agent.generate("Hello!", {
113
+ threadId: "conversation-123",
114
+ resourceId: "user-alice-456" // Same user across different threads
115
+ });
116
+ ```
117
+
118
+ ## Storage Adapter Support
119
+
120
+ Resource-scoped working memory requires specific storage adapters that support the `mastra_resources` table:
121
+
122
+ ### ✅ Supported Storage Adapters
123
+ - **LibSQL** (`@mastra/libsql`)
124
+ - **PostgreSQL** (`@mastra/pg`)
125
+ - **Upstash** (`@mastra/upstash`)
126
+
41
127
  ## Custom Templates
42
128
 
43
129
  Templates guide the agent on what information to track and update in working memory. While a default template is used if none is provided, you'll typically want to define a custom template tailored to your agent's specific use case to ensure it remembers the most relevant information.
@@ -122,6 +208,61 @@ const paragraphMemory = new Memory({
122
208
  });
123
209
  ```
124
210
 
211
+ ## Structured Working Memory
212
+
213
+ Working memory can also be defined using a structured schema instead of a Markdown template. This allows you to specify the exact fields and types that should be tracked, using a [Zod](https://zod.dev/) schema. When using a schema, the agent will see and update working memory as a JSON object matching your schema.
214
+
215
+ **Important:** You must specify either `template` or `schema`, but not both.
216
+
217
+ ### Example: Schema-Based Working Memory
218
+
219
+ ```typescript
220
+ import { z } from 'zod';
221
+ import { Memory } from '@mastra/memory';
222
+
223
+ const userProfileSchema = z.object({
224
+ name: z.string().optional(),
225
+ location: z.string().optional(),
226
+ timezone: z.string().optional(),
227
+ preferences: z.object({
228
+ communicationStyle: z.string().optional(),
229
+ projectGoal: z.string().optional(),
230
+ deadlines: z.array(z.string()).optional(),
231
+ }).optional(),
232
+ });
233
+
234
+ const memory = new Memory({
235
+ options: {
236
+ workingMemory: {
237
+ enabled: true,
238
+ schema: userProfileSchema,
239
+ // template: ... (do not set)
240
+ },
241
+ },
242
+ });
243
+ ```
244
+
245
+ When a schema is provided, the agent receives the working memory as a JSON object. For example:
246
+
247
+ ```json
248
+ {
249
+ "name": "Sam",
250
+ "location": "Berlin",
251
+ "timezone": "CET",
252
+ "preferences": {
253
+ "communicationStyle": "Formal",
254
+ "projectGoal": "Launch MVP",
255
+ "deadlines": ["2025-07-01"]
256
+ }
257
+ }
258
+ ```
259
+
260
+ ## Choosing Between Template and Schema
261
+
262
+ - Use a **template** (Markdown) if you want the agent to maintain memory as a free-form text block, such as a user profile or scratchpad.
263
+ - Use a **schema** if you need structured, type-safe data that can be validated and programmatically accessed as JSON.
264
+ - Only one mode can be active at a time: setting both `template` and `schema` is not supported.
265
+
125
266
  ## Example: Multi-step Retention
126
267
 
127
268
  Below is a simplified view of how the `User Profile` template updates across a short user
@@ -161,3 +302,5 @@ instructions on _how_ and _when_ to use this template in your agent's `instructi
161
302
 
162
303
  - [Streaming working memory](/examples/memory/streaming-working-memory)
163
304
  - [Using a working memory template](/examples/memory/streaming-working-memory-advanced)
305
+ - [Using a working memory schema](/examples/memory/streaming-working-memory-structured)
306
+ - [Per-resource working memory](https://github.com/mastra-ai/mastra/tree/main/examples/memory-per-resource-example) - Complete example showing resource-scoped memory persistence
@@ -0,0 +1,137 @@
1
+ ## Complex tasks requiring multiple primitives
2
+
3
+ As an example, we have an AgentNetwork with 3 primitives at its disposal:
4
+
5
+ - `agent1`: A general research agent that can do research on a given topic.
6
+ - `agent2`: A general writing agent that can write a full report based on the researched material.
7
+ - `workflow1`: A workflow that can research a given city and write a full report based on the researched material (using both agent1 and agent2).
8
+
9
+ We use the `loop` method to create a task that requires multiple primitives. The AgentNetwork will, using memory, figure out which primitives to call and in which order, as well as when the task is complete.
10
+
11
+ ```typescript
12
+ import { NewAgentNetwork } from '@mastra/core/network/vNext';
13
+ import { Agent } from '@mastra/core/agent';
14
+ import { createStep, createWorkflow } from '@mastra/core/workflows';
15
+ import { Memory } from '@mastra/memory';
16
+ import { openai } from '@ai-sdk/openai';
17
+ import { LibSQLStore } from '@mastra/libsql';
18
+ import { z } from 'zod';
19
+ import { RuntimeContext } from '@mastra/core/runtime-context';
20
+
21
+ const memory = new Memory({
22
+ storage: new LibSQLStore({
23
+ url: 'file:../mastra.db', // Or your database URL
24
+ }),
25
+ });
26
+
27
+ const agentStep1 = createStep({
28
+ id: 'agent-step',
29
+ description: 'This step is used to do research and text synthesis.',
30
+ inputSchema: z.object({
31
+ city: z.string().describe('The city to research'),
32
+ }),
33
+ outputSchema: z.object({
34
+ text: z.string(),
35
+ }),
36
+ execute: async ({ inputData }) => {
37
+ const resp = await agent1.generate(inputData.city, {
38
+ output: z.object({
39
+ text: z.string(),
40
+ }),
41
+ });
42
+
43
+ return { text: resp.object.text };
44
+ },
45
+ });
46
+
47
+ const agentStep2 = createStep({
48
+ id: 'agent-step-two',
49
+ description: 'This step is used to do research and text synthesis.',
50
+ inputSchema: z.object({
51
+ text: z.string().describe('The city to research'),
52
+ }),
53
+ outputSchema: z.object({
54
+ text: z.string(),
55
+ }),
56
+ execute: async ({ inputData }) => {
57
+ const resp = await agent2.generate(inputData.text, {
58
+ output: z.object({
59
+ text: z.string(),
60
+ }),
61
+ });
62
+
63
+ return { text: resp.object.text };
64
+ },
65
+ });
66
+
67
+ const workflow1 = createWorkflow({
68
+ id: 'workflow1',
69
+ description:
70
+ 'This workflow is perfect for researching a specific city. It should be used when you have a city in mind to research.',
71
+ steps: [],
72
+ inputSchema: z.object({
73
+ city: z.string(),
74
+ }),
75
+ outputSchema: z.object({
76
+ text: z.string(),
77
+ }),
78
+ })
79
+ .then(agentStep1)
80
+ .then(agentStep2)
81
+ .commit();
82
+
83
+ const agent1 = new Agent({
84
+ name: 'agent1',
85
+ instructions:
86
+ 'This agent is used to do research, but not create full responses. Answer in bullet points only and be concise.',
87
+ description:
88
+ 'This agent is used to do research, but not create full responses. Answer in bullet points only and be concise.',
89
+ model: openai('gpt-4o'),
90
+ });
91
+
92
+ const agent2 = new Agent({
93
+ name: 'agent2',
94
+ description:
95
+ 'This agent is used to do text synthesis on researched material. Write a full report based on the researched material. Writes reports in full paragraphs. Should be used to synthesize text from different sources together as a final report.',
96
+ instructions:
97
+ 'This agent is used to do text synthesis on researched material. Write a full report based on the researched material. Do not use bullet points. Write full paragraphs. There should not be a single bullet point in the final report.',
98
+ model: openai('gpt-4o'),
99
+ });
100
+
101
+ const network = new NewAgentNetwork({
102
+ id: 'test-network',
103
+ name: 'Test Network',
104
+ instructions:
105
+ 'You are a network of writers and researchers. The user will ask you to research a topic. You always need to answer with a full report. Bullet points are NOT a full report. WRITE FULL PARAGRAPHS like this is a blog post or something similar. You should not rely on partial information.',
106
+ model: openai('gpt-4o'),
107
+ agents: {
108
+ agent1,
109
+ agent2,
110
+ },
111
+ workflows: {
112
+ workflow1,
113
+ },
114
+ memory: memory,
115
+ });
116
+
117
+ const runtimeContext = new RuntimeContext();
118
+
119
+ console.log(
120
+ // specifying the task, note that there is a mention here about using an agent for synthesis. This is because the routing agent can actually do some synthesis on results on its own, so this will force it to use agent2 instead
121
+ await network.loop(
122
+ 'What are the biggest cities in France? Give me 3. How are they like? Find cities, then do thorough research on each city, and give me a final full report synthesizing all that information. Make sure to use an agent for synthesis.',
123
+ { runtimeContext },
124
+ ),
125
+ );
126
+ ```
127
+
128
+ For the given task (research 3 biggest cities in France and write a full report), the AgentNetwork will call the following primitives:
129
+
130
+ 1. `agent1` to find the 3 biggest cities in France.
131
+ 2. `workflow1` to research each city one by one. The workflow uses `memory` to figure out which cities have already been researched and makes sure it has researched all of them before proceeding.
132
+ 3. `agent2` to synthesize the final report.
133
+
134
+ ### How It Works
135
+
136
+ - The underlying engine is a Mastra workflow that wraps the single call `generate` workflow.
137
+ - The workflow will repeatedly call the network execution workflow with a `dountil` structure, until the routing model determines the task is complete. This check is used as the `dountil` condition.
@@ -0,0 +1,85 @@
1
+ ---
2
+ title: "Handling Complex LLM Operations | Networks | Mastra"
3
+ description: "Networks in Mastra help you execute individual or multiple Mastra primitives in a non-deterministic way using a single API."
4
+ ---
5
+
6
+ # Mastra vNext Agent Network
7
+
8
+ The vNext Agent Network module introduces a flexible, composable and non-deterministic way to orchestrate multiple specialized agents and workflows, enabling complex, reasoning and task completion.
9
+
10
+ There are two main problem areas that this system is designed to solve:
11
+
12
+ - Scenarios where a single agent is insufficient, and tasks require collaboration, routing, or sequential/parallel execution across multiple agents and workflows.
13
+ - Scenarios where the task is not fully defined and is initiated with unstructured input. The AgentNetwork can figure out which primitive to call and turn unstructured input into a structured task.
14
+
15
+ ## Differences from Workflows
16
+
17
+ - Workflows are linear or branched sequences of steps. This creates a deterministic flow of execution.
18
+ - Agent Networks add a layer of non-deterministic LLM-based orchestration, allowing dynamic, multi-agent collaboration and routing. This creates a non-deterministic flow of execution.
19
+
20
+ ## Differences from current experimental implementation
21
+
22
+ - The current implementation of AgentNetwork relies on tool calls to call other agents in the network. The vNext implementation is using Mastra workflows under the hood to break down the execution to individual tasks.
23
+ - New methods, `.generate()` for a one-off "playbook"-like execution of a single primitive in the network, more suitable for a chat-based interface where you iterate on a solution. The `.loop()` method is still available for more complex tasks and operates much like the current implementation.
24
+
25
+ ## Important details
26
+
27
+ - Providing memory to the AgentNetwork is _not_ optional when using the `loop` method, as it is required to store the task history. Memory is the core primitive used for any decisions on which primitives to run, as well as determine task completion.
28
+ - Any available primitives (agents, workflows) are used based on their descriptions. The better the description, the better the routing agent will be able to select the right primitive. For workflows, the input schema is also used to determine which inputs to use when calling the workflow. More descriptive naming yields better results.
29
+ - When primitives with overlapping capabilities are available, the routing agent will use the most specific primitive. For example, if both an agent and a workflow can do research, it will use the input schema of the worklfow to determine
30
+
31
+ ## Registering the network in Mastra
32
+
33
+ ```typescript
34
+ const mastra = new Mastra({
35
+ vnext_networks: {
36
+ 'test-network': network,
37
+ },
38
+ });
39
+
40
+ // using the network
41
+ const network = mastra.vnext_getNetwork('test-network');
42
+
43
+ if (!network) {
44
+ throw new Error('Network not found');
45
+ }
46
+
47
+ console.log(await network.generate('What are the biggest cities in France?', { runtimeContext }));
48
+ ```
49
+
50
+ ## Using @mastra/client-js
51
+
52
+ You can use the `@mastra/client-js` package to run the network from the client side.
53
+
54
+ ```typescript
55
+ import { MastraClient } from '@mastra/client-js';
56
+
57
+ const client = new MastraClient();
58
+
59
+ const network = client.getVNextNetwork('test-network');
60
+
61
+ console.log(await network.generate('What are the biggest cities in France?', { runtimeContext }));
62
+ ```
63
+
64
+ You can also stream the response
65
+
66
+ ```typescript
67
+ const stream = await network.stream('What are the biggest cities in France?', { runtimeContext });
68
+
69
+ for await (const chunk of stream) {
70
+ console.log(chunk);
71
+ }
72
+ ```
73
+
74
+ And for loops
75
+
76
+ ```typescript
77
+ console.log(
78
+ // specifying the task, note that there is a mention here about using an agent for synthesis. This is because the routing agent can actually do some synthesis on results on its own, so this will force it to use agent2 instead
79
+ await network.loop(
80
+ 'What are the biggest cities in France? Give me 3. How are they like? Find cities, then do thorough research on each city, and give me a final full report synthesizing all that information. Make sure to use an agent for synthesis.',
81
+ { runtimeContext },
82
+ ),
83
+ );
84
+ ```
85
+
@@ -0,0 +1,131 @@
1
+ ## Unstructured input to structured task
2
+
3
+ As an example, we have an AgentNetwork with 3 primitives at its disposal:
4
+
5
+ - `agent1`: A general research agent that can do research on a given topic.
6
+ - `agent2`: A general writing agent that can write a full report based on the researched material.
7
+ - `workflow1`: A workflow that can research a given city and write a full report based on the researched material (using both agent1 and agent2).
8
+
9
+ The AgentNetwork is able to route the task to the most appropriate primitive based on the task and the context.
10
+ To ask the AgentNetwork to act on unstructured (text) input, we can use the `generate` method.
11
+
12
+ ```typescript
13
+ import { NewAgentNetwork } from '@mastra/core/network/vNext';
14
+ import { Agent } from '@mastra/core/agent';
15
+ import { createStep, createWorkflow } from '@mastra/core/workflows';
16
+ import { Memory } from '@mastra/memory';
17
+ import { openai } from '@ai-sdk/openai';
18
+ import { LibSQLStore } from '@mastra/libsql';
19
+ import { z } from 'zod';
20
+ import { RuntimeContext } from '@mastra/core/runtime-context';
21
+
22
+ const memory = new Memory({
23
+ storage: new LibSQLStore({
24
+ url: 'file:../mastra.db', // Or your database URL
25
+ }),
26
+ });
27
+
28
+ const agent1 = new Agent({
29
+ name: 'agent1',
30
+ instructions:
31
+ 'This agent is used to do research, but not create full responses. Answer in bullet points only and be concise.',
32
+ description:
33
+ 'This agent is used to do research, but not create full responses. Answer in bullet points only and be concise.',
34
+ model: openai('gpt-4o'),
35
+ });
36
+
37
+ const agent2 = new Agent({
38
+ name: 'agent2',
39
+ description: 'This agent is used to do text synthesis on researched material. It writes articles in full paragraphs.',
40
+ instructions:
41
+ 'This agent is used to do text synthesis on researched material. Write a full report based on the researched material. Do not use bullet points. Write full paragraphs. There should not be a single bullet point in the final report. You write articles.',
42
+ model: openai('gpt-4o'),
43
+ });
44
+
45
+ const agentStep1 = createStep({
46
+ id: 'agent-step',
47
+ description: 'This step is used to do research and text synthesis.',
48
+ inputSchema: z.object({
49
+ city: z.string().describe('The city to research'),
50
+ }),
51
+ outputSchema: z.object({
52
+ text: z.string(),
53
+ }),
54
+ execute: async ({ inputData }) => {
55
+ const resp = await agent1.generate(inputData.city, {
56
+ output: z.object({
57
+ text: z.string(),
58
+ }),
59
+ });
60
+
61
+ return { text: resp.object.text };
62
+ },
63
+ });
64
+
65
+ const agentStep2 = createStep({
66
+ id: 'agent-step-two',
67
+ description: 'This step is used to do research and text synthesis.',
68
+ inputSchema: z.object({
69
+ text: z.string().describe('The city to research'),
70
+ }),
71
+ outputSchema: z.object({
72
+ text: z.string(),
73
+ }),
74
+ execute: async ({ inputData }) => {
75
+ const resp = await agent2.generate(inputData.text, {
76
+ output: z.object({
77
+ text: z.string(),
78
+ }),
79
+ });
80
+
81
+ return { text: resp.object.text };
82
+ },
83
+ });
84
+
85
+ const workflow1 = createWorkflow({
86
+ id: 'workflow1',
87
+ description: 'This workflow is perfect for researching a specific city.',
88
+ steps: [],
89
+ inputSchema: z.object({
90
+ city: z.string(),
91
+ }),
92
+ outputSchema: z.object({
93
+ text: z.string(),
94
+ }),
95
+ })
96
+ .then(agentStep1)
97
+ .then(agentStep2)
98
+ .commit();
99
+
100
+ const network = new NewAgentNetwork({
101
+ id: 'test-network',
102
+ name: 'Test Network',
103
+ instructions:
104
+ 'You can research cities. You can also synthesize research material. You can also write a full report based on the researched material.',
105
+ model: openai('gpt-4o'),
106
+ agents: {
107
+ agent1,
108
+ agent2,
109
+ },
110
+ workflows: {
111
+ workflow1,
112
+ },
113
+ memory: memory,
114
+ });
115
+
116
+ const runtimeContext = new RuntimeContext();
117
+
118
+ // This will call agent1, as the workflow is meant to be used with individual cities. The best primitive according to the routing agent is thus agent1 which is a general research primitive.
119
+ console.log(await network.generate('What are the biggest cities in France? How are they like?', { runtimeContext }));
120
+ // This will call workflow1, as it is the most suitable primitive according to the routing agent when researching individual cities.
121
+ console.log(await network.generate('Tell me more about Paris', { runtimeContext }));
122
+ ```
123
+
124
+ The AgentNetwork will call the most appropriate primitive based on the task and the context. In the case of researching specific cities, it can figure out how to turn unstructured input into structured workflow inputs based on the workflow's input schema and description. It also knows, that for any other research topic, `agent1` is likely the most appropriate primitive.
125
+
126
+ ### How It Works
127
+
128
+ - The underlying engine is a Mastra workflow.
129
+ - As a first step, the network uses a **routing agent** to decide which agent or workflow should handle each step.
130
+ - The routing agent will generate a prompt and or structured input for the selected primitive.
131
+ - The next step in the workflow is a `.branch()` that will select the right primitive, calling either an agent step or a workflow step with the input generated by the routing agent.
@@ -59,7 +59,7 @@ npm install @opentelemetry/api langfuse-vercel
59
59
  import {
60
60
  NodeSDK,
61
61
  ATTR_SERVICE_NAME,
62
- Resource,
62
+ resourceFromAttributes,
63
63
  } from "@mastra/core/telemetry/otel-vendor";
64
64
  import { LangfuseExporter } from "langfuse-vercel";
65
65
 
@@ -69,7 +69,7 @@ export function register() {
69
69
  });
70
70
 
71
71
  const sdk = new NodeSDK({
72
- resource: new Resource({
72
+ resource: resourceFromAttributes({
73
73
  [ATTR_SERVICE_NAME]: "ai",
74
74
  }),
75
75
  traceExporter: exporter,
@@ -98,6 +98,47 @@ while (true) {
98
98
  }
99
99
  ```
100
100
 
101
+ ### Client tools
102
+
103
+ Client-side tools allow you to execute custom functions on the client side when the agent requests them.
104
+
105
+ #### Basic Usage
106
+
107
+ ```typescript
108
+ import { createTool } from '@mastra/core/tools';
109
+ import { z } from 'zod';
110
+
111
+ const colorChangeTool = createTool({
112
+ id: 'changeColor',
113
+ description: 'Changes the background color',
114
+ inputSchema: z.object({
115
+ color: z.string(),
116
+ }),
117
+ execute: async ({ context }) => {
118
+ document.body.style.backgroundColor = context.color;
119
+ return { success: true };
120
+ }
121
+ })
122
+
123
+
124
+ // Use with generate
125
+ const response = await agent.generate({
126
+ messages: 'Change the background to blue',
127
+ clientTools: {colorChangeTool},
128
+ });
129
+
130
+ // Use with stream
131
+ const response = await agent.stream({
132
+ messages: 'Change the background to green',
133
+ clientTools: {colorChangeTool},
134
+ });
135
+
136
+ response.processDataStream({
137
+ onTextPart: (text) => console.log(text),
138
+ onToolCallPart: (toolCall) => console.log('Tool called:', toolCall.toolName),
139
+ });
140
+ ```
141
+
101
142
  ### Get Agent Tool
102
143
 
103
144
  Retrieve information about a specific tool available to the agent: