|
| 1 | +<!-- AGENTS-META {"title":"Chat App","version":"1.0.0","applies_to":"app/chat/","last_updated":"2025-11-29T00:00:00Z","status":"stable"} --> |
| 2 | +# App/Chat |
| 3 | + |
| 4 | +## Overview |
| 5 | + |
| 6 | +The `/chat` route provides a rich AI chat interface built with **AI Elements** (30 components) integrated with **26+ Mastra agents**. Uses AI SDK v5 patterns with streaming, reasoning display, tool execution, and source citations. |
| 7 | + |
| 8 | +## Architecture |
| 9 | + |
| 10 | +```mermaid |
| 11 | +graph TB |
| 12 | + subgraph ChatPage["app/chat/page.tsx"] |
| 13 | + ChatProvider["ChatProvider (Context)"] |
| 14 | + ChatProvider --> ChatHeader |
| 15 | + ChatProvider --> ChatMessages |
| 16 | + ChatProvider --> ChatInput |
| 17 | + end |
| 18 | + |
| 19 | + subgraph Providers["providers/"] |
| 20 | + ChatContext["chat-context.tsx<br/>AI SDK v5 types"] |
| 21 | + end |
| 22 | + |
| 23 | + subgraph Components["components/"] |
| 24 | + ChatHeader["chat-header.tsx<br/>ModelSelector"] |
| 25 | + ChatMessages["chat-messages.tsx<br/>Conversation/Message"] |
| 26 | + ChatInput["chat-input.tsx<br/>PromptInput"] |
| 27 | + AgentReasoning["agent-reasoning.tsx<br/>Reasoning/ChainOfThought"] |
| 28 | + AgentTools["agent-tools.tsx<br/>Tool display"] |
| 29 | + AgentSources["agent-sources.tsx<br/>Sources citations"] |
| 30 | + AgentArtifact["agent-artifact.tsx<br/>Code artifacts"] |
| 31 | + end |
| 32 | + |
| 33 | + subgraph Config["config/"] |
| 34 | + AgentConfig["agents.ts<br/>26+ agent configs"] |
| 35 | + end |
| 36 | + |
| 37 | + subgraph AIElements["AI Elements (imported)"] |
| 38 | + Conversation |
| 39 | + Message |
| 40 | + PromptInput |
| 41 | + ModelSelector |
| 42 | + Reasoning |
| 43 | + Tool |
| 44 | + Sources |
| 45 | + Artifact |
| 46 | + end |
| 47 | + |
| 48 | + ChatPage --> Providers |
| 49 | + ChatPage --> Components |
| 50 | + Components --> Config |
| 51 | + Components --> AIElements |
| 52 | +``` |
| 53 | + |
| 54 | +## File Structure |
| 55 | + |
| 56 | +```plaintext |
| 57 | +app/chat/ |
| 58 | +├── page.tsx # Main chat page with ChatProvider |
| 59 | +├── providers/ |
| 60 | +│ └── chat-context.tsx # React Context with AI SDK v5 types |
| 61 | +├── config/ |
| 62 | +│ └── agents.ts # 26+ agent configurations with feature flags |
| 63 | +└── components/ |
| 64 | + ├── chat-header.tsx # Header with ModelSelector |
| 65 | + ├── chat-messages.tsx # Message list with streaming |
| 66 | + ├── chat-input.tsx # PromptInput with submit |
| 67 | + ├── agent-reasoning.tsx # Reasoning/ChainOfThought display |
| 68 | + ├── agent-tools.tsx # Tool invocation display |
| 69 | + ├── agent-sources.tsx # Sources citations for research |
| 70 | + └── agent-artifact.tsx # Code/content artifacts |
| 71 | +``` |
| 72 | + |
| 73 | +## Key Patterns |
| 74 | + |
| 75 | +### AI SDK v5 Compatibility |
| 76 | + |
| 77 | +The chat uses AI SDK v5 types and patterns: |
| 78 | + |
| 79 | +```typescript |
| 80 | +// Type imports |
| 81 | +import type { UIMessage, DynamicToolUIPart, TextUIPart, ReasoningUIPart } from "ai" |
| 82 | +import { isTextUIPart, isReasoningUIPart, isToolOrDynamicToolUIPart } from "ai" |
| 83 | + |
| 84 | +// Message parts (NOT content) |
| 85 | +const textPart = message.parts?.find(isTextUIPart) |
| 86 | +const content = textPart?.text || "" |
| 87 | + |
| 88 | +// Tool states: input-available, output-available, output-error |
| 89 | +const tools = message.parts?.filter(isToolOrDynamicToolUIPart) |
| 90 | +``` |
| 91 | + |
| 92 | +### Mastra Stream Chunk Types |
| 93 | + |
| 94 | +```typescript |
| 95 | +// From @mastra/core/stream ChunkType: |
| 96 | +case "text-delta": // Streaming text content |
| 97 | +case "reasoning-delta": // Streaming reasoning (NOT "reasoning") |
| 98 | +case "tool-call": // Tool invocation started |
| 99 | +case "tool-result": // Tool execution complete |
| 100 | +case "source": // Research sources |
| 101 | +case "finish": // payload.output.usage.inputTokens |
| 102 | +``` |
| 103 | + |
| 104 | +### Agent Configuration |
| 105 | + |
| 106 | +```typescript |
| 107 | +// config/agents.ts |
| 108 | +export interface AgentConfig { |
| 109 | + id: string |
| 110 | + name: string |
| 111 | + description: string |
| 112 | + category: 'core' | 'research' | 'content' | 'data' | 'financial' | 'diagram' | 'utility' |
| 113 | + features: { |
| 114 | + reasoning: boolean // Show Reasoning component |
| 115 | + chainOfThought: boolean // Show ChainOfThought steps |
| 116 | + tools: boolean // Show Tool invocations |
| 117 | + sources: boolean // Show Sources citations |
| 118 | + canvas: boolean // Show Canvas (future) |
| 119 | + artifacts: boolean // Show code artifacts |
| 120 | + fileUpload: boolean // Enable file attachments |
| 121 | + } |
| 122 | +} |
| 123 | +``` |
| 124 | + |
| 125 | +## Agent Categories |
| 126 | + |
| 127 | +| Category | Agents | Count | |
| 128 | +|----------|--------|-------| |
| 129 | +| **Core** | weatherAgent, a2aCoordinatorAgent | 2 | |
| 130 | +| **Research** | researchAgent, researchPaperAgent, documentProcessingAgent, knowledgeIndexingAgent | 4 | |
| 131 | +| **Content** | copywriterAgent, editorAgent, contentStrategistAgent, scriptWriterAgent, reportAgent | 5 | |
| 132 | +| **Data** | dataExportAgent, dataIngestionAgent, dataTransformationAgent | 3 | |
| 133 | +| **Financial** | stockAnalysisAgent, chartTypeAdvisorAgent, chartDataProcessorAgent, chartGeneratorAgent, chartSupervisorAgent | 5 | |
| 134 | +| **Diagram** | csvToExcalidrawAgent, imageToCsvAgent, excalidrawValidatorAgent | 3 | |
| 135 | +| **Utility** | evaluationAgent, learningExtractionAgent, dane, sqlAgent | 4 | |
| 136 | + |
| 137 | +## AI Elements Used |
| 138 | + |
| 139 | +| Component | File | Purpose | |
| 140 | +|-----------|------|---------| |
| 141 | +| `Conversation`, `ConversationContent`, `ConversationEmptyState`, `ConversationScrollButton` | chat-messages.tsx | Message container | |
| 142 | +| `Message`, `MessageContent`, `MessageResponse`, `MessageToolbar`, `MessageActions`, `MessageAction` | chat-messages.tsx | Individual messages | |
| 143 | +| `PromptInput`, `PromptInputTextarea`, `PromptInputFooter`, `PromptInputSubmit` | chat-input.tsx | Input form | |
| 144 | +| `ModelSelector`, `ModelSelectorTrigger`, `ModelSelectorContent`, `ModelSelectorList`, `ModelSelectorGroup`, `ModelSelectorItem` | chat-header.tsx | Agent selection | |
| 145 | +| `Reasoning`, `ReasoningTrigger`, `ReasoningContent` | agent-reasoning.tsx | AI thinking display | |
| 146 | +| `Tool`, `ToolHeader`, `ToolContent`, `ToolInput`, `ToolOutput` | agent-tools.tsx | Tool execution | |
| 147 | +| `Sources`, `SourcesTrigger`, `SourcesContent`, `Source` | agent-sources.tsx | Citations | |
| 148 | +| `Artifact`, `ArtifactHeader`, `ArtifactContent`, `ArtifactActions` | agent-artifact.tsx | Code artifacts | |
| 149 | +| `Loader` | chat-messages.tsx | Loading indicator | |
| 150 | +| `CodeBlock`, `CodeBlockCopyButton` | agent-artifact.tsx | Syntax highlighting | |
| 151 | + |
| 152 | +## Implementation Status |
| 153 | + |
| 154 | +| Task | Status | Description | |
| 155 | +|------|--------|-------------| |
| 156 | +| AIEL-001 | ✅ | ChatContext provider with AI SDK v5 | |
| 157 | +| AIEL-002 | ✅ | Agent config system (26+ agents) | |
| 158 | +| AIEL-003 | ✅ | ChatHeader with ModelSelector | |
| 159 | +| AIEL-004 | ✅ | ChatMessages with streaming | |
| 160 | +| AIEL-005 | ✅ | ChatInput with PromptInput | |
| 161 | +| AIEL-006 | ✅ | Reasoning display | |
| 162 | +| AIEL-007 | ✅ | Tool execution display | |
| 163 | +| AIEL-008 | ✅ | Sources citations | |
| 164 | +| AIEL-009 | ✅ | Context (token usage) tracking | |
| 165 | +| AIEL-010 | ✅ | File upload support | |
| 166 | +| AIEL-011 | ✅ | Artifact display | |
| 167 | +| AIEL-012 | ✅ | Page integration complete | |
| 168 | +| AIEL-013 | ⬜ | E2E tests | |
| 169 | + |
| 170 | +**Completion: 12/13 (92%)** |
| 171 | + |
| 172 | +## Usage |
| 173 | + |
| 174 | +```tsx |
| 175 | +// app/chat/page.tsx |
| 176 | +import { ChatProvider } from "./providers/chat-context" |
| 177 | +import { ChatHeader } from "./components/chat-header" |
| 178 | +import { ChatMessages } from "./components/chat-messages" |
| 179 | +import { ChatInput } from "./components/chat-input" |
| 180 | + |
| 181 | +export default function ChatPage() { |
| 182 | + return ( |
| 183 | + <ChatProvider defaultAgent="researchAgent"> |
| 184 | + <main className="flex h-screen flex-col bg-background"> |
| 185 | + <ChatHeader /> |
| 186 | + <ChatMessages /> |
| 187 | + <ChatInput /> |
| 188 | + </main> |
| 189 | + </ChatProvider> |
| 190 | + ) |
| 191 | +} |
| 192 | +``` |
| 193 | + |
| 194 | +## Remaining Work |
| 195 | + |
| 196 | +1. **AIEL-013**: Create `app/chat/__tests__/chat.test.tsx` with Vitest (optional) |
| 197 | + |
| 198 | +--- |
| 199 | + |
| 200 | +*Last updated: 2025-11-29* |
0 commit comments