Skip to content

aahalani/streaming

Repository files navigation

AI-Thinking Simulator

A Next.js application that provides an interactive learning experience through AI-generated content with real-time streaming, fill-in-the-blank exercises, and contextual Q&A support.

🎯 Overview

This project creates an interactive learning experience where AI explanations are streamed character-by-character, with periodic fill-in-the-blank questions and contextual chat support. Students can ask questions about any part of the explanation through expandable accordions.

The current implementation focuses on coding explanations (specifically a Python function example), but the system is designed to be flexible for various educational content.

✨ Features

  • Real-time Text Streaming: AI explanations appear with a typewriter effect.
  • Interactive Blanks: Students fill in missing information during explanations.
  • Contextual Q&A: Chat system that understands the current explanation context.
  • Clean Architecture: Core streaming logic is separated into a reusable React hook (useTextStreamer).
  • Component-Based UI: The interface is broken down into modular, maintainable components.
  • User Authentication: Secure login system with session management.
  • Responsive Design: Clean, dark-themed interface optimized for learning.

πŸš€ Quick Start

Prerequisites

  • Node.js 18+
  • pnpm (recommended) or npm
  • PostgreSQL database
  • DeepSeek API key

Setup Instructions

  1. Install dependencies:

    pnpm install
  2. Configure environment variables: Create a .env.local file in the root directory:

    DEEPSEEK_API_KEY=your_deepseek_api_key_here
    DATABASE_URL=postgresql://username:password@localhost:5432/database_name
  3. Database Setup: Use a local or cloud-based PostgreSQL instance (e.g., Supabase, Neon). Update the DATABASE_URL with your connection string.

  4. Initialize Database: Generate and apply the database schema.

    npx drizzle-kit generate
    npx drizzle-kit push
  5. Start development server:

    pnpm dev
  6. Access the application:

πŸ“ Project Structure

The project follows a clean, feature-oriented structure.

Key Directories

  • app/: Contains all routes and API endpoints.
    • app/streaming/page.tsx: The main page component for the learning interface.
    • app/api/: Server-side logic for AI generation, authentication, and data access.
  • components/: Reusable React components.
    • components/streaming/: Components specific to the streaming interface.
  • hooks/: Custom React hooks for shared logic.
    • hooks/useTextStreamer.ts: The core hook managing the text streaming animation and state.
  • lib/: Shared utilities, like database connection and helpers.
  • drizzle/: Database migration files generated by Drizzle ORM.

Component Structure

components/ └── streaming/ # Streaming-specific components β”œβ”€β”€ ModernBlankInput.tsx # Fill-in-the-blank UI β”œβ”€β”€ ChatAccordion.tsx # Q&A chat interface β”œβ”€β”€ ModernAIOutputDisplay.tsx # Final AI answer display └── PerformanceSummary.tsx # Student progress tracking

πŸ”§ Key Implementation Details

Core Logic: The useTextStreamer Hook

All the complex, low-level logic for text streaming is encapsulated in the hooks/useTextStreamer.ts custom hook. This keeps the main page component clean and focused on high-level state management.

The hook is responsible for:

  • Processing the source text and detecting BLANK(...) and paragraph breaks.
  • Managing timers for the character-by-character "typing" animation.
  • Signaling to the parent component when user interaction (feedback or a blank input) is required.
  • Providing simple functions (injectIntoStream, completeParagraph, resetStream) for the parent to control the stream's flow.

Main Page: app/streaming/page.tsx

This file serves as the main controller for the learning experience. It uses the useTextStreamer hook and is responsible for:

  • Fetching question data from the API.
  • Managing high-level application state (current question, completed content, etc.).
  • Handling user events (e.g., submitting an answer, asking a question in the chat).
  • Rendering the appropriate UI components based on the state from the hook and the application.

API Integration

The app/api/generate/route.ts file handles all communication with the DeepSeek API for context-aware chat responses.

Content Format

AI explanations use BLANK(answer) placeholders for interactive elements:

The function should return BLANK(-1) if the value is not found. The difference between the max and min keys is BLANK(6).

Animation Configuration

Key timing constants are defined in hooks/useTextStreamer.ts:

const TYPING_INTERVAL_MS = 20;      // Time between typing intervals
const CHARS_PER_TYPE_INTERVAL = 3; // Characters rendered per interval

πŸ—„οΈ Database

The project uses Drizzle ORM to interact with a PostgreSQL database.

Schema: schema.ts - Defines the users, questions, and logs tables.

Database Client: lib/db.ts - Manages the database connection.

Migrations: Stored in the drizzle/ directory.

Available Commands

# Generate a new migration file based on schema changes
pnpm db:generate

# Push schema changes directly to the database (for development)
pnpm db:push

# Run all pending migrations
pnpm db:migrate

# Open Drizzle Studio to view and manage your data
pnpm db:studio

πŸš€ Deployment

Environment Variables for Production

Ensure these variables are set in your deployment environment:

DEEPSEEK_API_KEY=your_production_api_key
DATABASE_URL=your_production_database_url
NEXTAUTH_SECRET=your_secure_random_string # Generate with `openssl rand -base64 32`
NODE_ENV=production

πŸ” Development Notes

Adding New Questions

Insert a new row into the questions table in your database:

INSERT INTO questions (question, content) VALUES (
  'Your question title',
  'Your explanation content with BLANK(answer) placeholders...'
);

The new question will automatically be available in the application.

Customizing The Experience

To change the streaming speed, adjust the constants in hooks/useTextStreamer.ts.

To modify the UI, edit the components in components/streaming/.

To add new interactions, extend the useTextStreamer hook and the StreamingPage component.


Note: This project was developed by Avval Halani. Please feel free to contact me with any questions.

πŸš€ Quick Start

Prerequisites

  • Node.js 18+
  • pnpm (recommended) or npm
  • PostgreSQL database
  • DeepSeek API key

Setup Instructions

  1. Install dependencies:

    pnpm install
  2. Configure environment variables: Create .env.local in the root directory:

    DEEPSEEK_API_KEY=your_deepseek_api_key_here
    DATABASE_URL=postgresql://username:password@localhost:5432/database_name
  3. Database Setup:

    Option A: Local PostgreSQL Setup

    Install PostgreSQL locally and create a database:

    # Update DATABASE_URL in .env.local
    DATABASE_URL=postgresql://username:password@localhost:5432/streaming_app

    Option B: Cloud Database (Recommended)

    Use a cloud provider like:

    • Supabase (free tier available)
    • Neon (serverless postgres)

    Example with Supabase:

    1. Create account at supabase.com
    2. Create new project
    3. Copy connection string from Settings > Database
    4. Update .env.local:
    DATABASE_URL=postgresql://postgres:[password]@[host].supabase.co:5432/postgres
  4. Initialize Database:

    # Generate and run migrations
    npx drizzle-kit generate
    npx drizzle-kit push
    
    # Or use the migration command
    pnpm db:migrate
  5. Seed Database (Optional):

    Add sample questions to your database:

    # You can manually insert data or create a seed script
    # Example questions are provided in the schema comments
  6. Start development server:

    pnpm dev
  7. Access the application:

First-Time Setup Checklist

When setting up the project on a new machine:

  • Install PostgreSQL or setup cloud database
  • Create .env.local with correct DATABASE_URL
  • Run pnpm install to install dependencies
  • Run pnpm db:reset to create database tables
  • Create your first user account through the application
  • Add questions to the database
  • Start development with pnpm dev

πŸ—„οΈ Database Schema

The application uses the following database tables:

Users Table

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL,
  email VARCHAR(255) NOT NULL UNIQUE,
  password TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT now()
);

Questions Table

CREATE TABLE questions (
  id SERIAL PRIMARY KEY,
  question TEXT NOT NULL,
  content TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT now()
);

Logs Table

CREATE TABLE logs (
  id SERIAL PRIMARY KEY,
  user_id TEXT,
  action TEXT NOT NULL,
  details JSONB DEFAULT '{}'::jsonb,
  level TEXT NOT NULL,
  timestamp TIMESTAMP WITH TIME ZONE DEFAULT now()
);

Sample Data

Example question entry:

INSERT INTO questions (question, content) VALUES (
  'Explain the identical function',
  'Let me walk you through this step by step...\n\nThe `identical` function takes two parameters: a dictionary `d` and a value `val`...'
);

