@mastra/mcp-docs-server 1.1.46-alpha.2 → 1.1.46-alpha.4
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/agent-builder/browser.md +1 -1
- package/.docs/docs/agent-builder/channels.md +1 -1
- package/.docs/docs/agent-builder/integrations.md +73 -0
- package/.docs/docs/agent-builder/overview.md +1 -0
- package/.docs/docs/agents/adding-voice.md +1 -1
- package/.docs/docs/agents/agent-approval.md +2 -2
- package/.docs/docs/agents/background-tasks.md +1 -1
- package/.docs/docs/agents/channels.md +2 -2
- package/.docs/docs/agents/code-mode.md +20 -56
- package/.docs/docs/agents/overview.md +1 -0
- package/.docs/docs/agents/sdk-agents.md +165 -1
- package/.docs/docs/agents/supervisor-agents.md +40 -2
- package/.docs/docs/agents/using-tools.md +59 -1
- package/.docs/docs/browser/agent-browser.md +1 -1
- package/.docs/docs/browser/browser-viewer.md +22 -15
- package/.docs/docs/browser/overview.md +1 -1
- package/.docs/docs/browser/stagehand.md +1 -1
- package/.docs/docs/editor/overview.md +6 -6
- package/.docs/docs/editor/prompts.md +3 -3
- package/.docs/docs/editor/tools.md +2 -2
- package/.docs/docs/evals/evals-with-memory.md +8 -8
- package/.docs/docs/mastra-platform/observability.md +1 -1
- package/.docs/docs/mastra-platform/server.md +1 -1
- package/.docs/docs/mcp/mcp-apps.md +4 -4
- package/.docs/docs/memory/observational-memory.md +1 -1
- package/.docs/docs/memory/working-memory.md +2 -2
- package/.docs/docs/observability/integrations/bridges/datadog.md +1 -1
- package/.docs/docs/observability/integrations/bridges/otel.md +1 -1
- package/.docs/docs/observability/integrations/exporters/laminar.md +1 -1
- package/.docs/docs/observability/integrations/exporters/langfuse.md +26 -1
- package/.docs/docs/observability/integrations/exporters/mastra-platform.md +1 -1
- package/.docs/docs/observability/integrations/exporters/mastra-storage.md +4 -4
- package/.docs/docs/observability/integrations/exporters/otel.md +1 -1
- package/.docs/docs/observability/integrations/overview.md +1 -1
- package/.docs/docs/observability/logging.md +1 -1
- package/.docs/docs/observability/metrics/overview.md +3 -3
- package/.docs/docs/observability/metrics/querying.md +2 -2
- package/.docs/docs/observability/storage.md +2 -2
- package/.docs/docs/observability/tracing/overview.md +1 -1
- package/.docs/docs/server/auth/fga.md +15 -15
- package/.docs/docs/server/auth/okta.md +2 -2
- package/.docs/docs/server/auth/workos.md +1 -1
- package/.docs/docs/server/custom-api-routes.md +1 -1
- package/.docs/docs/server/pubsub.md +4 -4
- package/.docs/docs/studio/auth.md +1 -1
- package/.docs/docs/studio/observability.md +3 -1
- package/.docs/docs/workflows/scheduled-workflows.md +13 -13
- package/.docs/docs/workspace/filesystem.md +1 -1
- package/.docs/docs/workspace/lsp.md +1 -1
- package/.docs/docs/workspace/overview.md +35 -1
- package/.docs/docs/workspace/sandbox.md +4 -3
- package/.docs/guides/build-your-ui/ai-sdk-ui.md +2 -2
- package/.docs/guides/deployment/aws-bedrock-agentcore.md +3 -3
- package/.docs/guides/deployment/inngest.md +5 -5
- package/.docs/guides/deployment/temporal.md +3 -3
- package/.docs/guides/getting-started/nestjs.md +1 -1
- package/.docs/guides/migrations/mastra-cloud.md +3 -3
- package/.docs/guides/migrations/upgrade-to-v1/overview.md +1 -1
- package/.docs/guides/migrations/upgrade-to-v1/tracing.md +1 -1
- package/.docs/models/gateways/custom-gateways.md +57 -7
- package/.docs/reference/acp/acp-agent.md +2 -2
- package/.docs/reference/agents/agent.md +44 -0
- package/.docs/reference/agents/channels.md +1 -1
- package/.docs/reference/agents/durable-agent.md +2 -2
- package/.docs/reference/agents/generate.md +2 -0
- package/.docs/reference/agents/generateLegacy.md +2 -0
- package/.docs/reference/ai-sdk/handle-chat-stream.md +1 -1
- package/.docs/reference/ai-sdk/to-ai-sdk-stream.md +1 -1
- package/.docs/reference/auth/okta.md +1 -1
- package/.docs/reference/auth/workos.md +1 -1
- package/.docs/reference/browser/agent-browser.md +1 -1
- package/.docs/reference/browser/browser-viewer.md +11 -9
- package/.docs/reference/browser/stagehand-browser.md +1 -1
- package/.docs/reference/cli/mastra.md +3 -1
- package/.docs/reference/client-js/responses.md +2 -2
- package/.docs/reference/client-js/workflows.md +1 -1
- package/.docs/reference/configuration.md +1 -1
- package/.docs/reference/core/mastra-model-gateway.md +15 -1
- package/.docs/reference/core/removeWorkspace.md +26 -0
- package/.docs/reference/editor/browser-provider.md +1 -1
- package/.docs/reference/editor/storage-browser-ref.md +3 -3
- package/.docs/reference/editor/storage-workspace-ref.md +1 -1
- package/.docs/reference/evals/rubric.md +113 -0
- package/.docs/reference/evals/trajectory-accuracy.md +3 -3
- package/.docs/reference/harness/harness-class.md +81 -62
- package/.docs/reference/index.md +5 -0
- package/.docs/reference/memory/serialized-memory-config.md +1 -1
- package/.docs/reference/observability/metrics/automatic-metrics.md +3 -3
- package/.docs/reference/observability/tracing/bridges/datadog.md +1 -1
- package/.docs/reference/observability/tracing/exporters/cloud-exporter.md +3 -3
- package/.docs/reference/observability/tracing/exporters/default-exporter.md +1 -1
- package/.docs/reference/observability/tracing/exporters/mastra-platform-exporter.md +5 -5
- package/.docs/reference/observability/tracing/exporters/mastra-storage-exporter.md +1 -1
- package/.docs/reference/observability/tracing/exporters/otel.md +1 -1
- package/.docs/reference/observability/tracing/processors/sensitive-data-filter.md +2 -2
- package/.docs/reference/processors/cost-guard-processor.md +2 -2
- package/.docs/reference/processors/processor-interface.md +4 -4
- package/.docs/reference/processors/response-cache.md +2 -2
- package/.docs/reference/processors/skill-search-processor.md +3 -3
- package/.docs/reference/processors/tool-search-processor.md +108 -4
- package/.docs/reference/pubsub/base.md +1 -1
- package/.docs/reference/pubsub/caching-pubsub.md +2 -2
- package/.docs/reference/pubsub/event-emitter.md +3 -3
- package/.docs/reference/pubsub/google-cloud-pubsub.md +1 -1
- package/.docs/reference/pubsub/redis-streams.md +1 -1
- package/.docs/reference/pubsub/unix-socket-pubsub.md +1 -1
- package/.docs/reference/server/nestjs-adapter.md +2 -2
- package/.docs/reference/signals/task-signal-provider.md +62 -0
- package/.docs/reference/storage/clickhouse.md +49 -4
- package/.docs/reference/storage/composite.md +33 -1
- package/.docs/reference/storage/convex.md +2 -2
- package/.docs/reference/storage/dsql.md +7 -7
- package/.docs/reference/storage/duckdb.md +3 -3
- package/.docs/reference/storage/redis.md +3 -3
- package/.docs/reference/storage/spanner.md +7 -7
- package/.docs/reference/streaming/agents/stream.md +2 -0
- package/.docs/reference/streaming/agents/streamLegacy.md +2 -0
- package/.docs/reference/streaming/agents/streamUntilIdle.md +1 -1
- package/.docs/reference/tools/brightdata.md +3 -3
- package/.docs/reference/tools/create-code-mode.md +124 -0
- package/.docs/reference/tools/create-tool.md +1 -1
- package/.docs/reference/tools/mcp-client.md +5 -5
- package/.docs/reference/tools/mcp-server.md +45 -0
- package/.docs/reference/tools/perplexity.md +4 -4
- package/.docs/reference/tools/tavily.md +3 -3
- package/.docs/reference/voice/aws-nova-sonic.md +1 -1
- package/.docs/reference/voice/google-gemini-live.md +1 -1
- package/.docs/reference/voice/inworld-realtime.md +5 -5
- package/.docs/reference/voice/inworld.md +1 -1
- package/.docs/reference/voice/sarvam.md +1 -1
- package/.docs/reference/workspace/agentcore-runtime-sandbox.md +7 -7
- package/.docs/reference/workspace/azure-blob-filesystem.md +2 -2
- package/.docs/reference/workspace/files-sdk-filesystem.md +3 -3
- package/.docs/reference/workspace/google-drive-filesystem.md +7 -7
- package/.docs/reference/workspace/modal-sandbox.md +1 -1
- package/.docs/reference/workspace/railway-sandbox.md +230 -0
- package/.docs/reference/workspace/vercel-microvm-sandbox.md +1 -1
- package/.docs/reference/workspace/vercel.md +2 -2
- package/.docs/reference/workspace/workspace-class.md +39 -3
- package/CHANGELOG.md +17 -0
- package/dist/chunk-GLPCVXXO.js +2075 -0
- package/dist/chunk-GLPCVXXO.js.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/stdio.js +1 -2070
- package/dist/stdio.js.map +1 -1
- package/package.json +4 -4
|
@@ -46,7 +46,7 @@ new MastraEditor({
|
|
|
46
46
|
|
|
47
47
|
- `id` — provider identifier, matched against `StorageBrowserConfig.provider` (e.g., `'stagehand'`).
|
|
48
48
|
- `name` — display name shown in the Builder UI.
|
|
49
|
-
- `createBrowser(config)` — hydrates a stored browser config into a runtime `MastraBrowser`. This is where you inject runtime-only credentials (API keys, project IDs) that
|
|
49
|
+
- `createBrowser(config)` — hydrates a stored browser config into a runtime `MastraBrowser`. This is where you inject runtime-only credentials (API keys, project IDs) that aren't stored in the agent snapshot.
|
|
50
50
|
|
|
51
51
|
Browser classes ship as separate packages (e.g., `@mastra/stagehand`, `@mastra/agent-browser`). The provider entry is a plain object wrapping the class — register one entry per browser you want the Builder to expose to end users. See the [StorageBrowserRef reference](https://mastra.ai/reference/editor/storage-browser-ref) for the full `browser` field schema, including all `StorageBrowserConfig` options.
|
|
52
52
|
|
|
@@ -63,7 +63,7 @@ The Slack provider handles app creation, OAuth, slash commands, and message rout
|
|
|
63
63
|
|
|
64
64
|
`SlackProvider` requires one environment variable and accepts one optional override:
|
|
65
65
|
|
|
66
|
-
- `SLACK_APP_CONFIG_REFRESH_TOKEN` (required): the refresh token from your Slack app configuration tokens, available under **Your App Configuration Tokens** on [api.slack.com/apps](https://api.slack.com/apps). The refresh token
|
|
66
|
+
- `SLACK_APP_CONFIG_REFRESH_TOKEN` (required): the refresh token from your Slack app configuration tokens, available under **Your App Configuration Tokens** on [api.slack.com/apps](https://api.slack.com/apps). The refresh token doesn't expire, but the access tokens it issues rotate every 12 hours and are auto-persisted to `Mastra.storage`.
|
|
67
67
|
- `baseUrl` (optional): the public URL Slack should send events and OAuth callbacks to. Defaults to the running Mastra server's host and port (for example, `http://localhost:4111` in local development). Pass `baseUrl` explicitly when the public URL differs from the server's resolved address — typically a tunnel for local development (`cloudflared tunnel --url http://localhost:4111`) or a deployed URL in production.
|
|
68
68
|
|
|
69
69
|
## Storage requirement
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Tool providers
|
|
2
|
+
|
|
3
|
+
> **Note:** The Agent Builder is part of the Mastra Enterprise Edition. Production deployments require a valid EE license. [Contact sales](https://mastra.ai/contact) for more information.
|
|
4
|
+
|
|
5
|
+
Tool providers let Builder-created agents call tools from third-party apps such as Gmail, Slack, or GitHub. The Builder reuses the same tool providers as the editor, so any provider registered on `MastraEditor` is available in the Builder.
|
|
6
|
+
|
|
7
|
+
This page covers what's specific to the Builder: setting up connections, choosing a connection scope, and managing connections. To register a provider and enable its toolkits, see [Tools](https://mastra.ai/docs/editor/tools).
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
Before agents can use integration tools in the Builder:
|
|
12
|
+
|
|
13
|
+
- Register a tool provider on the `toolProviders` map of `MastraEditor` (see below).
|
|
14
|
+
- Set up a Composio auth config for each toolkit you want to use (see below).
|
|
15
|
+
- Configure a storage adapter on the `Mastra` instance. Connection state persists through `Mastra.storage`.
|
|
16
|
+
|
|
17
|
+
## Register a tool provider
|
|
18
|
+
|
|
19
|
+
The Builder reuses the editor's tool providers. Register each provider you want to expose on the `toolProviders` map of `MastraEditor`. Mastra ships providers for [Composio](https://composio.dev) and [Arcade](https://arcade.dev); add a provider by giving it a key and an instance.
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { Mastra } from '@mastra/core'
|
|
23
|
+
import { MastraEditor } from '@mastra/editor'
|
|
24
|
+
import { ComposioToolProvider } from '@mastra/editor/composio'
|
|
25
|
+
|
|
26
|
+
export const mastra = new Mastra({
|
|
27
|
+
agents: {
|
|
28
|
+
/* your agents */
|
|
29
|
+
},
|
|
30
|
+
editor: new MastraEditor({
|
|
31
|
+
toolProviders: {
|
|
32
|
+
composio: new ComposioToolProvider({
|
|
33
|
+
apiKey: process.env.COMPOSIO_API_KEY!,
|
|
34
|
+
allowedToolkits: ['gmail', 'googlecalendar'],
|
|
35
|
+
}),
|
|
36
|
+
},
|
|
37
|
+
}),
|
|
38
|
+
})
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Each provider's toolkits become available in the Builder once it is registered. Use `allowedToolkits` to restrict which toolkits the provider exposes — by slug, such as `gmail` or `googlecalendar`. Omit it to expose every toolkit the provider offers. To add another provider, import it and add another entry to `toolProviders`. For the full list of providers and their options, see [Tools — Integration providers](https://mastra.ai/docs/editor/tools).
|
|
42
|
+
|
|
43
|
+
## Set up a Composio auth config
|
|
44
|
+
|
|
45
|
+
Each toolkit a user can connect needs its own auth config in the [Composio dashboard](https://dashboard.composio.dev). An auth config defines how Composio authenticates with an app — its OAuth client, scopes, and credentials. Each toolkit needs its own because requirements vary by app: some share common OAuth methods, while others need extra setup. Without an enabled config, the connection flow fails.
|
|
46
|
+
|
|
47
|
+
1. Open the [Composio dashboard](https://dashboard.composio.dev) and select the toolkit you want to enable, for example **Gmail** or **GitHub**.
|
|
48
|
+
2. Create an auth config for the toolkit and complete the app-specific setup. Composio's [auth config docs](https://docs.composio.dev/docs/authenticating-tools) cover the fields each app requires.
|
|
49
|
+
3. Enable the auth config.
|
|
50
|
+
|
|
51
|
+
Keep exactly one auth config enabled per toolkit. When a user connects the toolkit, the provider resolves the single enabled config for that toolkit and starts the OAuth flow against it.
|
|
52
|
+
|
|
53
|
+
> **Warning:** The provider throws if a toolkit has zero enabled auth configs or more than one. Enable exactly one auth config per toolkit you expose in the Builder.
|
|
54
|
+
|
|
55
|
+
## Connect a toolkit
|
|
56
|
+
|
|
57
|
+
Once a provider is registered and its auth config is enabled, the toolkit can be connected from the Builder:
|
|
58
|
+
|
|
59
|
+
1. Open the agent and add the toolkit's tools.
|
|
60
|
+
2. Click **Connect** on the toolkit and complete the OAuth flow for the account you want to use.
|
|
61
|
+
|
|
62
|
+
The connected account is bound to the agent, and its tools are ready to use on the next run.
|
|
63
|
+
|
|
64
|
+
## Connection scope
|
|
65
|
+
|
|
66
|
+
When you select a toolkit's tools for an agent, you also pin a connection. The connection determines which account each tool call uses at runtime, with a scope that controls who shares the credential. Today connections are `per-author`: the connection belongs to the agent's author, and any invoker runs the agent with the author's account.
|
|
67
|
+
|
|
68
|
+
## Related
|
|
69
|
+
|
|
70
|
+
- [Tools](https://mastra.ai/docs/editor/tools): Register providers and browse toolkits in the editor.
|
|
71
|
+
- [ToolProvider reference](https://mastra.ai/reference/editor/tool-provider): Provider API details.
|
|
72
|
+
- [Agent Builder API reference](https://mastra.ai/reference/client-js/agent-builder): Manage connections programmatically with the `@mastra/client-js` SDK.
|
|
73
|
+
- [Agent Builder overview](https://mastra.ai/docs/agent-builder/overview)
|
|
@@ -9,6 +9,7 @@ The Agent Builder lets you build, configure, and operate Mastra agents all withi
|
|
|
9
9
|
- [**Memory**](https://mastra.ai/docs/agent-builder/memory): Configure the default memory shape for every Builder-created agent.
|
|
10
10
|
- [**Access control**](https://mastra.ai/docs/agent-builder/access-control): Gate the Builder behind Mastra RBAC roles and permissions.
|
|
11
11
|
- [**Channels**](https://mastra.ai/docs/agent-builder/channels): Connect Builder-created agents to Slack and other channels.
|
|
12
|
+
- [**Tool providers**](https://mastra.ai/docs/agent-builder/integrations): Connect Builder-created agents to third-party apps through OAuth-backed tool providers.
|
|
12
13
|
- [**Skill registries**](https://mastra.ai/docs/agent-builder/skill-registries): Browse and install community skills from opt-in registries.
|
|
13
14
|
- [**Deploying**](https://mastra.ai/docs/agent-builder/deploying): Swap local primitives for cloud-backed storage, filesystems, and sandboxes.
|
|
14
15
|
|
|
@@ -158,7 +158,7 @@ await voice.connect()
|
|
|
158
158
|
When you use a resolver:
|
|
159
159
|
|
|
160
160
|
- Each call to `getVoice()` returns a new instance, so concurrent sessions never share state.
|
|
161
|
-
- Mastra
|
|
161
|
+
- Mastra doesn't add tools or instructions to a resolver instance. Configure those inside the resolver or on the provider.
|
|
162
162
|
- You own the lifecycle of the returned instance, so call `disconnect()` or `close()` when the session ends.
|
|
163
163
|
|
|
164
164
|
The `agent.voice` getter has no request context, so it throws when `voice` is a resolver. Use `agent.getVoice({ requestContext })` instead.
|
|
@@ -96,7 +96,7 @@ const stream = await agent.stream('Clean up old records', {
|
|
|
96
96
|
})
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
A tool's own `requireApproval` setting still takes precedence: if a tool defines its own approval rule, that rule decides for that tool and the function above
|
|
99
|
+
A tool's own `requireApproval` setting still takes precedence: if a tool defines its own approval rule, that rule decides for that tool and the function above doesn't override it. If the function throws, the call requires approval (fail-safe).
|
|
100
100
|
|
|
101
101
|
> **Note:** Function-based `requireToolApproval` is only available on regular `stream()` / `generate()` calls. Durable agents and stored agents persist their options, and a function can't be serialized, so they accept only a boolean. If you pass a function in those contexts it falls back to requiring approval for every tool call.
|
|
102
102
|
|
|
@@ -106,7 +106,7 @@ A tool can also pause _during_ its `execute` function by calling `suspend()`. Th
|
|
|
106
106
|
|
|
107
107
|
The stream emits a `tool-call-suspended` chunk with a custom payload defined by the tool's `suspendSchema`. You resume by calling `resumeStream()` with data matching the tool's `resumeSchema`.
|
|
108
108
|
|
|
109
|
-
> **Note:** `suspend()`
|
|
109
|
+
> **Note:** `suspend()` doesn't throw — return immediately after calling it (e.g. `return await suspend({ ... })`). Code after `await suspend(...)` still runs before the tool pauses.
|
|
110
110
|
|
|
111
111
|
## Tool approval with `generate()`
|
|
112
112
|
|
|
@@ -104,7 +104,7 @@ When a tool is registered on an agent that has background tasks enabled, the mod
|
|
|
104
104
|
}
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
The `_background` override is a _modifier_ on tools the developer has already opted in at the tool or agent layer — it
|
|
107
|
+
The `_background` override is a _modifier_ on tools the developer has already opted in at the tool or agent layer — it's not a standalone opt-in. If a tool hasn't been opted in, `_background.enabled: true` from the model is ignored and the tool runs in the foreground. This keeps deterministic, foreground-only tools (calculators, lookups, schema validators) from being silently dispatched as tasks.
|
|
108
108
|
|
|
109
109
|
### Resolution order
|
|
110
110
|
|
|
@@ -84,7 +84,7 @@ When a user mentions the agent mid-conversation in a channel thread, the agent m
|
|
|
84
84
|
1. On the **first mention** in a thread, the agent fetches recent messages from the platform.
|
|
85
85
|
2. These messages are prepended to the user's message as conversation context.
|
|
86
86
|
3. After responding, the agent subscribes to the thread and has full history via Mastra's memory.
|
|
87
|
-
4. Subsequent messages in that thread
|
|
87
|
+
4. Subsequent messages in that thread **don't** re-fetch from the platform.
|
|
88
88
|
|
|
89
89
|
Set `threadContext: { maxMessages: 0 }` to disable this behavior. This only applies to non-DM threads.
|
|
90
90
|
|
|
@@ -114,7 +114,7 @@ const deleteFile = createTool({
|
|
|
114
114
|
|
|
115
115
|
When the agent calls this tool, users see a card with the tool name, arguments, and Approve/Deny buttons. The tool only executes after approval.
|
|
116
116
|
|
|
117
|
-
Set `toolDisplay: 'text'` on an adapter to render tool calls as plain text instead of interactive cards. In `'hidden'` mode the agent uses `autoResumeSuspendedTools` to let the LLM decide based on the conversation context, since hidden mode
|
|
117
|
+
Set `toolDisplay: 'text'` on an adapter to render tool calls as plain text instead of interactive cards. In `'hidden'` mode the agent uses `autoResumeSuspendedTools` to let the LLM decide based on the conversation context, since hidden mode doesn't post approval buttons.
|
|
118
118
|
|
|
119
119
|
## Multi-user awareness
|
|
120
120
|
|
|
@@ -4,27 +4,30 @@
|
|
|
4
4
|
|
|
5
5
|
> **Alpha:** This feature is in alpha. Breaking changes may occur without a major version bump until the API is stable.
|
|
6
6
|
|
|
7
|
-
Code mode
|
|
7
|
+
Code mode lets an agent run multi-tool computations in an isolated sandbox and return the result as a single, more accurate response. Instead of calling tools one turn at a time, the model writes a tailored function for the user query that orchestrates your existing tools as `external_*` functions, reduces or aggregates their results, and returns one structured answer.
|
|
8
8
|
|
|
9
|
-
`createCodeMode` returns this tool with the default id `execute_typescript`. The id is configurable, so an agent can have several code mode tools at once, each scoped to a different set of tools (see [Scoping tools across multiple code tools](#scoping-tools-across-multiple-code-tools)).
|
|
9
|
+
[`createCodeMode()`](https://mastra.ai/reference/tools/create-code-mode) returns this tool with the default `id` of `execute_typescript`. The `id` is configurable, so an agent can have several code mode tools at once, each scoped to a different set of tools (see [Scoping tools across multiple code tools](#scoping-tools-across-multiple-code-tools)).
|
|
10
10
|
|
|
11
11
|
## When to use code mode
|
|
12
12
|
|
|
13
|
-
Use code mode when
|
|
13
|
+
Use code mode when an agent touches multiple tools to answer a user query or perform a complex computation:
|
|
14
14
|
|
|
15
|
-
- Fewer round-trips:
|
|
16
|
-
-
|
|
17
|
-
-
|
|
15
|
+
- Fewer round-trips: A multi-tool query runs in one tool call instead of repeating the agentic loop for every tool decision.
|
|
16
|
+
- Smaller context: The function can reduce or aggregate large tool responses before returning them to the agent.
|
|
17
|
+
- Correct math: Sums, averages, and other arithmetic run as JavaScript, not as token prediction.
|
|
18
|
+
- Planning up front: Filtering, aggregation, and branching happen inside the function rather than across separate turns.
|
|
18
19
|
|
|
19
20
|
## How it works
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
Without code mode, multi-tool queries can run the agentic loop several times: the model chooses a tool, reads the result, chooses again, and repeats. Each turn adds the full tool response to the agent's context window which can lead to poorer reasoning and increased token usage.
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
With code mode, your tools keep running on the host with full validation, request context, and tracing. Only the model's orchestration code runs in the sandbox. Each `external_*` call is bridged back to the real tool on the host, and the function can reduce or aggregate results before returning one response to the agent.
|
|
25
|
+
|
|
26
|
+
The function runs in a [Workspace sandbox](https://mastra.ai/docs/workspace/overview). A sandbox is required, because code mode runs model-authored code and the execution boundary must be chosen deliberately. Pass one via `sandbox`, or run the agent in a workspace that provides one. To execute on the host machine, pass `new LocalSandbox()` explicitly. This runs the function as a host `node` process with host privileges, so only use it for trusted or local development.
|
|
24
27
|
|
|
25
28
|
## Quickstart
|
|
26
29
|
|
|
27
|
-
`createCodeMode` returns the tool plus generated instructions. With no `id`, the tool is named `execute_typescript`. Add both to your agent:
|
|
30
|
+
`createCodeMode()` returns the tool plus generated instructions. With no `id`, the tool is named `execute_typescript`. Add both to your agent:
|
|
28
31
|
|
|
29
32
|
```typescript
|
|
30
33
|
import { Agent } from '@mastra/core/agent'
|
|
@@ -83,52 +86,18 @@ return top.products.map((product, i) => {
|
|
|
83
86
|
|
|
84
87
|
All five rating lookups run in parallel, the averages are computed in JavaScript, and the agent receives one structured result.
|
|
85
88
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
const { tool, instructions } = createCodeMode({
|
|
90
|
-
tools: { getTopProducts, getProductRatings }, // exposed as external_*; only these can be called
|
|
91
|
-
sandbox, // required WorkspaceSandbox, unless the agent runs in a workspace that provides one
|
|
92
|
-
timeout: 30_000, // optional execution timeout in ms (default 30000)
|
|
93
|
-
id: 'execute_typescript', // optional tool id (default "execute_typescript")
|
|
94
|
-
})
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
| Option | Type | Description |
|
|
98
|
-
| --------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
99
|
-
| `tools` | `ToolsInput` | Tools exposed to the program as `external_<id>`. Only these may be called. |
|
|
100
|
-
| `sandbox` | `WorkspaceSandbox` | Sandbox to run the program in. Required unless the agent runs in a workspace that provides one. Pass `new LocalSandbox()` to run on the host. |
|
|
101
|
-
| `timeout` | `number` | Execution timeout in milliseconds. Default `30000`. |
|
|
102
|
-
| `id` | `string` | The generated tool's id. Default `execute_typescript`. |
|
|
103
|
-
|
|
104
|
-
## Result
|
|
105
|
-
|
|
106
|
-
The tool returns a `CodeModeToolResult`:
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
type CodeModeToolResult = {
|
|
110
|
-
success: boolean
|
|
111
|
-
result?: unknown // value returned by the program
|
|
112
|
-
logs?: string[] // captured console output
|
|
113
|
-
error?: { message: string; name?: string; line?: number }
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## Inspecting the instructions
|
|
89
|
+
For `createCodeMode()` to work well, keep these tips in mind:
|
|
118
90
|
|
|
119
|
-
|
|
91
|
+
- Keep tools focused, so each does one thing well and the model composes them in code.
|
|
92
|
+
- Code mode helps most when calls can be parallelized with `Promise.all`.
|
|
120
93
|
|
|
121
|
-
|
|
122
|
-
import { createCodeModeInstructions } from '@mastra/core/tools'
|
|
123
|
-
|
|
124
|
-
console.log(createCodeModeInstructions({ tools: { getTopProducts, getProductRatings } }))
|
|
125
|
-
```
|
|
94
|
+
> **Note:** Visit the [`createCodeMode()` reference](https://mastra.ai/reference/tools/create-code-mode) for configuration options, return values, result shape, and instructions inspection.
|
|
126
95
|
|
|
127
96
|
## Scoping tools across multiple code tools
|
|
128
97
|
|
|
129
|
-
`createCodeMode` captures its own allow-list. Call it more than once to give an agent several code tools, each scoped to a different subset of tools.
|
|
98
|
+
`createCodeMode()` captures its own allow-list. Call it more than once to give an agent several code tools, each scoped to a different subset of tools. It can only call the `external_*` functions for the tools passed to its own `createCodeMode()` call, so the subsets stay isolated.
|
|
130
99
|
|
|
131
|
-
Give each tool a distinct `id` so their ids
|
|
100
|
+
Give each tool a distinct `id` so their ids don't collide, and add each tool's instructions to the agent:
|
|
132
101
|
|
|
133
102
|
```typescript
|
|
134
103
|
const sales = createCodeMode({
|
|
@@ -151,15 +120,10 @@ const agent = new Agent({
|
|
|
151
120
|
})
|
|
152
121
|
```
|
|
153
122
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
## Tips
|
|
157
|
-
|
|
158
|
-
- Keep tools focused, so each does one thing well and the model composes them in code.
|
|
159
|
-
- Code mode helps most when calls can be parallelized with `Promise.all`.
|
|
160
|
-
- Use `console.log` for debugging. Logs are captured in the result.
|
|
123
|
+
The generated code for `sales_code` can't call an inventory tool, and the reverse holds too. Use this for least-privilege scoping and to keep each tool's prompt surface small.
|
|
161
124
|
|
|
162
125
|
## Related
|
|
163
126
|
|
|
127
|
+
- [createCodeMode() reference](https://mastra.ai/reference/tools/create-code-mode)
|
|
164
128
|
- [Tools](https://mastra.ai/docs/agents/using-tools)
|
|
165
129
|
- [Workspace overview](https://mastra.ai/docs/workspace/overview)
|
|
@@ -89,6 +89,7 @@ Once your agent is running, use this table to find the right page for what you w
|
|
|
89
89
|
| Register subagents | [Tools](https://mastra.ai/docs/agents/using-tools) |
|
|
90
90
|
| Intercept or transform messages before and after generation | [Processors](https://mastra.ai/docs/agents/processors) |
|
|
91
91
|
| Keep your agent safe | [Guardrails](https://mastra.ai/docs/agents/guardrails) |
|
|
92
|
+
| Build agents that correct their work | [Rubric scorer](https://mastra.ai/docs/agents/supervisor-agents) |
|
|
92
93
|
| Swap instructions or models based on request context | [Dynamic configuration](https://mastra.ai/docs/server/request-context) |
|
|
93
94
|
| Add speech-to-text or text-to-speech | [Voice](https://mastra.ai/docs/agents/adding-voice) |
|
|
94
95
|
| Connect to Slack, Discord, or Telegram | [Channels](https://mastra.ai/docs/agents/channels) |
|
|
@@ -13,6 +13,7 @@ SDK agents let you use other agent SDK frameworks inside Mastra. Use them to reg
|
|
|
13
13
|
|
|
14
14
|
- [Claude Agent SDK](#claude-agent-sdk): Use `@mastra/claude` to register a Claude SDK agent and call it with Mastra `generate()` and `stream()`.
|
|
15
15
|
- [Cursor Agent SDK](#cursor-agent-sdk): Use `@mastra/cursor` to register a Cursor SDK agent and call it with Mastra `generate()` and `stream()`.
|
|
16
|
+
- [OpenAI Agents SDK](#openai-agents-sdk): Use `@mastra/openai` to register an OpenAI SDK agent and call it with Mastra `generate()` and `stream()`.
|
|
16
17
|
|
|
17
18
|
## Claude Agent SDK
|
|
18
19
|
|
|
@@ -216,6 +217,117 @@ export const cursorSDKAgent = new CursorSDKAgent({
|
|
|
216
217
|
})
|
|
217
218
|
```
|
|
218
219
|
|
|
220
|
+
## OpenAI Agents SDK
|
|
221
|
+
|
|
222
|
+
Use `@mastra/openai` to register an OpenAI Agents SDK agent in Mastra while keeping OpenAI-specific agent settings in OpenAI SDK options.
|
|
223
|
+
|
|
224
|
+
### Install OpenAI packages
|
|
225
|
+
|
|
226
|
+
Install the Mastra package and the OpenAI Agents SDK peer dependency:
|
|
227
|
+
|
|
228
|
+
**npm**:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
npm install @mastra/openai @openai/agents zod
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**pnpm**:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
pnpm add @mastra/openai @openai/agents zod
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Yarn**:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
yarn add @mastra/openai @openai/agents zod
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Bun**:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
bun add @mastra/openai @openai/agents zod
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Set the OpenAI SDK credential:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
export OPENAI_API_KEY="..."
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Create an OpenAI SDK agent
|
|
259
|
+
|
|
260
|
+
Configure OpenAI Agents SDK through `sdkOptions`. `OpenAISDKAgent` creates the OpenAI SDK agent on first use.
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
import { OpenAISDKAgent } from '@mastra/openai'
|
|
264
|
+
|
|
265
|
+
export const openaiSDKAgent = new OpenAISDKAgent({
|
|
266
|
+
id: 'openai-sdk-agent',
|
|
267
|
+
name: 'OpenAI SDK Agent',
|
|
268
|
+
description: 'Use OpenAI Agents SDK through Mastra.',
|
|
269
|
+
sdkOptions: {
|
|
270
|
+
name: 'Repository assistant',
|
|
271
|
+
instructions: 'Answer clearly and cite the relevant files.',
|
|
272
|
+
model: 'gpt-5',
|
|
273
|
+
},
|
|
274
|
+
})
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Use an existing OpenAI SDK agent
|
|
278
|
+
|
|
279
|
+
If your app already creates an OpenAI SDK agent, pass that agent to `OpenAISDKAgent` instead:
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import { Agent as OpenAIAgent } from '@openai/agents'
|
|
283
|
+
import { OpenAISDKAgent } from '@mastra/openai'
|
|
284
|
+
|
|
285
|
+
const sdkAgent = new OpenAIAgent({
|
|
286
|
+
name: 'Repository assistant',
|
|
287
|
+
instructions: 'Answer clearly and cite the relevant files.',
|
|
288
|
+
model: 'gpt-5',
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
export const openaiSDKAgent = new OpenAISDKAgent({
|
|
292
|
+
id: 'openai-sdk-agent',
|
|
293
|
+
name: 'OpenAI SDK Agent',
|
|
294
|
+
description: 'Use OpenAI Agents SDK through Mastra.',
|
|
295
|
+
agent: sdkAgent,
|
|
296
|
+
})
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Add OpenAI SDK tools
|
|
300
|
+
|
|
301
|
+
OpenAI Agents SDK tools are configured with OpenAI SDK options. Create tools with the OpenAI SDK, then pass them through `sdkOptions.tools`.
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
import { tool } from '@openai/agents'
|
|
305
|
+
import { OpenAISDKAgent } from '@mastra/openai'
|
|
306
|
+
import { z } from 'zod'
|
|
307
|
+
|
|
308
|
+
const getTemperature = tool({
|
|
309
|
+
name: 'get_temperature',
|
|
310
|
+
description: 'Get the current temperature for a city.',
|
|
311
|
+
parameters: z.object({
|
|
312
|
+
city: z.string(),
|
|
313
|
+
}),
|
|
314
|
+
execute: async ({ city }) => {
|
|
315
|
+
return `${city}: 27 C`
|
|
316
|
+
},
|
|
317
|
+
})
|
|
318
|
+
|
|
319
|
+
export const openaiSDKAgent = new OpenAISDKAgent({
|
|
320
|
+
id: 'openai-sdk-agent',
|
|
321
|
+
name: 'OpenAI SDK Agent',
|
|
322
|
+
description: 'Use OpenAI Agents SDK through Mastra.',
|
|
323
|
+
sdkOptions: {
|
|
324
|
+
name: 'Weather assistant',
|
|
325
|
+
model: 'gpt-5',
|
|
326
|
+
tools: [getTemperature],
|
|
327
|
+
},
|
|
328
|
+
})
|
|
329
|
+
```
|
|
330
|
+
|
|
219
331
|
## Register SDK agents
|
|
220
332
|
|
|
221
333
|
Register SDK agents in the Mastra instance like other agents:
|
|
@@ -224,11 +336,13 @@ Register SDK agents in the Mastra instance like other agents:
|
|
|
224
336
|
import { Mastra } from '@mastra/core'
|
|
225
337
|
import { claudeSDKAgent } from './agents/claude-sdk-agent'
|
|
226
338
|
import { cursorSDKAgent } from './agents/cursor-sdk-agent'
|
|
339
|
+
import { openaiSDKAgent } from './agents/openai-sdk-agent'
|
|
227
340
|
|
|
228
341
|
export const mastra = new Mastra({
|
|
229
342
|
agents: {
|
|
230
343
|
claudeSDKAgent,
|
|
231
344
|
cursorSDKAgent,
|
|
345
|
+
openaiSDKAgent,
|
|
232
346
|
},
|
|
233
347
|
})
|
|
234
348
|
```
|
|
@@ -246,11 +360,61 @@ for await (const chunk of stream.textStream) {
|
|
|
246
360
|
}
|
|
247
361
|
```
|
|
248
362
|
|
|
363
|
+
## Resume SDK runs
|
|
364
|
+
|
|
365
|
+
SDK agents support Mastra `resumeGenerate()` and `resumeStream()` with provider-native resume data. Pass the message to continue with and the resume identifier used by the underlying SDK.
|
|
366
|
+
|
|
367
|
+
Claude SDK agents can resume a known session with `sessionId`:
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
const result = await claudeSDKAgent.resumeGenerate({
|
|
371
|
+
message: 'Continue the previous task.',
|
|
372
|
+
sessionId: 'claude-session-id',
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
console.log(result.text)
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
OpenAI SDK agents can resume with a previous response, conversation, or session:
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
const stream = await openaiSDKAgent.resumeStream({
|
|
382
|
+
message: 'Continue the previous task.',
|
|
383
|
+
previousResponseId: 'resp_123',
|
|
384
|
+
})
|
|
385
|
+
|
|
386
|
+
for await (const chunk of stream.textStream) {
|
|
387
|
+
process.stdout.write(chunk)
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Cursor SDK agents can continue with the wrapped SDK agent. If you need to resume a stored Cursor SDK agent by ID, pass `agentId` in `resumeData`.
|
|
392
|
+
|
|
393
|
+
## Structured output
|
|
394
|
+
|
|
395
|
+
Claude and OpenAI SDK agents support Mastra `structuredOutput` through their provider-native structured output APIs. The validated value is available on `result.object`.
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
import { z } from 'zod'
|
|
399
|
+
|
|
400
|
+
const result = await openaiSDKAgent.generate<{ summary: string }>('Summarize this project.', {
|
|
401
|
+
structuredOutput: {
|
|
402
|
+
schema: z.object({
|
|
403
|
+
summary: z.string(),
|
|
404
|
+
}),
|
|
405
|
+
},
|
|
406
|
+
})
|
|
407
|
+
|
|
408
|
+
console.log(result.object.summary)
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
Cursor SDK agents throw a clear error when `structuredOutput` is requested because the Cursor TypeScript SDK doesn't expose a schema-constrained output API.
|
|
412
|
+
|
|
249
413
|
## Observability
|
|
250
414
|
|
|
251
415
|
SDK agents create Mastra agent and model spans for `generate()` and `stream()` calls. Mastra records SDK-provided usage, tool activity, and provider metadata when the vendor SDK exposes those events.
|
|
252
416
|
|
|
253
|
-
Claude SDK runs can include SDK-estimated cost from the Claude result message. Cursor SDK runs include token usage from Cursor interaction updates.
|
|
417
|
+
Claude SDK runs can include SDK-estimated cost from the Claude result message. Cursor SDK runs include token usage from Cursor interaction updates. OpenAI SDK runs include token usage from OpenAI run state.
|
|
254
418
|
|
|
255
419
|
For storage and dashboard setup, see [Observability](https://mastra.ai/docs/observability/overview).
|
|
256
420
|
|
|
@@ -169,7 +169,7 @@ The callback receives `messages` (the full conversation history), `primitiveId`
|
|
|
169
169
|
|
|
170
170
|
## Subagent result context
|
|
171
171
|
|
|
172
|
-
When a subagent completes, the supervisor model receives the subagent's text response in later iterations. Nested tool calls and subagent metadata, such as thread and resource IDs,
|
|
172
|
+
When a subagent completes, the supervisor model receives the subagent's text response in later iterations. Nested tool calls and subagent metadata, such as thread and resource IDs, aren't added to the supervisor model context.
|
|
173
173
|
|
|
174
174
|
Application code and UI integrations can still inspect the raw delegation result, including `subAgentToolResults`, from the tool result payload. This keeps debugging and display data available without sending nested tool arguments or outputs back into the supervisor's next model call.
|
|
175
175
|
|
|
@@ -263,7 +263,7 @@ for await (const chunk of stream.fullStream) {
|
|
|
263
263
|
|
|
264
264
|
## Task completion scoring
|
|
265
265
|
|
|
266
|
-
Task completion scorers
|
|
266
|
+
Agents don't always produce a complete, correct output on the first try. Task completion scorers can help with that by validating whether the task is complete after each iteration. If validation fails, the supervisor continues iterating. Feedback from failed scorers is included in the conversation context so subagents can see what was missing.
|
|
267
267
|
|
|
268
268
|
```typescript
|
|
269
269
|
import { createScorer } from '@mastra/core/evals'
|
|
@@ -290,6 +290,44 @@ const stream = await supervisor.stream('Research AI in education', {
|
|
|
290
290
|
})
|
|
291
291
|
```
|
|
292
292
|
|
|
293
|
+
### Rubric scorer
|
|
294
|
+
|
|
295
|
+
The built-in rubric scorer lets you define what "correct" looks like as a checklist and have the agent self-evaluate and iterate until every criterion is satisfied or `maxSteps` is reached.
|
|
296
|
+
|
|
297
|
+
It works as an **LLM-as-judge** scorer: a separate grader model reviews the agent's output against the rubric after each iteration. If every required criterion passes, the loop ends. If anything falls short, per-criterion feedback is injected back into the conversation and the agent tries again.
|
|
298
|
+
|
|
299
|
+
This is most effective for tasks with clear, verifiable success criteria. You can use it like so:
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
import { Agent } from '@mastra/core/agent'
|
|
303
|
+
import { createRubricScorer } from '@mastra/evals/scorers/prebuilt'
|
|
304
|
+
|
|
305
|
+
const supervisor = new Agent({
|
|
306
|
+
id: 'supervisor',
|
|
307
|
+
instructions: 'You coordinate research and writing using specialized agents.',
|
|
308
|
+
model: 'openai/gpt-5.5',
|
|
309
|
+
agents: { researchAgent, writingAgent },
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
const rubricScorer = createRubricScorer({
|
|
313
|
+
model: 'openai/gpt-5-mini',
|
|
314
|
+
criteria: [
|
|
315
|
+
{ description: 'The response includes an analysis section' },
|
|
316
|
+
{ description: 'The response includes concrete recommendations' },
|
|
317
|
+
],
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
const stream = await supervisor.stream('Research AI in education', {
|
|
321
|
+
maxSteps: 10,
|
|
322
|
+
isTaskComplete: {
|
|
323
|
+
scorers: [rubricScorer],
|
|
324
|
+
strategy: 'all',
|
|
325
|
+
},
|
|
326
|
+
})
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
For full API details, see the [rubric scorer reference](https://mastra.ai/reference/evals/rubric).
|
|
330
|
+
|
|
293
331
|
## Writing effective instructions
|
|
294
332
|
|
|
295
333
|
Clear instructions are essential for effective delegation. Your supervisor's `instructions` should specify available resources, when to use each one, how to coordinate them, and success criteria.
|
|
@@ -228,10 +228,68 @@ export const weatherTool = createTool({
|
|
|
228
228
|
|
|
229
229
|
Use `transform` when a tool returns raw data your application needs, but browser-facing streams or user-visible transcript messages should receive a smaller or safer shape. `transform` is separate from `toModelOutput`: `toModelOutput` shapes the payload sent back to the model, while `transform` shapes tool input, output, errors, approval payloads, and suspension payloads for `display` and `transcript` targets.
|
|
230
230
|
|
|
231
|
-
If a transform is configured and it fails, Mastra
|
|
231
|
+
If a transform is configured and it fails, Mastra doesn't fall back to the raw payload for display or transcript targets. Input deltas are suppressed when no safe `inputDelta` transform is available.
|
|
232
232
|
|
|
233
233
|
See the [`createTool()` reference](https://mastra.ai/reference/tools/create-tool) for a `transform` example. For shared rules across several tools, configure the agent-level `transform` policy in the [`Agent` constructor](https://mastra.ai/reference/agents/agent).
|
|
234
234
|
|
|
235
|
+
## Run logic around tool calls
|
|
236
|
+
|
|
237
|
+
Use `hooks` to run custom logic before and after every tool call an agent makes. Hooks apply to all tool sources: assigned tools, memory tools, toolsets, client tools, agent and workflow tools, and [workspace tools](https://mastra.ai/docs/workspace/overview). Common uses include logging, auditing, input validation, and blocking specific calls.
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { Agent } from '@mastra/core/agent'
|
|
241
|
+
|
|
242
|
+
export const supportAgent = new Agent({
|
|
243
|
+
name: 'support-agent',
|
|
244
|
+
instructions: 'Help users with their questions.',
|
|
245
|
+
model: 'openai/gpt-5.5',
|
|
246
|
+
hooks: {
|
|
247
|
+
beforeToolCall: ({ toolName, input }) => {
|
|
248
|
+
console.log(`Running ${toolName}`, input)
|
|
249
|
+
},
|
|
250
|
+
afterToolCall: ({ toolName, output, error }) => {
|
|
251
|
+
console.log(`Finished ${toolName}`, { output, error })
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
})
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
`beforeToolCall` runs before the tool executes and receives the tool name, input, and execution context. Return `{ proceed: false, output }` to skip the tool call entirely — the agent receives `output` as the tool result:
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
const guardedAgent = new Agent({
|
|
261
|
+
name: 'guarded-agent',
|
|
262
|
+
instructions: 'Run shell commands for the user.',
|
|
263
|
+
model: 'openai/gpt-5.5',
|
|
264
|
+
hooks: {
|
|
265
|
+
beforeToolCall: ({ toolName, input }) => {
|
|
266
|
+
const command = (input as { command?: string }).command ?? ''
|
|
267
|
+
if (toolName === 'execute_command' && command.includes('rm -rf')) {
|
|
268
|
+
return { proceed: false, output: 'Command blocked by policy.' }
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
})
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
`afterToolCall` runs after the tool finishes, whether it succeeded or failed. On success it receives `output`; if the tool threw, it receives `error` instead and the error is re-thrown after the hook runs.
|
|
276
|
+
|
|
277
|
+
### Per-execution hooks
|
|
278
|
+
|
|
279
|
+
Pass `hooks` to `.generate()` or `.stream()` to set hooks for a single execution. Per-execution hooks override matching agent-level hooks:
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
await supportAgent.generate('Look up the order status', {
|
|
283
|
+
hooks: {
|
|
284
|
+
beforeToolCall: ({ toolName }) => {
|
|
285
|
+
console.log(`This run only: ${toolName}`)
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
})
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Agent-level and per-execution hooks merge per key: passing only `beforeToolCall` at execution time keeps the agent-level `afterToolCall`.
|
|
292
|
+
|
|
235
293
|
## Control tool selection
|
|
236
294
|
|
|
237
295
|
Pass `toolChoice` or `activeTools` to `.generate()` or `.stream()` to control which tools the agent uses at runtime.
|
|
@@ -71,7 +71,7 @@ When the agent uses the `browser_screenshot` tool, it captures a PNG image of th
|
|
|
71
71
|
|
|
72
72
|
Use screenshots when you need to visually inspect the page — for example, evaluating images, layout, or colors. For text or structured data, use `browser_snapshot` instead.
|
|
73
73
|
|
|
74
|
-
To disable the screenshot tool for models that
|
|
74
|
+
To disable the screenshot tool for models that don't support vision, use `excludeTools`:
|
|
75
75
|
|
|
76
76
|
```typescript
|
|
77
77
|
const browser = new AgentBrowser({
|