--- name: ai-app description: | Full-stack AI application generator with Next.js, AI SDK, and ai-elements. Use when creating chatbots, agent dashboards, or custom AI applications. Triggers: chatbot, chat app, agent dashboard, AI application, Next.js AI, useChat, streamText, ai-elements, build AI app, create chatbot argument-hint: "[app-type or description]" --- # AI App Generator Build full-stack AI applications with Next.js, AI SDK, and ai-elements. ## Quick Start ### 1. Scaffold Project ```bash bunx --bun shadcn@latest create --preset "https://ui.shadcn.com/init?base=radix&style=nova&baseColor=neutral&theme=neutral&iconLibrary=lucide&font=geist-sans&menuAccent=subtle&menuColor=default&radius=default" --template next my-ai-app cd my-ai-app ``` ### 2. Install Dependencies ```bash bun add ai@6 @ai-sdk/react @ai-sdk/anthropic zod bunx --bun ai-elements@latest ``` > **Version:** the patterns below target **AI SDK 6** (`ToolLoopAgent`, > `createAgentUIStreamResponse`, `toUIMessageStreamResponse`), which is why the > install is pinned to `ai@6` — an unpinned `bun add ai` resolves to v7 and the > examples here will not match. For a v7 build, scaffold with these steps and > then follow `/ai-sdk-7` for the API surface. ### 3. Configure Environment ```bash # .env.local - Choose your provider ANTHROPIC_API_KEY=sk-ant-... # OPENAI_API_KEY=sk-... # GOOGLE_GENERATIVE_AI_API_KEY=... ``` ### 4. Generate Application Based on user requirements, generate: - **Chatbot**: See [references/chatbot.md](references/chatbot.md) - **Agent Dashboard**: See [references/agent-dashboard.md](references/agent-dashboard.md) - **Custom**: Combine patterns as needed ## Application Types ### Chatbot Simple conversational AI with streaming responses. | Feature | Implementation | |---------|----------------| | Chat UI | Conversation + Message + PromptInput | | API | streamText + toUIMessageStreamResponse | | Extras | Reasoning, Sources, File attachments | ### Agent Dashboard Multi-agent interface with tool visualization. | Feature | Implementation | |---------|----------------| | Agents | ToolLoopAgent with tools | | UI | Dashboard layout + Tool components | | API | createAgentUIStreamResponse | | Extras | Status monitoring, tool approval | ### Custom AI App Mix and match based on user needs: - Web search chatbot - Code generation assistant - Document analyzer - Multi-modal chat ## Project Structure ``` my-ai-app/ ├── app/ │ ├── page.tsx # Main UI │ ├── layout.tsx # Root layout │ ├── globals.css # Theme │ └── api/ │ └── chat/ │ └── route.ts # AI endpoint ├── components/ │ ├── ai-elements/ # AI Elements components │ ├── ui/ # shadcn/ui components │ └── chat.tsx # Chat component (if extracted) ├── lib/ │ ├── utils.ts # Utilities │ └── ai.ts # AI configuration (optional) ├── ai/ # Agent definitions (if needed) │ └── assistant.ts └── .env.local # API keys ``` See [references/project-structure.md](references/project-structure.md) for details. ## Core Patterns ### API Route ```typescript // app/api/chat/route.ts import { streamText, UIMessage, convertToModelMessages } from 'ai'; import { anthropic } from '@ai-sdk/anthropic'; export const maxDuration = 30; export async function POST(req: Request) { const { messages }: { messages: UIMessage[] } = await req.json(); const result = streamText({ model: anthropic('claude-sonnet-5'), messages: await convertToModelMessages(messages), system: 'You are a helpful assistant.', }); return result.toUIMessageStreamResponse({ sendSources: true, sendReasoning: true, }); } ``` ### Chat Page ```tsx // app/page.tsx 'use client'; import { useChat } from '@ai-sdk/react'; import { DefaultChatTransport } from 'ai'; import { Conversation, ConversationContent, ConversationScrollButton, } from '@/components/ai-elements/conversation'; import { Message, MessageContent, MessageResponse, } from '@/components/ai-elements/message'; import { PromptInput, PromptInputBody, PromptInputTextarea, PromptInputFooter, PromptInputSubmit, type PromptInputMessage, } from '@/components/ai-elements/prompt-input'; import { Loader } from '@/components/ai-elements/loader'; import { useState } from 'react'; export default function ChatPage() { const [input, setInput] = useState(''); const { messages, sendMessage, status } = useChat({ transport: new DefaultChatTransport({ api: '/api/chat' }), }); const handleSubmit = (message: PromptInputMessage) => { if (!message.text.trim()) return; sendMessage({ text: message.text, files: message.files }); setInput(''); }; return (