πŸ”§ Database Management

Drizzle ORM Configuration

The project uses Drizzle ORM with the following configuration:

  • Schema: schema.ts - Database schema definitions
  • Database client: lib/db.ts - Database connection
  • Migrations: drizzle/ - Auto-generated migration files

Available Commands

# Generate new migration
pnpm db:generate

# Push schema changes to database
pnpm db:push

# Run migrations
pnpm db:migrate

# View database in Drizzle Studio
pnpm db:studio

# Reset database (drops all data and recreates tables)
pnpm db:reset

Database Reset

The reset command completely wipes your database and recreates all tables with the proper schema:

# Reset database - WARNING: This deletes ALL data
pnpm db:reset

What the reset does:

  • βœ… Drops all existing tables (users, questions, logs)
  • βœ… Recreates empty tables with proper schema
  • βœ… Creates necessary indexes for performance
  • ❌ Does NOT insert sample data - you start with clean, empty tables

When to use reset:

  • Setting up the project for the first time
  • Switching to a new database
  • During development when you need to start fresh
  • After major schema changes

⚠️ Warning: This command will delete ALL data in your database. Make sure you have backups of any important data before running it.

Switching Databases

To use a different database:

  1. Update environment variables:

    DATABASE_URL=postgresql://new_username:new_password@new_host:5432/new_database
  2. Run migrations:

    npx drizzle-kit push
  3. Seed with sample data (if needed)

πŸ“ Key File Locations

Core Application Files

Component Structure

components/
β”œβ”€β”€ streaming/          # Streaming-specific components
β”‚   β”œβ”€β”€ BlankInput      # Fill-in-the-blank interactions
β”‚   β”œβ”€β”€ ChatAccordion   # Q&A chat interface
β”‚   β”œβ”€β”€ ParagraphFeedback # Feedback collection
β”‚   β”œβ”€β”€ PerformanceSummary # Student progress tracking
β”‚   └── TextRenderer   # Markdown text display
└── ui/                # Reusable UI components (shadcn/ui)
    └── accordion.tsx  # Base accordion component

πŸ”§ Key Implementation Details

Main Logic Location

All core functionality is in app/streaming/page.tsx:

  • Text streaming with typewriter effect
  • Blank detection and handling (BLANK(answer) format)
  • Chat accordion management
  • Performance tracking
  • User authentication checks
  • Activity logging

API Integration

The app/api/generate/route.ts file handles:

  • DeepSeek API integration
  • Context-aware chat responses
  • User authentication verification
  • Request/response logging
  • Error handling and fallbacks

Authentication System

Logging System

The application logs all user interactions:

  • User actions: Question navigation, feedback, responses
  • AI interactions: Requests, responses, errors
  • Authentication: Login attempts, successes, failures
  • Performance: Response times, error rates

Content Format

AI explanations use BLANK(answer) placeholders for interactive elements:

The function should return BLANK(-1) if val is not found...
The difference between max and min keys is BLANK(6)...

Animation Configuration

Key timing constants in app/streaming/page.tsx:

const TYPING_INTERVAL_MS = 100; // Speed between typing intervals
const CHARS_PER_TYPE_INTERVAL = 30; // Characters per interval
const ANIMATION_CHARS_PER_SECOND = 30; // Animation speed
const FEEDBACK_DURATION_MS = 1500; // Feedback display time

πŸš€ Deployment

Environment Variables for Production

DEEPSEEK_API_KEY=your_production_api_key
DATABASE_URL=your_production_database_url
NEXTAUTH_SECRET=your_secure_random_string
NODE_ENV=production

πŸ” Development Notes

Adding New Questions

  1. Insert into database:

    INSERT INTO questions (question, content) VALUES (
      'Your question title',
      'Your explanation content with BLANK(answer) placeholders...'
    );
  2. Questions automatically appear in the application

Customizing Logging

Modify lib/logger.ts to:

  • Add new log levels
  • Change log format
  • Add custom fields
  • Integrate with external services

Performance Monitoring

Check the logs table for:

  • User engagement metrics
  • AI response performance
  • Error patterns
  • Feature usage statistics

Note: This project was developed by Avval Halani. Please feel free to contact me for any questions.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors