ai-sdk-ui-master

Expert skill for AI SDK UI (v6), ai package, and ai-elements in AgentStack with Mastra backend.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "ai-sdk-ui-master" with this command: npx skills add ssdeanx/agentstack/ssdeanx-agentstack-ai-sdk-ui-master

AI SDK UI Master

Expert skill for AI SDK UI (v6), ai package, and ai-elements in AgentStack with Mastra backend.

Stack Overview

Package Version Purpose

ai

^6.0.97 UIMessage, parts, createUIMessageStream, createUIMessageStreamResponse, type guards

@ai-sdk/react

^3.0.99 useChat hook

@mastra/ai-sdk

^1.0.5 toAISdkStream, chatRoute, networkRoute, workflowRoute

ai-elements local 50+ components in src/components/ai-elements/

Key File Map

Purpose Location

Chat provider app/chat/providers/chat-context.tsx

Chat types app/chat/providers/chat-context-types.ts

Message rendering app/chat/components/chat-messages.tsx

Stream conversion lib/client-stream-to-ai-sdk.ts

API chat route app/api/chat/route.ts

MastraClient lib/mastra-client.ts

Agent config app/chat/config/agents.ts

Base ai-elements (library components)

Reusable building blocks in src/components/ai-elements/ — not in tools/ or custom/ .

Category Location Reference

Conversation & Messaging src/components/ai-elements/

Base: conversation-messaging

Code & Development src/components/ai-elements/

Base: code-development

Reasoning & Debugging src/components/ai-elements/

Base: reasoning-debugging

Input & Controls src/components/ai-elements/

Base: input-controls

Visualization & Canvas src/components/ai-elements/

Base: visualization-canvas

Media & Audio src/components/ai-elements/

Base: media-audio

Agent & Tool (base) src/components/ai-elements/ — Tool, ToolHeader, ToolContent, etc. Base: agent-tool

Other (base) src/components/ai-elements/ — loader, context, sources, plan, … Base: other

Custom tool UIs (project-specific)

Mastra tool result renderers in src/components/ai-elements/tools/ . They use base ai-elements (e.g. tool.tsx ).

What Location Reference

Custom tool UIs ↔ Mastra src/components/ai-elements/tools/

Part 3: Custom tool UIs

Backend → toolName → UI table — Backend → stream toolName → UI mapping

Other project-specific src/components/ai-elements/custom/

Part 4: Other project-specific (custom/)

Tool name → UI: Stream toolName is matched in app/chat/components/agent-tools.tsx ; custom UIs live in src/components/ai-elements/tools/ . Fallback uses base Tool /ToolHeader /ToolContent from tool.tsx . Types from ai-elements/tools/types.ts via InferUITool<typeof mastraTool> .

Mastra Backend (one reference per subdirectory)

Purpose Location Reference

Mastra entry src/mastra/index.ts

mastra-reference.md

Agents (31+) src/mastra/agents/

mastra-reference.md

Tools (60+) src/mastra/tools/

mastra-reference.md

Networks (13) src/mastra/networks/

mastra-reference.md

Workflows (15+) src/mastra/workflows/

mastra-reference.md

Config src/mastra/config/

mastra-reference.md

A2A coordination src/mastra/a2a/

mastra-reference.md

MCP server src/mastra/mcp/

mastra-reference.md

Evals/scorers src/mastra/evals/

mastra-reference.md

Services src/mastra/services/

mastra-reference.md

Data src/mastra/data/

mastra-reference.md

Policy src/mastra/policy/

mastra-reference.md

Transport Pattern

Chat connects directly to Mastra API (NEXT_PUBLIC_MASTRA_API_URL , default http://localhost:4111 ). Do not use MastraClient for chat streaming.

import { useChat } from '@ai-sdk/react' import { DefaultChatTransport } from 'ai' import { RequestContext, MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY } from '@mastra/core/request-context'

const MASTRA_API_URL = process.env.NEXT_PUBLIC_MASTRA_API_URL ?? 'http://localhost:4111'

const transport = new DefaultChatTransport({ api: ${MASTRA_API_URL}/chat/${selectedAgent}, prepareSendMessagesRequest({ messages: outgoingMessages }) { const last = outgoingMessages[outgoingMessages.length - 1] const textPart = last?.parts?.find((p): p is TextUIPart => p.type === 'text') const requestContext = new RequestContext() requestContext.set(MASTRA_RESOURCE_ID_KEY, resourceId) requestContext.set(MASTRA_THREAD_ID_KEY, threadId)

return {
  body: {
    id: selectedAgent,
    messages: outgoingMessages,
    memory: { thread: threadId, resource: resourceId },
    resourceId,
    data: { agentId: selectedAgent, threadId, input: textPart?.text ?? '' },
    requestContext,
  },
}

}, })

const { messages, sendMessage, stop, status } = useChat({ transport })

UIMessage Parts (AI SDK v6)

Use message.parts , not message.content . Each part has a type discriminator.

Part Type Type Guard Purpose

text

isTextUIPart

Text content

reasoning

isReasoningUIPart

Thinking/reasoning

tool-* / dynamic-tool

isToolUIPart / isToolOrDynamicToolUIPart

Tool invocations

file

isFileUIPart

Attachments

source-url / source-document

— Citations

data

isDataUIPart

Structured data

import { isTextUIPart, isReasoningUIPart, isToolOrDynamicToolUIPart, isFileUIPart, isDataUIPart, } from 'ai'

const textPart = message.parts?.find(isTextUIPart) const content = textPart?.text ?? ''

const tools = message.parts?.filter(isToolOrDynamicToolUIPart) const fileParts = message.parts?.filter(isFileUIPart)

AI Elements Integration Map

Component File AI Elements Used

chat-messages.tsx

Conversation, Message, CodeBlock, Attachments, AudioPlayer, Transcription, Image

agent-reasoning.tsx

Reasoning, ReasoningTrigger, ReasoningContent

agent-chain-of-thought.tsx

ChainOfThought, ChainOfThoughtHeader, ChainOfThoughtContent, ChainOfThoughtStep

agent-tools.tsx

Tool, ToolHeader, ToolInput, ToolOutput

agent-sources.tsx

Sources, SourcesTrigger, SourcesContent, Source

agent-artifact.tsx

Artifact, ArtifactHeader, ArtifactContent, ArtifactActions, ArtifactCode

agent-sandbox.tsx

Sandbox, FileTree, Terminal, TestResults, SchemaDisplay, StackTrace

agent-workflow.tsx

Canvas, Node, Edge, Panel

chat-input.tsx

PromptInput, SpeechInput, Context (token usage), ModelSelector

Import from @/src/components/ai-elements/<component> :

import { Message, MessageContent, MessageResponse } from '@/src/components/ai-elements/message' import { Reasoning, ReasoningTrigger, ReasoningContent } from '@/src/components/ai-elements/reasoning' import { Tool, ToolHeader, ToolInput, ToolOutput } from '@/src/components/ai-elements/tool'

Agent Config Features

agentConfig.features controls which agent-* components render. Check before rendering:

const { agentConfig } = useChatContext()

if (agentConfig.features.reasoning) { // Render AgentReasoning } if (agentConfig.features.tools) { // Render AgentTools } if (agentConfig.features.sources) { // Render AgentSources } if (agentConfig.features.artifacts) { // Render AgentArtifact }

See app/chat/config/agents.ts for full AgentFeatures schema.

Mastra Stream Conversion

Server-side (Next.js API routes)

import { toAISdkStream } from '@mastra/ai-sdk' import { createUIMessageStream, createUIMessageStreamResponse } from 'ai'

const stream = await agent.stream(messages, { threadId, resourceId, requestContext })

const uiStream = createUIMessageStream({ originalMessages: messages, execute: async ({ writer }) => { const aiStream = toAISdkStream(stream, { from: 'agent', sendReasoning: true, sendSources: true, }) for await (const value of aiStream) { await writer.write(value) } }, })

return createUIMessageStreamResponse({ stream: uiStream })

Mastra chatRoute config (src/mastra/index.ts)

chatRoute({ path: '/chat/:agentId', sendStart: true, sendFinish: true, sendReasoning: true, sendSources: true, })

MastraClient vs Direct Transport

Use Case Approach

Chat streaming DefaultChatTransport → Mastra API directly

Network streaming DefaultChatTransport → /network/:agentId

Workflow streaming DefaultChatTransport → /workflow/:workflowId

Dashboard (agents, workflows, traces, threads) MastraClient from lib/mastra-client.ts

Do not use MastraClient for chat/network/workflow streaming.

Anti-Patterns

  • Do not use MastraClient for chat streaming — use DefaultChatTransport.

  • Use message.parts not message.content — AI SDK v6 is parts-based.

  • Import type guards from ai — not custom implementations.

  • Check agentConfig.features before rendering agent-* components.

  • Use RequestContext for multi-tenancy (resourceId, threadId) in prepareSendMessagesRequest.

Quick Reference

ChatContext value (useChatContext)

  • messages , status , isLoading , error

  • sendMessage(text, files?) , stopGeneration() , clearMessages()

  • selectedAgent , agentConfig , selectAgent(id)

  • streamingContent , streamingReasoning , toolInvocations , sources

  • threadId , resourceId , setThreadId , setResourceId

  • webPreview , setWebPreview , checkpoints , createCheckpoint , restoreCheckpoint

Endpoints

  • Chat: ${MASTRA_API_URL}/chat/${agentId}

  • Network: ${MASTRA_API_URL}/network/${agentId}

  • Workflow: ${MASTRA_API_URL}/workflow/${workflowId}

Additional Resources

  • AI Elements (one ref per category): ai-elements-reference.md

  • Mastra backend (one ref per subdir): mastra-reference.md

  • Agent config, API routes: reference.md

  • Agent config schema: app/chat/config/agents.ts

  • app/api/mastra routes: agents, workflows, threads, traces, tools, vectors, memory

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

test-cases

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

product-requirements

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

gemini

No summary provided by upstream source.

Repository SourceNeeds Review