Skip to content

Repository files navigation

Frontend for REID Lab Research

A survey collection client. It supports two chat modes ("One-Shot" and "Conversational"), keeps API keys server-side behind provider modules, and syncs user sessions to a PostgreSQL database as they go.

How it fits together

graph TD
    User([User Browser]) -->|1. Consent on Welcome page| Welcome[Welcome Page]
    Welcome -->|2. Academic Details| Ident[Identification Page]
    Ident -->|3. View Rules| Instructions[Instructions Page]
    Instructions -->|4. Unlock Chat| MainUI[Chat Workspace]
    
    MainUI -->|5. Toggle Tabs| ModeSwitch{Tab Mode?}
    ModeSwitch -->|One-Shot| OneShot[One-Shot Chat: Disabled input after 1st query]
    ModeSwitch -->|Conversational| Conversational[Conversational Chat: Multi-turn]
    
    OneShot -->|6. Send Message| ChatStream[SSE Chat Stream]
    Conversational -->|6. Send Message| ChatStream
    
    ChatStream -->|7. POST /api/chat| FastAPIServer[FastAPI Proxy Server]
    FastAPIServer -->|8. Call Provider Services| ProviderService[LLM Service Orchestrator]
    ProviderService -->|9. Forward SSE Stream| Providers[Gemini, ChatGPT, DeepSeek, or Claude APIs]
    Providers -->|10. Relay Chunks| FastAPIServer
    FastAPIServer -->|11. Render Markdown Chunks| User
    
    User -->|12. POST /api/sync| SyncAPI[FastAPI Sync Route]
    SyncAPI -->|13. Verify & Create Table| PostgresDB[(PostgreSQL Database)]
    PostgresDB -->|14. Upsert ON CONFLICT| PostgresDB
Loading

What's in here

Onboarding Users go through welcome → identification → instructions → chat, each its own FastAPI route with guards so you can't skip ahead to the chat window. We hash the (lowercased) Penn State ID with SHA-256 to identify each survey response. Progress gets saved to local storage so a refresh doesn't wipe out someone's session, and the major field autocompletes against a list of Penn State engineering majors.

Two chat modes One-Shot locks the input after a single message goes out; no follow-ups. Conversational is just normal multi-turn chat. You can flip between the two tabs without losing what's already been typed in either one.

Provider layer Chat, survey, and page routes are split into their own FastAPI routers rather than one giant file. Each model provider (Gemini, OpenAI, DeepSeek, Anthropic) lives in its own module, and if a given API key isn't set, that provider just falls back gracefully instead of breaking things.

Database sync database.py handles the connection pool and makes sure tables exist. Sessions get upserted (ON CONFLICT DO UPDATE) so Postgres stays current as people use the app.

Copy in one place All the UI text headings, rules, labels, placeholders lives in strings.json, so you can tweak wording without touching any markup.

Mobile-friendly Tuned viewport and touch targets, since most people are hitting this from a QR code on a poster.

Getting started

1. Set up your .env

GEMINI_API_KEY=your_gemini_api_key
OPENAI_API_KEY=your_openai_api_key
DEEPSEEK_API_KEY=your_deepseek_api_key
ANTHROPIC_API_KEY=your_anthropic_api_key
DATABASE_URL=postgresql://username:password@host.docker.internal:5432/database_name

2. Build and run with Docker

# Build the image
docker build -t gemini-chat-client .

# Run the container
docker run -d \
  --name gemini-chat-container \
  -p 8080:8080 \
  --env-file .env \
  -v $(pwd):/usr/src/app \
  gemini-chat-client

Then just open http://localhost:8080.

About

A human-centric LLM inferencing survey frontend for REID Lab.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages