Skip to content

Commit 65a2dd5

Browse files
committed
feat: Add comprehensive references and sidebar component for AI SDK UI
- Create `mastra-reference.md` to document the Mastra backend structure, including agents, tools, networks, workflows, configuration, A2A coordination, MCP server, evaluations, services, data processing, and policy definitions. - Create `reference.md` to provide an extended reference for AI elements, agent configuration schema, and API routes for the dashboard, linking to the newly created `mastra-reference.md`. - Implement `MainSidebar` component in `main-sidebar.tsx` to enhance the user interface with navigation for agents, tools, workflows, and observability features. - Fetch and display agents, tools, workflows, traces, threads, and vector indices from the backend. - Include collapsible sections for better organization of sidebar items. - Add functionality to select agents and create new threads directly from the sidebar.
1 parent a6c5687 commit 65a2dd5

13 files changed

Lines changed: 1876 additions & 596 deletions

File tree

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
---
2+
name: ai-sdk-ui-master
3+
description: Expert guidance for AI SDK UI (v6), @ai-sdk/react, and ai-elements in AgentStack. Use when building or modifying chat interfaces, streaming UIs, message rendering, tool displays, Mastra integration, or ai-elements components. Covers useChat, DefaultChatTransport, UIMessage parts, type guards, and Mastra toAISdkStream.
4+
---
5+
6+
# AI SDK UI Master
7+
8+
Expert skill for AI SDK UI (v6), `ai` package, and ai-elements in AgentStack with Mastra backend.
9+
10+
## Stack Overview
11+
12+
| Package | Version | Purpose |
13+
|---------|---------|---------|
14+
| `ai` | ^6.0.97 | UIMessage, parts, createUIMessageStream, createUIMessageStreamResponse, type guards |
15+
| `@ai-sdk/react` | ^3.0.99 | useChat hook |
16+
| `@mastra/ai-sdk` | ^1.0.5 | toAISdkStream, chatRoute, networkRoute, workflowRoute |
17+
| ai-elements | local | 50+ components in `src/components/ai-elements/` |
18+
19+
## Key File Map
20+
21+
| Purpose | Location |
22+
|---------|----------|
23+
| Chat provider | `app/chat/providers/chat-context.tsx` |
24+
| Chat types | `app/chat/providers/chat-context-types.ts` |
25+
| Message rendering | `app/chat/components/chat-messages.tsx` |
26+
| Stream conversion | `lib/client-stream-to-ai-sdk.ts` |
27+
| API chat route | `app/api/chat/route.ts` |
28+
| MastraClient | `lib/mastra-client.ts` |
29+
| Agent config | `app/chat/config/agents.ts` |
30+
31+
### Base ai-elements (library components)
32+
33+
Reusable building blocks in `src/components/ai-elements/`**not** in `tools/` or `custom/`.
34+
35+
| Category | Location | Reference |
36+
|----------|----------|-----------|
37+
| Conversation & Messaging | `src/components/ai-elements/` | [Base: conversation-messaging](ai-elements-reference.md#base-conversation-messaging) |
38+
| Code & Development | `src/components/ai-elements/` | [Base: code-development](ai-elements-reference.md#base-code-development) |
39+
| Reasoning & Debugging | `src/components/ai-elements/` | [Base: reasoning-debugging](ai-elements-reference.md#base-reasoning-debugging) |
40+
| Input & Controls | `src/components/ai-elements/` | [Base: input-controls](ai-elements-reference.md#base-input-controls) |
41+
| Visualization & Canvas | `src/components/ai-elements/` | [Base: visualization-canvas](ai-elements-reference.md#base-visualization-canvas) |
42+
| Media & Audio | `src/components/ai-elements/` | [Base: media-audio](ai-elements-reference.md#base-media-audio) |
43+
| Agent & Tool (base) | `src/components/ai-elements/` — Tool, ToolHeader, ToolContent, etc. | [Base: agent-tool](ai-elements-reference.md#base-agent-tool) |
44+
| Other (base) | `src/components/ai-elements/` — loader, context, sources, plan, … | [Base: other](ai-elements-reference.md#base-other) |
45+
46+
### Custom tool UIs (project-specific)
47+
48+
Mastra tool result renderers in `src/components/ai-elements/tools/`. They **use** base ai-elements (e.g. `tool.tsx`).
49+
50+
| What | Location | Reference |
51+
|------|----------|-----------|
52+
| Custom tool UIs ↔ Mastra | `src/components/ai-elements/tools/` | [Part 3: Custom tool UIs](ai-elements-reference.md#part-3-custom-tool-uis-project-specific) |
53+
| Backend → toolName → UI table || [Backend → stream toolName → UI mapping](ai-elements-reference.md#backend--stream-toolname--ui-mapping) |
54+
| Other project-specific | `src/components/ai-elements/custom/` | [Part 4: Other project-specific (custom/)](ai-elements-reference.md#part-4-other-project-specific-custom) |
55+
56+
**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>`.
57+
58+
### Mastra Backend (one reference per subdirectory)
59+
60+
| Purpose | Location | Reference |
61+
|---------|----------|-----------|
62+
| Mastra entry | `src/mastra/index.ts` | [mastra-reference.md](mastra-reference.md#src-mastra-index) |
63+
| Agents (31+) | `src/mastra/agents/` | [mastra-reference.md](mastra-reference.md#src-mastra-agents) |
64+
| Tools (60+) | `src/mastra/tools/` | [mastra-reference.md](mastra-reference.md#src-mastra-tools) |
65+
| Networks (13) | `src/mastra/networks/` | [mastra-reference.md](mastra-reference.md#src-mastra-networks) |
66+
| Workflows (15+) | `src/mastra/workflows/` | [mastra-reference.md](mastra-reference.md#src-mastra-workflows) |
67+
| Config | `src/mastra/config/` | [mastra-reference.md](mastra-reference.md#src-mastra-config) |
68+
| A2A coordination | `src/mastra/a2a/` | [mastra-reference.md](mastra-reference.md#src-mastra-a2a) |
69+
| MCP server | `src/mastra/mcp/` | [mastra-reference.md](mastra-reference.md#src-mastra-mcp) |
70+
| Evals/scorers | `src/mastra/evals/` | [mastra-reference.md](mastra-reference.md#src-mastra-evals) |
71+
| Services | `src/mastra/services/` | [mastra-reference.md](mastra-reference.md#src-mastra-services) |
72+
| Data | `src/mastra/data/` | [mastra-reference.md](mastra-reference.md#src-mastra-data) |
73+
| Policy | `src/mastra/policy/` | [mastra-reference.md](mastra-reference.md#src-mastra-policy) |
74+
75+
## Transport Pattern
76+
77+
Chat connects **directly** to Mastra API (`NEXT_PUBLIC_MASTRA_API_URL`, default `http://localhost:4111`). Do not use MastraClient for chat streaming.
78+
79+
```tsx
80+
import { useChat } from '@ai-sdk/react'
81+
import { DefaultChatTransport } from 'ai'
82+
import { RequestContext, MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY } from '@mastra/core/request-context'
83+
84+
const MASTRA_API_URL = process.env.NEXT_PUBLIC_MASTRA_API_URL ?? 'http://localhost:4111'
85+
86+
const transport = new DefaultChatTransport({
87+
api: `${MASTRA_API_URL}/chat/${selectedAgent}`,
88+
prepareSendMessagesRequest({ messages: outgoingMessages }) {
89+
const last = outgoingMessages[outgoingMessages.length - 1]
90+
const textPart = last?.parts?.find((p): p is TextUIPart => p.type === 'text')
91+
const requestContext = new RequestContext()
92+
requestContext.set(MASTRA_RESOURCE_ID_KEY, resourceId)
93+
requestContext.set(MASTRA_THREAD_ID_KEY, threadId)
94+
95+
return {
96+
body: {
97+
id: selectedAgent,
98+
messages: outgoingMessages,
99+
memory: { thread: threadId, resource: resourceId },
100+
resourceId,
101+
data: { agentId: selectedAgent, threadId, input: textPart?.text ?? '' },
102+
requestContext,
103+
},
104+
}
105+
},
106+
})
107+
108+
const { messages, sendMessage, stop, status } = useChat({ transport })
109+
```
110+
111+
## UIMessage Parts (AI SDK v6)
112+
113+
Use `message.parts`, not `message.content`. Each part has a `type` discriminator.
114+
115+
| Part Type | Type Guard | Purpose |
116+
|-----------|------------|---------|
117+
| `text` | `isTextUIPart` | Text content |
118+
| `reasoning` | `isReasoningUIPart` | Thinking/reasoning |
119+
| `tool-*` / `dynamic-tool` | `isToolUIPart` / `isToolOrDynamicToolUIPart` | Tool invocations |
120+
| `file` | `isFileUIPart` | Attachments |
121+
| `source-url` / `source-document` || Citations |
122+
| `data` | `isDataUIPart` | Structured data |
123+
124+
```tsx
125+
import {
126+
isTextUIPart,
127+
isReasoningUIPart,
128+
isToolOrDynamicToolUIPart,
129+
isFileUIPart,
130+
isDataUIPart,
131+
} from 'ai'
132+
133+
const textPart = message.parts?.find(isTextUIPart)
134+
const content = textPart?.text ?? ''
135+
136+
const tools = message.parts?.filter(isToolOrDynamicToolUIPart)
137+
const fileParts = message.parts?.filter(isFileUIPart)
138+
```
139+
140+
## AI Elements Integration Map
141+
142+
| Component File | AI Elements Used |
143+
|----------------|------------------|
144+
| `chat-messages.tsx` | Conversation, Message, CodeBlock, Attachments, AudioPlayer, Transcription, Image |
145+
| `agent-reasoning.tsx` | Reasoning, ReasoningTrigger, ReasoningContent |
146+
| `agent-chain-of-thought.tsx` | ChainOfThought, ChainOfThoughtHeader, ChainOfThoughtContent, ChainOfThoughtStep |
147+
| `agent-tools.tsx` | Tool, ToolHeader, ToolInput, ToolOutput |
148+
| `agent-sources.tsx` | Sources, SourcesTrigger, SourcesContent, Source |
149+
| `agent-artifact.tsx` | Artifact, ArtifactHeader, ArtifactContent, ArtifactActions, ArtifactCode |
150+
| `agent-sandbox.tsx` | Sandbox, FileTree, Terminal, TestResults, SchemaDisplay, StackTrace |
151+
| `agent-workflow.tsx` | Canvas, Node, Edge, Panel |
152+
| `chat-input.tsx` | PromptInput, SpeechInput, Context (token usage), ModelSelector |
153+
154+
Import from `@/src/components/ai-elements/<component>`:
155+
156+
```tsx
157+
import { Message, MessageContent, MessageResponse } from '@/src/components/ai-elements/message'
158+
import { Reasoning, ReasoningTrigger, ReasoningContent } from '@/src/components/ai-elements/reasoning'
159+
import { Tool, ToolHeader, ToolInput, ToolOutput } from '@/src/components/ai-elements/tool'
160+
```
161+
162+
## Agent Config Features
163+
164+
`agentConfig.features` controls which agent-* components render. Check before rendering:
165+
166+
```tsx
167+
const { agentConfig } = useChatContext()
168+
169+
if (agentConfig.features.reasoning) {
170+
// Render AgentReasoning
171+
}
172+
if (agentConfig.features.tools) {
173+
// Render AgentTools
174+
}
175+
if (agentConfig.features.sources) {
176+
// Render AgentSources
177+
}
178+
if (agentConfig.features.artifacts) {
179+
// Render AgentArtifact
180+
}
181+
```
182+
183+
See `app/chat/config/agents.ts` for full `AgentFeatures` schema.
184+
185+
## Mastra Stream Conversion
186+
187+
### Server-side (Next.js API routes)
188+
189+
```tsx
190+
import { toAISdkStream } from '@mastra/ai-sdk'
191+
import { createUIMessageStream, createUIMessageStreamResponse } from 'ai'
192+
193+
const stream = await agent.stream(messages, { threadId, resourceId, requestContext })
194+
195+
const uiStream = createUIMessageStream({
196+
originalMessages: messages,
197+
execute: async ({ writer }) => {
198+
const aiStream = toAISdkStream(stream, {
199+
from: 'agent',
200+
sendReasoning: true,
201+
sendSources: true,
202+
})
203+
for await (const value of aiStream) {
204+
await writer.write(value)
205+
}
206+
},
207+
})
208+
209+
return createUIMessageStreamResponse({ stream: uiStream })
210+
```
211+
212+
### Mastra chatRoute config (src/mastra/index.ts)
213+
214+
```ts
215+
chatRoute({
216+
path: '/chat/:agentId',
217+
sendStart: true,
218+
sendFinish: true,
219+
sendReasoning: true,
220+
sendSources: true,
221+
})
222+
```
223+
224+
## MastraClient vs Direct Transport
225+
226+
| Use Case | Approach |
227+
|----------|----------|
228+
| Chat streaming | `DefaultChatTransport` → Mastra API directly |
229+
| Network streaming | `DefaultChatTransport``/network/:agentId` |
230+
| Workflow streaming | `DefaultChatTransport``/workflow/:workflowId` |
231+
| Dashboard (agents, workflows, traces, threads) | `MastraClient` from `lib/mastra-client.ts` |
232+
233+
**Do not** use MastraClient for chat/network/workflow streaming.
234+
235+
## Anti-Patterns
236+
237+
1. **Do not use MastraClient for chat streaming** — use DefaultChatTransport.
238+
2. **Use `message.parts` not `message.content`** — AI SDK v6 is parts-based.
239+
3. **Import type guards from `ai`** — not custom implementations.
240+
4. **Check agentConfig.features** before rendering agent-* components.
241+
5. **Use RequestContext** for multi-tenancy (resourceId, threadId) in prepareSendMessagesRequest.
242+
243+
## Quick Reference
244+
245+
### ChatContext value (useChatContext)
246+
247+
- `messages`, `status`, `isLoading`, `error`
248+
- `sendMessage(text, files?)`, `stopGeneration()`, `clearMessages()`
249+
- `selectedAgent`, `agentConfig`, `selectAgent(id)`
250+
- `streamingContent`, `streamingReasoning`, `toolInvocations`, `sources`
251+
- `threadId`, `resourceId`, `setThreadId`, `setResourceId`
252+
- `webPreview`, `setWebPreview`, `checkpoints`, `createCheckpoint`, `restoreCheckpoint`
253+
254+
### Endpoints
255+
256+
- Chat: `${MASTRA_API_URL}/chat/${agentId}`
257+
- Network: `${MASTRA_API_URL}/network/${agentId}`
258+
- Workflow: `${MASTRA_API_URL}/workflow/${workflowId}`
259+
260+
## Additional Resources
261+
262+
- **AI Elements (one ref per category):** [ai-elements-reference.md](ai-elements-reference.md)
263+
- **Mastra backend (one ref per subdir):** [mastra-reference.md](mastra-reference.md)
264+
- Agent config, API routes: [reference.md](reference.md)
265+
- Agent config schema: `app/chat/config/agents.ts`
266+
- app/api/mastra routes: agents, workflows, threads, traces, tools, vectors, memory

0 commit comments

Comments
 (0)