Generate a fully functional, multi-page Next.js MVP application for 'LLM Persona Lab'. This application allows users to train small Language Models (LLMs) from scratch, customize their personalities, and interact with them. The goal is to demystify how LLMs work through hands-on experimentation.
PROJECT OVERVIEW:
'LLM Persona Lab' is an educational SaaS platform that empowers users to understand the inner workings of Large Language Models (LLMs) by building, training, and customizing their own small LLMs. Users can define custom personalities for their models, making the learning process interactive and engaging. The core value proposition lies in providing an accessible, hands-on environment for learning about AI and NLP without requiring deep technical expertise or significant computational resources. It solves the problem of abstract understanding of LLMs by offering a tangible, experimental playground.
TECH STACK:
- Framework: Next.js (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- UI Components: shadcn/ui
- ORM: Drizzle ORM (with PostgreSQL or SQLite for MVP)
- Authentication: NextAuth.js (or Clerk for easier integration)
- State Management: Zustand or Jotai for global state, React Context API for local state.
- Form Handling: React Hook Form + Zod for validation
- Fetching: React Query (TanStack Query) for server state management
- Deployment: Vercel
- Optional: A simple charting library like Chart.js or Recharts for visualizing training progress.
DATABASE SCHEMA:
Primary tables:
1. `users`:
- `id` (UUID, Primary Key)
- `name` (TEXT)
- `email` (TEXT, Unique)
- `emailVerified` (TIMESTAMP)
- `image` (TEXT)
- `createdAt` (TIMESTAMP)
- `updatedAt` (TIMESTAMP)
2. `trained_models`:
- `id` (UUID, Primary Key)
- `userId` (UUID, Foreign Key to `users.id`)
- `modelName` (TEXT, e.g., 'MyFirstChatbot')
- `parameters` (JSONB, e.g., `{"paramCount": 9000000, "layerCount": 6, "hiddenSize": 512}`)
- `trainingDataSize` (INTEGER, e.g., 60000)
- `trainingTimeMinutes` (INTEGER)
- `pytorchCodeSnippet` (TEXT, ~130 lines)
- `personalityProfile` (JSONB, e.g., `{"basePersona": "witty_robot", "customTraits": {"tone": "sarcastic", "knowledgeDomain": "90s Tech", "quirks": "uses 80s slang"}}`)
- `createdAt` (TIMESTAMP)
- `updatedAt` (TIMESTAMP)
3. `training_logs` (Optional for MVP, useful for detailed progress):
- `id` (UUID, Primary Key)
- `modelId` (UUID, Foreign Key to `trained_models.id`)
- `epoch` (INTEGER)
- `loss` (REAL)
- `accuracy` (REAL)
- `timestamp` (TIMESTAMP)
Relations:
- One-to-Many: `users` to `trained_models` (A user can have multiple trained models).
- One-to-Many: `trained_models` to `training_logs` (A model can have multiple training log entries).
CORE FEATURES & USER FLOW:
1. Authentication Flow:
- User lands on the homepage.
- Clicks 'Sign Up' or 'Log In'.
- Redirected to NextAuth.js provider (e.g., Google, GitHub, Email/Password).
- Upon successful authentication, redirected to the Dashboard.
- Protected routes (Dashboard, Model Training, My Models) require authentication.
2. Dashboard:
- Displays a welcome message.
- Shows a summary of the user's existing trained models (name, status, last active).
- Provides quick links to 'Train New Model' and 'My Models'.
- Might include a featured learning resource or tutorial.
3. Train New Model Page:
- User Interface (UI) for configuring a new LLM.
- **Model Configuration Form:**
- `modelName` (Input, e.g., 'My Creative Writer')
- `parameterCount` (Slider/Input, default ~9M, adjustable range, e.g., 1M-50M)
- `trainingDataSize` (Slider/Input, default 60K, adjustable range, e.g., 10K-100K synthetic conversations)
- `trainingTimeEstimate` (Display based on params, e.g., '~5 mins on T4 GPU')
- `personalityPreset` (Dropdown: 'Default Transformer', 'Witty Robot', 'Wise Mentor', 'Sarcastic AI', etc.)
- `customTraits` (Optional fields: `tone`, `knowledgeDomain`, `quirks` - Text inputs)
- **'Start Training' Button:**
- On click, initiates a backend process (simulated or actual if infrastructure allows).
- Displays a loading indicator and estimated time.
- User can navigate away; training continues in the background (or provides real-time updates if feasible).
- **Backend:** API route `/api/train` receives configuration, potentially triggers a background job, stores config in DB.
4. My Models Page:
- Lists all models trained by the user.
- Each model entry shows: Name, Status (Training, Ready, Error), Parameters, Training Data Size, Date Created.
- Actions per model: 'Chat', 'Edit Personality', 'View Details', 'Delete'.
5. Model Chat Interface:
- Accessed by clicking 'Chat' on a trained model.
- Displays the chat history.
- Input field for user messages.
- Send button.
- **Backend:** API route `/api/chat/{modelId}` receives user message, queries the LLM (or simulated response based on `personalityProfile`), returns LLM response.
- **Response Handling:** Displays the LLM's response in the chat interface.
6. Learning Resources Section:
- Simple page with articles/links explaining:
- What is an LLM?
- Transformer Architecture Basics
- Parameters vs. Training Data
- The Role of Personality in LLMs
- PyTorch basics (optional)
API & DATA FETCHING:
- `POST /api/auth/*`: Handled by NextAuth.js.
- `POST /api/models`: Create a new model configuration. Request Body: `{ modelName, parameterCount, trainingDataSize, personalityPreset, customTraits }`. Response: `{ modelId, status: 'TRAINING' }`.
- `GET /api/models`: Fetch list of user's models. Response: `[{ id, modelName, status, parameters, trainingDataSize, createdAt }, ...]`. Uses React Query for caching.
- `GET /api/models/{modelId}`: Fetch details of a specific model. Response: `{ ...modelDetails }`. Uses React Query.
- `POST /api/models/{modelId}/chat`: Send message to a trained model. Request Body: `{ message }`. Response: `{ reply }`. Uses React Query mutations.
- `DELETE /api/models/{modelId}`: Delete a model.
- Data Flow: Components use `useQuery` (GET) and `useMutation` (POST/DELETE) from React Query to interact with API routes. Server components can fetch initial data directly.
UI/UX DESIGN & VISUAL IDENTITY:
- Style: Minimalist Clean with subtle AI/tech-inspired elements.
- Color Palette:
- Primary: `#1E40AF` (Deep Blue)
- Secondary: `#3B82F6` (Bright Blue)
- Accent: `#6366F1` (Indigo/Purple for highlights)
- Background: `#F9FAFB` (Light Gray)
- Text: `#1F2937` (Dark Gray)
- Card/Element Background: `#FFFFFF` (White)
- Typography:
- Headings: Inter (Semi-bold)
- Body Text: Inter (Regular)
- Layout:
- Sidebar navigation for core sections (Dashboard, Train, My Models, Learn).
- Main content area displays page-specific information.
- Clean cards for displaying model information.
- Focus on clear calls to action.
- Responsiveness:
- Mobile-first approach. Sidebar collapses into a hamburger menu on smaller screens.
- Flexbox and Grid for layout.
- Ensure readability and usability across all device sizes.
- Animations:
- Subtle fade-ins for content loading.
- Smooth transitions for route changes.
- Loading spinners/skeletons for data fetching.
- Hover effects on buttons and interactive elements.
COMPONENT BREAKDOWN (Next.js App Router structure):
- `app/
- (auth)
- layout.tsx (Auth layout)
- page.tsx (Sign In/Sign Up options)
- (marketing)
- layout.tsx (Marketing layout)
- page.tsx (Homepage/Landing Page)
- (app)
- layout.tsx (Main App layout with sidebar)
- dashboard
- page.tsx (Dashboard component)
- train
- page.tsx (Model Training configuration page)
- models
- page.tsx (List of user's models)
- [modelId]
- page.tsx (Chat interface for a specific model)
- details
- page.tsx (Model details page)
- learn
- page.tsx (Learning resources page)
- api
- auth
- [...nextauth]
- route.ts (NextAuth.js handler)
- models
- route.ts (Handles GET /api/models, POST /api/models)
- [modelId]
- route.ts (Handles GET /api/models/[modelId], DELETE /api/models/[modelId])
- chat
- route.ts (Handles POST /api/models/[modelId]/chat)
- components/
- ui/
- Card.tsx, Button.tsx, Input.tsx, Label.tsx, etc. (shadcn/ui components)
- layout/
- Sidebar.tsx, Navbar.tsx, Footer.tsx
- features/
- ModelCard.tsx, TrainingForm.tsx, ChatWindow.tsx, LearningResource.tsx
- common/
- LoadingSpinner.tsx, ErrorMessage.tsx, DataTable.tsx
State Management:
- Global State (Zustand/Jotai): User authentication status, potentially UI theme.
- Server State (React Query): All data fetched from the backend (models list, model details, chat history).
- Local Component State: Form inputs, UI element states (e.g., dropdown open/closed), chat input buffer.
ANIMATIONS:
- Page transitions: `Framer Motion` for smooth entry/exit animations on route changes.
- Loading States: `Tailwind CSS` animations for spinners, `react-loading-skeleton` for content placeholders.
- UI Elements: Subtle `hover` effects on buttons, links, and cards using Tailwind's default transitions and `group-hover` utilities.
- Chat Interface: Smooth scrolling to the bottom as new messages appear.
EDGE CASES:
- **Authentication:** Redirect unauthenticated users to the login page. Handle expired sessions.
- **Empty States:** Display user-friendly messages and clear calls to action on pages with no data (e.g., 'No models trained yet. Start training your first LLM!').
- **Form Validation:** Use Zod with React Hook Form to validate all user inputs on the training form (e.g., model name required, parameter count within range). Display clear error messages next to fields.
- **Training Process:** Simulate training progress if actual backend execution is not feasible for MVP. Provide clear feedback on training status (STARTING, PROGRESS, SUCCESS, FAILED). Handle potential backend errors gracefully.
- **API Errors:** Implement global error handling for API requests. Display user-friendly error messages (e.g., 'Failed to load models. Please try again later.').
- **Model Interaction:** Handle cases where the LLM might return empty or nonsensical responses. Implement basic filtering or retry mechanisms if necessary.
- **Rate Limiting:** (Future consideration) Implement rate limiting on API endpoints to prevent abuse.
SAMPLE DATA (for frontend mocking and initial DB state):
1. User:
```json
{
"id": "user-1234-abcd",
"name": "Alice Wonderland",
"email": "alice@example.com",
"image": "/images/alice.jpg"
}
```
2. Trained Model (Ready):
```json
{
"id": "model-a1b2-c3d4",
"userId": "user-1234-abcd",
"modelName": "Curious CatBot",
"parameters": {"paramCount": 9500000, "layerCount": 7, "hiddenSize": 512},
"trainingDataSize": 65000,
"trainingTimeMinutes": 6,
"personalityProfile": {"basePersona": "curious_cat", "customTraits": {"tone": "inquisitive", "knowledgeDomain": "Physics", "quirks": "Often asks 'why?'"}},
"status": "READY",
"createdAt": "2023-10-26T10:00:00Z"
}
```
3. Trained Model (Training):
```json
{
"id": "model-e5f6-g7h8",
"userId": "user-1234-abcd",
"modelName": "Story Weaver",
"parameters": {"paramCount": 12000000, "layerCount": 8, "hiddenSize": 576},
"trainingDataSize": 80000,
"trainingTimeMinutes": 9,
"personalityProfile": {"basePersona": "creative_writer", "customTraits": {"tone": "imaginative", "knowledgeDomain": "Fantasy", "quirks": "Uses metaphors frequently"}},
"status": "TRAINING",
"createdAt": "2023-10-27T11:00:00Z"
}
```
4. Chat Message (User):
```json
{
"role": "user",
"content": "Can you explain quantum entanglement in simple terms?"
}
```
5. Chat Message (LLM Reply):
```json
{
"role": "assistant",
"content": "Imagine you have two linked coins. If one lands heads, you instantly know the other is tails, no matter how far apart they are! It's like they're spooky twins, connected by a hidden rule. Why? Well, that's the really deep question!"
}
```
6. Learning Resource:
```json
{
"id": "lr-001",
"title": "Understanding Transformer Models",
"summary": "A brief overview of the transformer architecture, the backbone of modern LLMs.",
"url": "/learn/transformers",
"tags": ["AI", "NLP", "Transformers"]
}
```
7. Empty Model List State:
```html
<div class="text-center py-10">
<h3 class="text-lg font-semibold mb-2">No Models Yet!</h3>
<p class="text-gray-600 mb-4">Your trained models will appear here. Ready to build your first AI personality?</p>
<Button>Train Your First Model</Button>
</div>
```
8. Training Form Initial State:
```json
{
"modelName": "",
"parameterCount": 9000000,
"trainingDataSize": 60000,
"personalityPreset": "default",
"customTraits": {"tone": "", "knowledgeDomain": "", "quirks": ""}
}
```
9. Mock Personality Trait (User Input):
```json
{
"tone": "sarcastic",
"knowledgeDomain": "1980s Sci-Fi Movies",
"quirks": "Often references 'Blade Runner'. Ends sentences with 'Affirmative.'"
}
```
10. Mock Training Log Entry:
```json
{
"epoch": 100,
"loss": 0.15,
"accuracy": 0.92,
"timestamp": "2023-10-27T11:30:00Z"
}
```