@mastra/mcp-docs-server 1.0.0-beta.4 → 1.0.0-beta.6
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/%40internal%2Fstorage-test-utils.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fagent-builder.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fai-sdk.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fastra.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fchroma.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fclickhouse.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fclient-js.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fcloudflare-d1.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fcloudflare.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fconvex.md +29 -0
- package/.docs/organized/changelogs/%40mastra%2Fcore.md +411 -211
- package/.docs/organized/changelogs/%40mastra%2Fcouchbase.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-cloud.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-cloudflare.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-netlify.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-vercel.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fdeployer.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fduckdb.md +42 -0
- package/.docs/organized/changelogs/%40mastra%2Fdynamodb.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Felasticsearch.md +52 -0
- package/.docs/organized/changelogs/%40mastra%2Fevals.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Flance.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Flibsql.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Floggers.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fmcp-docs-server.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fmcp-registry-registry.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fmcp.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fmemory.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fmongodb.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fmssql.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fopensearch.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fpg.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fpinecone.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fplayground-ui.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fqdrant.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Frag.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Freact.md +89 -1
- package/.docs/organized/changelogs/%40mastra%2Fs3vectors.md +9 -0
- package/.docs/organized/changelogs/%40mastra%2Fschema-compat.md +42 -0
- package/.docs/organized/changelogs/%40mastra%2Fserver.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fturbopuffer.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fupstash.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fvectorize.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-azure.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-cloudflare.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-deepgram.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-elevenlabs.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-gladia.md +92 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-google-gemini-live.md +67 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-google.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-murf.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-openai-realtime.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-openai.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-playai.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-sarvam.md +201 -1
- package/.docs/organized/changelogs/%40mastra%2Fvoice-speechify.md +201 -1
- package/.docs/organized/changelogs/create-mastra.md +201 -1
- package/.docs/organized/changelogs/mastra.md +201 -1
- package/.docs/organized/code-examples/agui.md +1 -0
- package/.docs/organized/code-examples/ai-sdk-v5.md +1 -0
- package/.docs/organized/code-examples/mcp-server-adapters.md +721 -0
- package/.docs/organized/code-examples/memory-with-processors.md +1 -1
- package/.docs/organized/code-examples/quick-start.md +1 -1
- package/.docs/organized/code-examples/server-app-access.md +342 -0
- package/.docs/raw/agents/adding-voice.mdx +7 -10
- package/.docs/raw/agents/agent-approval.mdx +189 -0
- package/.docs/raw/agents/guardrails.mdx +26 -23
- package/.docs/raw/agents/networks.mdx +2 -2
- package/.docs/raw/agents/overview.mdx +27 -62
- package/.docs/raw/agents/processors.mdx +279 -0
- package/.docs/raw/agents/using-tools.mdx +4 -5
- package/.docs/raw/course/01-first-agent/05-running-playground.md +5 -5
- package/.docs/raw/course/01-first-agent/09-testing-your-agent.md +3 -3
- package/.docs/raw/course/01-first-agent/13-testing-your-tool.md +3 -3
- package/.docs/raw/course/01-first-agent/17-testing-memory.md +2 -2
- package/.docs/raw/course/04-workflows/07-using-playground.md +1 -1
- package/.docs/raw/deployment/building-mastra.mdx +1 -1
- package/.docs/raw/deployment/cloud-providers/amazon-ec2.mdx +1 -1
- package/.docs/raw/deployment/cloud-providers/aws-lambda.mdx +1 -1
- package/.docs/raw/deployment/cloud-providers/azure-app-services.mdx +1 -1
- package/.docs/raw/deployment/cloud-providers/digital-ocean.mdx +1 -1
- package/.docs/raw/deployment/cloud-providers/index.mdx +20 -27
- package/.docs/raw/deployment/cloud-providers/netlify-deployer.mdx +44 -13
- package/.docs/raw/deployment/mastra-cloud/observability.mdx +19 -17
- package/.docs/raw/deployment/mastra-cloud/setting-up.mdx +1 -1
- package/.docs/raw/deployment/overview.mdx +2 -2
- package/.docs/raw/deployment/web-framework.mdx +5 -5
- package/.docs/raw/evals/custom-scorers.mdx +3 -5
- package/.docs/raw/evals/overview.mdx +2 -3
- package/.docs/raw/evals/running-in-ci.mdx +0 -2
- package/.docs/raw/{guides/guide → getting-started}/manual-install.mdx +2 -2
- package/.docs/raw/getting-started/project-structure.mdx +1 -1
- package/.docs/raw/getting-started/start.mdx +72 -0
- package/.docs/raw/getting-started/studio.mdx +1 -1
- package/.docs/raw/{frameworks/agentic-uis/ai-sdk.mdx → guides/build-your-ui/ai-sdk-ui.mdx} +113 -11
- package/.docs/raw/{frameworks/web-frameworks → guides/getting-started}/astro.mdx +23 -25
- package/.docs/raw/{frameworks/servers → guides/getting-started}/express.mdx +3 -4
- package/.docs/raw/guides/{quickstarts/nextjs.mdx → getting-started/next-js.mdx} +11 -11
- package/.docs/raw/guides/{quickstarts/standalone-server.mdx → getting-started/quickstart.mdx} +7 -7
- package/.docs/raw/{frameworks/web-frameworks → guides/getting-started}/sveltekit.mdx +23 -25
- package/.docs/raw/{frameworks/web-frameworks → guides/getting-started}/vite-react.mdx +7 -7
- package/.docs/raw/guides/guide/ai-recruiter.mdx +2 -3
- package/.docs/raw/guides/guide/chef-michel.mdx +2 -3
- package/.docs/raw/guides/guide/notes-mcp-server.mdx +2 -2
- package/.docs/raw/guides/guide/research-assistant.mdx +7 -8
- package/.docs/raw/guides/guide/stock-agent.mdx +4 -6
- package/.docs/raw/guides/guide/web-search.mdx +12 -10
- package/.docs/raw/guides/guide/whatsapp-chat-bot.mdx +421 -0
- package/.docs/raw/guides/index.mdx +3 -35
- package/.docs/raw/guides/migrations/agentnetwork.mdx +4 -4
- package/.docs/raw/guides/migrations/ai-sdk-v4-to-v5.mdx +1 -1
- package/.docs/raw/guides/migrations/upgrade-to-v1/agent.mdx +40 -0
- package/.docs/raw/guides/migrations/upgrade-to-v1/tools.mdx +5 -0
- package/.docs/raw/guides/migrations/upgrade-to-v1/workflows.mdx +51 -0
- package/.docs/raw/guides/migrations/vnext-to-standard-apis.mdx +2 -2
- package/.docs/raw/index.mdx +2 -2
- package/.docs/raw/mcp/overview.mdx +3 -5
- package/.docs/raw/memory/memory-processors.mdx +264 -79
- package/.docs/raw/memory/semantic-recall.mdx +7 -7
- package/.docs/raw/memory/storage/memory-with-libsql.mdx +2 -4
- package/.docs/raw/memory/storage/memory-with-mongodb.mdx +2 -4
- package/.docs/raw/memory/storage/memory-with-pg.mdx +2 -4
- package/.docs/raw/memory/storage/memory-with-upstash.mdx +2 -4
- package/.docs/raw/memory/threads-and-resources.mdx +3 -3
- package/.docs/raw/memory/working-memory.mdx +14 -7
- package/.docs/raw/{logging.mdx → observability/logging.mdx} +1 -1
- package/.docs/raw/observability/overview.mdx +2 -3
- package/.docs/raw/observability/tracing/bridges/otel.mdx +176 -0
- package/.docs/raw/observability/tracing/exporters/arize.mdx +17 -0
- package/.docs/raw/observability/tracing/exporters/braintrust.mdx +19 -0
- package/.docs/raw/observability/tracing/exporters/langfuse.mdx +20 -0
- package/.docs/raw/observability/tracing/exporters/langsmith.mdx +12 -0
- package/.docs/raw/observability/tracing/exporters/otel.mdx +25 -5
- package/.docs/raw/observability/tracing/exporters/posthog.mdx +107 -0
- package/.docs/raw/observability/tracing/overview.mdx +74 -8
- package/.docs/raw/observability/tracing/processors/sensitive-data-filter.mdx +0 -1
- package/.docs/raw/rag/chunking-and-embedding.mdx +16 -17
- package/.docs/raw/rag/overview.mdx +3 -2
- package/.docs/raw/rag/retrieval.mdx +43 -38
- package/.docs/raw/rag/vector-databases.mdx +93 -2
- package/.docs/raw/reference/agents/agent.mdx +7 -10
- package/.docs/raw/reference/agents/generate.mdx +55 -6
- package/.docs/raw/reference/agents/generateLegacy.mdx +2 -2
- package/.docs/raw/reference/agents/getLLM.mdx +1 -1
- package/.docs/raw/reference/agents/network.mdx +46 -3
- package/.docs/raw/reference/cli/mastra.mdx +2 -1
- package/.docs/raw/reference/client-js/agents.mdx +3 -3
- package/.docs/raw/reference/client-js/memory.mdx +43 -0
- package/.docs/raw/reference/client-js/workflows.mdx +92 -63
- package/.docs/raw/reference/core/getLogger.mdx +1 -1
- package/.docs/raw/reference/core/listLogs.mdx +1 -1
- package/.docs/raw/reference/core/listLogsByRunId.mdx +1 -1
- package/.docs/raw/reference/core/mastra-model-gateway.mdx +5 -19
- package/.docs/raw/reference/core/setLogger.mdx +1 -1
- package/.docs/raw/reference/core/setTelemetry.mdx +1 -1
- package/.docs/raw/reference/deployer/netlify.mdx +1 -2
- package/.docs/raw/reference/evals/answer-relevancy.mdx +28 -98
- package/.docs/raw/reference/evals/answer-similarity.mdx +12 -258
- package/.docs/raw/reference/evals/bias.mdx +29 -87
- package/.docs/raw/reference/evals/completeness.mdx +31 -90
- package/.docs/raw/reference/evals/content-similarity.mdx +28 -88
- package/.docs/raw/reference/evals/context-precision.mdx +28 -130
- package/.docs/raw/reference/evals/context-relevance.mdx +11 -11
- package/.docs/raw/reference/evals/faithfulness.mdx +28 -101
- package/.docs/raw/reference/evals/hallucination.mdx +28 -103
- package/.docs/raw/reference/evals/keyword-coverage.mdx +28 -107
- package/.docs/raw/reference/evals/noise-sensitivity.mdx +11 -11
- package/.docs/raw/reference/evals/prompt-alignment.mdx +15 -15
- package/.docs/raw/reference/evals/scorer-utils.mdx +362 -0
- package/.docs/raw/reference/evals/textual-difference.mdx +27 -100
- package/.docs/raw/reference/evals/tone-consistency.mdx +25 -98
- package/.docs/raw/reference/evals/tool-call-accuracy.mdx +7 -7
- package/.docs/raw/reference/evals/toxicity.mdx +29 -92
- package/.docs/raw/reference/index.mdx +1 -0
- package/.docs/raw/reference/memory/memory-class.mdx +5 -7
- package/.docs/raw/reference/observability/tracing/bridges/otel.mdx +150 -0
- package/.docs/raw/reference/observability/tracing/configuration.mdx +0 -4
- package/.docs/raw/reference/observability/tracing/exporters/arize.mdx +4 -0
- package/.docs/raw/reference/observability/tracing/exporters/langsmith.mdx +17 -1
- package/.docs/raw/reference/observability/tracing/exporters/otel.mdx +6 -0
- package/.docs/raw/reference/observability/tracing/exporters/posthog.mdx +132 -0
- package/.docs/raw/reference/observability/tracing/instances.mdx +0 -4
- package/.docs/raw/reference/observability/tracing/interfaces.mdx +29 -4
- package/.docs/raw/reference/observability/tracing/spans.mdx +0 -4
- package/.docs/raw/reference/processors/batch-parts-processor.mdx +1 -1
- package/.docs/raw/reference/processors/language-detector.mdx +10 -3
- package/.docs/raw/reference/processors/message-history-processor.mdx +131 -0
- package/.docs/raw/reference/processors/moderation-processor.mdx +12 -5
- package/.docs/raw/reference/processors/pii-detector.mdx +12 -5
- package/.docs/raw/reference/processors/processor-interface.mdx +502 -0
- package/.docs/raw/reference/processors/prompt-injection-detector.mdx +10 -3
- package/.docs/raw/reference/processors/semantic-recall-processor.mdx +197 -0
- package/.docs/raw/reference/processors/system-prompt-scrubber.mdx +3 -4
- package/.docs/raw/reference/processors/token-limiter-processor.mdx +2 -2
- package/.docs/raw/reference/processors/tool-call-filter.mdx +125 -0
- package/.docs/raw/reference/processors/unicode-normalizer.mdx +1 -1
- package/.docs/raw/reference/processors/working-memory-processor.mdx +221 -0
- package/.docs/raw/reference/rag/embeddings.mdx +5 -5
- package/.docs/raw/reference/rag/rerank.mdx +1 -2
- package/.docs/raw/reference/rag/rerankWithScorer.mdx +0 -1
- package/.docs/raw/reference/storage/cloudflare-d1.mdx +37 -0
- package/.docs/raw/reference/storage/convex.mdx +164 -0
- package/.docs/raw/reference/storage/lance.mdx +33 -0
- package/.docs/raw/reference/storage/libsql.mdx +37 -0
- package/.docs/raw/reference/storage/mongodb.mdx +39 -0
- package/.docs/raw/reference/storage/mssql.mdx +37 -0
- package/.docs/raw/reference/storage/postgresql.mdx +37 -0
- package/.docs/raw/reference/streaming/ChunkType.mdx +1 -1
- package/.docs/raw/reference/streaming/agents/stream.mdx +64 -2
- package/.docs/raw/reference/streaming/workflows/observeStream.mdx +7 -9
- package/.docs/raw/reference/streaming/workflows/{resumeStreamVNext.mdx → resumeStream.mdx} +51 -11
- package/.docs/raw/reference/streaming/workflows/stream.mdx +83 -24
- package/.docs/raw/reference/templates/overview.mdx +1 -4
- package/.docs/raw/reference/tools/client.mdx +1 -2
- package/.docs/raw/reference/tools/create-tool.mdx +132 -0
- package/.docs/raw/reference/tools/graph-rag-tool.mdx +5 -5
- package/.docs/raw/reference/tools/mcp-client.mdx +76 -21
- package/.docs/raw/reference/tools/mcp-server.mdx +1 -2
- package/.docs/raw/reference/tools/vector-query-tool.mdx +14 -15
- package/.docs/raw/reference/vectors/chroma.mdx +81 -1
- package/.docs/raw/reference/vectors/convex.mdx +429 -0
- package/.docs/raw/reference/vectors/couchbase.mdx +24 -17
- package/.docs/raw/reference/vectors/duckdb.mdx +462 -0
- package/.docs/raw/reference/vectors/elasticsearch.mdx +310 -0
- package/.docs/raw/reference/vectors/lance.mdx +38 -22
- package/.docs/raw/reference/vectors/libsql.mdx +35 -2
- package/.docs/raw/reference/vectors/mongodb.mdx +35 -2
- package/.docs/raw/reference/vectors/opensearch.mdx +37 -16
- package/.docs/raw/reference/vectors/pg.mdx +43 -36
- package/.docs/raw/reference/vectors/pinecone.mdx +48 -1
- package/.docs/raw/reference/vectors/qdrant.mdx +36 -1
- package/.docs/raw/reference/vectors/turbopuffer.mdx +74 -0
- package/.docs/raw/reference/voice/google.mdx +159 -20
- package/.docs/raw/reference/voice/openai-realtime.mdx +2 -2
- package/.docs/raw/reference/voice/voice.addInstructions.mdx +2 -3
- package/.docs/raw/reference/voice/voice.addTools.mdx +1 -1
- package/.docs/raw/reference/voice/voice.answer.mdx +1 -1
- package/.docs/raw/reference/voice/voice.close.mdx +1 -1
- package/.docs/raw/reference/voice/voice.connect.mdx +1 -1
- package/.docs/raw/reference/voice/voice.off.mdx +1 -1
- package/.docs/raw/reference/voice/voice.on.mdx +1 -1
- package/.docs/raw/reference/voice/voice.send.mdx +1 -1
- package/.docs/raw/reference/voice/voice.updateConfig.mdx +1 -1
- package/.docs/raw/reference/workflows/run-methods/restart.mdx +142 -0
- package/.docs/raw/reference/workflows/run-methods/resume.mdx +44 -0
- package/.docs/raw/reference/workflows/run-methods/start.mdx +44 -0
- package/.docs/raw/reference/workflows/run.mdx +13 -5
- package/.docs/raw/reference/workflows/step.mdx +13 -0
- package/.docs/raw/reference/workflows/workflow.mdx +19 -0
- package/.docs/raw/server-db/mastra-client.mdx +1 -2
- package/.docs/raw/server-db/mastra-server.mdx +30 -1
- package/.docs/raw/server-db/request-context.mdx +0 -1
- package/.docs/raw/server-db/storage.mdx +11 -0
- package/.docs/raw/streaming/overview.mdx +26 -15
- package/.docs/raw/streaming/tool-streaming.mdx +48 -5
- package/.docs/raw/streaming/workflow-streaming.mdx +5 -11
- package/.docs/raw/tools-mcp/advanced-usage.mdx +1 -2
- package/.docs/raw/tools-mcp/mcp-overview.mdx +3 -5
- package/.docs/raw/voice/overview.mdx +21 -41
- package/.docs/raw/voice/speech-to-speech.mdx +4 -4
- package/.docs/raw/voice/speech-to-text.mdx +1 -2
- package/.docs/raw/voice/text-to-speech.mdx +1 -2
- package/.docs/raw/workflows/control-flow.mdx +180 -0
- package/.docs/raw/workflows/error-handling.mdx +1 -0
- package/.docs/raw/workflows/human-in-the-loop.mdx +4 -4
- package/.docs/raw/workflows/overview.mdx +56 -44
- package/.docs/raw/workflows/snapshots.mdx +1 -0
- package/.docs/raw/workflows/suspend-and-resume.mdx +85 -16
- package/.docs/raw/workflows/time-travel.mdx +313 -0
- package/.docs/raw/workflows/workflow-state.mdx +191 -0
- package/CHANGELOG.md +18 -0
- package/dist/{chunk-5NJC7NRO.js → chunk-4CM2BQNP.js} +24 -4
- package/dist/prepare-docs/package-changes.d.ts.map +1 -1
- package/dist/prepare-docs/prepare.js +1 -1
- package/dist/stdio.js +1 -1
- package/package.json +7 -7
- package/.docs/raw/agents/human-in-the-loop-with-tools.mdx +0 -90
- package/.docs/raw/frameworks/agentic-uis/cedar-os.mdx +0 -102
- package/.docs/raw/frameworks/agentic-uis/openrouter.mdx +0 -179
- package/.docs/raw/frameworks/web-frameworks/next-js.mdx +0 -379
- package/.docs/raw/getting-started/quickstart.mdx +0 -27
- package/.docs/raw/getting-started/templates.mdx +0 -73
- package/.docs/raw/reference/streaming/workflows/observeStreamVNext.mdx +0 -47
- package/.docs/raw/reference/streaming/workflows/streamVNext.mdx +0 -153
- /package/.docs/raw/{frameworks/agentic-uis → guides/build-your-ui}/assistant-ui.mdx +0 -0
- /package/.docs/raw/{frameworks/agentic-uis → guides/build-your-ui}/copilotkit.mdx +0 -0
|
@@ -68,7 +68,7 @@ const agent = new Agent({
|
|
|
68
68
|
id: 'forgetful-job-interviewer',
|
|
69
69
|
name: 'Forgetful Job Interviewer',
|
|
70
70
|
instructions:
|
|
71
|
-
"You are a professional job interviewer for a technology company. Conduct insightful interviews by asking relevant questions about skills, experience, and problem-solving abilities. Respond to candidate answers and ask follow-up questions. Keep the interview professional and engaging. Remember details the candidate shares earlier in the conversation. Sometimes you forget things by accident. The system will show you if you forgot. Don't be
|
|
71
|
+
"You are a professional job interviewer for a technology company. Conduct insightful interviews by asking relevant questions about skills, experience, and problem-solving abilities. Respond to candidate answers and ask follow-up questions. Keep the interview professional and engaging. Remember details the candidate shares earlier in the conversation. Sometimes you forget things by accident. The system will show you if you forgot. Don't be embarrassed, you can admit when you forget something, you'll know when you do because there will be a message wrapped in <forgetten> tags. Don't refer to the user by their name, it comes across as too eager",
|
|
72
72
|
model: openai('gpt-4o'),
|
|
73
73
|
memory: new Memory({
|
|
74
74
|
processors: [
|
|
@@ -64,7 +64,7 @@ export const catOne = new Agent({
|
|
|
64
64
|
id: 'cat-one',
|
|
65
65
|
name: 'Cat One',
|
|
66
66
|
instructions:
|
|
67
|
-
'You are a feline expert with comprehensive knowledge of all cat species, from domestic breeds to wild big cats. As a lifelong cat specialist, you understand their behavior, biology, social structures, and evolutionary history in great depth. If you are asked for a specie name, do not return a paragraph, a
|
|
67
|
+
'You are a feline expert with comprehensive knowledge of all cat species, from domestic breeds to wild big cats. As a lifelong cat specialist, you understand their behavior, biology, social structures, and evolutionary history in great depth. If you are asked for a specie name, do not return a paragraph, a succinct two or three letter name of the species will suffice.',
|
|
68
68
|
model: openai('gpt-4o'),
|
|
69
69
|
});
|
|
70
70
|
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
### package.json
|
|
2
|
+
```json
|
|
3
|
+
{
|
|
4
|
+
"name": "examples-server-app-access",
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@mastra/core": "latest",
|
|
7
|
+
"@mastra/hono": "latest",
|
|
8
|
+
"hono": "^4.10.4",
|
|
9
|
+
"zod": "^3.25.76"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@types/node": "22.13.17",
|
|
13
|
+
"tsx": "^4.19.3",
|
|
14
|
+
"typescript": "^5.8.3"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### demo-cli-batch.ts
|
|
20
|
+
```typescript
|
|
21
|
+
/**
|
|
22
|
+
* Demo: Direct Server App Access
|
|
23
|
+
*
|
|
24
|
+
* This demonstrates how to use mastra.getServerApp() to call routes
|
|
25
|
+
* directly without running an HTTP server.
|
|
26
|
+
*
|
|
27
|
+
* Use case: CLI scripts, batch processing, testing, background jobs
|
|
28
|
+
*
|
|
29
|
+
* NOTE: The base URL (http://internal) is just a placeholder - Hono's app.fetch()
|
|
30
|
+
* processes requests in-memory and only uses the path. The hostname is ignored.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { MastraServer } from '@mastra/hono';
|
|
34
|
+
import { Hono } from 'hono';
|
|
35
|
+
import type { Hono as HonoType } from 'hono';
|
|
36
|
+
|
|
37
|
+
import { mastra } from './mastra';
|
|
38
|
+
|
|
39
|
+
// Base URL is a placeholder - only the path matters for in-memory routing
|
|
40
|
+
const BASE_URL = 'http://internal';
|
|
41
|
+
|
|
42
|
+
async function main() {
|
|
43
|
+
// Create and initialize server (no port binding)
|
|
44
|
+
const app = new Hono();
|
|
45
|
+
const adapter = new MastraServer({ app: app as any, mastra });
|
|
46
|
+
await adapter.init();
|
|
47
|
+
|
|
48
|
+
// Get the server app - works because MastraServer auto-registers with mastra
|
|
49
|
+
const serverApp = mastra.getServerApp<HonoType>();
|
|
50
|
+
if (!serverApp) throw new Error('Server app not initialized');
|
|
51
|
+
|
|
52
|
+
// List tools
|
|
53
|
+
console.log('--- List Tools ---');
|
|
54
|
+
const toolsResponse = await serverApp.fetch(new Request(`${BASE_URL}/api/tools`));
|
|
55
|
+
const tools = (await toolsResponse.json()) as Record<string, unknown>;
|
|
56
|
+
console.log(`Tools: ${Object.keys(tools).join(', ') || '(none registered by key)'}`);
|
|
57
|
+
|
|
58
|
+
// Execute a tool
|
|
59
|
+
console.log('\n--- Execute Tool ---');
|
|
60
|
+
const calcResponse = await serverApp.fetch(
|
|
61
|
+
new Request(`${BASE_URL}/api/tools/calculator/execute`, {
|
|
62
|
+
method: 'POST',
|
|
63
|
+
headers: { 'Content-Type': 'application/json' },
|
|
64
|
+
body: JSON.stringify({ data: { operation: 'multiply', a: 7, b: 6 } }),
|
|
65
|
+
}),
|
|
66
|
+
);
|
|
67
|
+
console.log(`Result: ${JSON.stringify(await calcResponse.json())}`);
|
|
68
|
+
|
|
69
|
+
// List workflows
|
|
70
|
+
console.log('\n--- List Workflows ---');
|
|
71
|
+
const workflowsResponse = await serverApp.fetch(new Request(`${BASE_URL}/api/workflows`));
|
|
72
|
+
const workflows = (await workflowsResponse.json()) as Record<string, unknown>;
|
|
73
|
+
console.log(`Workflows: ${Object.keys(workflows).join(', ')}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
main().catch(console.error);
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### mastra/index.ts
|
|
81
|
+
```typescript
|
|
82
|
+
import { Mastra } from '@mastra/core/mastra';
|
|
83
|
+
|
|
84
|
+
import { calculatorTool, timestampTool } from './tools';
|
|
85
|
+
import { dailyReportWorkflow, paymentProcessorWorkflow, processMessageWorkflow } from './workflows';
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Main Mastra instance configured with tools and workflows
|
|
89
|
+
* for demonstrating server app access patterns.
|
|
90
|
+
*/
|
|
91
|
+
export const mastra = new Mastra({
|
|
92
|
+
tools: {
|
|
93
|
+
calculatorTool,
|
|
94
|
+
timestampTool,
|
|
95
|
+
},
|
|
96
|
+
workflows: {
|
|
97
|
+
processMessageWorkflow,
|
|
98
|
+
dailyReportWorkflow,
|
|
99
|
+
paymentProcessorWorkflow,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### mastra/tools/index.ts
|
|
106
|
+
```typescript
|
|
107
|
+
import { createTool } from '@mastra/core/tools';
|
|
108
|
+
import { z } from 'zod';
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Calculator tool - performs basic arithmetic operations
|
|
112
|
+
*/
|
|
113
|
+
export const calculatorTool = createTool({
|
|
114
|
+
id: 'calculator',
|
|
115
|
+
description: 'Performs basic arithmetic operations',
|
|
116
|
+
inputSchema: z.object({
|
|
117
|
+
operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
|
|
118
|
+
a: z.number(),
|
|
119
|
+
b: z.number(),
|
|
120
|
+
}),
|
|
121
|
+
execute: async ({ operation, a, b }) => {
|
|
122
|
+
if (operation === 'divide' && b === 0) {
|
|
123
|
+
throw new Error('Cannot divide by zero');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
let result: number;
|
|
127
|
+
switch (operation) {
|
|
128
|
+
case 'add':
|
|
129
|
+
result = a + b;
|
|
130
|
+
break;
|
|
131
|
+
case 'subtract':
|
|
132
|
+
result = a - b;
|
|
133
|
+
break;
|
|
134
|
+
case 'multiply':
|
|
135
|
+
result = a * b;
|
|
136
|
+
break;
|
|
137
|
+
case 'divide':
|
|
138
|
+
result = a / b;
|
|
139
|
+
break;
|
|
140
|
+
default:
|
|
141
|
+
throw new Error(`Unsupported operation: ${operation}`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return { result, operation, operands: { a, b } };
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Timestamp tool - returns current timestamp in various formats
|
|
150
|
+
*/
|
|
151
|
+
export const timestampTool = createTool({
|
|
152
|
+
id: 'timestamp',
|
|
153
|
+
description: 'Returns the current timestamp in various formats',
|
|
154
|
+
inputSchema: z.object({
|
|
155
|
+
format: z.enum(['iso', 'unix', 'readable']).default('iso'),
|
|
156
|
+
}),
|
|
157
|
+
execute: async ({ format }) => {
|
|
158
|
+
const now = new Date();
|
|
159
|
+
|
|
160
|
+
let timestamp: string;
|
|
161
|
+
switch (format) {
|
|
162
|
+
case 'unix':
|
|
163
|
+
timestamp = Math.floor(now.getTime() / 1000).toString();
|
|
164
|
+
break;
|
|
165
|
+
case 'readable':
|
|
166
|
+
timestamp = now.toLocaleString();
|
|
167
|
+
break;
|
|
168
|
+
case 'iso':
|
|
169
|
+
default:
|
|
170
|
+
timestamp = now.toISOString();
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return { timestamp, format };
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### mastra/workflows/index.ts
|
|
181
|
+
```typescript
|
|
182
|
+
import { createStep, createWorkflow } from '@mastra/core/workflows';
|
|
183
|
+
import { z } from 'zod';
|
|
184
|
+
|
|
185
|
+
// --- Process Message Workflow ---
|
|
186
|
+
|
|
187
|
+
const validateStep = createStep({
|
|
188
|
+
id: 'validate',
|
|
189
|
+
description: 'Validates the incoming message',
|
|
190
|
+
inputSchema: z.object({
|
|
191
|
+
message: z.string(),
|
|
192
|
+
priority: z.enum(['low', 'medium', 'high']).default('medium'),
|
|
193
|
+
}),
|
|
194
|
+
outputSchema: z.object({
|
|
195
|
+
valid: z.boolean(),
|
|
196
|
+
message: z.string(),
|
|
197
|
+
priority: z.enum(['low', 'medium', 'high']),
|
|
198
|
+
}),
|
|
199
|
+
execute: async ({ inputData }) => {
|
|
200
|
+
const valid = inputData.message.length > 0 && inputData.message.length < 1000;
|
|
201
|
+
return {
|
|
202
|
+
valid,
|
|
203
|
+
message: inputData.message,
|
|
204
|
+
priority: inputData.priority,
|
|
205
|
+
};
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
const processStep = createStep({
|
|
210
|
+
id: 'process',
|
|
211
|
+
description: 'Processes the validated message',
|
|
212
|
+
inputSchema: z.object({
|
|
213
|
+
valid: z.boolean(),
|
|
214
|
+
message: z.string(),
|
|
215
|
+
priority: z.enum(['low', 'medium', 'high']),
|
|
216
|
+
}),
|
|
217
|
+
outputSchema: z.object({
|
|
218
|
+
processed: z.boolean(),
|
|
219
|
+
result: z.string(),
|
|
220
|
+
timestamp: z.string(),
|
|
221
|
+
}),
|
|
222
|
+
execute: async ({ inputData }) => {
|
|
223
|
+
if (!inputData.valid) {
|
|
224
|
+
return {
|
|
225
|
+
processed: false,
|
|
226
|
+
result: 'Invalid message',
|
|
227
|
+
timestamp: new Date().toISOString(),
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const result = `Processed [${inputData.priority}]: ${inputData.message.substring(0, 50)}...`;
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
processed: true,
|
|
235
|
+
result,
|
|
236
|
+
timestamp: new Date().toISOString(),
|
|
237
|
+
};
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
export const processMessageWorkflow = createWorkflow({
|
|
242
|
+
id: 'process-message',
|
|
243
|
+
description: 'Validates and processes a message',
|
|
244
|
+
inputSchema: z.object({
|
|
245
|
+
message: z.string(),
|
|
246
|
+
priority: z.enum(['low', 'medium', 'high']).default('medium'),
|
|
247
|
+
}),
|
|
248
|
+
outputSchema: z.object({
|
|
249
|
+
processed: z.boolean(),
|
|
250
|
+
result: z.string(),
|
|
251
|
+
timestamp: z.string(),
|
|
252
|
+
}),
|
|
253
|
+
})
|
|
254
|
+
.then(validateStep)
|
|
255
|
+
.then(processStep)
|
|
256
|
+
.commit();
|
|
257
|
+
|
|
258
|
+
// --- Daily Report Workflow ---
|
|
259
|
+
|
|
260
|
+
const generateReportStep = createStep({
|
|
261
|
+
id: 'generate-report',
|
|
262
|
+
description: 'Generates a daily report',
|
|
263
|
+
inputSchema: z.object({
|
|
264
|
+
date: z.string(),
|
|
265
|
+
reportType: z.enum(['summary', 'detailed']).default('summary'),
|
|
266
|
+
}),
|
|
267
|
+
outputSchema: z.object({
|
|
268
|
+
reportId: z.string(),
|
|
269
|
+
status: z.string(),
|
|
270
|
+
generatedAt: z.string(),
|
|
271
|
+
}),
|
|
272
|
+
execute: async ({ inputData }) => {
|
|
273
|
+
const reportId = `RPT-${Date.now()}`;
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
reportId,
|
|
277
|
+
status: `Generated ${inputData.reportType} report for ${inputData.date}`,
|
|
278
|
+
generatedAt: new Date().toISOString(),
|
|
279
|
+
};
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
export const dailyReportWorkflow = createWorkflow({
|
|
284
|
+
id: 'daily-report',
|
|
285
|
+
description: 'Generates daily reports',
|
|
286
|
+
inputSchema: z.object({
|
|
287
|
+
date: z.string(),
|
|
288
|
+
reportType: z.enum(['summary', 'detailed']).default('summary'),
|
|
289
|
+
}),
|
|
290
|
+
outputSchema: z.object({
|
|
291
|
+
reportId: z.string(),
|
|
292
|
+
status: z.string(),
|
|
293
|
+
generatedAt: z.string(),
|
|
294
|
+
}),
|
|
295
|
+
})
|
|
296
|
+
.then(generateReportStep)
|
|
297
|
+
.commit();
|
|
298
|
+
|
|
299
|
+
// --- Payment Processor Workflow ---
|
|
300
|
+
|
|
301
|
+
const processPaymentStep = createStep({
|
|
302
|
+
id: 'process-payment',
|
|
303
|
+
description: 'Processes a payment transaction',
|
|
304
|
+
inputSchema: z.object({
|
|
305
|
+
amount: z.number(),
|
|
306
|
+
currency: z.string(),
|
|
307
|
+
customerId: z.string(),
|
|
308
|
+
}),
|
|
309
|
+
outputSchema: z.object({
|
|
310
|
+
transactionId: z.string(),
|
|
311
|
+
status: z.string(),
|
|
312
|
+
processedAt: z.string(),
|
|
313
|
+
}),
|
|
314
|
+
execute: async ({ inputData }) => {
|
|
315
|
+
const transactionId = `TXN-${Date.now()}`;
|
|
316
|
+
|
|
317
|
+
return {
|
|
318
|
+
transactionId,
|
|
319
|
+
status: `Processed ${inputData.currency} ${inputData.amount} for customer ${inputData.customerId}`,
|
|
320
|
+
processedAt: new Date().toISOString(),
|
|
321
|
+
};
|
|
322
|
+
},
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
export const paymentProcessorWorkflow = createWorkflow({
|
|
326
|
+
id: 'payment-processor',
|
|
327
|
+
description: 'Processes payment transactions',
|
|
328
|
+
inputSchema: z.object({
|
|
329
|
+
amount: z.number(),
|
|
330
|
+
currency: z.string(),
|
|
331
|
+
customerId: z.string(),
|
|
332
|
+
}),
|
|
333
|
+
outputSchema: z.object({
|
|
334
|
+
transactionId: z.string(),
|
|
335
|
+
status: z.string(),
|
|
336
|
+
processedAt: z.string(),
|
|
337
|
+
}),
|
|
338
|
+
})
|
|
339
|
+
.then(processPaymentStep)
|
|
340
|
+
.commit();
|
|
341
|
+
|
|
342
|
+
```
|
|
@@ -15,7 +15,6 @@ import { createReadStream } from "fs";
|
|
|
15
15
|
import path from "path";
|
|
16
16
|
import { Agent } from "@mastra/core/agent";
|
|
17
17
|
import { OpenAIVoice } from "@mastra/voice-openai";
|
|
18
|
-
import { openai } from "@ai-sdk/openai";
|
|
19
18
|
|
|
20
19
|
// Initialize the voice provider with default settings
|
|
21
20
|
const voice = new OpenAIVoice();
|
|
@@ -25,7 +24,7 @@ export const agent = new Agent({
|
|
|
25
24
|
id: "voice-agent",
|
|
26
25
|
name: "Voice Agent",
|
|
27
26
|
instructions: `You are a helpful assistant with both STT and TTS capabilities.`,
|
|
28
|
-
model: openai
|
|
27
|
+
model: "openai/gpt-5.1",
|
|
29
28
|
voice,
|
|
30
29
|
});
|
|
31
30
|
|
|
@@ -105,7 +104,7 @@ import { search, calculate } from "../tools";
|
|
|
105
104
|
// Initialize the realtime voice provider
|
|
106
105
|
const voice = new OpenAIRealtimeVoice({
|
|
107
106
|
apiKey: process.env.OPENAI_API_KEY,
|
|
108
|
-
model: "gpt-
|
|
107
|
+
model: "gpt-5.1-realtime",
|
|
109
108
|
speaker: "alloy",
|
|
110
109
|
});
|
|
111
110
|
|
|
@@ -114,7 +113,7 @@ export const agent = new Agent({
|
|
|
114
113
|
id: "speech-to-speech-agent",
|
|
115
114
|
name: "Speech-to-Speech Agent",
|
|
116
115
|
instructions: `You are a helpful assistant with speech-to-speech capabilities.`,
|
|
117
|
-
model: openai
|
|
116
|
+
model: "openai/gpt-5.1",
|
|
118
117
|
tools: {
|
|
119
118
|
// Tools configured on Agent are passed to voice provider
|
|
120
119
|
search,
|
|
@@ -178,7 +177,6 @@ import { Agent } from "@mastra/core/agent";
|
|
|
178
177
|
import { CompositeVoice } from "@mastra/core/voice";
|
|
179
178
|
import { OpenAIVoice } from "@mastra/voice-openai";
|
|
180
179
|
import { Mastra } from "@mastra/core";
|
|
181
|
-
import { openai } from "@ai-sdk/openai";
|
|
182
180
|
|
|
183
181
|
// Saves an audio stream to a file in the audio directory, creating the directory if it doesn't exist.
|
|
184
182
|
export const saveAudioToFile = async (
|
|
@@ -217,7 +215,7 @@ export const convertToText = async (
|
|
|
217
215
|
export const hybridVoiceAgent = new Agent({
|
|
218
216
|
id: "hybrid-voice-agent",
|
|
219
217
|
name: "Hybrid Voice Agent",
|
|
220
|
-
model: openai
|
|
218
|
+
model: "openai/gpt-5.1",
|
|
221
219
|
instructions: "You can speak and listen using different providers.",
|
|
222
220
|
voice: new CompositeVoice({
|
|
223
221
|
input: new OpenAIVoice(),
|
|
@@ -229,7 +227,7 @@ export const unifiedVoiceAgent = new Agent({
|
|
|
229
227
|
id: "unified-voice-agent",
|
|
230
228
|
name: "Unified Voice Agent",
|
|
231
229
|
instructions: "You are an agent with both STT and TTS capabilities.",
|
|
232
|
-
model: openai
|
|
230
|
+
model: "openai/gpt-5.1",
|
|
233
231
|
voice: new OpenAIVoice(),
|
|
234
232
|
});
|
|
235
233
|
|
|
@@ -269,13 +267,12 @@ import { Agent } from "@mastra/core/agent";
|
|
|
269
267
|
import { CompositeVoice } from "@mastra/core/voice";
|
|
270
268
|
import { OpenAIVoice } from "@mastra/voice-openai";
|
|
271
269
|
import { PlayAIVoice } from "@mastra/voice-playai";
|
|
272
|
-
import { openai } from "@ai-sdk/openai";
|
|
273
270
|
|
|
274
271
|
export const agent = new Agent({
|
|
275
272
|
id: "voice-agent",
|
|
276
273
|
name: "Voice Agent",
|
|
277
274
|
instructions: `You are a helpful assistant with both STT and TTS capabilities.`,
|
|
278
|
-
model: openai
|
|
275
|
+
model: "openai/gpt-5.1",
|
|
279
276
|
|
|
280
277
|
// Create a composite voice using OpenAI for listening and PlayAI for speaking
|
|
281
278
|
voice: new CompositeVoice({
|
|
@@ -300,7 +297,7 @@ export const agent = new Agent({
|
|
|
300
297
|
id: "aisdk-voice-agent",
|
|
301
298
|
name: "AI SDK Voice Agent",
|
|
302
299
|
instructions: `You are a helpful assistant with voice capabilities.`,
|
|
303
|
-
model: openai("gpt-
|
|
300
|
+
model: openai("gpt-5.1"),
|
|
304
301
|
|
|
305
302
|
// Pass AI SDK models directly to CompositeVoice
|
|
306
303
|
voice: new CompositeVoice({
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Agent Approval | Agents"
|
|
3
|
+
description: Learn how to require approvals and suspend tool execution while keeping humans in control of agent workflows.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agent Approval
|
|
7
|
+
|
|
8
|
+
Agents sometimes require the same [human-in-the-loop](/docs/v1/workflows/human-in-the-loop) oversight used in workflows when calling tools that handle sensitive operations, like deleting resources or performing running long processes. With agent approval you can suspend a tool call and provide feedback to the user, or approve or decline a tool call based on targeted application conditions.
|
|
9
|
+
|
|
10
|
+
## Tool call approval
|
|
11
|
+
|
|
12
|
+
Tool call approval can be enabled at the agent level and apply to every tool the agent uses, or at the tool level providing more granular control over individual tool calls.
|
|
13
|
+
|
|
14
|
+
### Storage
|
|
15
|
+
|
|
16
|
+
Agent approval uses a snapshot to capture the state of the request. Ensure you've enabled a storage provider in your main Mastra instance. If storage isn't enabled you'll see an error relating to snapshot not found.
|
|
17
|
+
|
|
18
|
+
```typescript title="src/mastra/index.ts"
|
|
19
|
+
import { Mastra } from "@mastra/core/mastra";
|
|
20
|
+
import { LibSQLStore } from "@mastra/libsql";
|
|
21
|
+
|
|
22
|
+
export const mastra = new Mastra({
|
|
23
|
+
// ...
|
|
24
|
+
storage: new LibSQLStore({
|
|
25
|
+
id: "mastra-storage",
|
|
26
|
+
url: ":memory:"
|
|
27
|
+
})
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## Agent-level approval
|
|
33
|
+
|
|
34
|
+
When calling an agent using `.stream()` set `requireToolApproval` to `true` which will prevent the agent from calling any of the tools defined in its configuration.
|
|
35
|
+
|
|
36
|
+
```typescript showLineNumbers
|
|
37
|
+
const stream = await agent.stream("What's the weather in London?", {
|
|
38
|
+
requireToolApproval: true
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Approving tool calls
|
|
43
|
+
|
|
44
|
+
To approve a tool call, access `approveToolCall` from the `agent`, passing in the `runId` of the stream. This will let the agent know its now OK to call its tools.
|
|
45
|
+
|
|
46
|
+
```typescript showLineNumbers
|
|
47
|
+
const handleApproval = async () => {
|
|
48
|
+
const approvedStream = await agent.approveToolCall({ runId: stream.runId });
|
|
49
|
+
|
|
50
|
+
for await (const chunk of approvedStream.textStream) {
|
|
51
|
+
process.stdout.write(chunk);
|
|
52
|
+
}
|
|
53
|
+
process.stdout.write("\n");
|
|
54
|
+
};
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Declining tool calls
|
|
58
|
+
|
|
59
|
+
To decline a tool call, access the `declineToolCall` from the `agent`. You will see the streamed response from the agent, but it won't call its tools.
|
|
60
|
+
|
|
61
|
+
```typescript showLineNumbers
|
|
62
|
+
const handleDecline = async () => {
|
|
63
|
+
const declinedStream = await agent.declineToolCall({ runId: stream.runId });
|
|
64
|
+
|
|
65
|
+
for await (const chunk of declinedStream.textStream) {
|
|
66
|
+
process.stdout.write(chunk);
|
|
67
|
+
}
|
|
68
|
+
process.stdout.write("\n");
|
|
69
|
+
};
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Tool-level approval
|
|
73
|
+
|
|
74
|
+
There are two types of tool call approval. The first uses `requireApproval`, which is a property on the tool definition, while `requireToolApproval` is a parameter passed to `agent.stream()`. The second uses `suspend` and lets the agent provide context or confirmation prompts so the user can decide whether the tool call should continue.
|
|
75
|
+
|
|
76
|
+
### Tool approval using `requireToolApproval`
|
|
77
|
+
|
|
78
|
+
In this approach, `requireApproval` is configured on the tool definition (shown below) rather than on the agent.
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
export const testTool = createTool({
|
|
82
|
+
id: "test-tool",
|
|
83
|
+
description: "Fetches weather for a location",
|
|
84
|
+
inputSchema: z.object({
|
|
85
|
+
location: z.string()
|
|
86
|
+
}),
|
|
87
|
+
outputSchema: z.object({
|
|
88
|
+
weather: z.string()
|
|
89
|
+
}),
|
|
90
|
+
resumeSchema: z.object({
|
|
91
|
+
approved: z.boolean()
|
|
92
|
+
}),
|
|
93
|
+
execute: async ({ location }) => {
|
|
94
|
+
const response = await fetch(`https://wttr.in/${location}?format=3`);
|
|
95
|
+
const weather = await response.text();
|
|
96
|
+
|
|
97
|
+
return { weather };
|
|
98
|
+
},
|
|
99
|
+
requireApproval: true
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
When `requireApproval` is true for a tool, the stream will include chunks of type `tool-call-approval` to indicate that the call is paused. To continue the call, invoke `resumeStream` with the required `resumeSchema` and the `runId`.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
const stream = await agent.stream("What's the weather in London?");
|
|
107
|
+
|
|
108
|
+
for await (const chunk of stream.fullStream) {
|
|
109
|
+
if (chunk.type === "tool-call-approval") {
|
|
110
|
+
console.log("Approval required.");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const handleResume = async () => {
|
|
115
|
+
const resumedStream = await agent.resumeStream({ approved: true }, { runId: stream.runId });
|
|
116
|
+
|
|
117
|
+
for await (const chunk of resumedStream.textStream) {
|
|
118
|
+
process.stdout.write(chunk);
|
|
119
|
+
}
|
|
120
|
+
process.stdout.write("\n");
|
|
121
|
+
};
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
### Tool approval using `suspend`
|
|
126
|
+
|
|
127
|
+
With this approach, neither the agent nor the tool uses `requireApproval`. Instead, the tool implementation calls `suspend` to pause execution and return context or confirmation prompts to the user.
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
|
|
131
|
+
export const testToolB = createTool({
|
|
132
|
+
id: "test-tool-b",
|
|
133
|
+
description: "Fetches weather for a location",
|
|
134
|
+
inputSchema: z.object({
|
|
135
|
+
location: z.string()
|
|
136
|
+
}),
|
|
137
|
+
outputSchema: z.object({
|
|
138
|
+
weather: z.string()
|
|
139
|
+
}),
|
|
140
|
+
resumeSchema: z.object({
|
|
141
|
+
approved: z.boolean()
|
|
142
|
+
}),
|
|
143
|
+
suspendSchema: z.object({
|
|
144
|
+
reason: z.string()
|
|
145
|
+
}),
|
|
146
|
+
execute: async ({ location }, { agent } = {}) => {
|
|
147
|
+
const { resumeData: { approved } = {}, suspend } = agent ?? {};
|
|
148
|
+
|
|
149
|
+
if (!approved) {
|
|
150
|
+
return suspend?.({ reason: "Approval required." });
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const response = await fetch(`https://wttr.in/${location}?format=3`);
|
|
154
|
+
const weather = await response.text();
|
|
155
|
+
|
|
156
|
+
return { weather };
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
With this approach the stream will include a `tool-call-suspended` chunk, and the `suspendPayload` will contain the `reason` defined by the tool's `suspendSchema`. To continue the call, invoke `resumeStream` with the required `resumeSchema` and the `runId`.
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
const stream = await agent.stream("What's the weather in London?");
|
|
165
|
+
|
|
166
|
+
for await (const chunk of stream.fullStream) {
|
|
167
|
+
if (chunk.type === "tool-call-suspended") {
|
|
168
|
+
console.log(chunk.payload.suspendPayload);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const handleResume = async () => {
|
|
173
|
+
const resumedStream = await agent.resumeStream({ approved: true }, { runId: stream.runId });
|
|
174
|
+
|
|
175
|
+
for await (const chunk of resumedStream.textStream) {
|
|
176
|
+
process.stdout.write(chunk);
|
|
177
|
+
}
|
|
178
|
+
process.stdout.write("\n");
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Related
|
|
184
|
+
|
|
185
|
+
- [Using Tools](./using-tools)
|
|
186
|
+
- [Agent Overview](./overview)
|
|
187
|
+
- [Tools Overview](../mcp/overview)
|
|
188
|
+
- [Agent Memory](./agent-memory)
|
|
189
|
+
- [Request Context](/docs/v1/server-db/request-context)
|