This guide provides detailed instructions for developers working on the AI Chatbot project, covering installation, setup, and development workflows.
- Node.js (v16.x or later)
- npm or yarn
- Git
-
Clone the repository:
git clone https://github.com/yourusername/ai-chatbot.git cd ai-chatbot -
Install dependencies:
npm install # or yarn install -
Set up environment variables:
cp .env.example .env.local
Edit the
.env.localfile to add any necessary API keys or configuration values. -
Start the development server:
npm run dev # or yarn dev -
Open http://localhost:3000 in your browser to see the application.
ai-chatbot/
├── app/ # Next.js app router pages
│ ├── (auth)/ # Authentication pages (login, register)
│ ├── (chat)/ # Chat application pages
│ └── layout.tsx # Root layout component
├── components/ # Reusable React components
│ ├── ui/ # UI components (buttons, inputs, etc.)
│ ├── chat.tsx # Main chat component
│ ├── message.tsx # Message component
│ ├── artifact.tsx # Artifact container component
│ ├── version-footer.tsx # Version control UI
│ └── ... # Other components
├── artifacts/ # Artifact type implementations
│ ├── text/ # Text artifact components
│ ├── image/ # Image artifact components
│ └── sheet/ # Sheet artifact components
├── hooks/ # Custom React hooks
│ ├── use-artifact.ts # Artifact state management
│ ├── use-chat-visibility.ts # Chat visibility control
│ ├── use-mobile.tsx # Mobile device detection
│ └── ... # Other hooks
├── lib/ # Utility functions and services
│ ├── ai/ # AI-related utilities and types
│ ├── services/ # API services (mock and real)
│ └── utils.ts # General utilities
├── public/ # Static assets
├── styles/ # Global styles
├── docs/ # Documentation
├── .env.example # Example environment variables
├── next.config.js # Next.js configuration
├── package.json # Dependencies and scripts
└── tsconfig.json # TypeScript configuration
-
Create the component file in the
componentsdirectory:/** * MyComponent * * Description of what this component does. * Features: * - Feature 1 * - Feature 2 */ export function MyComponent({ prop1, prop2 }: MyComponentProps) { return <div>{/* Component content */}</div>; } interface MyComponentProps { prop1: string; prop2: number; }
-
Export the component from its directory (if part of a group):
// components/index.ts export * from './MyComponent';
-
Import and use the component elsewhere:
import { MyComponent } from '@/components/MyComponent';
-
Understand the chat component hierarchy:
Chatis the main containerMessagesrenders the collection of messagesMessagerenders individual messagesMultimodalInputhandles user inputDataStreamHandlerprocesses streaming data
-
To modify message rendering, edit
components/message.tsx -
To change how messages are processed, modify
lib/services/mock-api-service.ts(for mock implementation) orlib/ai/react.ts(for general chat handling) -
To modify data streaming behavior, update
components/data-stream-handler.tsx
The artifact system uses a pluggable architecture for different content types:
-
Understanding Artifact Types:
- Artifacts are defined in
/artifacts/{type}/client.tsx - Each artifact type implements a standard interface
- Core artifact UI is in
components/artifact.tsx - State management is handled with
useArtifacthook
- Artifacts are defined in
-
Adding a New Artifact Type:
/** * My New Artifact Type * * Description of what this artifact type does. * Features: * - Feature 1 * - Feature 2 */ import { ArtifactContentProps } from '@/lib/types'; export const myNewArtifact = { kind: 'mynew', name: 'My New Artifact', description: 'Description of the new artifact type', // Optional initialization function initialize: ({ documentId, setMetadata }) => { // Set up any initial state or metadata setMetadata({ /* initial metadata */ }); }, // Component to render the content content: ({ content, onSaveContent, mode, isCurrentVersion, metadata, setMetadata, // other props... }: ArtifactContentProps) => { return <div>{/* Artifact content implementation */}</div>; }, };
-
Register the New Artifact Type:
// components/artifact.tsx import { myNewArtifact } from '@/artifacts/mynew/client'; // Add to artifact definitions export const artifactDefinitions = [ textArtifact, imageArtifact, sheetArtifact, myNewArtifact, // Add your new artifact type ];
-
Testing Your Artifact:
- Add a test trigger in the mock service
- Use specialized mock data for your artifact type
- See
docs/ARTIFACT-TESTING.mdfor detailed testing procedures
The version control system supports both API and localStorage backends:
-
Version Data Structure:
interface Document { id: string; kind: string; title: string; content: string; createdAt: Date; updatedAt: Date; userId: string; }
-
Creating New Versions:
// For API documents mutate<Array<Document>>( `/api/document?id=${artifact.documentId}`, async (currentDocuments) => { if (!currentDocuments) return undefined; // Create new version with current content await fetch(`/api/document?id=${artifact.documentId}`, { method: 'POST', body: JSON.stringify({ title: artifact.title, content: updatedContent, kind: artifact.kind, }), }); // Return updated documents array with new version const newDocument = { ...currentDocument, content: updatedContent, createdAt: new Date(), }; return [...currentDocuments, newDocument]; }, { revalidate: false }, // Prevent automatic revalidation ); // For local documents setLocalDocuments((currentDocuments) => { if (!currentDocuments) return undefined; const newDocument = { id: actualDocumentId, kind: artifact.kind, title: artifact.title, content: updatedContent, createdAt: new Date(), updatedAt: new Date(), userId: 'local-user', }; return [...currentDocuments, newDocument]; });
-
Navigating Versions:
const handleVersionChange = ( type: 'next' | 'prev' | 'toggle' | 'latest', ) => { if (!documents) return; if (type === 'latest') { setCurrentVersionIndex(documents.length - 1); setMode('edit'); } if (type === 'toggle') { setMode((mode) => (mode === 'edit' ? 'diff' : 'edit')); } if (type === 'prev') { if (currentVersionIndex > 0) { setCurrentVersionIndex((index) => index - 1); } } else if (type === 'next') { if (currentVersionIndex < documents.length - 1) { setCurrentVersionIndex((index) => index + 1); } } };
-
Debouncing Content Changes:
// Import the debounce hook import { useDebounceCallback } from 'usehooks-ts'; // Set up debounced save function const debouncedHandleContentChange = useDebounceCallback( handleContentChange, 1000, // 1 second debounce time ); // Use in your component const saveContent = (updatedContent: string, debounce: boolean) => { setIsContentDirty(true); // Show saving indicator if (debounce) { debouncedHandleContentChange(updatedContent); } else { handleContentChange(updatedContent); } };
The application uses SWR (stale-while-revalidate) for data fetching and state management:
-
Fetching Documents:
const { data: documents, mutate } = useSWR<Array<Document>>( `/api/document?id=${documentId}`, fetcher, );
-
Mutating Data:
// Update data and revalidate mutate(newData); // Update data without revalidation mutate(newData, { revalidate: false }); // Function-based updates mutate((currentData) => { // Transform current data return [...currentData, newItem]; });
-
Global State with SWR:
// In a hook const { data: state, mutate: setState } = useSWR('unique-key', null, { fallbackData: initialState, }); // Usage elsewhere setState(newState);
The application provides several custom hooks for common functionality:
-
useArtifact:
const { artifact, setArtifact, metadata, setMetadata } = useArtifact(); // Update artifact state setArtifact((current) => ({ ...current, content: newContent, })); // Update metadata setMetadata(newMetadata);
-
useArtifactSelector (for optimized rerenders):
// Only rerender when title changes const title = useArtifactSelector((state) => state.title);
-
useMobile:
const isMobile = useMobile(); return ( <div className={isMobile ? "mobile-view" : "desktop-view"}> {/* Responsive content */} </div> );
The application includes several testing commands for development:
test image artifact: Generates a sample image artifacttest text artifact: Creates a text document artifacttest sheet artifact: Produces a spreadsheet artifacttest streaming: Demonstrates streaming response capabilitiesartifact testing: Shows complete artifact testing procedures
Refer to these documents for specific aspects of the application:
PROJECT-OVERVIEW.md: High-level understanding of the systemCOMPONENT-ARCHITECTURE.md: Component relationships and structureARTIFACT-SYSTEM.md: Details of the artifact implementationVERSION-CONTROL-SYSTEM.md: Documentation for version control featuresMOCK-API-INTEGRATION.md: Details on the mock API implementationREAL-API-INTEGRATION.md: Guide for integrating real backend APIsARTIFACT-TESTING.md: Procedures for testing artifact functionality
-
Component Documentation:
- Add file description comments to every component
- Document props with JSDoc comments
- Include section comments in complex components
-
State Management:
- Use SWR for global state when possible
- Use React Context for deeply nested state
- Use local component state for UI-specific state
- Leverage custom hooks to encapsulate complex logic
-
Performance Optimization:
- Memoize expensive components with React.memo
- Use debouncing for expensive operations (like content editing)
- Implement custom equality checks for memoized components
- Create selectors for optimized state updates
-
Code Style:
- Follow existing code formatting patterns
- Use meaningful variable and function names
- Add comments for complex logic
- Maintain consistent naming conventions
-
Version Control:
- Create proper version detection checks
- Use debounced saving for content changes
- Provide clear UI indicators for version operations
- Maintain consistent behavior across storage backends