### Creating Workflows with Mastra AI (TypeScript) Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Illustrates how to define and execute complex, multi-step processes using Mastra AI's workflow capabilities. This example chains a weather fetching step with an activity planning step, demonstrating input/output handling and agent interaction within a workflow. ```typescript // src/mastra/workflows/activities-workflow.ts import { createStep, createWorkflow } from "@mastra/core/workflows"; import { z } from "zod"; const fetchWeather = createStep({ id: "fetch-weather", description: "Get weather for a location", inputSchema: z.object({ location: z.string().describe("The location to get the weather for"), }), outputSchema: z.object({ temperature: z.number(), conditions: z.string(), location: z.string(), }), execute: async ({ inputData }) => { // Fetch weather data... return { temperature: 22, conditions: "Sunny", location: inputData.location }; }, }); const planActivities = createStep({ id: "plan-activities", description: "Suggests activities based on weather conditions", inputSchema: z.object({ temperature: z.number(), conditions: z.string(), location: z.string(), }), outputSchema: z.object({ activities: z.string(), }), execute: async ({ inputData, mastra }) => { const agent = mastra?.getAgent("weatherAgent"); if (!agent) throw new Error("Weather agent not found"); const prompt = `Based on the weather in ${inputData.location} (${inputData.temperature}C, ${inputData.conditions}), suggest appropriate activities.`; const response = await agent.stream([{ role: "user", content: prompt }]); let activitiesText = ""; for await (const chunk of response.textStream) { activitiesText += chunk; } return { activities: activitiesText }; }, }); export const activitiesWorkflow = createWorkflow({ id: "weather-workflow", description: "Suggests activities based on weather forecast", inputSchema: z.object({ location: z.string().describe("The location to get the weather for"), }), outputSchema: z.object({ activities: z.string(), }), }) .then(fetchWeather) .then(planActivities); activitiesWorkflow.commit(); ``` -------------------------------- ### Get Memory Status with useMemory Hook (TypeScript) Source: https://context7.com/mastra-ai/ui-dojo/llms.txt The `useMemory` hook retrieves the memory status for a given agent. It leverages `react-query` for efficient data fetching. The hook takes an optional `agentId` and enables the query only when an `agentId` is present. Memory status is considered stale after 5 minutes. ```typescript export const useMemory = (agentId?: string) => { const client = useMastraClient(); return useQuery({ queryKey: ["memory", agentId], queryFn: () => (agentId ? client.getMemoryStatus(agentId) : null), enabled: Boolean(agentId), staleTime: 5 * 60 * 1000, }); }; ``` -------------------------------- ### Configure Mastra Server with AI SDK and CopilotKit Integration (TypeScript) Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Sets up the Mastra server, registering agents, workflows, and API routes for AI SDK and CopilotKit integrations. It configures storage, logging, and server settings including CORS and API endpoints for chat, workflows, networks, and CopilotKit. ```typescript // src/mastra/index.ts import { Mastra } from "@mastra/core/mastra"; import { registerCopilotKit } from "@ag-ui/mastra/copilotkit"; import { PinoLogger } from "@mastra/loggers"; import { LibSQLStore } from "@mastra/libsql"; import { chatRoute, workflowRoute, networkRoute } from "@mastra/ai-sdk"; import { ghibliAgent } from "./agents/ghibli-agent"; import { weatherAgent } from "./agents/weather-agent"; import { routingAgent } from "./agents/routing-agent"; import { activitiesWorkflow } from "./workflows/activities-workflow"; export const mastra = new Mastra({ agents: { ghibliAgent, weatherAgent, routingAgent, }, workflows: { activitiesWorkflow, }, storage: new LibSQLStore({ id: "mastra-storage", url: ":memory:", }), logger: new PinoLogger({ name: "Mastra", level: "info", }), server: { port: 4750, cors: { origin: "*", allowMethods: ["*"], allowHeaders: ["*"], }, apiRoutes: [ // Chat endpoint for direct agent communication chatRoute({ path: "/chat/:agentId", }), // Workflow endpoint for multi-step processes workflowRoute({ path: "/workflow/:workflowId", }), // Network endpoint for agent coordination networkRoute({ path: "/network", agent: "routingAgent", }), // CopilotKit integration registerCopilotKit({ path: "/copilotkit", resourceId: "copilotkit-resource", }), ], }, }); ``` -------------------------------- ### Create and Execute Client-Side Agent Tools Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Shows how to define a tool that interacts with the browser DOM and integrate it into a React component using the useChat hook. The onToolCall handler intercepts tool requests from the agent to execute client-side logic. ```typescript import { createTool } from "@mastra/client-js"; import z from "zod"; export function changeBgColor(color: string) { if (typeof window !== "undefined") { document.body.style.setProperty("--background", color); } } export const colorChangeTool = createTool({ id: "changeColor", description: "Changes the background color", inputSchema: z.object({ color: z.string(), }), }); const ClientToolDemo = () => { const { messages, sendMessage } = useChat({ transport: new DefaultChatTransport({ api: `${MASTRA_BASE_URL}/chat/bgColorAgent`, }), onToolCall: ({ toolCall }) => { if (toolCall.toolName === "colorChangeTool") { changeBgColor(toolCall.input.color); } }, }); return (
); }; ``` -------------------------------- ### Consume Agent Networks in React Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Shows how to consume streamed agent coordination data from a network route, displaying active agent steps and their respective inputs/outputs. ```typescript import { useChat } from "@ai-sdk/react"; import { DefaultChatTransport } from "ai"; const NetworkDemo = () => { const [input, setInput] = useState(""); const { messages, sendMessage, status } = useChat({ transport: new DefaultChatTransport({ api: `${MASTRA_BASE_URL}/network`, }), }); return (
setInput(e.target.value)} /> {messages.map((message) => (
{message.parts.map((part, i) => { if (part.type === "text") { return

{part.text}

; } if (part.type === "data-network") { const networkData = part.data; const steps = networkData.steps || []; return (

Agent Network Execution ({networkData.status})

{steps.map((step, stepIndex) => (
{step.name}: {step.status} {step.input &&
Input: {JSON.stringify(step.input)}
} {step.output &&
Output: {JSON.stringify(step.output)}
}
))}
); } return null; })}
))}
); }; ``` -------------------------------- ### Implement Human-in-the-Loop Workflow with Mastra Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Demonstrates how to create a multi-step workflow that suspends execution to await user approval. It utilizes suspendSchema and resumeSchema to handle state transitions between the initial request, approval, and finalization steps. ```typescript import { createStep, createWorkflow } from "@mastra/core/workflows"; import { z } from "zod"; const processRequest = createStep({ id: "process-request", description: "Process the initial request", inputSchema: z.object({ requestType: z.string(), amount: z.number().optional(), details: z.string(), }), outputSchema: z.object({ requestId: z.string(), summary: z.string(), }), execute: async ({ inputData }) => { const requestId = `REQ-${Date.now()}`; return { requestId, summary: `Request for ${inputData.requestType}: ${inputData.details}`, }; }, }); const requestApproval = createStep({ id: "request-approval", description: "Request approval from user before proceeding", inputSchema: z.object({ requestId: z.string(), summary: z.string(), }), outputSchema: z.object({ approved: z.boolean(), requestId: z.string(), approvedBy: z.string().optional(), }), resumeSchema: z.object({ approved: z.boolean(), approverName: z.string().optional(), }), suspendSchema: z.object({ message: z.string(), requestId: z.string(), }), execute: async ({ inputData, resumeData, suspend, bail }) => { if (resumeData?.approved === false) { return bail({ message: `Request ${inputData.requestId} rejected.` }); } if (resumeData?.approved) { return { approved: true, requestId: inputData.requestId, approvedBy: resumeData.approverName || "User", }; } return await suspend({ message: `Please review request: ${inputData.summary}`, requestId: inputData.requestId, }); }, }); const finalizeRequest = createStep({ id: "finalize-request", description: "Finalize the approved request", inputSchema: z.object({ approved: z.boolean(), requestId: z.string(), approvedBy: z.string().optional(), }), outputSchema: z.object({ status: z.string(), message: z.string(), }), execute: async ({ inputData }) => ({ status: "approved", message: `Request ${inputData.requestId} approved by ${inputData.approvedBy}!`, }), }); export const approvalWorkflow = createWorkflow({ id: "approval-workflow", description: "Workflow with human approval step", inputSchema: z.object({ requestType: z.string(), amount: z.number().optional(), details: z.string(), }), outputSchema: z.object({ status: z.string(), message: z.string(), }), }) .then(processRequest) .then(requestApproval) .then(finalizeRequest); approvalWorkflow.commit(); ``` -------------------------------- ### Generative UI with Tool Rendering (TypeScript) Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Demonstrates how to create a generative UI that customizes the rendering of tool outputs using the useChat hook from @ai-sdk/react. It handles different message types, including text and tool-specific outputs like weather data, and allows for custom component rendering based on tool state. ```typescript // src/pages/ai-sdk/generative-user-interfaces.tsx import { useChat } from "@ai-sdk/react"; import { DefaultChatTransport } from "ai"; import { Weather } from "@/components/weather"; const GenerativeUIDemo = () => { const [input, setInput] = useState(""); const { messages, sendMessage, status } = useChat({ transport: new DefaultChatTransport({ api: `${MASTRA_BASE_URL}/chat/weatherAgent`, }), }); return (
{ e.preventDefault(); sendMessage({ text: input }); setInput(""); }}> setInput(e.target.value)} placeholder="Enter a city name" />
{messages.map((message) => (
{message.parts.map((part, index) => { // Render user messages as text if (part.type === "text" && message.role === "user") { return

{part.text}

; } // Render tool outputs with custom Weather component if (part.type === "tool-weatherTool") { switch (part.state) { case "input-available": return Loading weather...; case "output-available": return ; case "output-error": return Error: {part.errorText}; default: return null; } } return null; })}
))}
); }; ``` -------------------------------- ### Integrate Mastra Agents with Vercel AI SDK useChat Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Demonstrates connecting a frontend application to a Mastra agent endpoint using the Vercel AI SDK's useChat hook. It includes custom transport configuration and message handling for text and reasoning parts. ```typescript import { useChat } from "@ai-sdk/react"; import { DefaultChatTransport } from "ai"; const MASTRA_BASE_URL = "http://localhost:4750"; const AISdkDemo = () => { const [input, setInput] = useState(""); const [model, setModel] = useState("openai/gpt-4o-mini"); const { messages, sendMessage, status, regenerate } = useChat({ transport: new DefaultChatTransport({ api: `${MASTRA_BASE_URL}/chat/ghibliAgent`, }), }); const handleSubmit = (message) => { if (!message.text) return; sendMessage( { text: message.text, files: message.files }, { body: { model: model } } ); setInput(""); }; return (
{messages.map((message) => (
{message.parts.map((part, i) => { if (part.type === "text") { return

{part.text}

; } if (part.type === "reasoning") { return
Reasoning{part.text}
; } return null; })}
))} {status === "submitted" && Loading...} setInput(e.target.value)} />
); }; ``` -------------------------------- ### Integrate Assistant UI with Mastra using useExternalStoreRuntime Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Connects the Assistant UI Thread component to Mastra's messaging system. It uses a custom provider to map Mastra chat events to the Assistant UI runtime, supporting streaming responses and message cancellation. ```typescript import { toAssistantUIMessage, useChat, type MastraUIMessage } from "@mastra/react"; import { toAISdkV5Messages } from "@mastra/ai-sdk/ui"; import { AssistantRuntimeProvider, useExternalStoreRuntime, type AppendMessage } from "@assistant-ui/react"; import { Thread } from "@/components/assistant-ui/thread"; const CustomRuntimeProvider = ({ children, agentId, initialMessages, threadId }) => { const { messages, sendMessage, cancelRun, isRunning, setMessages } = useChat({ agentId, initializeMessages: () => initialMessages || [], }); const abortControllerRef = useRef(null); const onNew = async (message: AppendMessage) => { if (message.content[0]?.type !== "text") { throw new Error("Only text messages are supported"); } const input = message.content[0].text; const controller = new AbortController(); abortControllerRef.current = controller; try { await sendMessage({ message: input, mode: "stream", threadId, signal: controller.signal, }); } catch (error) { if (error.name !== "AbortError") { setMessages((curr) => [ ...curr, { role: "assistant", parts: [{ type: "text", text: `${error}` }] }, ]); } } }; const onCancel = async () => { abortControllerRef.current?.abort(); cancelRun?.(); }; const runtime = useExternalStoreRuntime({ isRunning, messages: messages.map(toAssistantUIMessage), convertMessage: (x) => x, onNew, onCancel, }); return ( {children} ); }; ``` -------------------------------- ### Consume Mastra Workflows in React Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Demonstrates how to use the useChat hook with DefaultChatTransport to stream workflow status and outputs from a Mastra backend to a React UI. ```typescript import { useChat } from "@ai-sdk/react"; import { DefaultChatTransport } from "ai"; const WorkflowDemo = () => { const [input, setInput] = useState(""); const { messages, sendMessage, status } = useChat({ transport: new DefaultChatTransport({ api: `${MASTRA_BASE_URL}/workflow/activitiesWorkflow`, prepareSendMessagesRequest: ({ messages }) => ({ body: { inputData: { location: messages[messages.length - 1].parts[0].text, }, }, }), }), }); return (
{ e.preventDefault(); sendMessage({ text: input }); setInput(""); }}> setInput(e.target.value)} placeholder="Enter a city name" />
{messages.map((message) => (
{message.parts.map((part, index) => { if (part.type === "data-workflow") { const steps = Object.values(part.data.steps); return (
{steps.map((step) => (
{step.name}: {step.status} {step.status === "success" &&
{JSON.stringify(step.output, null, 2)}
}
))}
); } return null; })}
))}
); }; ``` -------------------------------- ### Integrate CopilotKit with Mastra Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Configures the CopilotKit React components to communicate with a Mastra agent. Requires the runtime URL of the Mastra server and the specific agent identifier. ```typescript import { CopilotChat } from "@copilotkit/react-ui"; import { CopilotKit } from "@copilotkit/react-core"; import "@copilotkit/react-ui/styles.css"; const MASTRA_BASE_URL = "http://localhost:4750"; function CopilotKitDemo() { return ( ); } ``` -------------------------------- ### Create Weather Agent with Memory and Tools (TypeScript) Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Defines a 'Weather Agent' using Mastra's Agent class, including its ID, name, description, instructions, model, tools, and memory. This agent is designed to provide weather information using a predefined 'weatherTool'. ```typescript // src/mastra/agents/weather-agent.ts import { Agent } from "@mastra/core/agent"; import { Memory } from "@mastra/memory"; import { weatherTool } from "../tools/weather-tool"; export const weatherAgent = new Agent({ id: "weather-agent", name: "Weather Agent", description: "This agent provides weather information for a given location", instructions: ` You are a helpful weather assistant that provides accurate weather information. Your primary function is to help users get weather details for specific locations. - Always ask for a location if none is provided - If the location name isn't in English, please translate it - Include relevant details like humidity, wind conditions, and precipitation - Keep responses concise but informative Use the weatherTool to fetch current weather data. `, model: "openai/gpt-4o-mini", tools: { weatherTool }, memory: new Memory(), }); ``` -------------------------------- ### Configure Multi-Agent Networks Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Defines a routing agent that coordinates specialized agents and workflows, enabling complex task delegation based on user intent. ```typescript import { Agent } from "@mastra/core/agent"; import { weatherAgent } from "./weather-agent"; import { ghibliAgent } from "./ghibli-agent"; import { Memory } from "@mastra/memory"; import { activitiesWorkflow } from "../workflows/activities-workflow"; export const routingAgent = new Agent({ id: "routing-agent", name: "Routing Agent", instructions: `You are a routing agent that directs user queries to the appropriate specialized agent.\n\n Available agents:\n - weatherAgent: Provides weather information for specific locations.\n - ghibliAgent: Answers questions about Studio Ghibli films and characters.\n\n Available workflows:\n - activitiesWorkflow: Helps plan activities in various cities.\n\n Route queries based on topic: weather queries to Weather Agent, Ghibli queries to Ghibli Agent, activity planning to the workflow.`, model: "openai/gpt-4o-mini", agents: { weatherAgent, ghibliAgent, }, workflows: { activitiesWorkflow, }, memory: new Memory(), }); ``` -------------------------------- ### Fetch Agent Details with useAgent Hook (TypeScript) Source: https://context7.com/mastra-ai/ui-dojo/llms.txt The `useAgent` hook fetches details for a specific agent using the Mastra client. It utilizes `react-query` for data fetching and caching. It requires an `agentId` and returns query state including data, loading, and error information. The query is enabled only when an `agentId` is provided. ```typescript import { useMastraClient } from "@mastra/react"; import { useQuery } from "@tanstack/react-query"; export const useAgent = (agentId?: string) => { const client = useMastraClient(); return useQuery({ queryKey: ["agent", agentId], queryFn: () => (agentId ? client.getAgent(agentId).details() : null), retry: false, enabled: Boolean(agentId), }); }; ``` -------------------------------- ### Create Custom Tools with Zod Schemas in Mastra Source: https://context7.com/mastra-ai/ui-dojo/llms.txt Defines an executable tool using Mastra's createTool function. It utilizes Zod to enforce strict input and output schemas, ensuring data integrity during agent execution. ```typescript import { createTool } from "@mastra/core/tools"; import { z } from "zod"; export const forecastSchema = z.object({ date: z.string(), maxTemp: z.number(), minTemp: z.number(), precipitationChance: z.number(), temperature: z.number(), feelsLike: z.number(), humidity: z.number(), windSpeed: z.number(), windGust: z.number(), conditions: z.string(), location: z.string(), icon: z.string(), }); export const weatherTool = createTool({ id: "get-weather", description: "Get current weather for a location", inputSchema: z.object({ location: z.string().describe("The location to get the weather for"), }), outputSchema: forecastSchema, execute: async (inputData) => { const geocodingUrl = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(inputData.location)}&count=1`; const geocodingResponse = await fetch(geocodingUrl); const geocodingData = await geocodingResponse.json(); if (!geocodingData.results?.[0]) { throw new Error(`Location '${inputData.location}' not found`); } const { latitude, longitude, name } = geocodingData.results[0]; const weatherUrl = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,wind_gusts_10m,weather_code&hourly=precipitation_probability,temperature_2m`; const response = await fetch(weatherUrl); const data = await response.json(); return { date: new Date().toISOString(), maxTemp: Math.max(...data.hourly.temperature_2m), minTemp: Math.min(...data.hourly.temperature_2m), temperature: data.current.temperature_2m, feelsLike: data.current.apparent_temperature, humidity: data.current.relative_humidity_2m, windSpeed: data.current.wind_speed_10m, windGust: data.current.wind_gusts_10m, conditions: "Clear sky", location: name, precipitationChance: Math.max(...data.hourly.precipitation_probability), icon: "sun", }; }, }); ``` -------------------------------- ### List Memory Threads with useThreads Hook (TypeScript) Source: https://context7.com/mastra-ai/ui-dojo/llms.txt The `useThreads` hook lists memory threads associated with a resource and agent. It depends on `react-query` and the Mastra client. The hook requires `resourceId`, `agentId`, and `isMemoryEnabled` as parameters. The query is only executed if `isMemoryEnabled` is true. ```typescript export const useThreads = ({ resourceId, agentId, isMemoryEnabled }) => { const client = useMastraClient(); return useQuery({ queryKey: ["memory", "threads", resourceId, agentId], queryFn: async () => { if (!isMemoryEnabled) return null; const result = await client.listMemoryThreads({ resourceId, agentId }); return result.threads; }, enabled: Boolean(isMemoryEnabled), }); }; ``` -------------------------------- ### Fetch Agent Messages with useAgentMessages Hook (TypeScript) Source: https://context7.com/mastra-ai/ui-dojo/llms.txt The `useAgentMessages` hook fetches messages for a specific thread belonging to an agent. It uses `react-query` for data management. This hook requires `threadId`, `agentId`, and `memory` object. The query is enabled only if `memory` is truthy and `threadId` is provided. ```typescript export const useAgentMessages = ({ threadId, agentId, memory }) => { const client = useMastraClient(); return useQuery({ queryKey: ["memory", "messages", threadId, agentId], queryFn: () => threadId ? client.listThreadMessages(threadId, { agentId }) : null, enabled: memory && Boolean(threadId), }); }; ``` -------------------------------- ### Delete Thread with useDeleteThread Hook (TypeScript) Source: https://context7.com/mastra-ai/ui-dojo/llms.txt The `useDeleteThread` hook provides functionality to delete a memory thread. It utilizes `react-query`'s `useMutation` hook for handling mutations and `useQueryClient` for cache invalidation. The mutation function takes `threadId` and `agentId` to identify and delete the thread. On successful deletion, it invalidates the 'memory threads' query to refresh the list. ```typescript import { useMutation, useQueryClient } from "@tanstack/react-query"; export const useDeleteThread = () => { const client = useMastraClient(); const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ threadId, agentId }) => { const thread = client.getMemoryThread({ threadId, agentId }); return thread.delete(); }, onSuccess: (_, { agentId }) => { queryClient.invalidateQueries({ queryKey: ["memory", "threads", agentId, agentId] }); }, }); }; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.